/* ==========================================================================
   MZ Construction Management — site stylesheet
   Design system: stark black / concrete white, hi-vis amber accent.
   Sections:  1 tokens · 2 reset · 3 layout · 4 type · 5 motion engine
              6 buttons · 7 header · 8 texture · 9 hero · 10 stats
              11 cards · 12 projects · 13 filters · 14 process · 15 sectors
              16 marquee · 17 CTA · 18 contact · 19 footer · 20 responsive
   Edit tokens in :root to reskin the whole site.
   ========================================================================== */

/* ---------- 1. Tokens ---------------------------------------------------- */
:root{
  /* Colour */
  --ink:        #0A0A0A;   /* brand black                       */
  --ink-2:      #121212;   /* raised dark surface               */
  --ink-3:      #242424;   /* dark hairlines                    */
  --paper:      #FFFFFF;
  --concrete:   #F4F3F0;   /* warm off-white section band       */
  --concrete-2: #E5E3DE;
  --steel:      #4F4F55;   /* body text on light                */
  --steel-2:    #86868A;   /* muted / captions                  */
  --line:       #DEDCD7;
  --line-dark:  rgba(255,255,255,.12);
  --hi:         #FFB000;   /* hi-vis amber                      */
  --hi-deep:    #E09400;

  /* Layout */
  --max:  1280px;
  --gut:  clamp(20px, 5vw, 68px);
  --sect: clamp(72px, 9.5vw, 140px);

  /* Header — fixed, so every hero has to reserve its height. Both values are
     read by .hero--home / .hero--page and by the mobile drawer's offset. */
  --head-h:       86px;
  --head-h-stuck: 72px;

  /* Elevation — a construction site is lit from above; shadows are long,
     soft and slightly warm rather than the default neutral grey blur. */
  --sh-1: 0 2px 8px -4px rgba(20,16,8,.28);
  --sh-2: 0 18px 40px -26px rgba(20,16,8,.45);
  --sh-3: 0 34px 70px -34px rgba(20,16,8,.5);
  --sh-hi: 0 16px 34px -20px rgba(224,148,0,.55);

  /* Type — mono carries every technical annotation, which is what makes the
     site read as a construction document rather than a brochure */
  --f-display: "Archivo", "Helvetica Neue", Arial, sans-serif;
  --f-body:    "Inter", "Helvetica Neue", Arial, sans-serif;
  --f-mono:    "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  /* Motion — expo-out reads as "premium"; io for symmetric moves */
  --e-out: cubic-bezier(.16, 1, .3, 1);
  --e-io:  cubic-bezier(.65, 0, .35, 1);
  --ease:  var(--e-out);
}

/* ---------- 2. Reset ----------------------------------------------------- */
*,*::before,*::after{ box-sizing:border-box; }
html{ -webkit-text-size-adjust:100%; scroll-behavior:smooth; }
body{
  margin:0;
  background:var(--paper);
  color:var(--ink);
  font-family:var(--f-body);
  font-size:17px;
  line-height:1.65;
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}
img,svg{ max-width:100%; display:block; }
a{ color:inherit; }
button{ font:inherit; color:inherit; }
h1,h2,h3,h4{ margin:0; font-family:var(--f-display); font-weight:800; }
p{ margin:0; }
ul{ margin:0; padding:0; list-style:none; }

:focus-visible{ outline:3px solid var(--hi); outline-offset:3px; }
[hidden]{ display:none !important; }   /* beats .proj{display:flex} when filtering */

/* Highlighting text should feel like a marker passing over a drawing, not
   like the OS default blue landing on a black-and-amber page. */
::selection{ background:var(--hi); color:var(--ink); text-shadow:none; }
::-moz-selection{ background:var(--hi); color:var(--ink); text-shadow:none; }

/* The scrollbar is on screen the entire visit, so it gets the same treatment
   as everything else: a hairline gutter with an amber slug running in it. */
@supports (scrollbar-width: thin){
  html{ scrollbar-width:thin; scrollbar-color:var(--concrete-2) transparent; }
}
::-webkit-scrollbar{ width:11px; height:11px; }
::-webkit-scrollbar-track{ background:var(--concrete); }
::-webkit-scrollbar-thumb{
  background:var(--concrete-2); border:3px solid var(--concrete);
  transition:background .3s var(--e-out);
}
::-webkit-scrollbar-thumb:hover{ background:var(--hi-deep); }

/* Numerals in tabular contexts (phone numbers, counts, coordinates) should
   never jitter as they change */
.h1,.h2,.tel{ font-variant-numeric:tabular-nums; }

/* Every anchor target has to clear the sticky header — and that header
   shrinks once you scroll, which changes document height mid-jump, so the
   margin is set generously rather than to the exact header height. */
[id]{ scroll-margin-top:clamp(118px, 15vh, 152px); }

.skip{
  position:absolute; left:-9999px; top:0; z-index:300;
  background:var(--ink); color:#fff; padding:14px 20px; font-weight:600;
}
.skip:focus{ left:0; }

/* Visible to screen readers only — used for table captions that would be
   redundant on screen but give the table an accessible name. */
.sr-only{
  position:absolute; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0;
}

/* Film grain — a whisper of texture so flat black reads as a surface */
/* No mix-blend-mode: a viewport-sized blended layer forces the browser to
   re-blend the whole screen on every scrolled frame. Plain opacity composites
   once and then just rides along. */
body::after{
  content:""; position:fixed; inset:0; z-index:190; pointer-events:none;
  opacity:.035;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='140' height='140'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/></filter><rect width='140' height='140' filter='url(%23n)'/></svg>");
}

/* Scroll progress rail */
.progress{
  position:fixed; top:0; left:0; right:0; height:3px; z-index:200;
  transform:scaleX(0); transform-origin:0 50%;
  background:linear-gradient(90deg, var(--hi), var(--hi-deep));
  will-change:transform;
}

/* ==========================================================================
   2a. INTRO — the sheet is issued before it is read
   Shown once per browser session, skipped entirely under reduced motion, and
   impossible to get stuck behind: main.js removes it on a hard timeout.
   ========================================================================== */
.intro{
  position:fixed; inset:0; z-index:400; background:var(--ink); color:#fff;
  display:grid; place-content:center; justify-items:center; gap:26px;
  padding:var(--gut);
  transition:transform 1s var(--e-out), opacity .6s var(--e-out);
}
.intro-done .intro{ transform:translateY(-101%); opacity:0; pointer-events:none; }
.intro img{ width:88px; opacity:.92; }
.intro-line{
  width:min(300px, 62vw); height:1px; background:rgba(255,255,255,.18); position:relative;
}
.intro-line i{
  position:absolute; inset:0; background:var(--hi);
  transform:scaleX(0); transform-origin:0 50%;
  animation:issue 1.25s var(--e-io) .18s forwards;
}
@keyframes issue{ to{ transform:scaleX(1); } }
.intro-meta{
  display:flex; justify-content:space-between; width:min(300px, 62vw);
  font-family:var(--f-mono); font-weight:500; font-size:10px;
  letter-spacing:.22em; text-transform:uppercase; color:rgba(255,255,255,.5);
}
.intro-meta b{ color:var(--hi); font-weight:500; font-variant-numeric:tabular-nums; }
/* Nothing may sit above the intro while it is on screen */
.intro-active .site-head,
.intro-active .sheet-rail,
.intro-active .progress{ opacity:0; transition:opacity .4s var(--e-out); }

/* ==========================================================================
   2c. SURVEYING RETICLE — the hero reads the pointer like an instrument
   ========================================================================== */
.reticle{
  position:absolute; inset:0; z-index:2; pointer-events:none;
  opacity:0; transition:opacity .45s var(--e-out);
}
.hero.is-tracking .reticle{ opacity:1; }
.reticle i{ position:absolute; background:rgba(255,176,0,.3); display:block; }
.reticle .rx{ top:0; bottom:0; width:1px; left:0; transform:translateX(var(--rx,50%)); }
.reticle .ry{ left:0; right:0; height:1px; top:0; transform:translateY(var(--ry,50%)); }
.reticle b{
  position:absolute; left:0; top:0;
  transform:translate(calc(var(--rx,0px) + 16px), calc(var(--ry,0px) + 14px));
  font-family:var(--f-mono); font-weight:500; font-size:10px; letter-spacing:.16em;
  color:var(--hi); white-space:nowrap; font-variant-numeric:tabular-nums;
}

/* ==========================================================================
   2b. SHEET RAIL — which sheet am I on
   Colour is switched by JS (.on-dark) rather than mix-blend-mode: a fixed
   blended layer has to be re-composited against whatever scrolls beneath it,
   which is one of the cheapest ways to make a page stutter.
   ========================================================================== */
.sheet-rail{
  position:fixed; right:22px; top:50%; transform:translateY(-50%); z-index:95;
  display:grid; gap:15px; pointer-events:auto;
}
.sheet-rail a{
  display:flex; align-items:center; justify-content:flex-end; gap:10px;
  text-decoration:none; color:var(--ink); opacity:.42;
  font-family:var(--f-mono); font-weight:500; font-size:10px; letter-spacing:.14em;
  transition:opacity .45s var(--e-out), color .4s var(--e-out);
}
.sheet-rail a i{
  display:block; width:12px; height:1px; background:var(--ink);
  transition:width .55s var(--e-out), background .4s var(--e-out);
}
.sheet-rail.on-dark a{ color:#fff; }
.sheet-rail.on-dark a i{ background:#fff; }
.sheet-rail a em{
  font-style:normal; text-transform:uppercase; letter-spacing:.16em;
  max-width:0; overflow:hidden; white-space:nowrap; opacity:0;
  transition:max-width .55s var(--e-out), opacity .45s var(--e-out);
}
.sheet-rail a:hover{ opacity:1; }
.sheet-rail a:hover em{ max-width:12ch; opacity:1; }
.sheet-rail a.is-current{ opacity:1; }
.sheet-rail a.is-current i{ width:30px; }
@media (max-width:1180px){ .sheet-rail{ display:none; } }
/* It is a scroll indicator driven entirely by script, and its light/dark
   switching is too — with no JS it would sit dark-on-dark, so hide it. */
html:not(.js) .sheet-rail{ display:none; }

/* ==========================================================================
   2d. PAGE TRANSITIONS
   Browsers that support cross-document view transitions cross-fade between
   pages instead of flashing white. Everywhere else this block is inert and
   navigation behaves exactly as it always has.
   ========================================================================== */
@view-transition{ navigation:auto; }
::view-transition-old(root){ animation:vtOut .3s var(--e-io) both; }
::view-transition-new(root){ animation:vtIn .42s var(--e-out) both; }
@keyframes vtOut{ to{ opacity:0; } }
@keyframes vtIn{ from{ opacity:0; transform:translateY(12px); } }
@media (prefers-reduced-motion:reduce){
  ::view-transition-old(root),
  ::view-transition-new(root){ animation:none; }
}

/* ---------- 3. Layout helpers -------------------------------------------- */
.wrap{ width:100%; max-width:var(--max); margin-inline:auto; padding-inline:var(--gut); }
.section{ padding-block:var(--sect); position:relative; }
.section--tight{ padding-block:clamp(52px,6.5vw,88px); }
.dark{ background:var(--ink); color:#fff; }
.dark p, .dark li{ color:rgba(255,255,255,.72); }
.band{ background:var(--concrete); }

/* Drafting paper: a faint grid plus a ruled sheet edge, so the light
   sections read as printed drawings rather than as blank slides */
.paper{
  position:relative;
  background-image:
    linear-gradient(rgba(10,10,10,.026) 1px, transparent 1px),
    linear-gradient(90deg, rgba(10,10,10,.026) 1px, transparent 1px);
  background-size:38px 38px;
}
.band.paper{ background-color:var(--concrete); }
.paper::before{
  content:""; position:absolute; top:0; left:0; right:0; height:8px;
  background-image:repeating-linear-gradient(90deg, var(--line) 0 1px, transparent 1px 24px);
  pointer-events:none;
}
.paper > *{ position:relative; }

.grid{ display:grid; gap:clamp(22px,2.6vw,34px); }
.g-2{ grid-template-columns:repeat(2,1fr); }
.g-3{ grid-template-columns:repeat(3,1fr); }
.g-4{ grid-template-columns:repeat(4,1fr); }

.lede{
  display:grid; gap:clamp(20px,4vw,64px);
  grid-template-columns:minmax(0,1fr) minmax(0,.85fr);
  align-items:end;
  margin-bottom:clamp(36px,4.5vw,60px);
}

/* --- Wider band, used once, so the work section breaks the page rhythm --- */
.wrap--wide{ max-width:1600px; }

/* --- The same courtesy for the light sections. Flat #FFF reads as an
       absence of ink; a barely-there warm falloff from the top edge reads as
       a lit surface. Kept under 3% so it is felt rather than seen — at any
       strength where you could name it as a gradient it starts to look like
       a print artefact on what is meant to be clean drawing paper. ----- */
.section:not(.dark):not(.cta),
.statement{ position:relative; isolation:isolate; }
.section:not(.dark):not(.cta)::after,
.statement::after{
  content:""; position:absolute; inset:0; z-index:-1; pointer-events:none;
  background:
    radial-gradient(120% 58% at 50% 0%,   rgba(255,176,0,.030), transparent 68%),
    radial-gradient(100% 45% at 50% 100%, rgba(10,10,10,.024),  transparent 72%);
}

/* --- Depth on the black sections: flat #0A0A0A reads as a hole, a soft
       top-lit falloff reads as a surface ------------------------------- */
.dark, .cta{ isolation:isolate; }
.dark::after, .cta::after{
  content:""; position:absolute; inset:0; z-index:-1; pointer-events:none;
  background:
    radial-gradient(130% 70% at 50% 0%,  rgba(255,255,255,.05), transparent 62%),
    radial-gradient(100% 60% at 50% 100%, rgba(0,0,0,.55),      transparent 70%);
}

/* --- Amber sheet edge drawing itself across the top of a dark section --- */
.sect-edge{
  position:absolute; top:0; left:0; right:0; height:2px; z-index:3;
  background:linear-gradient(90deg, var(--hi), rgba(255,176,0,0));
  transform-origin:0 50%;
}
.js .sect-edge{ transform:scaleX(0); transition:transform 1.4s var(--e-out); }
.js .sect-edge.in{ transform:scaleX(1); }

/* --- Drawing stamp, angled the way a real one lands on a sheet --------- */
.stamp{
  display:inline-block; margin-top:28px; padding:11px 16px 12px;
  border:2px solid rgba(255,176,0,.55); color:rgba(255,176,0,.75);
  transform:rotate(-6deg); user-select:none; pointer-events:none;
  font-family:var(--f-mono); font-weight:500; text-transform:uppercase;
}
.stamp span{ display:block; font-size:12px; letter-spacing:.2em; }
.stamp em{
  display:block; font-style:normal; font-size:9px; letter-spacing:.18em;
  margin-top:5px; color:rgba(255,176,0,.5);
}

/* --- Scroll readout at the foot of the sheet rail ---------------------- */
.rail-pct{
  display:block; text-align:right; padding-top:6px; margin-top:4px;
  border-top:1px solid rgba(10,10,10,.3);
  font-family:var(--f-mono); font-weight:500; font-size:9.5px;
  letter-spacing:.16em; color:var(--ink); opacity:.55;
  font-variant-numeric:tabular-nums;
  transition:color .4s var(--e-out), border-color .4s var(--e-out);
}
.sheet-rail.on-dark .rail-pct{ color:#fff; border-top-color:rgba(255,255,255,.35); }

/* ---------- 4. Type ------------------------------------------------------ */
.eyebrow{
  display:flex; align-items:flex-start; gap:14px;
  font-family:var(--f-mono); font-weight:500; font-size:11.5px;
  letter-spacing:.2em; text-transform:uppercase; color:var(--steel-2);
  margin:0 0 22px;
}
/* the rule draws itself in when the block reveals */
.eyebrow::before{
  content:""; width:34px; height:2px; background:var(--hi); flex:none;
  margin-top:.52em; transform-origin:0 50%;
}
.js .in .eyebrow::before,
.js .eyebrow.in::before{ animation:ruleIn .8s var(--e-out) both .1s; }
@keyframes ruleIn{ from{ transform:scaleX(0) } to{ transform:scaleX(1) } }
:is(.dark,.hero,.cta,.site-foot,.elev-band) .eyebrow{ color:rgba(255,255,255,.68); }

/* text-wrap:balance evens the line lengths of a heading so it never leaves a
   single orphaned word on the last line. It is capped by the spec at a few
   lines, which is exactly the range headings live in, and it degrades to
   normal wrapping where unsupported. */
.h1{ font-size:clamp(27px,8.6vw,88px); line-height:.93; letter-spacing:-.035em; text-transform:uppercase; }
.h2{ font-size:clamp(26px,5.4vw,56px); line-height:1.0; letter-spacing:-.028em; text-transform:uppercase; text-wrap:balance; }
.h3{ font-size:clamp(20px,2vw,25px); line-height:1.15; letter-spacing:-.012em; text-wrap:balance; }
.h4{ font-size:17px; line-height:1.3; letter-spacing:.005em; font-weight:700; text-wrap:balance; }

/* Not balance: a lede is longer than the few lines balance is defined over.
   pretty only fixes the last line, which is the orphan we actually see. */
.sub{ font-size:clamp(17px,1.5vw,20px); line-height:1.62; color:var(--steel); max-width:62ch; text-wrap:pretty; }
:is(.dark,.hero,.cta,.site-foot,.elev-band) .sub{ color:rgba(255,255,255,.8); }
.small{ font-size:15px; color:var(--steel); }
:is(.dark,.hero,.cta,.site-foot,.elev-band) .small{ color:rgba(255,255,255,.66); }

/* ---------- 5. Motion engine --------------------------------------------
   Everything is gated behind .js so a scripting failure can never leave the
   page blank, and behind prefers-reduced-motion at the bottom of the file. */

.js [data-rv]{
  opacity:0; will-change:opacity, transform;
  transition:opacity .9s var(--e-out), transform 1s var(--e-out), clip-path 1s var(--e-out);
  transition-delay:var(--d, 0ms);
}
.js [data-rv="up"]    { transform:translate3d(0,38px,0); }
.js [data-rv="left"]  { transform:translate3d(-46px,0,0); }
.js [data-rv="right"] { transform:translate3d(46px,0,0); }
.js [data-rv="scale"] { transform:scale(.93); }
.js [data-rv="clip"]  { opacity:1; clip-path:inset(0 100% 0 0); }
/* clip-path only on the variant that needs it — applying it to every revealed
   element silently clips absolutely-positioned children that sit outside the
   element's own box (this ate the process-stage nodes). */
.js [data-rv].in{ opacity:1; transform:none; }
.js [data-rv="clip"].in{ clip-path:inset(0 0 0 0); }

/* Word-by-word headline reveal (JS wraps words in .w > span) */
.split .w{ display:inline-block; overflow:hidden; vertical-align:bottom; padding-bottom:.06em; }
.js .split .w > span{
  display:inline-block; transform:translate3d(0,110%,0);
  transition:transform 1.05s var(--e-out); transition-delay:var(--d,0ms);
}
.js .split.in .w > span{ transform:none; }

/* Media curtain — the panel wipes away to expose the photo */
.js .media-wipe::after{
  content:""; position:absolute; inset:0; z-index:3; background:var(--ink);
  transform-origin:100% 50%; transition:transform 1.1s var(--e-out); transition-delay:var(--d,0ms);
}
.js .media-wipe.in::after{ transform:scaleX(0); }

/* ---------- 6. Buttons --------------------------------------------------- */
.btn{
  position:relative; overflow:hidden; isolation:isolate;
  display:inline-flex; align-items:center; gap:11px;
  padding:17px 30px; border:2px solid var(--ink); background:var(--ink); color:#fff;
  font-family:var(--f-display); font-weight:700; font-size:13px;
  letter-spacing:.14em; text-transform:uppercase; text-decoration:none;
  cursor:pointer;
  box-shadow:var(--sh-1);
  transition:color .4s var(--e-out), border-color .4s var(--e-out),
             transform .55s var(--e-out), box-shadow .55s var(--e-out);
}
/* amber sweeps in from the left rather than snapping */
.btn::before{
  content:""; position:absolute; inset:0; z-index:-1; background:var(--hi);
  transform:scaleX(0); transform-origin:0 50%; transition:transform .5s var(--e-out);
}
/* The lift is 2px and the shadow is amber-tinted, so the button appears to
   rise off the sheet into the same warm light the fill is coming from. */
.btn:hover{
  color:var(--ink); border-color:var(--hi);
  transform:translateY(-2px); box-shadow:var(--sh-hi);
}
.btn:hover::before{ transform:scaleX(1); }
.btn:active{ transform:translateY(0); box-shadow:var(--sh-1); transition-duration:.1s; }
/* A magnetised button writes its own transform inline, so it must not also be
   told to translate on hover — the two would fight for the same property. */
.btn[data-magnet]:hover, .btn[data-magnet]:active{ transform:none; }

.btn--ghost{ background:transparent; color:var(--ink); }
.btn--ghost:hover{ color:var(--ink); }
:is(.dark,.hero,.cta,.site-foot,.elev-band) .btn{ background:#fff; border-color:#fff; color:var(--ink); }
:is(.dark,.hero,.cta,.site-foot,.elev-band) .btn:hover{ color:var(--ink); border-color:var(--hi); }
:is(.dark,.hero,.cta,.site-foot,.elev-band) .btn--ghost{ background:transparent; color:#fff; border-color:rgba(255,255,255,.45); }
:is(.dark,.hero,.cta,.site-foot,.elev-band) .btn--ghost:hover{ color:var(--ink); border-color:var(--hi); }
.btn--sm{ padding:12px 21px; font-size:12px; }
.btn-row{ display:flex; flex-wrap:wrap; gap:14px; margin-top:38px; }

.tlink{
  position:relative; display:inline-flex; align-items:center; gap:9px; text-decoration:none;
  font-family:var(--f-display); font-weight:700; font-size:13px;
  letter-spacing:.14em; text-transform:uppercase;
  padding-bottom:7px;
}
.tlink::after{
  content:""; position:absolute; left:0; right:0; bottom:0; height:2px; background:var(--hi);
  transform-origin:0 50%; transition:transform .5s var(--e-out);
}
.tlink:hover::after{ animation:swipe .6s var(--e-out); }
@keyframes swipe{
  0%{ transform:scaleX(1); transform-origin:100% 50% }
  49%{ transform:scaleX(0); transform-origin:100% 50% }
  50%{ transform:scaleX(0); transform-origin:0 50% }
  100%{ transform:scaleX(1); transform-origin:0 50% }
}
.tlink .arw{ transition:transform .5s var(--e-out); }
.tlink:hover .arw{ transform:translateX(6px); }

/* ==========================================================================
   7. Header — a bar that belongs to whatever it is passing over
   Fixed rather than sticky, so the hero runs full-bleed underneath it and the
   masthead reads as part of the sheet instead of a white slab bolted above it.
   Two independent switches, both driven from main.js:
     .is-stuck  — has the visitor scrolled? fades the glass panel in
     .on-dark   — is the bar currently over a black band? inverts the chrome
   Because they are independent, the bar can be transparent-over-dark at the
   top of the hero, dark glass mid-hero, and light glass over a paper section,
   without any of those states needing to know about the others.
   ========================================================================== */
.site-head{
  position:fixed; top:0; left:0; right:0; z-index:100;
  transition:color .45s var(--e-out);
}
/* The glass lives on its own layer: an unpainted (opacity:0) pseudo-element
   applies no backdrop-filter, so the top of the hero is never blurred, and
   fading it in costs one composited layer rather than a background repaint. */
.site-head::before{
  content:""; position:absolute; inset:0; z-index:-1;
  background:rgba(255,255,255,.72);
  -webkit-backdrop-filter:blur(18px) saturate(1.6);
          backdrop-filter:blur(18px) saturate(1.6);
  border-bottom:1px solid var(--line);
  box-shadow:var(--sh-2);
  opacity:0;
  transition:opacity .5s var(--e-out), background .45s var(--e-out),
             border-color .45s var(--e-out);
}
.site-head.is-stuck::before,
.site-head.nav-open::before{ opacity:1; }
.site-head.on-dark::before{
  background:rgba(10,10,10,.62);
  border-bottom-color:rgba(255,255,255,.13);
}
/* Drawer open: the panel underneath it is paper, so the bar goes light no
   matter what is scrolled behind it — and opaque, not glass, so the bar and
   the drawer read as one sheet rather than two slightly different whites. */
.site-head.nav-open::before{
  background:var(--paper); border-bottom-color:transparent;
  -webkit-backdrop-filter:none; backdrop-filter:none;
}
/* No JS means no .is-stuck will ever be set — give it the solid bar it used
   to have rather than leaving dark text floating on a dark hero. */
html:not(.js) .site-head::before{ opacity:1; }

.head-inner{
  max-width:var(--max); margin-inline:auto; padding-inline:var(--gut);
  display:flex; align-items:center; gap:24px; min-height:var(--head-h);
  transition:min-height .4s var(--e-out);
}
/* :not(.nav-open) rather than a later override — the drawer is positioned at
   the bar's full height, so the bar must stay at full height while the drawer
   is down or a sliver of the page shows through the gap between the two. */
.site-head.is-stuck:not(.nav-open) .head-inner{ min-height:var(--head-h-stuck); }

/* --- 7a. inverted chrome, used whenever the bar sits over black --------- */
.site-head.on-dark:not(.nav-open) .brand .wm b,
.site-head.on-dark:not(.nav-open) .nav > a,
.site-head.on-dark:not(.nav-open) .head-cta .tel{ color:#fff; }
.site-head.on-dark:not(.nav-open) .brand .wm span{ color:rgba(255,255,255,.62); }
.site-head.on-dark:not(.nav-open) .head-cta .tel:hover{ color:var(--hi); }
/* The mark is a black line drawing; the white copy is a separate file that
   cross-fades over it, which keeps the strokes crisp where a filter would
   soften them. */
.site-head.on-dark:not(.nav-open) .brand .mark-dark{ opacity:0; }
.site-head.on-dark:not(.nav-open) .brand .mark-light{ opacity:1; }
.site-head.on-dark:not(.nav-open) .btn{
  background:#fff; border-color:#fff; color:var(--ink);
}
.site-head.on-dark:not(.nav-open) .btn:hover{ color:var(--ink); border-color:var(--hi); }
.site-head.on-dark:not(.nav-open) .burger{ border-color:rgba(255,255,255,.32); }
.site-head.on-dark:not(.nav-open) .burger:hover{ border-color:#fff; }
.site-head.on-dark:not(.nav-open) .burger span,
.site-head.on-dark:not(.nav-open) .burger span::before,
.site-head.on-dark:not(.nav-open) .burger span::after{ background:#fff; }
.site-head.on-dark:not(.nav-open) .burger[aria-expanded="true"] span{ background:transparent; }

.brand{
  display:flex; align-items:center; gap:13px; text-decoration:none; margin-right:auto;
}
/* Both marks occupy the same cell so the swap cannot shift the wordmark */
.brand .mark{ display:grid; flex:none; }
.brand .mark img{
  grid-area:1/1; height:40px; width:auto;
  transition:height .4s var(--e-out), transform .5s var(--e-out), opacity .4s var(--e-out);
}
.brand .mark-light{ opacity:0; }
.site-head.is-stuck .brand .mark img{ height:34px; }
.brand:hover .mark img{ transform:translateY(-2px); }
.brand .wm{ display:flex; flex-direction:column; line-height:1; }
.brand .wm b{
  font-family:var(--f-display); font-weight:900; font-size:24px;
  letter-spacing:.02em; color:var(--ink); transition:color .45s var(--e-out);
}
.brand .wm span{
  font-family:var(--f-display); font-weight:600; font-size:8.5px;
  letter-spacing:.19em; text-transform:uppercase; color:var(--steel-2); margin-top:4px;
  transition:color .45s var(--e-out);
}

.nav{ display:flex; align-items:center; gap:clamp(14px,2.2vw,32px); }
.nav a{
  position:relative; text-decoration:none; padding:9px 0;
  font-family:var(--f-display); font-weight:600; font-size:13px;
  letter-spacing:.13em; text-transform:uppercase; color:var(--ink);
  transition:color .45s var(--e-out);
}
.nav a::after{
  content:""; position:absolute; left:0; right:0; bottom:2px; height:2px;
  background:var(--hi); transform:scaleX(0); transform-origin:0 50%;
  transition:transform .45s var(--e-out);
}
.nav a:hover::after{ transform:scaleX(1); }
.nav a[aria-current="page"]::after{ transform:scaleX(1); }

/* Phone + CTA live in the header on desktop and inside the drawer on mobile,
   so the two conversion paths are never off-screen. */
.nav .nav-mob{ display:none; }

.head-cta{ display:flex; align-items:center; gap:18px; }
.head-cta .tel{
  text-decoration:none; font-family:var(--f-display); font-weight:700;
  font-size:14px; letter-spacing:.04em; white-space:nowrap;
  transition:color .3s var(--e-out);
}
.head-cta .tel:hover{ color:var(--hi-deep); }

.burger{
  display:none; width:46px; height:46px; border:1px solid var(--line);
  background:none; cursor:pointer; padding:0; place-items:center;
  transition:border-color .3s var(--e-out), background .3s var(--e-out);
}
.burger:hover{ border-color:var(--ink); }
.burger span{ display:block; width:20px; height:2px; background:var(--ink); position:relative; transition:background .2s; }
.burger span::before,.burger span::after{
  content:""; position:absolute; left:0; width:20px; height:2px; background:var(--ink);
  transition:transform .4s var(--e-out);
}
.burger span::before{ top:-6px; } .burger span::after{ top:6px; }
.burger[aria-expanded="true"] span{ background:transparent; }
.burger[aria-expanded="true"] span::before{ transform:translateY(6px) rotate(45deg); }
.burger[aria-expanded="true"] span::after{ transform:translateY(-6px) rotate(-45deg); }

/* ---------- 8. Blueprint texture ---------------------------------------- */
/* overflow clips the oversized drifting grid to the section */
.bp{ position:relative; isolation:isolate; overflow:hidden; }
.bp::before{
  content:""; position:absolute; inset:-72px; z-index:-1; pointer-events:none;
  will-change:transform;
  background-image:
    linear-gradient(rgba(255,255,255,.055) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,.055) 1px, transparent 1px);
  background-size:68px 68px;
  animation:driftB 44s linear infinite;
}
@keyframes driftB{ to{ transform:translate3d(68px, 68px, 0); } }

/* ==========================================================================
   9. HERO — the drawing sheet
   Layers, back to front: grid → glow → self-drawing elevation → registration
   marks and sheet number → copy → title block. The whole thing is built to
   read as sheet A-01 of a set of construction documents.
   ========================================================================== */
.hero{
  position:relative; background:var(--ink); color:#fff; overflow:hidden;
  padding-block:clamp(96px,13vw,168px);
}

/* --- 9a. full-height home hero --- */
/* The header floats over this rather than sitting above it, so the sheet runs
   edge to edge and the title block lands exactly on the fold — seeing it there
   is what tells the visitor they are looking at a drawing sheet. The copy
   clears the bar with padding instead of the section being shortened. */
.hero--home{
  min-height:100svh; padding:0;
  display:grid; grid-template-rows:1fr auto;
  cursor:crosshair;                       /* surveying, not decoration */
}
.hero--home a, .hero--home button{ cursor:pointer; }
.hero--home > .wrap{
  display:flex; flex-direction:column; justify-content:center;
  padding-block:calc(var(--head-h) + clamp(22px,3.4vh,48px)) clamp(16px,2.4vh,28px);
}
/* Compact the copy stack a touch so the title block still lands on the fold
   with the scroll cue in place */
.hero--home .dimline{ margin:clamp(22px,3vh,32px) 0 clamp(20px,2.6vh,28px); }
.hero--home .sub{ margin-top:0; max-width:50ch; }
.hero--home .btn-row{ margin-top:clamp(24px,3.4vh,34px); }
.hero--home .h1{ font-size:clamp(33px,8vw,84px); }

/* --- 9b. dual-pitch survey grid --- */
/* Oversized by more than one tile so translating it never exposes an edge.
   Transform animates on the compositor; background-position repaints. */
.hero-grid{
  position:absolute; inset:-180px; z-index:0; pointer-events:none;
  will-change:transform;
  background-image:
    linear-gradient(rgba(255,255,255,.030) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,.030) 1px, transparent 1px),
    linear-gradient(rgba(255,255,255,.060) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,.060) 1px, transparent 1px);
  background-size:34px 34px, 34px 34px, 170px 170px, 170px 170px;
  animation:drift 62s linear infinite;
  -webkit-mask-image:radial-gradient(125% 105% at 28% 42%, #000 26%, transparent 80%);
          mask-image:radial-gradient(125% 105% at 28% 42%, #000 26%, transparent 80%);
}
@keyframes drift{ to{ transform:translate3d(170px, 170px, 0); } }

/* --- 9c. the elevation, drawn line by line on load --- */
.hero-draw{
  position:absolute; right:-6%; bottom:2%; width:min(70vw, 1010px); height:auto;
  z-index:1; pointer-events:none; opacity:.75;
  translate:0 var(--dy, 0px); will-change:translate;
  /* Two masks intersected: fade at top and bottom, and fade out to the left
     so the drawing never competes with the headline sitting over it */
  -webkit-mask-image:
    linear-gradient(180deg, transparent, #000 22%, #000 90%, transparent),
    linear-gradient(90deg, transparent 2%, #000 42%);
  -webkit-mask-composite:source-in;
          mask-image:
    linear-gradient(180deg, transparent, #000 22%, #000 90%, transparent),
    linear-gradient(90deg, transparent 2%, #000 42%);
          mask-composite:intersect;
}
.hero-draw *{
  fill:none; stroke:rgba(255,255,255,.46); stroke-width:1;
  vector-effect:non-scaling-stroke;
}
.hero-draw .hi{ stroke:var(--hi); opacity:.8; }
.hero-draw .dash{ stroke:rgba(255,255,255,.24); stroke-dasharray:.02 .022; }
/* pathLength="1" on every element normalises the dash maths, so one rule
   draws a 400px mullion and a 12px tick at exactly the same rate */
.js .hero-draw *:not(.dash):not(g){ stroke-dasharray:1; stroke-dashoffset:1; }
.intro-done .hero-draw *:not(.dash):not(g){
  animation:draw 1.5s var(--e-out) forwards;
  animation-delay:calc(var(--dd, 0s) + .15s);
}
@keyframes draw{ to{ stroke-dashoffset:0; } }

/* The hook hangs off the jib, so it swings from the jib rather than its own
   centre. Starts only after the drawing has finished being drawn. */
.hero-draw .hook{
  transform-box:view-box; transform-origin:852px 163px;
}
.intro-done .hero-draw .hook{ animation:sway 8s var(--e-io) 2s infinite; }
@keyframes sway{
  0%,100%{ transform:rotate(-1.15deg); }
  50%    { transform:rotate(1.15deg); }
}

/* --- 9d. sheet furniture: corner marks + vertical sheet number --- */
.reg{
  position:absolute; width:24px; height:24px; z-index:4; pointer-events:none;
  opacity:0;
}
html:not(.js) .reg, html:not(.js) .sheet-no{ opacity:1; }
.intro-done .reg{ animation:fadeIn .9s var(--e-out) 1.15s forwards; }
.reg::before,.reg::after{ content:""; position:absolute; background:rgba(255,255,255,.4); }
.reg::before{ width:100%; height:1px; } .reg::after{ height:100%; width:1px; }
.reg--tl{ top:24px; left:24px; } .reg--tl::before{ top:0 } .reg--tl::after{ left:0 }
.reg--tr{ top:24px; right:24px; } .reg--tr::before{ top:0 } .reg--tr::after{ right:0 }
.reg--bl{ bottom:24px; left:24px; } .reg--bl::before{ bottom:0 } .reg--bl::after{ left:0 }
.reg--br{ bottom:24px; right:24px; } .reg--br::before{ bottom:0 } .reg--br::after{ right:0 }
@keyframes fadeIn{ to{ opacity:1 } }

.sheet-no{
  position:absolute; left:26px; top:50%; z-index:4; pointer-events:none;
  writing-mode:vertical-rl; transform:translateY(-50%) rotate(180deg);
  font-family:var(--f-mono); font-size:10.5px; font-weight:500;
  letter-spacing:.36em; text-transform:uppercase; color:rgba(255,255,255,.34);
  opacity:0;
}
.intro-done .sheet-no{ animation:fadeIn .9s var(--e-out) 1.35s forwards; }

/* --- 9e. dimension line under the headline --- */
.dimline{
  position:relative; height:1px; background:rgba(255,255,255,.28);
  width:min(560px, 82%); margin:clamp(30px,4vh,42px) 0 clamp(26px,3.4vh,34px);
  transform-origin:0 50%;
}
.js .dimline{ transform:scaleX(0); }
.intro-done .dimline{ animation:dimIn 1.1s var(--e-out) .8s forwards; }
@keyframes dimIn{ to{ transform:scaleX(1) } }
.dimline::before,.dimline::after{
  content:""; position:absolute; top:-6px; width:1px; height:13px; background:var(--hi);
}
.dimline::before{ left:0; } .dimline::after{ right:0; }
.dimline span{
  position:absolute; left:50%; top:-9px; transform:translateX(-50%);
  background:var(--ink); padding:0 14px;
  font-family:var(--f-mono); font-size:10px; font-weight:500;
  letter-spacing:.26em; text-transform:uppercase; color:var(--hi);
  white-space:nowrap;
}

/* --- 9f. title block --- */
/* Sits over the tail of the elevation, so it needs its own ground to stay
   legible — the drawing's grade line lands on its top rule by design */
.titleblock{
  position:relative; z-index:3;
  border-top:1px solid rgba(255,255,255,.19);
  background:linear-gradient(180deg, rgba(10,10,10,.94), var(--ink));
}
/* minmax(0,1fr) not 1fr: a long unbreakable value (an email address) has a
   min-content width, and plain 1fr lets it blow its column out and crush the
   others. */
.tb-inner{
  max-width:var(--max); margin-inline:auto; padding-inline:var(--gut);
  display:grid; grid-template-columns:repeat(4, minmax(0,1fr));
}
/* Variant for a title block whose first cell carries the email address.
   The doubled class raises specificity over `.tb-cell b`, which is defined
   later in this file and would otherwise win on order alone. */
.tb-inner--email{
  grid-template-columns:minmax(0,1.75fr) minmax(0,1fr) minmax(0,1fr) minmax(0,.9fr);
}
.tb-cell.tb-cell--email b{ font-size:clamp(13px,1.2vw,17px); letter-spacing:-.005em; }
.tb-cell{
  padding:20px 26px 24px 0; border-right:1px solid rgba(255,255,255,.13);
  position:relative;
}
.tb-cell:last-child{ border-right:0; padding-right:0; }
.tb-cell::before{
  content:""; position:absolute; left:0; top:-1px; width:0; height:2px; background:var(--hi);
  transition:width 1s var(--e-out); transition-delay:var(--d,0ms);
}
.tb-cell.in::before{ width:30px; }
.tb-cell i{
  display:block; font-style:normal; font-family:var(--f-mono);
  font-size:10px; font-weight:500; letter-spacing:.22em; text-transform:uppercase;
  color:rgba(255,255,255,.44); margin-bottom:10px;
}
.tb-cell b{
  display:block; font-family:var(--f-display); font-weight:800;
  font-size:clamp(23px,2.5vw,31px); line-height:1; letter-spacing:-.025em; color:#fff;
  font-variant-numeric:tabular-nums;
}
.tb-cell em{
  display:block; font-style:normal; margin-top:9px;
  font-size:12.5px; line-height:1.42; color:rgba(255,255,255,.56);
}
/* Optional photo layer — see the override block at the bottom of this file */
.hero::after{
  content:""; position:absolute; inset:0; z-index:0;
  background-image:var(--hero-img, none);
  background-size:cover; background-position:center;
  opacity:var(--hero-op, .34);
}
/* Lift only the real content above the decorative layers — the layers set
   their own position, and a blanket `.hero > *` would knock them out of it */
.hero > .wrap,
.hero > .titleblock{ position:relative; z-index:3; }

/* Amber glow that tracks the pointer — JS sets --mx / --my */
.hero-glow{
  position:absolute; inset:0; z-index:1; pointer-events:none;
  background:radial-gradient(620px circle at var(--mx,72%) var(--my,44%),
             rgba(255,176,0,.15), transparent 64%);
  transition:opacity .6s var(--e-out); opacity:0;
}
.hero.is-live .hero-glow{ opacity:1; }

/* Ghosted mark bleeding off the right edge; JS nudges --py on scroll.
   Interior pages only — the home hero carries the elevation drawing. */
.hero-mark{
  position:absolute; right:-4%; top:50%; z-index:1;
  transform:translate3d(0, calc(-50% + var(--py,0px)), 0);
  width:min(46vw,580px); opacity:.055; pointer-events:none;
  will-change:transform;
}

/* Survey line sweeping down the hero once on load, then idling */
.hero-scan{
  position:absolute; left:0; right:0; top:0; height:1px; z-index:1; pointer-events:none;
  background:linear-gradient(90deg, transparent, rgba(255,176,0,.55), transparent);
  animation:scan 9s var(--e-io) infinite;
}
@keyframes scan{
  0%{ transform:translateY(0); opacity:0 }
  8%{ opacity:1 }
  55%{ transform:translateY(min(52vh,520px)); opacity:0 }
  100%{ transform:translateY(min(52vh,520px)); opacity:0 }
}

.hero .h1{ max-width:16ch; }
.hero .sub{ margin-top:30px; }

/* Interior heroes reserve the floating bar's height on top of their own
   padding, so the page tag never starts underneath the masthead. */
.hero--page{ padding-block:calc(var(--head-h) + clamp(52px,7vw,96px)) clamp(72px,9vw,120px); }
/* Interior sheets fill the viewport exactly as the home sheet does: the copy
   sits in the middle of the band and the title block lands on the fold, so no
   sliver of the next section ever shows beneath the hero on a tall screen. */
.hero--page{
  min-height:100svh; padding-top:calc(var(--head-h) + clamp(16px,3vh,40px)); padding-bottom:0;
  display:grid; grid-template-rows:minmax(0,1fr) auto;
  --tb-gap:calc(150px + clamp(18px,3vh,40px));   /* title block + breathing room */
}
.hero--page > .wrap{
  display:flex; flex-direction:column; justify-content:center;
  padding-bottom:clamp(24px,4vh,56px);
}
.hero--page > .titleblock{ align-self:end; }
.hero--page .h1{ max-width:20ch; }

.page-tag{
  font-family:var(--f-display); font-weight:600; font-size:12px;
  letter-spacing:.24em; text-transform:uppercase; color:rgba(255,255,255,.58);
  margin-bottom:20px;
}

/* Scroll cue */
.scroll-cue{
  display:inline-flex; align-items:center; gap:12px; margin-top:clamp(40px,5vw,60px);
  font-family:var(--f-display); font-weight:600; font-size:11px;
  letter-spacing:.22em; text-transform:uppercase; color:rgba(255,255,255,.5);
  text-decoration:none;
}
.scroll-cue i{
  display:block; width:1px; height:38px; background:rgba(255,255,255,.28); position:relative; overflow:hidden;
}
.scroll-cue i::after{
  content:""; position:absolute; inset:0; background:var(--hi);
  animation:cue 2.4s var(--e-io) infinite;
}
@keyframes cue{
  0%{ transform:translateY(-100%) } 55%{ transform:translateY(100%) } 100%{ transform:translateY(100%) }
}

/* ---------- 10. Stat strip ----------------------------------------------- */
.stats{
  display:grid; grid-template-columns:repeat(4,1fr);
  border-top:1px solid var(--line-dark); margin-top:clamp(52px,6.5vw,84px);
}
.stat{ padding:32px 26px 0 0; border-right:1px solid var(--line-dark); position:relative; }
.stat:last-child{ border-right:0; }
.stat::before{
  content:""; position:absolute; left:0; top:-1px; width:0; height:2px; background:var(--hi);
  transition:width .9s var(--e-out); transition-delay:var(--d,0ms);
}
.stat.in::before{ width:38px; }
.stat b{
  display:block; font-family:var(--f-display); font-weight:800;
  font-size:clamp(32px,3.6vw,46px); line-height:1; letter-spacing:-.025em; color:#fff;
  font-variant-numeric:tabular-nums;
}
.stat span{
  display:block; margin-top:11px; font-size:13.5px; line-height:1.45;
  color:rgba(255,255,255,.6);
}

/* ==========================================================================
   10b. STATEMENT — copy that lights up as it is read
   JS sets .lit on each word as the block travels through the viewport, so
   the paragraph fills in under the reader rather than simply appearing.
   ========================================================================== */
.statement{ padding-block:clamp(88px,11vw,164px); }
.scrolltext{
  font-family:var(--f-display); font-weight:700;
  font-size:clamp(25px,3.55vw,47px); line-height:1.22; letter-spacing:-.024em;
  max-width:19ch; text-wrap:balance;
}
@supports (width: 60ch){ .scrolltext{ max-width:min(100%, 21ch); } }
.scrolltext .wd{ color:rgba(10,10,10,.15); transition:color .5s var(--e-out); }
.scrolltext .wd.lit{ color:var(--ink); }
.scrolltext .wd.hi{ color:rgba(224,148,0,.22); }
.scrolltext .wd.hi.lit{ color:var(--hi-deep); }
/* No JS, or reduced motion: show the finished state */
html:not(.js) .scrolltext .wd, .scrolltext.static .wd{ color:var(--ink); }

/* Two columns: the statement carries the weight, drawing notes fill what
   would otherwise be a dead right-hand column with real method detail. */
.statement-grid{
  display:grid; gap:clamp(34px,5vw,84px);
  grid-template-columns:minmax(0,1.12fr) minmax(0,.88fr);
  align-items:end;
}
.notes{ border-top:1px solid var(--line); padding-top:26px; }
.notes h3{
  font-family:var(--f-mono); font-weight:500; font-size:10px;
  letter-spacing:.22em; text-transform:uppercase; color:var(--steel-2);
  margin-bottom:22px;
}
.notes ol{ counter-reset:n; display:grid; gap:17px; margin-bottom:30px; }
.notes li{
  counter-increment:n; display:grid; grid-template-columns:auto minmax(0,1fr); gap:15px;
  font-size:14.5px; line-height:1.55; color:var(--steel);
}
.notes li::before{
  content:counter(n, decimal-leading-zero);
  font-family:var(--f-mono); font-size:10.5px; font-weight:500;
  color:var(--hi-deep); padding-top:4px; letter-spacing:.06em;
}

/* ==========================================================================
   10c. SERVICE INDEX — a drawing index that opens
   Rows expand on hover, on keyboard focus, and on tap (JS adds .open). The
   0fr → 1fr grid-row trick animates to auto height without measuring.
   ========================================================================== */
.svc-list{ border-top:1px solid var(--line); }
.svc-row{ position:relative; border-bottom:1px solid var(--line); }
.svc-row::before{
  content:""; position:absolute; inset:0; z-index:0; pointer-events:none;
  background:linear-gradient(90deg, rgba(255,176,0,.13), transparent 58%);
  opacity:0; transition:opacity .6s var(--e-out);
}
.svc-row:hover::before,
.svc-row:focus-within::before,
.svc-row.open::before{ opacity:1; }

.svc-head{
  position:relative; z-index:1; width:100%; background:none; border:0; cursor:pointer;
  display:grid; grid-template-columns:auto minmax(0,1fr) auto;
  gap:clamp(18px,3.5vw,52px); align-items:center; text-align:left;
  padding:clamp(22px,2.8vw,34px) 0;
  transition:padding-left .6s var(--e-out);
}
.svc-row:hover .svc-head,
.svc-row:focus-within .svc-head,
.svc-row.open .svc-head{ padding-left:clamp(10px,1.4vw,20px); }

.svc-num{
  font-family:var(--f-mono); font-weight:500; font-size:12px; letter-spacing:.14em;
  color:var(--steel-2); transition:color .45s var(--e-out); align-self:start; padding-top:.7em;
}
.svc-row:hover .svc-num,
.svc-row:focus-within .svc-num,
.svc-row.open .svc-num{ color:var(--hi-deep); }

.svc-name{
  font-family:var(--f-display); font-weight:800; text-transform:uppercase;
  font-size:clamp(25px,4.1vw,54px); line-height:1; letter-spacing:-.032em; color:var(--ink);
}

/* + that becomes × */
.svc-plus{ position:relative; width:24px; height:24px; flex:none; }
.svc-plus::before,.svc-plus::after{
  content:""; position:absolute; inset:0; margin:auto; background:var(--ink);
  transition:transform .55s var(--e-out), background .45s var(--e-out);
}
.svc-plus::before{ width:22px; height:2px; }
.svc-plus::after{ width:2px; height:22px; }
.svc-row:hover .svc-plus::before,
.svc-row:focus-within .svc-plus::before,
.svc-row.open .svc-plus::before{ transform:rotate(180deg); background:var(--hi-deep); }
.svc-row:hover .svc-plus::after,
.svc-row:focus-within .svc-plus::after,
.svc-row.open .svc-plus::after{ transform:rotate(90deg); background:var(--hi-deep); }

/* Open by default so a no-JS visitor still reads every service; the .js
   class collapses them and hands control to hover / focus / tap. */
.svc-body{
  position:relative; z-index:1;
  display:grid; grid-template-rows:1fr;
}
.js .svc-body{
  grid-template-rows:0fr;
  transition:grid-template-rows .75s var(--e-out);
}
.svc-body > div{ overflow:hidden; }
.js .svc-row:hover .svc-body,
.js .svc-row:focus-within .svc-body,
.js .svc-row.open .svc-body{ grid-template-rows:1fr; }

.svc-detail{
  display:grid; gap:clamp(20px,3.5vw,58px);
  grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  padding:0 0 clamp(30px,3.6vw,44px) clamp(48px,7vw,108px);
}
.svc-detail p{ color:var(--steel); font-size:15.5px; line-height:1.6; }

.svc-foot{
  display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between;
  gap:18px; margin-top:clamp(30px,3.6vw,44px);
}
.svc-foot p{ color:var(--steel); font-size:15.5px; max-width:52ch; }

/* ==========================================================================
   10d. FEATURED WORK — one elevation, not three cards
   The buildings share a ground line and a scale, so they read as a single
   drawing. Grid bubbles A/B/C link each building to its entry beneath, and
   hovering either half highlights both.
   ========================================================================== */
.elev-band{
  position:relative; margin-top:clamp(30px,4vw,52px);
  /* symmetrical now that the band closes on its own footer rather than
     spilling into section padding */
  padding-block:clamp(34px,4.5vw,60px) clamp(40px,4.8vw,64px);
  background:var(--ink); color:#fff; overflow:hidden; isolation:isolate;
}
.elev-band::before{                       /* survey grid, static: no repaint */
  content:""; position:absolute; inset:0; z-index:-1; pointer-events:none;
  background-image:
    linear-gradient(rgba(255,255,255,.05) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,.05) 1px, transparent 1px);
  background-size:44px 44px;
  -webkit-mask-image:radial-gradient(120% 100% at 50% 40%, #000 35%, transparent 85%);
          mask-image:radial-gradient(120% 100% at 50% 40%, #000 35%, transparent 85%);
}
.elev-inner{ padding-inline:clamp(12px,3vw,44px); }
.elev{ width:100%; height:auto; overflow:visible; display:block; }

.elev *{
  fill:none; stroke:rgba(255,255,255,.44); stroke-width:1.15;
  vector-effect:non-scaling-stroke; stroke-linecap:square;
  transition:stroke .45s var(--e-out), opacity .45s var(--e-out);
}
.elev .hi{ stroke:rgba(255,176,0,.72); }
.elev .fade{ stroke:rgba(255,255,255,.2); }
.elev .dash{ stroke:rgba(255,255,255,.28); stroke-dasharray:.05 .05; }

/* draws itself in, same mechanism as the hero elevation */
.elev text.bub{
  fill:rgba(255,176,0,.85); stroke:none;
  font-family:var(--f-mono); font-weight:500; font-size:15px;
  letter-spacing:.04em; text-anchor:middle;
}
.js .elev *:not(g):not(text){ stroke-dasharray:1; stroke-dashoffset:1; }
.js .elev.in *:not(g):not(text){
  animation:draw 1.3s var(--e-out) forwards;
  animation-delay:calc(var(--dd, 0s) + .25s);
}

/* one building lit, the rest stepped back */
[data-work][data-hi] .elev .bldg{ opacity:.28; }
[data-work][data-hi="a"] .elev .bldg[data-b="a"],
[data-work][data-hi="b"] .elev .bldg[data-b="b"],
[data-work][data-hi="c"] .elev .bldg[data-b="c"]{ opacity:1; }
[data-work][data-hi="a"] .elev .bldg[data-b="a"] *,
[data-work][data-hi="b"] .elev .bldg[data-b="b"] *,
[data-work][data-hi="c"] .elev .bldg[data-b="c"] *{ stroke:var(--hi); }

/* --- the three entries beneath, keyed to the grid bubbles --- */
.pj-row{
  display:grid; grid-template-columns:repeat(3, minmax(0,1fr));
  gap:clamp(20px,3vw,44px); margin-top:clamp(26px,3.2vw,40px);
}
.pj{
  position:relative; display:block; text-decoration:none; color:inherit;
  padding-top:22px; border-top:1px solid rgba(255,255,255,.16);
  transition:border-color .45s var(--e-out), transform .55s var(--e-out);
}
/* The entry rises to meet the pointer as its rule fills and its building
   lights up in the elevation above — three cues, one gesture. */
.pj:hover, .pj:focus-visible{ transform:translateY(-4px); }
.pj::after{
  content:""; position:absolute; left:0; top:-1px; height:2px; width:0;
  background:var(--hi); transition:width .55s var(--e-out);
}
.pj:hover::after, .pj:focus-visible::after{ width:100%; }
.pj-key{
  display:inline-grid; place-items:center; width:30px; height:30px;
  border:1px solid rgba(255,255,255,.4); border-radius:50%;
  font-family:var(--f-mono); font-weight:500; font-size:11px; letter-spacing:.04em;
  margin-bottom:16px; transition:border-color .45s var(--e-out), color .45s var(--e-out);
}
.pj:hover .pj-key, .pj:focus-visible .pj-key{ border-color:var(--hi); color:var(--hi); }
.pj-tag{
  display:block; font-family:var(--f-mono); font-weight:500; font-size:10.5px;
  letter-spacing:.18em; text-transform:uppercase; color:rgba(255,255,255,.5);
  margin-bottom:10px; transition:color .45s var(--e-out);
}
.pj:hover .pj-tag{ color:var(--hi); }
.pj h3{
  font-family:var(--f-display); font-weight:800; text-transform:uppercase;
  font-size:clamp(18px,1.85vw,24px); line-height:1.12; letter-spacing:-.022em; color:#fff;
}
.pj p{ margin-top:11px; font-size:14.5px; line-height:1.55; color:rgba(255,255,255,.66); }
.pj-meta{
  display:flex; flex-wrap:wrap; gap:4px 10px; margin-top:16px;
  font-family:var(--f-mono); font-size:10.5px; letter-spacing:.12em;
  text-transform:uppercase; color:rgba(255,255,255,.38);
}
.pj-meta span + span::before{ content:"/"; margin-right:10px; opacity:.5; }

/* The sheet's footer. It used to sit on white below the band, which left an
   orphaned strip of paper trapped between two black sheets and ended the
   drawing on nothing. Inside the band it does what the hero's title block
   does: closes the sheet and hands you the next one. */
.work-foot{
  display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between;
  gap:20px;
  margin-top:clamp(30px,3.6vw,44px);
  padding-top:clamp(20px,2.3vw,28px);
  border-top:1px solid rgba(255,255,255,.16);
  position:relative;
}
/* Same amber start-tick the title block and stat strip use, so the footer is
   recognisably part of the same drawing furniture. */
.work-foot::before{
  content:""; position:absolute; left:0; top:-1px; width:0; height:2px;
  background:var(--hi); transition:width 1s var(--e-out);
}
.work-foot.in::before{ width:38px; }
.work-foot .small{ max-width:46ch; }

/* The band is full-bleed dark and now ends on its own footer, so the section
   must not add paper beneath it — the elevation sheet butts straight into the
   sectors sheet, and that section's .sect-edge draws the amber seam. */
.section--flush-b{ padding-bottom:0; }

@media (max-width:900px){
  .pj-row{ grid-template-columns:repeat(2, minmax(0,1fr)); }
}
@media (max-width:760px){
  /* at this scale the dimension lines and grid bubbles are smaller than the
     stroke weight — drop them and keep the skyline */
  .elev .annot{ display:none; }
  .elev{ min-height:96px; }
}
@media (max-width:600px){
  .pj-row{ grid-template-columns:1fr; gap:26px; }
}

/* ==========================================================================
   10e. CRITICAL PATH — the process drawn as the schedule it actually is
   A bar chart rather than a numbered list, because the claim being made is
   about overlap: precon is still running when design coordination starts,
   and quality & safety spans nearly the whole job. A list cannot show that;
   a schedule shows it at a glance.

   Geometry comes off two custom properties per bar, set inline in the HTML:
     --s  how far along the job the activity starts
     --w  how long it runs
   Both are percentages of the track, so the whole chart rescales with the
   column and no width is ever hard-coded in the stylesheet.
   ========================================================================== */
.gantt{
  margin-top:clamp(34px,4.5vw,58px);
  border-top:1px solid var(--line);
}

/* --- the phase header, aligned to the track column --------------------- */
/* Shares .gantt-row's column template so the phase bands line up with the
   bars beneath them; the empty first cell reserves the label gutter. */
.gantt-scale,
.gantt-row{
  display:grid;
  grid-template-columns:minmax(0, 268px) minmax(0, 1fr);
  gap:clamp(18px, 3vw, 40px);
  align-items:center;
}
.gantt-scale{ padding:14px 0 12px; }
.gantt-phases{ display:flex; }
.gantt-phases span{
  position:relative; padding:0 0 0 12px;
  flex:0 0 auto; min-width:0;      /* honour the inline width, clip if tight */
  font-family:var(--f-mono); font-weight:500; font-size:10px;
  letter-spacing:.2em; text-transform:uppercase; color:var(--steel-2);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
/* A tick at each phase boundary, the way a schedule marks its milestones */
.gantt-phases span::before{
  content:""; position:absolute; left:0; top:-3px; width:1px; height:11px;
  background:var(--hi);
}

/* --- one activity ------------------------------------------------------- */
.gantt-row{
  padding:clamp(15px,1.7vw,20px) 0;
  border-top:1px solid var(--line);
  position:relative;
}
.gantt-row:first-of-type{ border-top:0; }

.gantt-label b{
  display:block; font-family:var(--f-display); font-weight:800;
  font-size:clamp(15px,1.35vw,17.5px); line-height:1.2; letter-spacing:-.012em;
  color:var(--ink);
}
.gantt-label em{
  display:block; margin-top:6px; font-style:normal;
  font-size:13px; line-height:1.5; color:var(--steel);
}

/* --- the track: ruled ground for the bar to sit on --------------------- */
/* Hairlines every 10% give the eye something to measure a bar's start and
   length against — without them the bars float and the overlap stops
   reading as a schedule. Drawn as a gradient rather than as elements so a
   seven-row chart costs seven backgrounds, not seventy divs. */
.gantt-track{
  position:relative; height:42px;
  background-image:repeating-linear-gradient(90deg,
    var(--line) 0 1px, transparent 1px 10%);
  background-position:0 0;
}
.gantt-track::after{                       /* closing rule on the right edge */
  content:""; position:absolute; right:0; top:0; bottom:0; width:1px;
  background:var(--line);
}

/* --- the bar ------------------------------------------------------------ */
.gantt-bar{
  position:absolute; top:50%; translate:0 -50%;
  left:var(--s, 0%); width:var(--w, 10%); height:28px;
  background:var(--ink); color:#fff;
  display:flex; align-items:center;
  padding-inline:11px; overflow:hidden;
  box-shadow:var(--sh-1);
}
/* Amber leading edge: the date an activity starts is the thing a schedule is
   read for, so it is the one part of the bar that is picked out. */
.gantt-bar::before{
  content:""; position:absolute; left:0; top:0; bottom:0; width:3px;
  background:var(--hi);
}
.gantt-bar > span{
  font-family:var(--f-mono); font-weight:500; font-size:10px;
  letter-spacing:.16em; text-transform:uppercase; white-space:nowrap;
  overflow:hidden; text-overflow:ellipsis;
}
/* The activity that runs through everything else gets the amber fill */
.gantt-bar--hi{ background:var(--hi); color:var(--ink); }
.gantt-bar--hi::before{ background:var(--ink); }

/* Wipe rather than scale: scaling a bar scales its caption with it, and
   animating width would relayout the row on every frame. clip-path leaves the
   text at its final size and position and simply uncovers it, left to right,
   so the chart draws itself the way a bar is filled in on a real programme. */
.js .gantt-bar{ clip-path:inset(0 100% 0 0); }
.js .gantt-row.in .gantt-bar{
  clip-path:inset(0 0 0 0);
  transition:clip-path 1s var(--e-out);
  transition-delay:var(--d, 0ms);
}

/* --- the activity that never stops -------------------------------------- */
/* Owner reporting has no bar because it has no start and no end: it runs the
   full width of the job. A dashed rule with end stops says that in the
   vocabulary the rest of the drawing already uses. */
.gantt-row--span .gantt-track{ background-image:none; }
.gantt-row--span .gantt-track::before{
  content:""; position:absolute; left:0; right:0; top:50%; height:1px;
  translate:0 -50%;
  background-image:repeating-linear-gradient(90deg,
    var(--hi-deep) 0 7px, transparent 7px 14px);
}
.gantt-row--span .gantt-track::after{
  /* end stops at both ends, replacing the plain right-hand rule */
  content:""; left:0; right:0; top:50%; bottom:auto; width:auto; height:13px;
  translate:0 -50%; background:none;
  border-left:1px solid var(--hi-deep); border-right:1px solid var(--hi-deep);
}
.js .gantt-row--span .gantt-track::before{
  transform-origin:0 50%; transform:scaleX(0);
  transition:transform 1.1s var(--e-out); transition-delay:.5s;
}
.js .gantt-row--span.in .gantt-track::before{ transform:scaleX(1); }

/* ==========================================================================
   10f. ABOUT — section drawing, stepped pillars, staged process, checklist
   ========================================================================== */

/* --- the cut section behind the About hero --- */
.hero-sect{
  position:absolute; right:-5%; bottom:1%; width:min(66vw, 920px); height:auto;
  z-index:1; pointer-events:none; opacity:.78;
  translate:0 var(--dy, 0px); will-change:translate;
  -webkit-mask-image:
    linear-gradient(180deg, transparent, #000 16%, #000 94%, transparent),
    linear-gradient(90deg, transparent 0%, #000 30%);
  -webkit-mask-composite:source-in;
          mask-image:
    linear-gradient(180deg, transparent, #000 16%, #000 94%, transparent),
    linear-gradient(90deg, transparent 0%, #000 30%);
          mask-composite:intersect;
}
.hero-sect *{
  fill:none; stroke:rgba(255,255,255,.42); stroke-width:1;
  vector-effect:non-scaling-stroke; stroke-linecap:square;
}
.hero-sect .hi{ stroke:var(--hi); opacity:.78; }
.hero-sect .fade{ stroke:rgba(255,255,255,.2); }
.hero-sect .dash{ stroke:rgba(255,255,255,.2); stroke-dasharray:.02 .022; }
.hero-sect text.lvl{
  fill:rgba(255,176,0,.85); stroke:none; text-anchor:middle;
  font-family:var(--f-mono); font-weight:500; font-size:14px;
}
.js .hero-sect *:not(.dash):not(text){ stroke-dasharray:1; stroke-dashoffset:1; }
.intro-done .hero-sect *:not(.dash):not(text){
  animation:draw 1.5s var(--e-out) forwards;
  animation-delay:calc(var(--dd, 0s) + .15s);
}

/* --- stepped pillars: three blocks walking down and across --- */
.pillars{ display:grid; gap:0; counter-reset:pl; }
.pillar{
  counter-increment:pl; position:relative;
  display:grid; grid-template-columns:auto minmax(0,1fr) minmax(0,1.15fr);
  gap:clamp(18px,3.4vw,54px); align-items:start;
  padding:clamp(30px,3.6vw,46px) 0; border-top:1px solid var(--line);
}
.pillar:last-child{ border-bottom:1px solid var(--line); }
.pillar:nth-child(2){ padding-left:clamp(0px,3vw,52px); }
.pillar:nth-child(3){ padding-left:clamp(0px,6vw,104px); }
.pillar::before{
  content:counter(pl, decimal-leading-zero);
  font-family:var(--f-mono); font-weight:500; font-size:12px; letter-spacing:.14em;
  color:var(--hi-deep); padding-top:.55em;
}
.pillar h3{
  font-family:var(--f-display); font-weight:800; text-transform:uppercase;
  font-size:clamp(21px,2.5vw,32px); line-height:1.06; letter-spacing:-.028em;
}
.pillar p{ color:var(--steel); font-size:15.5px; line-height:1.6; }

/* --- staged process: a rule that fills as you read down it --- */
.stages{ position:relative; padding-left:clamp(52px,7vw,86px); }
/* z-index matters here: a parent's ::after paints after its children, so
   without this the fill line would cover the nodes sitting on it. */
.stages::before,
.stages::after{
  content:""; position:absolute; left:clamp(17px,2.4vw,30px); top:8px; width:1px;
  z-index:0;
}
.stages::before{ bottom:8px; background:var(--line); }
.stages::after{
  height:var(--fill, 0%); background:var(--hi);
  transition:height .18s linear;
}
.stage{ position:relative; z-index:1; padding-block:clamp(20px,2.6vw,30px); }
.stage-node{
  position:absolute; z-index:2; left:calc(clamp(17px,2.4vw,30px) - clamp(52px,7vw,86px) - 8px);
  top:calc(clamp(20px,2.6vw,30px) + 4px);
  width:17px; height:17px; border-radius:50%;
  border:1px solid var(--line); background:var(--paper);
  display:grid; place-items:center;
  transition:border-color .5s var(--e-out), background .5s var(--e-out);
}
.stage-node::after{
  content:""; width:5px; height:5px; border-radius:50%; background:var(--line);
  transition:background .5s var(--e-out), transform .5s var(--e-out);
}
.stage.lit .stage-node{ border-color:var(--hi); }
.stage.lit .stage-node::after{ background:var(--hi); transform:scale(1.5); }
.stage-key{
  display:block; font-family:var(--f-mono); font-weight:500; font-size:10.5px;
  letter-spacing:.2em; text-transform:uppercase; color:var(--steel-2); margin-bottom:9px;
  transition:color .5s var(--e-out);
}
.stage.lit .stage-key{ color:var(--hi-deep); }
.stage h3{
  font-family:var(--f-display); font-weight:800; text-transform:uppercase;
  font-size:clamp(19px,2vw,26px); line-height:1.1; letter-spacing:-.024em;
}
.stage p{ margin-top:11px; color:var(--steel); font-size:15.5px; line-height:1.6; max-width:62ch; }
.stage-out{
  display:flex; flex-wrap:wrap; gap:7px; margin-top:15px;
}
.stage-out span{
  border:1px solid var(--line); padding:6px 11px;
  font-family:var(--f-mono); font-size:10px; letter-spacing:.14em;
  text-transform:uppercase; color:var(--steel);
  transition:border-color .5s var(--e-out), color .5s var(--e-out);
}
.stage.lit .stage-out span{ border-color:rgba(255,176,0,.5); color:var(--ink); }

/* --- QA/QC checklist that ticks itself in --- */
.checksheet{ border:1px solid var(--line-dark); }
.cs-head{
  display:flex; justify-content:space-between; gap:16px; flex-wrap:wrap;
  padding:15px 20px; border-bottom:1px solid var(--line-dark);
  font-family:var(--f-mono); font-weight:500; font-size:10.5px;
  letter-spacing:.2em; text-transform:uppercase; color:rgba(255,255,255,.55);
}
.cs-row{
  display:grid; grid-template-columns:auto minmax(0,1fr); gap:16px; align-items:center;
  padding:14px 20px; border-top:1px solid rgba(255,255,255,.07);
  font-size:15px; color:rgba(255,255,255,.76);
}
.cs-row:first-of-type{ border-top:0; }
.cs-row:nth-child(odd){ background:rgba(255,255,255,.018); }
.cs-box{ width:17px; height:17px; border:1px solid rgba(255,255,255,.34); display:block; }
.cs-box svg{ width:100%; height:100%; overflow:visible; }
.cs-box path{
  fill:none; stroke:var(--hi); stroke-width:2.4; stroke-linecap:round;
  vector-effect:non-scaling-stroke;
}
.js .cs-box path{ stroke-dasharray:1; stroke-dashoffset:1; }
.js .checksheet.in .cs-box path{
  animation:draw .5s var(--e-out) forwards; animation-delay:var(--dd, 0s);
}

@media (max-width:860px){
  .pillar{ grid-template-columns:auto minmax(0,1fr); }
  .pillar > p{ grid-column:2; }
  .pillar:nth-child(2), .pillar:nth-child(3){ padding-left:0; }
  .hero-sect{ opacity:.4; width:120vw; right:-30%; bottom:2%; }
}

/* ==========================================================================
   10g. SERVICES — plan drawing, spec clauses, delivery matrix
   ========================================================================== */

/* --- the floor plan behind the Services hero --- */
.hero-plan{
  position:absolute; right:-6%; bottom:2%; width:min(62vw, 880px); height:auto;
  z-index:1; pointer-events:none; opacity:.72;
  translate:0 var(--dy, 0px); will-change:translate;
  -webkit-mask-image:
    linear-gradient(180deg, transparent, #000 18%, #000 92%, transparent),
    linear-gradient(90deg, transparent 0%, #000 32%);
  -webkit-mask-composite:source-in;
          mask-image:
    linear-gradient(180deg, transparent, #000 18%, #000 92%, transparent),
    linear-gradient(90deg, transparent 0%, #000 32%);
          mask-composite:intersect;
}
.hero-plan *{
  fill:none; stroke:rgba(255,255,255,.42); stroke-width:1;
  vector-effect:non-scaling-stroke; stroke-linecap:square;
}
.hero-plan .hi{ stroke:var(--hi); opacity:.78; }
.hero-plan .fade{ stroke:rgba(255,255,255,.2); }
.hero-plan .dash{ stroke:rgba(255,255,255,.2); stroke-dasharray:.02 .022; }
.hero-plan text.bub{
  fill:rgba(255,176,0,.85); stroke:none; text-anchor:middle;
  font-family:var(--f-mono); font-weight:500; font-size:18px;
}
.js .hero-plan *:not(.dash):not(text){ stroke-dasharray:1; stroke-dashoffset:1; }
.intro-done .hero-plan *:not(.dash):not(text){
  animation:draw 1.5s var(--e-out) forwards;
  animation-delay:calc(var(--dd, 0s) + .15s);
}

/* --- specification sections: clause-numbered the way a real spec is --- */
.spec-sec{
  display:grid; grid-template-columns:minmax(0,.85fr) minmax(0,1.15fr);
  gap:clamp(24px,4vw,68px);
  padding:clamp(34px,4.2vw,54px) 0; border-top:1px solid var(--line);
}
.spec-sec:last-of-type{ border-bottom:1px solid var(--line); }
.spec-no{
  font-family:var(--f-mono); font-weight:500; font-size:11px; letter-spacing:.2em;
  text-transform:uppercase; color:var(--hi-deep); margin-bottom:14px;
}
.spec-sec h2{
  font-family:var(--f-display); font-weight:800; text-transform:uppercase;
  font-size:clamp(24px,3.1vw,42px); line-height:1.02; letter-spacing:-.03em;
}
.spec-lead{ margin-top:16px; color:var(--steel); font-size:16px; line-height:1.6; }
/* Mono uppercase is a label device, not a body device — the sentence itself
   stays in the body face so it can actually be read. */
.spec-when{
  margin-top:22px; padding-top:16px; border-top:1px solid var(--line);
  font-size:14.5px; line-height:1.6; color:var(--steel);
}
.spec-when b{
  display:block; margin-bottom:8px;
  font-family:var(--f-mono); font-weight:500; font-size:10px;
  letter-spacing:.2em; text-transform:uppercase; color:var(--steel-2);
}

.clauses{ display:grid; gap:0; }
.clause{
  display:grid; grid-template-columns:auto minmax(0,1fr); gap:clamp(14px,2vw,26px);
  padding:13px 0; border-top:1px solid var(--line);
  font-size:15.5px; line-height:1.55; color:var(--steel);
  transition:background .4s var(--e-out), padding-left .5s var(--e-out);
}
.clause:first-child{ border-top:0; padding-top:0; }
.clause:hover{ background:rgba(255,176,0,.06); padding-left:10px; }
.clause i{
  font-style:normal; font-family:var(--f-mono); font-size:11px;
  letter-spacing:.08em; color:var(--steel-2); padding-top:3px;
  font-variant-numeric:tabular-nums;
}
.clause:hover i{ color:var(--hi-deep); }

/* --- delivery-method comparison matrix --- */
.matrix{ width:100%; border-collapse:collapse; font-size:15px; }
.matrix caption{ text-align:left; margin-bottom:18px; color:var(--steel); font-size:15.5px; }
.matrix th, .matrix td{
  text-align:left; padding:16px clamp(12px,1.6vw,22px);
  border-top:1px solid var(--line-dark); vertical-align:top;
}
.matrix thead th{
  border-top:0; padding-top:0; color:#fff;
  font-family:var(--f-display); font-weight:800; text-transform:uppercase;
  font-size:clamp(15px,1.5vw,19px); letter-spacing:-.014em;
}
.matrix thead th:first-child{
  font-family:var(--f-mono); font-weight:500; font-size:10.5px;
  letter-spacing:.2em; color:rgba(255,255,255,.5); text-transform:uppercase;
}
.matrix tbody th{
  font-family:var(--f-mono); font-weight:500; font-size:10.5px;
  letter-spacing:.16em; text-transform:uppercase; color:rgba(255,255,255,.55);
  width:clamp(140px,18vw,220px);
}
.matrix td{ color:rgba(255,255,255,.78); }
.matrix tbody tr{ transition:background .4s var(--e-out); }
.matrix tbody tr:hover{ background:rgba(255,176,0,.06); }
.matrix .yes{ color:var(--hi); }
.matrix-wrap{ overflow-x:auto; }

@media (max-width:860px){
  .spec-sec{ grid-template-columns:1fr; gap:26px; }
  .hero-plan{ opacity:.4; width:130vw; right:-34%; bottom:3%; }
  .matrix{ min-width:640px; }
}

/* ==========================================================================
   10h. PROJECTS — site plan, project register
   ========================================================================== */
.hero-site{
  position:absolute; right:-5%; bottom:0; width:min(62vw, 900px); height:auto;
  z-index:1; pointer-events:none; opacity:.7;
  translate:0 var(--dy, 0px); will-change:translate;
  -webkit-mask-image:
    linear-gradient(180deg, transparent, #000 18%, #000 92%, transparent),
    linear-gradient(90deg, transparent 0%, #000 32%);
  -webkit-mask-composite:source-in;
          mask-image:
    linear-gradient(180deg, transparent, #000 18%, #000 92%, transparent),
    linear-gradient(90deg, transparent 0%, #000 32%);
          mask-composite:intersect;
}
.hero-site *{
  fill:none; stroke:rgba(255,255,255,.42); stroke-width:1;
  vector-effect:non-scaling-stroke; stroke-linecap:square;
}
.hero-site .hi{ stroke:var(--hi); opacity:.78; }
.hero-site .fade{ stroke:rgba(255,255,255,.2); }
.hero-site .dash{ stroke:rgba(255,255,255,.24); stroke-dasharray:.012 .014; }
.hero-site text.bub{
  fill:rgba(255,176,0,.85); stroke:none; text-anchor:middle;
  font-family:var(--f-mono); font-weight:500; font-size:17px;
}
.js .hero-site *:not(.dash):not(text){ stroke-dasharray:1; stroke-dashoffset:1; }
.intro-done .hero-site *:not(.dash):not(text){
  animation:draw 1.5s var(--e-out) forwards;
  animation-delay:calc(var(--dd, 0s) + .15s);
}

/* --- placeholder artwork per building type, restored for the register ---
   Declared here, not inline: a url() inside a custom property resolves
   against the stylesheet, which is also what makes it work from disk. */
.media--distribution{ --art:url("../img/art/distribution.svg"); --art-size:86%; }
.media--retail      { --art:url("../img/art/retail.svg");       --art-size:86%; }
.media--restaurant  { --art:url("../img/art/restaurant.svg");   --art-size:86%; }
.media--healthcare  { --art:url("../img/art/healthcare.svg");   --art-size:86%; }
.media--education   { --art:url("../img/art/education.svg");    --art-size:86%; }
.media--residential { --art:url("../img/art/residential.svg");  --art-size:86%; }
.media--fuel        { --art:url("../img/art/fuel.svg");         --art-size:86%; }
.media--mixeduse    { --art:url("../img/art/mixeduse.svg");     --art-size:86%; }

/* --- register: filter bar with live counts --- */
.reg-bar{
  display:flex; flex-wrap:wrap; gap:14px 20px; align-items:flex-end;
  padding-bottom:20px; border-bottom:1px solid var(--line);
  margin-bottom:clamp(28px,3.4vw,44px);
}
/* the filter group carries its own rule elsewhere — inside the register bar
   that would double up with .reg-bar's, so strip it here */
.reg-bar .filters{
  flex:1 1 auto; margin-bottom:0; padding-bottom:0; border-bottom:0;
}
.reg-bar .reg-count{
  flex:none; margin-left:auto; white-space:nowrap;
  font-family:var(--f-mono); font-size:11px;
  letter-spacing:.16em; text-transform:uppercase; color:var(--steel-2);
  font-variant-numeric:tabular-nums;
}
.filters button b{
  font-weight:500; opacity:.55; margin-left:7px;
  font-variant-numeric:tabular-nums;
}

/* --- project index number over the drawing --- */
.proj{ position:relative; }
.proj-no{
  position:absolute; left:16px; top:14px; z-index:5;
  font-family:var(--f-mono); font-weight:500; font-size:11px;
  letter-spacing:.16em; color:rgba(255,255,255,.7);
}
.proj-tag{ font-family:var(--f-mono) !important; }

@media (max-width:860px){
  .hero-site{ opacity:.4; width:128vw; right:-32%; bottom:2%; }
}

/* ==========================================================================
   10i. CONTACT — wall-section detail, form sheet
   ========================================================================== */
.hero-detail{
  position:absolute; right:2%; bottom:-4%; width:min(30vw, 380px); height:auto;
  z-index:1; pointer-events:none; opacity:.72;
  translate:0 var(--dy, 0px); will-change:translate;
  -webkit-mask-image:linear-gradient(180deg, transparent, #000 16%, #000 88%, transparent);
          mask-image:linear-gradient(180deg, transparent, #000 16%, #000 88%, transparent);
}
.hero-detail *{
  fill:none; stroke:rgba(255,255,255,.42); stroke-width:1;
  vector-effect:non-scaling-stroke; stroke-linecap:square;
}
.hero-detail .hi{ stroke:var(--hi); opacity:.78; }
.hero-detail .fade{ stroke:rgba(255,255,255,.22); }
.hero-detail text.lbl{
  fill:rgba(255,176,0,.8); stroke:none;
  font-family:var(--f-mono); font-weight:500; font-size:19px; letter-spacing:.1em;
}
.js .hero-detail *:not(text){ stroke-dasharray:1; stroke-dashoffset:1; }
.intro-done .hero-detail *:not(text){
  animation:draw 1.5s var(--e-out) forwards;
  animation-delay:calc(var(--dd, 0s) + .15s);
}

/* --- the form presented as a sheet --- */
.form-sheet{ border:1px solid var(--line); background:var(--paper); }
.form-head{
  display:flex; justify-content:space-between; gap:16px; flex-wrap:wrap;
  padding:16px 22px; border-bottom:1px solid var(--line);
  font-family:var(--f-mono); font-weight:500; font-size:10.5px;
  letter-spacing:.2em; text-transform:uppercase; color:var(--steel-2);
}
.form-body{ padding:clamp(24px,3vw,36px) clamp(20px,2.6vw,30px); }
.form-legend{
  margin-top:18px; font-family:var(--f-mono); font-size:10.5px;
  letter-spacing:.14em; text-transform:uppercase; color:var(--steel-2);
}
.form-legend span{ color:var(--hi-deep); }

/* --- contact details as a schedule --- */
.info-block dt{ font-family:var(--f-mono) !important; }
.contact-grid{ align-items:start; }

@media (max-width:1024px){
  .hero-detail{ display:none; }
}

/* --- Title block, reused to close every page as it opened -----------------
   NOTE: this block was once lost to an over-wide section replacement, which
   left every closing title block unstyled. Keep it out of the 10x ranges. */
.titleblock--foot{
  background:none; backdrop-filter:none;
  margin-top:clamp(44px,5.5vw,74px);
}
.titleblock--foot .tb-inner{
  padding-inline:0; max-width:none;
  grid-template-columns:minmax(0,1.7fr) minmax(0,1fr) minmax(0,1.15fr) minmax(0,.75fr);
}
.titleblock--foot .tb-cell b{ font-size:clamp(16px,1.6vw,21px); letter-spacing:-.012em; }
.titleblock--foot .tb-cell:first-child b{ font-size:clamp(13px,1.3vw,17px); }
.titleblock--foot .tb-cell a{
  text-decoration:none; color:#fff; overflow-wrap:anywhere;
  background-image:linear-gradient(var(--hi), var(--hi));
  background-size:0 2px; background-position:0 100%; background-repeat:no-repeat;
  transition:background-size .5s var(--e-out), color .35s var(--e-out);
  padding-bottom:3px;
}
.titleblock--foot .tb-cell a:hover{ background-size:100% 2px; color:var(--hi); }

/* ---------- 11. Cards ---------------------------------------------------- */
.card{
  position:relative; background:var(--paper); border:1px solid var(--line);
  padding:clamp(26px,3vw,38px); display:flex; flex-direction:column; gap:14px;
  transition:border-color .5s var(--e-out), transform .5s var(--e-out), box-shadow .5s var(--e-out);
}
.card:hover{
  border-color:var(--ink); transform:translateY(-6px);
  box-shadow:0 30px 60px -40px rgba(0,0,0,.5);
}
.card .num{
  font-family:var(--f-display); font-weight:700; font-size:12px;
  letter-spacing:.2em; color:var(--steel-2); transition:color .4s var(--e-out);
}
.card:hover .num{ color:var(--hi-deep); }
.card p{ color:var(--steel); font-size:15.5px; }
.dark .card{ background:var(--ink-2); border-color:var(--ink-3); }
.dark .card:hover{ border-color:var(--hi); box-shadow:0 30px 60px -40px rgba(255,176,0,.35); }
.dark .card:hover .num{ color:var(--hi); }

/* Service card — accent rule draws across the top edge */
.svc::before{
  content:""; position:absolute; left:-1px; top:-1px; width:52px; height:3px;
  background:var(--hi); transform:scaleX(0); transform-origin:0 50%;
  transition:transform .55s var(--e-out);
}
.svc:hover::before{ transform:scaleX(1); }

.checks{ display:grid; gap:11px; margin-top:6px; }
.checks li{
  position:relative; padding-left:26px; font-size:15px; color:var(--steel); line-height:1.5;
}
.checks li::before{
  content:""; position:absolute; left:0; top:9px; width:9px; height:9px;
  border:2px solid var(--hi); background:transparent;
  transition:background .35s var(--e-out), transform .35s var(--e-out);
}
.card:hover .checks li::before,
.step:hover .checks li::before{ background:var(--hi); transform:rotate(45deg); }
.dark .checks li{ color:rgba(255,255,255,.72); }

/* ---------- 12. Project cards -------------------------------------------- */
.proj{
  position:relative; display:flex; flex-direction:column; text-decoration:none;
  border:1px solid var(--line); background:var(--paper);
  transition:border-color .5s var(--e-out), transform .5s var(--e-out), box-shadow .5s var(--e-out);
}
.proj:hover{
  border-color:var(--ink); transform:translateY(-6px);
  box-shadow:0 34px 64px -44px rgba(0,0,0,.55);
}

/* The blueprint panel is the media box's own background, not an error state.
   A real photo is a child element and simply covers it, so cards never flash
   a bare grey box while a lazy-loaded image is still pending. */
.media{
  position:relative; aspect-ratio:4/3; overflow:hidden;
  background:
    var(--art, url("../img/mark-ghost.png")) center 54% / var(--art-size, 44%) no-repeat,
    linear-gradient(rgba(255,255,255,.06) 1px, transparent 1px) 0 0 / 34px 34px,
    linear-gradient(90deg, rgba(255,255,255,.06) 1px, transparent 1px) 0 0 / 34px 34px,
    var(--ink);
}
.media img{
  width:100%; height:100%; object-fit:cover;
  transition:transform 1.1s var(--e-out), filter .7s var(--e-out);
}
.proj:hover .media img{ transform:scale(1.07); filter:saturate(1.08); }

/* Amber sheen sweeping diagonally across the photo on hover */
.media::before{
  content:""; position:absolute; inset:0; z-index:2; pointer-events:none;
  background:linear-gradient(115deg, transparent 38%, rgba(255,176,0,.16) 50%, transparent 62%);
  transform:translateX(-110%); transition:transform .95s var(--e-out);
}
.proj:hover .media::before{ transform:translateX(110%); }

/* Placeholder artwork, drawn line by line when the card scrolls into view —
   the same pathLength="1" trick as the hero elevation. A real photo is a
   later sibling at a higher z-index, so it simply covers this. */
.media-art{
  position:absolute; inset:0; z-index:1; pointer-events:none;
  display:grid; place-items:center; padding:9% 7%;
}
.media-art .art{ width:100%; height:auto; overflow:visible; }
.media-art .art *{
  fill:none; stroke:rgba(255,255,255,.5); stroke-width:1.15;
  vector-effect:non-scaling-stroke; stroke-linecap:square;
}
.media-art .art .hi{ stroke:var(--hi); opacity:.78; }
.media-art .art .fade{ stroke:rgba(255,255,255,.26); }
.js .media-art .art *{ stroke-dasharray:1; stroke-dashoffset:1; }
.js .in .media-art .art *{
  animation:draw 1.35s var(--e-out) forwards;
  animation-delay:calc(var(--dd, 0s) + .45s);
}
.media img{ position:relative; z-index:2; }
/* Cards carrying their own inline drawing drop the generic ghost mark */
.media--drawn{
  background:
    linear-gradient(rgba(255,255,255,.06) 1px, transparent 1px) 0 0 / 34px 34px,
    linear-gradient(90deg, rgba(255,255,255,.06) 1px, transparent 1px) 0 0 / 34px 34px,
    var(--ink);
}

/* Hide the broken-image glyph when the photo file is not there yet */
.media.is-empty img{ display:none; }

.proj-body{ padding:26px clamp(20px,2.4vw,30px) 30px; display:flex; flex-direction:column; gap:10px; flex:1; }
.proj-tag{
  font-family:var(--f-display); font-weight:700; font-size:11px;
  letter-spacing:.18em; text-transform:uppercase; color:var(--steel-2);
  transition:color .4s var(--e-out);
}
.proj:hover .proj-tag{ color:var(--hi-deep); }
.proj h3{ font-size:20px; line-height:1.2; text-transform:uppercase; letter-spacing:-.012em; }
.proj p{ font-size:15px; color:var(--steel); }
.proj .meta{
  margin-top:auto; padding-top:17px; border-top:1px solid var(--line);
  font-size:13px; color:var(--steel-2); display:flex; gap:4px 10px; flex-wrap:wrap;
}
/* Separator leads its own item, so a wrapped line never starts or ends
   on a dangling slash */
.proj .meta span + span::before{ content:"/"; color:var(--line); margin-right:10px; }

.pill{
  position:absolute; left:16px; top:16px; z-index:4;
  background:var(--hi); color:var(--ink);
  font-family:var(--f-display); font-weight:700; font-size:11px;
  letter-spacing:.14em; text-transform:uppercase; padding:7px 12px;
  display:inline-flex; align-items:center; gap:7px;
}
.pill::before{
  content:""; width:6px; height:6px; border-radius:50%; background:var(--ink);
  animation:blip 1.9s var(--e-io) infinite;
}
@keyframes blip{ 0%,100%{ opacity:1; transform:scale(1) } 50%{ opacity:.25; transform:scale(.7) } }

/* ---------- 13. Filter tabs ---------------------------------------------- */
.filters{
  display:flex; flex-wrap:wrap; gap:8px;
  margin-bottom:clamp(32px,4vw,50px);
  border-bottom:1px solid var(--line); padding-bottom:20px;
}
.filters button{
  position:relative; overflow:hidden; isolation:isolate;
  border:1px solid var(--line); background:transparent; cursor:pointer;
  padding:12px 19px; font-family:var(--f-display); font-weight:600; font-size:12.5px;
  letter-spacing:.12em; text-transform:uppercase; color:var(--steel);
  transition:color .4s var(--e-out), border-color .4s var(--e-out);
}
.filters button::before{
  content:""; position:absolute; inset:0; z-index:-1; background:var(--ink);
  transform:scaleY(0); transform-origin:50% 100%; transition:transform .45s var(--e-out);
}
.filters button:hover{ color:#fff; border-color:var(--ink); }
.filters button:hover::before{ transform:scaleY(1); }
.filters button[aria-pressed="true"]{ color:#fff; border-color:var(--ink); }
.filters button[aria-pressed="true"]::before{ transform:scaleY(1); }

/* Cards fade/slide as the filter changes */
.proj{ transition:border-color .5s var(--e-out), transform .5s var(--e-out),
        box-shadow .5s var(--e-out), opacity .35s var(--e-out); }
.js .filtering .proj{ opacity:0; transform:translateY(12px); }

/* ---------- 14. Numbered process ---------------------------------------- */
.steps{ counter-reset:s; display:grid; gap:0; }
.step{
  counter-increment:s; display:grid; position:relative;
  grid-template-columns:auto minmax(0,1fr) minmax(0,1.5fr);
  gap:clamp(16px,3vw,46px); align-items:start;
  padding:34px 0; border-top:1px solid var(--line);
  transition:padding-left .55s var(--e-out);
}
.step:last-child{ border-bottom:1px solid var(--line); }
.step::before{
  content:counter(s,decimal-leading-zero);
  font-family:var(--f-display); font-weight:800; font-size:15px;
  letter-spacing:.06em; color:var(--hi); padding-top:5px;
  transition:transform .55s var(--e-out);
}
/* amber wash bleeding in from the left edge on hover */
.step::after{
  content:""; position:absolute; left:calc(var(--gut) * -1); right:calc(var(--gut) * -1); top:0; bottom:0;
  z-index:-1; background:linear-gradient(90deg, rgba(255,176,0,.09), transparent 55%);
  opacity:0; transition:opacity .55s var(--e-out);
}
.step:hover{ padding-left:14px; }
.step:hover::before{ transform:scale(1.5); }
.step:hover::after{ opacity:1; }
.step h3{ text-transform:uppercase; font-size:clamp(18px,1.9vw,23px); }
.step p{ color:var(--steel); font-size:15.5px; }
.dark .step{ border-color:var(--ink-3); }

/* ---------- 15. Sector list ---------------------------------------------- */
.sectors{ display:grid; gap:0; }
.sector{
  position:relative; display:grid; align-items:baseline;
  grid-template-columns:auto clamp(150px,20vw,290px) minmax(0,1fr) auto;
  gap:clamp(14px,2.6vw,36px);
  padding:26px 0; border-top:1px solid var(--line-dark);
  transition:padding-left .6s var(--e-out);
}
.sector-idx{
  font-family:var(--f-mono); font-weight:500; font-size:11px; letter-spacing:.16em;
  color:rgba(255,255,255,.34); transition:color .5s var(--e-out); align-self:center;
}
.sector:hover .sector-idx{ color:var(--hi); }
.sector-arw{
  align-self:center; color:var(--hi); font-size:20px; line-height:1;
  opacity:0; transform:translateX(-10px);
  transition:opacity .5s var(--e-out), transform .5s var(--e-out);
}
.sector:hover .sector-arw{ opacity:1; transform:none; }
.sector:last-child{ border-bottom:1px solid var(--line-dark); }
.sector::after{
  content:""; position:absolute; left:calc(var(--gut) * -1); right:calc(var(--gut) * -1); top:0; bottom:0;
  z-index:-1; background:linear-gradient(90deg, rgba(255,176,0,.1), transparent 60%);
  opacity:0; transition:opacity .6s var(--e-out);
}
.sector:hover{ padding-left:18px; }
.sector:hover::after{ opacity:1; }
.sector b{
  font-family:var(--f-display); font-weight:800; text-transform:uppercase;
  font-size:clamp(21px,2.8vw,34px); letter-spacing:-.02em;
  flex:0 0 clamp(150px,22vw,300px); color:#fff;
  transition:color .5s var(--e-out);
}
.sector:hover b{ color:var(--hi); }
.sector-desc{ font-size:15.5px; color:rgba(255,255,255,.66); }

/* --- Sector artwork: hovering a row brings up that building type ---------
   Background images rather than inline SVG — these cross-fade, they do not
   need to draw themselves, and six inline drawings would bloat the page. */
.sectors{ position:relative; }
.sector-art{
  position:absolute; right:-3%; top:50%; z-index:0; pointer-events:none;
  width:min(40vw, 500px); aspect-ratio:600/380;
  transform:translateY(-50%) scale(.97);
  background-position:center; background-size:contain; background-repeat:no-repeat;
  opacity:0; transition:opacity .65s var(--e-out), transform .9s var(--e-out);
}
.sectors.is-showing .sector-art{ opacity:.3; transform:translateY(-50%) scale(1); }
.sector-art--commercial { --art:url("../img/art/distribution.svg"); }
.sector-art--retail     { --art:url("../img/art/retail.svg"); }
.sector-art--restaurant { --art:url("../img/art/restaurant.svg"); }
.sector-art--healthcare { --art:url("../img/art/healthcare.svg"); }
.sector-art--education  { --art:url("../img/art/education.svg"); }
.sector-art--residential{ --art:url("../img/art/residential.svg"); }
.sector-art{
  background-image:
    var(--art, none),
    linear-gradient(rgba(255,255,255,.05) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,.05) 1px, transparent 1px);
  background-size:84% auto, 26px 26px, 26px 26px;
  background-position:center 46%, 0 0, 0 0;
  background-repeat:no-repeat, repeat, repeat;
}
.sector{ position:relative; z-index:1; }
@media (max-width:1024px){ .sector-art{ display:none; } }

/* ---------- 16. Client marquee ------------------------------------------- */
.marquee{
  position:relative; overflow:hidden; padding-block:6px;
  -webkit-mask-image:linear-gradient(90deg, transparent, #000 8%, #000 86%, transparent);
          mask-image:linear-gradient(90deg, transparent, #000 8%, #000 86%, transparent);
}
.mq-track{ display:flex; width:max-content; animation:mq var(--mq-dur,46s) linear infinite; }
.marquee:hover .mq-track{ animation-play-state:paused; }
.marquee--rev .mq-track{ animation-direction:reverse; }
@keyframes mq{ to{ transform:translate3d(-50%,0,0); } }

.marquee--lg{ border-block:1px solid var(--line); padding-block:16px; }
.mq-track span{
  display:inline-flex; align-items:center; gap:22px; padding-inline:26px;
  font-family:var(--f-display); font-weight:800; font-size:clamp(22px,2.9vw,40px);
  letter-spacing:-.01em; text-transform:uppercase; white-space:nowrap;
  color:var(--ink); transition:color .35s var(--e-out);
  transform:skewX(var(--sk, 0deg)); will-change:transform;
}
.mq-track span::after{ content:""; width:7px; height:7px; background:var(--hi); flex:none; }
.marquee:hover .mq-track span{ color:var(--steel-2); }
.mq-track span:hover{ color:var(--hi-deep); }
.dark .mq-track span{ color:rgba(255,255,255,.9); }
.dark .marquee:hover .mq-track span{ color:rgba(255,255,255,.42); }
.dark .mq-track span:hover{ color:var(--hi); }

/* ---------- 17. CTA band ------------------------------------------------- */
.cta{ position:relative; background:var(--ink); color:#fff; padding-block:clamp(84px,10.5vw,150px); overflow:hidden; }
.cta .h2{ max-width:15ch; font-size:clamp(34px,5.2vw,68px); }
.cta-grid{
  display:grid; gap:clamp(28px,4vw,72px);
  grid-template-columns:minmax(0,1.15fr) minmax(0,1fr); align-items:center;
}
.cta-lines{ display:grid; gap:2px; }
.cta-lines a{
  position:relative; text-decoration:none; font-family:var(--f-display); font-weight:800;
  font-size:clamp(20px,2.3vw,28px); letter-spacing:-.018em; color:#fff;
  padding:18px 0; border-bottom:1px solid var(--line-dark);
  display:flex; flex-direction:column; align-items:flex-start; gap:5px;
  transition:color .45s var(--e-out), padding-left .5s var(--e-out);
  overflow-wrap:anywhere;
}
.cta-lines a::after{
  content:""; position:absolute; left:0; bottom:-1px; height:2px; width:100%;
  background:var(--hi); transform:scaleX(0); transform-origin:0 50%;
  transition:transform .55s var(--e-out);
}
.cta-lines a:hover{ color:var(--hi); padding-left:14px; }
.cta-lines a:hover::after{ transform:scaleX(1); }
.cta-lines a span{ font-family:var(--f-body); font-size:12px; font-weight:500;
  letter-spacing:.16em; text-transform:uppercase; color:rgba(255,255,255,.5); }
/* The email address is far longer than the other two — size it to fit one line */
.cta-lines a.is-email{ font-size:clamp(15px,1.75vw,21px); letter-spacing:-.005em; }

/* ---------- 18. Contact / form ------------------------------------------ */
.contact-grid{
  display:grid; gap:clamp(36px,5vw,80px);
  grid-template-columns:minmax(0,1fr) minmax(0,1.25fr); align-items:start;
}
.info-block{ padding:24px 0; border-top:1px solid var(--line); }
.info-block:first-of-type{ border-top:0; padding-top:0; }
.info-block dt{
  font-family:var(--f-display); font-weight:600; font-size:11.5px;
  letter-spacing:.2em; text-transform:uppercase; color:var(--steel-2); margin-bottom:9px;
}
.info-block dd{ margin:0; font-size:17px; }
.info-block dd > a{
  position:relative; text-decoration:none; padding-bottom:3px; word-break:break-word;
  background-image:linear-gradient(var(--hi), var(--hi));
  background-size:100% 2px; background-position:0 100%; background-repeat:no-repeat;
  transition:background-size .45s var(--e-out), color .3s var(--e-out);
}
.info-block dd > a:hover{ background-size:100% 100%; }

.form{ display:grid; gap:22px; }
.f-row{ display:grid; gap:22px; grid-template-columns:1fr 1fr; }
.field{ display:grid; gap:8px; }
.field label{
  font-family:var(--f-display); font-weight:600; font-size:11.5px;
  letter-spacing:.16em; text-transform:uppercase; color:var(--steel);
  transition:color .3s var(--e-out);
}
.field:focus-within label{ color:var(--ink); }
.field .req{ color:var(--hi-deep); }
.field input,.field select,.field textarea{
  font-family:var(--f-body); font-size:16px; color:var(--ink);
  padding:15px 17px; border:1px solid var(--line); background:var(--paper);
  border-radius:0; width:100%;
  transition:border-color .35s var(--e-out), box-shadow .35s var(--e-out);
}
.field input:hover,.field select:hover,.field textarea:hover{ border-color:var(--steel-2); }
.field input:focus,.field select:focus,.field textarea:focus{
  border-color:var(--ink); outline:none; box-shadow:0 3px 0 0 var(--hi);
}
.field textarea{ min-height:160px; resize:vertical; }
.field select{ appearance:none;
  background-image:linear-gradient(45deg,transparent 50%,var(--ink) 50%),linear-gradient(135deg,var(--ink) 50%,transparent 50%);
  background-position:calc(100% - 20px) 23px, calc(100% - 14px) 23px;
  background-size:6px 6px, 6px 6px; background-repeat:no-repeat; padding-right:44px; }
.hp{ position:absolute; left:-9999px; }
.form-note{ font-size:13.5px; color:var(--steel-2); }
.form-status{
  padding:16px 20px; border-left:3px solid var(--hi); background:var(--concrete);
  font-size:15px; display:none;
}
.form-status.show{ display:block; animation:popIn .55s var(--e-out) both; }
@keyframes popIn{ from{ opacity:0; transform:translateY(10px) } to{ opacity:1; transform:none } }

/* ==========================================================================
   18b. CUSTOM SELECT
   A native <select>'s dropdown list is drawn by the OS and cannot be styled,
   so JS upgrades it to a listbox. The real <select> stays in the form and
   still carries the value, which is what keeps the no-JS path working.
   ========================================================================== */
.sel{ position:relative; }
.sel-btn{
  width:100%; text-align:left; cursor:pointer;
  display:flex; align-items:center; justify-content:space-between; gap:12px;
  font-family:var(--f-body); font-size:16px; color:var(--ink);
  padding:15px 17px; border:1px solid var(--line); background:var(--paper);
  transition:border-color .35s var(--e-out), box-shadow .35s var(--e-out);
}
.sel-btn:hover{ border-color:var(--steel-2); }
.sel.is-open .sel-btn{ border-color:var(--ink); box-shadow:0 3px 0 0 var(--hi); }
.sel-btn[data-empty="true"] .sel-val{ color:var(--steel-2); }
.sel-arw{
  flex:none; width:8px; height:8px; margin-bottom:3px;
  border-right:1.5px solid var(--ink); border-bottom:1.5px solid var(--ink);
  transform:rotate(45deg); transition:transform .4s var(--e-out);
}
.sel.is-open .sel-arw{ transform:rotate(-135deg) translate(-3px,-3px); }

.sel-list{
  position:absolute; left:0; right:0; top:calc(100% + 6px); z-index:40;
  background:var(--paper); border:1px solid var(--ink);
  box-shadow:0 34px 64px -34px rgba(0,0,0,.45);
  max-height:min(330px, 52vh); overflow-y:auto; overscroll-behavior:contain;
  opacity:0; visibility:hidden; transform:translateY(-6px);
  transition:opacity .22s var(--e-out), transform .3s var(--e-out), visibility .3s;
}
.sel.is-open .sel-list{ opacity:1; visibility:visible; transform:none; }
.sel-list li{
  display:grid; grid-template-columns:auto auto minmax(0,1fr); align-items:center;
  gap:13px; padding:12px 17px; cursor:pointer;
  font-size:15.5px; color:var(--steel);
  border-top:1px solid var(--line);
  transition:background .2s var(--e-out), color .2s var(--e-out);
}
.sel-list li:first-child{ border-top:0; }
.sel-list li i{
  font-style:normal; font-family:var(--f-mono); font-size:10.5px;
  letter-spacing:.1em; color:var(--steel-2); font-variant-numeric:tabular-nums;
}
.sel-list li b{
  display:block; width:9px; height:9px; flex:none;
  border:1.5px solid var(--line); background:transparent;
  transition:background .2s var(--e-out), border-color .2s var(--e-out);
}
.sel-list li.is-active{ background:rgba(255,176,0,.1); color:var(--ink); }
.sel-list li.is-active i{ color:var(--hi-deep); }
.sel-list li[aria-selected="true"]{ color:var(--ink); }
.sel-list li[aria-selected="true"] b{ background:var(--hi); border-color:var(--hi); }

/* the real control still submits; it just stops being the visible one */
.field select.is-upgraded{ display:none; }

/* ---------- 19. Footer ---------------------------------------------------
   Built as a title block: four columns divided by full-height hairlines, so
   the difference in column length reads as structure rather than as a hole.
   ------------------------------------------------------------------------ */
.site-foot{
  background:var(--ink); color:rgba(255,255,255,.6);
  padding-block:0 30px; border-top:1px solid var(--ink-3);
  overflow:hidden;
}
.foot-grid{
  display:grid; gap:0; align-items:stretch;
  grid-template-columns:minmax(0,1.45fr) minmax(0,1fr) minmax(0,1.05fr) minmax(0,1.2fr);
}
.foot{
  padding:clamp(38px,4.4vw,58px) clamp(18px,2.2vw,32px) clamp(34px,4vw,52px) 0;
  border-right:1px solid var(--ink-3);
}
.foot:last-child{ border-right:0; padding-right:0; }
.foot-brand{ padding-right:clamp(26px,3.2vw,46px); }
.foot-logo{ width:124px; margin-bottom:22px; }
.foot h4{
  font-family:var(--f-mono); font-weight:500; font-size:10.5px;
  letter-spacing:.22em; text-transform:uppercase; color:rgba(255,255,255,.5);
  margin-bottom:20px;
}
.foot ul{ display:grid; gap:12px; }
.foot a{
  text-decoration:none; font-size:14.5px; color:rgba(255,255,255,.62);
  transition:color .35s var(--e-out), transform .35s var(--e-out);
  display:inline-block; word-break:break-word;
}
.foot a:hover{ color:var(--hi); transform:translateX(5px); }
.foot .btn{ margin-top:24px; }
.foot-hours{
  margin-top:22px; font-size:13px; line-height:1.5; color:rgba(255,255,255,.42);
}

/* Oversized outline wordmark anchoring the footer. Two lines, each sized to
   sit inside the gutter rather than bleeding off and reading as a clipping
   bug — the longest line is "MZ CONSTRUCTION" at 15 characters. */
.foot-word{
  margin-top:clamp(38px,4.6vw,64px);
  font-family:var(--f-display); font-weight:900; text-transform:uppercase;
  font-size:min(7.9vw, 111px); line-height:.86; letter-spacing:-.045em;
  color:transparent; -webkit-text-stroke:1px rgba(255,255,255,.17);
  user-select:none; pointer-events:none;
}
.foot-word span{ display:block; white-space:nowrap; }
@supports not (-webkit-text-stroke: 1px white){
  .foot-word{ color:rgba(255,255,255,.07); }
}
.foot-base{
  margin-top:clamp(26px,3.2vw,42px); padding-top:24px; border-top:1px solid var(--ink-3);
  display:flex; justify-content:space-between; gap:16px; flex-wrap:wrap; font-size:13px;
}
.foot-base a{ color:rgba(255,255,255,.62); }

@media (max-width:1024px){
  /* Two columns: brand across the top, then Navigate | Services, then Contact
     spanning full width with its details laid out along the row so it does
     not leave a void beside it. Dividers stated explicitly rather than by
     nth-child parity, which inverts once .foot-brand spans. */
  .foot-grid{ grid-template-columns:repeat(2, minmax(0,1fr)); }
  .foot{ border-top:1px solid var(--ink-3); }
  .foot-brand{ grid-column:1 / -1; border-top:0; border-right:0; padding-right:0; }
  .foot:nth-child(2){ border-right:1px solid var(--ink-3); }
  .foot:nth-child(3){ border-right:0; padding-right:0; }
  .foot:nth-child(4){ grid-column:1 / -1; border-right:0; padding-right:0; }
  .foot:nth-child(4) ul{ display:flex; flex-wrap:wrap; gap:12px clamp(20px,4vw,44px); }
  .foot-hours{ max-width:62ch; }
}
@media (max-width:620px){
  .foot-grid{ grid-template-columns:1fr; }
  .foot{ border-right:0; padding-right:0; padding-block:30px; }
  .foot:not(.foot-brand){ border-top:1px solid var(--ink-3); }
}

/* ---------- 20. Responsive ---------------------------------------------- */
/* --- new-section responsive ------------------------------------------- */
@media (max-width:1024px){
  .tb-inner,
  .titleblock--foot .tb-inner{ grid-template-columns:repeat(2,1fr); }
  .tb-cell{ padding-bottom:22px; }
  .tb-cell:nth-child(2n){ border-right:0; padding-right:0; }
  .tb-cell:nth-child(-n+2){ border-bottom:1px solid rgba(255,255,255,.11); }
  .statement-grid{ grid-template-columns:1fr; align-items:start; }
  .work-grid{ grid-template-columns:1fr; }
  .pcard--lead .media{ aspect-ratio:16/10; min-height:0; flex:0 0 auto; }
  .scrolltext{ max-width:26ch; }
}

@media (max-width:860px){
  .svc-detail{
    grid-template-columns:1fr; gap:20px;
    padding-left:clamp(28px,6vw,44px);
  }
  /* Stack the schedule: label over a full-width track, so the bars keep
     enough room to stay readable on a phone */
  .gantt-scale{ display:none; }
  .gantt-row{ grid-template-columns:1fr; gap:10px; padding:18px 0; }
  .gantt-track{ height:36px; }
  /* Bars get narrow enough to clip their own captions; position and colour
     still carry the meaning, and the row label states it in full */
  .gantt-bar > span{ display:none; }
  .sector{ grid-template-columns:auto minmax(0,1fr); row-gap:8px; }
  .sector-desc{ grid-column:1 / -1; }
  .sector-arw{ display:none; }
  .hero-draw{ opacity:.42; width:112vw; right:-24%; bottom:6%; }
  /* The gutter is too narrow here for the sheet number to clear body copy */
  .sheet-no{ display:none; }
}

@media (max-width:620px){
  .tb-inner,
  .titleblock--foot .tb-inner{ grid-template-columns:1fr; }
  .tb-cell{ border-right:0; padding-right:0; border-bottom:1px solid rgba(255,255,255,.11); }
  .tb-cell:last-child{ border-bottom:0; }
  .svc-head{ grid-template-columns:auto minmax(0,1fr) auto; gap:14px; }
  .svc-num{ padding-top:.45em; }
  .gantt-label em{ font-size:12.5px; }
}

@media (max-width:1024px){
  .g-4{ grid-template-columns:repeat(2,1fr); }
  .stats{ grid-template-columns:repeat(2,1fr); }
  .stat{ padding-bottom:28px; border-bottom:1px solid var(--line-dark); }
  .stat:nth-child(2n){ border-right:0; }
  .lede{ grid-template-columns:1fr; align-items:start; }
  .cta-grid,.contact-grid{ grid-template-columns:1fr; }
  .head-cta .tel{ display:none; }
}

@media (max-width:860px){
  .g-3{ grid-template-columns:repeat(2,1fr); }
  .foot-grid{ grid-template-columns:1fr 1fr; }
  .foot-brand{ grid-column:1/-1; }
  .step{ grid-template-columns:auto minmax(0,1fr); }
  /* :last-child, not p — the services page puts a <div> in that slot, and
     letting it fall into the auto-sized number column blows out the page */
  .step > :last-child{ grid-column:2; min-width:0; }

  /* Mobile nav */
  .burger{ display:grid; order:3; }
  .nav{
    position:fixed; inset:var(--head-h) 0 auto 0; display:grid; gap:0;
    background:var(--paper); border-bottom:1px solid var(--line);
    box-shadow:var(--sh-3);
    padding:8px var(--gut) 26px; align-items:stretch;
    clip-path:inset(0 0 100% 0); opacity:0; visibility:hidden;
    transition:clip-path .6s var(--e-out), opacity .4s var(--e-out), visibility .6s;
    max-height:calc(100svh - var(--head-h)); overflow:auto;
  }
  .nav.open{ clip-path:inset(0 0 0 0); opacity:1; visibility:visible; }
  .nav a{
    padding:17px 0; border-bottom:1px solid var(--line); font-size:15px;
    opacity:0; transform:translateY(10px);
    transition:opacity .5s var(--e-out), transform .5s var(--e-out);
  }
  .nav.open a{ opacity:1; transform:none; transition-delay:var(--nd,0ms); }
  .nav a::after{ display:none; }
  .nav a[aria-current="page"]{ color:var(--steel-2); }
  .head-cta .btn{ display:none; }
  .hero-mark{ display:none; }

  .nav .nav-mob{ display:block; }
  .nav .nav-mob--cta{ border-bottom:0; padding:18px 0 4px; }
  .nav .nav-mob--cta span{
    display:block; text-align:center; background:var(--ink); color:#fff;
    padding:16px 20px; letter-spacing:.13em;
  }
}

@media (max-width:620px){
  body{ font-size:16px; }
  .g-2,.g-3,.g-4{ grid-template-columns:1fr; }
  .stats{ grid-template-columns:1fr; }
  .stat{ border-right:0; padding-right:0; }
  .f-row{ grid-template-columns:1fr; }
  .sector{ flex-direction:column; gap:6px; }
  .sector b{ flex:none; }
  .foot-grid{ grid-template-columns:1fr; }
  .step:hover, .sector:hover{ padding-left:0; }
}

/* ---------- Reduced motion: strip every non-essential movement ---------- */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:.01ms !important; animation-iteration-count:1 !important;
    transition-duration:.01ms !important; scroll-behavior:auto !important;
  }
  .js [data-rv]{ opacity:1 !important; transform:none !important; clip-path:none !important; }
  /* decorative, and its reveal is clamped to nothing here — just show it */
  .js .sect-edge{ transform:none !important; }
  .js .split .w > span{ transform:none !important; }
  .js .media-wipe::after{ display:none; }
  .mq-track{ animation:none; }
  .hero-scan, .scroll-cue i::after, .pill::before{ display:none; }
  .progress{ display:none; }
}

@media print{
  .site-head,.cta,.burger,.btn-row,.progress,.marquee,.foot-word{ display:none; }
  body{ color:#000; }
  body::after{ display:none; }
}

/* ==========================================================================
   PHOTO OVERRIDES — edit this block once you have real photography
   --------------------------------------------------------------------------
   Save a wide, high-res shot as  assets/img/hero.jpg  then delete the two
   slashes at the start of the --hero-img line below.
   --hero-op controls how dark the photo sits behind the headline (0–1).
   ========================================================================== */
.hero{
  /* --hero-img: url("../img/hero.jpg"); */
  --hero-op: .34;
}

/* ==========================================================================
   21. v47 — THE SHEET COMES ALIVE
   Everything below layers on top of the drawing-sheet system without
   changing its tokens: an isometric skyline that builds itself in the hero,
   a trailing instrument cursor, and scroll-linked furniture down the page.
   ========================================================================== */

/* --- 21a. Hero: generative skyline ------------------------------------- */
.hero-city{
  position:absolute; inset:0; z-index:1; width:100%; height:100%;
  pointer-events:none; display:block;
  translate:0 var(--dy, 0px); will-change:translate;
  /* fade out toward the copy on the left, and off the top edge */
  -webkit-mask-image:
    linear-gradient(90deg, transparent 22%, rgba(0,0,0,.35) 46%, #000 62%),
    linear-gradient(180deg, transparent 4%, #000 26%, #000 92%, rgba(0,0,0,.4));
  -webkit-mask-composite:source-in;
          mask-image:
    linear-gradient(90deg, transparent 22%, rgba(0,0,0,.35) 46%, #000 62%),
    linear-gradient(180deg, transparent 4%, #000 26%, #000 92%, rgba(0,0,0,.4));
          mask-composite:intersect;
  opacity:0; transition:opacity 1.2s var(--e-out) .2s;
}
.intro-done .hero-city, html:not(.js) .hero-city{ opacity:1; }

/* A low sun behind the skyline: warm at the horizon, cooling upward. This is
   what makes the black read as night sky over a lit site instead of a void. */
.hero-horizon{
  position:absolute; inset:0; z-index:0; pointer-events:none;
  background:
    radial-gradient(56% 42% at 74% 62%, rgba(255,176,0,.16), transparent 70%),
    radial-gradient(38% 30% at 78% 66%, rgba(255,120,0,.10), transparent 70%),
    linear-gradient(180deg, rgba(255,255,255,.028), transparent 40%);
  opacity:0; transition:opacity 1.6s var(--e-out) .3s;
}
.intro-done .hero-horizon, html:not(.js) .hero-horizon{ opacity:1; }
.hero-glow{ background:radial-gradient(560px circle at var(--mx,72%) var(--my,44%), rgba(255,176,0,.11), transparent 64%); }

@media (max-width:860px){
  .hero-city{
    -webkit-mask-image:linear-gradient(180deg, transparent 0%, rgba(0,0,0,.35) 40%, #000 60%, #000 100%);
            mask-image:linear-gradient(180deg, transparent 0%, rgba(0,0,0,.35) 40%, #000 60%, #000 100%);
    opacity:.45;
  }
  .intro-done .hero-city{ opacity:.45; }
}

/* --- 21b. Hero: headline by the character ------------------------------ */
.split--chars .w{ padding-bottom:.08em; margin-bottom:-.08em; white-space:nowrap; }
.js .split--chars .c{
  display:inline-block; transform:translate3d(0,112%,0) rotate(6deg);
  transform-origin:0 100%; opacity:0;
  transition:transform 1.1s var(--e-out), opacity .5s var(--e-out);
  transition-delay:var(--d, 0ms);
}
.js .split--chars.in .c{ transform:none; opacity:1; }
/* the words in mark keep flowing as normal inline content */
.h1 mark.hl{ background:none; color:inherit; }

/* Marker highlight sweeps in behind "final punchlist" once the letters have
   landed — one stroke per word, so it can never run past a line break — and
   the letters go to ink so it reads like a real hi-vis marker. */
.hl .w{ position:relative; isolation:isolate; }
.hl .w::before{
  content:""; position:absolute; z-index:-1; left:-.05em; right:-.05em; top:.08em; bottom:0;
  background:var(--hi); transform:scaleX(0); transform-origin:0 50%;
  transition:transform .8s var(--e-out);
}
.hl .c{ transition:color .5s var(--e-out); }
.intro-done .split--chars.in .hl .w::before{ transform:scaleX(1); transition-delay:1.15s; }
.intro-done .split--chars.in .hl .w:nth-of-type(2)::before{ transition-delay:1.4s; }
.intro-done .split--chars.in .hl .c{ color:var(--ink); transition:color .5s var(--e-out) 1.35s, transform 1.1s var(--e-out) var(--d), opacity .5s var(--e-out) var(--d); }
/* no-JS: the marker is simply there */
html:not(.js) .hl{ background:var(--hi); color:var(--ink); }

.hero--home .scroll-cue{ margin-top:clamp(18px,2.6vh,30px); opacity:0; }
.intro-done .hero--home .scroll-cue{ animation:fadeIn 1s var(--e-out) 2s forwards; }
.hero--home .sub{ opacity:0; filter:blur(6px); transform:translateY(10px); }
.intro-done .hero--home .sub{ animation:blurIn 1.2s var(--e-out) 1s forwards; }
.hero--home .btn-row{ opacity:0; transform:translateY(14px); }
.intro-done .hero--home .btn-row{ animation:blurIn 1.1s var(--e-out) 1.3s forwards; }
.hero--home .eyebrow{ opacity:0; }
.intro-done .hero--home .eyebrow{ animation:fadeIn .8s var(--e-out) .3s forwards; }
html:not(.js) .hero--home :is(.sub,.btn-row,.eyebrow,.scroll-cue){ opacity:1; filter:none; transform:none; }
@keyframes blurIn{ to{ opacity:1; filter:blur(0); transform:none; } }

/* Every reveal on the page: headings arrive with a breath of blur as well as
   the rise, which reads as focus being pulled rather than a slide. */
.js .lede .sub{ opacity:0; filter:blur(5px); transform:translateY(12px);
  transition:opacity .9s var(--e-out) .25s, filter .9s var(--e-out) .25s, transform 1s var(--e-out) .25s; }
.js .lede.in .sub{ opacity:1; filter:blur(0); transform:none; }

/* --- 21c. Cursor -------------------------------------------------------- */
.cursor{ position:fixed; inset:0; z-index:500; pointer-events:none; display:none; }
.has-cursor .cursor{ display:block; }
.cur-ring, .cur-dot, .cur-label{
  position:absolute; left:0; top:0; will-change:transform;
}
.cur-ring::before{
  content:""; position:absolute; left:-18px; top:-18px; width:36px; height:36px;
  border:1px solid rgba(255,176,0,.9); border-radius:50%;
  transition:transform .45s var(--e-out), background .4s var(--e-out), border-color .4s var(--e-out), opacity .3s;
  transform:scale(.7); box-sizing:border-box;
}
.cur-dot::before{
  content:""; position:absolute; left:-2.5px; top:-2.5px; width:5px; height:5px;
  border-radius:50%; background:var(--hi);
  transition:transform .3s var(--e-out), opacity .3s;
}
.cursor.is-hover .cur-ring::before{ transform:scale(1.35); background:rgba(255,176,0,.10); }
.cursor.is-down  .cur-ring::before{ transform:scale(.55); background:rgba(255,176,0,.35); }
.cursor.is-text  .cur-ring::before{ opacity:0; }
.cursor.is-word  .cur-ring::before{ transform:scale(2.2); background:var(--hi); border-color:var(--hi); }
.cursor.is-word  .cur-dot::before{ opacity:0; }
.cur-label{
  font-family:var(--f-mono); font-weight:600; font-size:9.5px; letter-spacing:.2em;
  text-transform:uppercase; color:var(--ink); white-space:nowrap;
  opacity:0; transition:opacity .3s var(--e-out);
}
.cur-label{ display:grid; place-items:center; width:0; height:0; }
.cursor.is-word .cur-label{ opacity:1; }

/* --- 21d. Statement: ghost numeral ------------------------------------- */
.statement{ overflow:hidden; }
.wm-ghost{
  position:absolute; right:2%; top:50%; z-index:0; pointer-events:none; user-select:none;
  font-family:var(--f-display); font-weight:900; line-height:.8; letter-spacing:-.06em;
  font-size:clamp(240px, 36vw, 560px);
  color:transparent; -webkit-text-stroke:1.5px rgba(10,10,10,.11);
  transform:translate3d(0, calc(-50% + var(--py, 0px)), 0);
  will-change:transform;
}
@supports not (-webkit-text-stroke:1px #000){ .wm-ghost{ color:rgba(10,10,10,.035); } }
.statement .wrap{ position:relative; z-index:1; }
@media (max-width:1024px){ .wm-ghost{ font-size:clamp(200px,44vw,360px); top:auto; bottom:-.1em; transform:none; } }

/* --- 21e. Services: the sheet stack --------------------------------------
   Five services, five sheets. Each pins just below the header as it arrives
   and the next one slides up over it, so the set stacks like drawings on a
   plan table; the ones underneath step back and dim. JS writes --depth on
   each sheet (how many sheets sit on top of it); everything else is CSS. */
.sheets{ position:relative; margin-top:clamp(28px,3.5vw,44px); }
.sheet{
  position:sticky; top:calc(var(--head-h-stuck) + 26px + var(--i,0) * 14px);
  padding-bottom:clamp(20px,2.6vw,36px);
}
.sheet-in{
  position:relative; overflow:hidden; isolation:isolate;
  min-height:clamp(460px, 64vh, 600px);
  background:var(--ink); color:#fff;
  box-shadow:var(--sh-3), 0 -1px 0 rgba(255,255,255,.18);
  transform-origin:50% 0;
  transform:scale(calc(1 - var(--depth,0) * .04)) translateY(calc(var(--depth,0) * -6px));
  filter:brightness(calc(1 - var(--depth,0) * .22));
  transition:transform .6s var(--e-out), filter .6s var(--e-out);
  will-change:transform, filter;
  display:grid; grid-template-rows:auto 1fr;
}
.sheet-in::before{                    /* survey grid + top-lit falloff */
  content:""; position:absolute; inset:0; z-index:-1; pointer-events:none;
  background:
    radial-gradient(90% 60% at 80% 0%, rgba(255,176,0,.10), transparent 60%),
    linear-gradient(rgba(255,255,255,.045) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,.045) 1px, transparent 1px);
  background-size:auto, 34px 34px, 34px 34px;
}
.sheet-in .reg{ opacity:1; animation:none; width:18px; height:18px; }
.sheet-in .reg--tl{ top:14px; left:14px; } .sheet-in .reg--tr{ top:14px; right:14px; }
.sheet-in .reg--bl{ bottom:14px; left:14px; } .sheet-in .reg--br{ bottom:14px; right:14px; }
.sheet-in .reg::before, .sheet-in .reg::after{ background:rgba(255,255,255,.35); }

.sheet-head{
  display:flex; justify-content:space-between; gap:16px;
  padding:16px clamp(22px,3vw,44px) 14px;
  border-bottom:1px solid rgba(255,255,255,.14);
  font-family:var(--f-mono); font-weight:500; font-size:10.5px; letter-spacing:.2em;
  text-transform:uppercase; color:rgba(255,255,255,.55);
}
.sheet-head span:first-child{ color:var(--hi); }
.sheet-head .sheet-title{ color:rgba(255,255,255,.4); }
@media (max-width:620px){ .sheet-head .sheet-title{ display:none; } }

.sheet-body{
  display:grid; grid-template-columns:minmax(0,1.05fr) minmax(0,.95fr);
  gap:clamp(24px,4vw,64px); align-items:center;
  padding:clamp(28px,3.6vw,52px) clamp(22px,3vw,44px) clamp(30px,3.6vw,52px);
}
.sheet-copy{ position:relative; }
.sheet-ghost{
  position:absolute; left:-.06em; top:-.42em; z-index:0; pointer-events:none; user-select:none;
  font-family:var(--f-display); font-weight:900; font-size:clamp(150px,16vw,240px); line-height:1;
  letter-spacing:-.06em; color:transparent; -webkit-text-stroke:1px rgba(255,255,255,.12);
}
.sheet-copy > *:not(.sheet-ghost){ position:relative; z-index:1; }
.sheet-idx{
  display:inline-flex; align-items:center; gap:10px;
  font-family:var(--f-mono); font-weight:500; font-size:11.5px; letter-spacing:.22em; color:var(--hi);
  margin-bottom:18px;
}
.sheet-idx::before{ content:""; width:34px; height:2px; background:var(--hi); }
.sheet-copy h3{
  font-family:var(--f-display); font-weight:800; text-transform:uppercase;
  font-size:clamp(28px,3.6vw,50px); line-height:.98; letter-spacing:-.032em; color:#fff;
  max-width:12ch;
}
.sheet-copy p{ margin-top:18px; font-size:clamp(15px,1.15vw,17px); line-height:1.6; color:rgba(255,255,255,.74); max-width:48ch; }
.sheet-copy .checks{ margin-top:22px; gap:10px; }
.sheet-copy .checks li{ color:rgba(255,255,255,.8); font-size:14.5px; }
.sheet-copy .tlink{ margin-top:26px; color:#fff; }
.sheet-copy .tlink::after{ background:var(--hi); }

.sheet-fig{ margin:0; position:relative; }
.sheet-fig svg{ width:100%; height:auto; overflow:visible; display:block; }
.sheet-fig figcaption{
  margin-top:12px; padding-top:10px; border-top:1px solid rgba(255,255,255,.14);
  font-family:var(--f-mono); font-weight:500; font-size:10px; letter-spacing:.18em;
  text-transform:uppercase; color:rgba(255,255,255,.5);
}
.sheet-fig svg *{ fill:none; stroke-width:1.6; vector-effect:non-scaling-stroke; stroke-linecap:square; stroke-linejoin:miter; }
.sheet-fig .ln  *{ stroke:rgba(255,255,255,.62); }
.sheet-fig .fade *{ stroke:rgba(255,255,255,.28); }
.sheet-fig .hi *{ stroke:var(--hi); stroke-width:1.8; }
.sheet-fig .hi rect{ fill:rgba(255,176,0,.06); }
.sheet-fig .dash{ stroke-dasharray:.03 .025 !important; }
.js .sheet-fig svg *:not(g):not(.dash){ stroke-dasharray:1; stroke-dashoffset:1; }
.js .sheet.in .sheet-fig svg *:not(g):not(.dash){ animation:draw 1.3s var(--e-out) forwards; animation-delay:calc(var(--dd,0s) + .3s); }
.js .sheet-fig .dash{ opacity:0; transition:opacity .8s var(--e-out) 1.6s; }
.js .sheet.in .sheet-fig .dash{ opacity:1; }

/* Content of each sheet arrives after the sheet does */
.js .sheet .sheet-copy > *:not(.sheet-ghost), .js .sheet .sheet-fig{
  opacity:0; transform:translateY(16px);
  transition:opacity .8s var(--e-out), transform .9s var(--e-out);
}
.js .sheet.in .sheet-copy > *:not(.sheet-ghost), .js .sheet.in .sheet-fig{ opacity:1; transform:none; }
.js .sheet.in .sheet-copy > :nth-child(2){ transition-delay:.05s; }
.js .sheet.in .sheet-copy > :nth-child(3){ transition-delay:.12s; }
.js .sheet.in .sheet-copy > :nth-child(4){ transition-delay:.19s; }
.js .sheet.in .sheet-copy > :nth-child(5){ transition-delay:.26s; }
.js .sheet.in .sheet-copy > :nth-child(6){ transition-delay:.33s; }
.js .sheet.in .sheet-fig{ transition-delay:.15s; }

/* Below 900px the figure drops under the copy and a sheet grows taller than
   the viewport — stacking would then bury each figure before it was seen, so
   the sheets simply flow, one after another, with the same drawn entrance. */
@media (max-width:900px){
  .sheet-body{ grid-template-columns:1fr; gap:26px; }
  .sheet-fig{ max-width:520px; }
  .sheet-in{ min-height:0; transform:none !important; filter:none !important; }
  .sheet{ position:relative; top:auto; padding-bottom:18px; }
}
@media (max-width:620px){
  .sheet-ghost{ font-size:120px; }
}

/* --- 21f. Featured work: tilt + plotter scan --------------------------- */
.pj{
  transform:perspective(900px) rotateX(var(--rx,0deg)) rotateY(var(--ry,0deg)) translateY(var(--ty,0px));
  transition:border-color .45s var(--e-out), transform .55s var(--e-out);
  transform-style:preserve-3d;
}
.pj:hover, .pj:focus-visible{ --ty:-5px; transform:perspective(900px) rotateX(var(--rx,0deg)) rotateY(var(--ry,0deg)) translateY(var(--ty,0px)); }
.pj h3{ transition:color .4s var(--e-out); }
.pj:hover h3{ color:var(--hi); }
.elev-inner{ position:relative; }
.elev-scan{
  position:absolute; top:0; bottom:0; width:1px; left:0; z-index:2; pointer-events:none;
  background:linear-gradient(180deg, transparent, rgba(255,176,0,.75) 30%, rgba(255,176,0,.75) 70%, transparent);
  box-shadow:0 0 18px rgba(255,176,0,.35);
  opacity:0;
}
.js .elev-band.is-scanning .elev-scan{ animation:plot 9s var(--e-io) 1.6s infinite; }
@keyframes plot{
  0%{ left:2%; opacity:0 } 6%{ opacity:1 } 44%{ opacity:1 } 50%{ left:98%; opacity:0 } 100%{ left:98%; opacity:0 }
}

/* --- 21g. Sectors: the drawing follows the pointer ----------------------
   Hovering a row summons that building type as a small framed sheet that
   trails the cursor, lagging a beat so it feels carried rather than glued. */
.sector-art{
  right:auto; top:0; left:0; width:min(30vw,380px); aspect-ratio:600/380; height:auto;
  transform:translate3d(calc(var(--sx,0px) + 36px), calc(var(--sy,0px) - 100% - 22px), 0) scale(.92);
  transition:opacity .45s var(--e-out), transform .6s var(--e-out);
  background-color:var(--ink);

  outline:1px solid rgba(255,176,0,.45); outline-offset:-1px;
  box-shadow:var(--sh-3), 0 0 0 1px rgba(255,255,255,.06);
  will-change:transform;
  z-index:2;
}
.sector-art::after{
  content:"Fig. \2014  building type"; position:absolute; left:12px; bottom:9px;
  font-family:var(--f-mono); font-size:9px; letter-spacing:.2em; text-transform:uppercase;
  color:rgba(255,176,0,.8);
}
.sectors.is-showing .sector-art{
  opacity:1; transform:translate3d(calc(var(--sx,0px) + 36px), calc(var(--sy,0px) - 100% - 22px), 0) scale(1);
}
.sectors::after{                            /* pointer halo across the whole list */
  content:""; position:absolute; inset:0; z-index:0; pointer-events:none;
  background:radial-gradient(420px circle at var(--sx, 50%) var(--sy, 50%), rgba(255,176,0,.07), transparent 70%);
  opacity:0; transition:opacity .5s var(--e-out);
}
.sectors.is-showing::after{ opacity:1; }
/* keep the card inside the list on the right-hand half of the screen */
.sectors.art-flip .sector-art{ transform:translate3d(calc(var(--sx,0px) - 100% - 36px), calc(var(--sy,0px) - 100% - 22px), 0) scale(1); }

/* --- 21g2. Sectors: the drafting table --------------------------------
   Six sector sheets on a hairline grid. Each carries its building type as an
   inline drawing that draws itself when the tile arrives; the pointer lights
   a spotlight inside whichever tile it is over, and hover ignites the whole
   drawing amber and lifts the tile off the table. */
.tiles{
  display:grid; grid-template-columns:repeat(3, minmax(0,1fr)); gap:1px;
  background:rgba(255,255,255,.14); border:1px solid rgba(255,255,255,.14);
  position:relative; z-index:1;
}
.tile{
  position:relative; display:flex; flex-direction:column; text-decoration:none; color:#fff;
  background:var(--ink); min-height:clamp(320px, 30vw, 400px);
  padding:20px clamp(18px,2.2vw,30px) clamp(20px,2.4vw,30px);
  isolation:isolate; overflow:hidden;
  transition:background .5s var(--e-out), transform .6s var(--e-out), box-shadow .6s var(--e-out);
}
.tile::before{                                       /* pointer spotlight */
  content:""; position:absolute; inset:0; z-index:0; pointer-events:none;
  background:radial-gradient(360px circle at var(--mx,50%) var(--my,50%), rgba(255,176,0,.13), transparent 62%);
  opacity:0; transition:opacity .5s var(--e-out);
}
.tile::after{                                        /* amber start-tick, grows across the top */
  content:""; position:absolute; left:0; top:0; height:2px; width:32px; z-index:2;
  background:var(--hi); transition:width .7s var(--e-out);
}
.tile:hover, .tile:focus-visible{
  background:var(--ink-2); z-index:2;
  transform:translateY(-4px);
  box-shadow:0 40px 70px -40px rgba(0,0,0,.8), 0 0 0 1px rgba(255,176,0,.35);
}
.tile:hover::before, .tile:focus-visible::before{ opacity:1; }
.tile:hover::after, .tile:focus-visible::after{ width:100%; }

.tile-top{
  display:flex; justify-content:space-between; align-items:center; gap:12px;
  font-family:var(--f-mono); font-weight:500; font-size:10.5px; letter-spacing:.2em;
  text-transform:uppercase; color:rgba(255,255,255,.42);
  position:relative; z-index:2;
}
.tile-idx{ color:var(--hi); transition:letter-spacing .5s var(--e-out); }
.tile:hover .tile-idx{ letter-spacing:.3em; }
.tile-sheet{ opacity:.7; }

.tile-art{
  position:relative; z-index:1; width:100%; height:auto; margin:auto 0;
  padding-block:clamp(14px,2vw,26px) clamp(8px,1vw,14px);
  overflow:visible; display:block; flex:none;
  transform:scale(.98); transition:transform .8s var(--e-out);
}
.tile:hover .tile-art{ transform:scale(1.04) translateY(-4px); }
.tile-art *{ fill:none; vector-effect:non-scaling-stroke; stroke-linecap:square; transition:stroke .5s var(--e-out); }
.tile-art .ln   *{ stroke:rgba(255,255,255,.55); stroke-width:1.5; }
.tile-art .fade *{ stroke:rgba(255,255,255,.24); stroke-width:1.3; }
.tile-art .hi   *{ stroke:rgba(255,176,0,.75); stroke-width:1.7; }
.tile:hover .tile-art .ln *{ stroke:var(--hi); }
.tile:hover .tile-art .fade *{ stroke:rgba(255,176,0,.45); }
.tile:hover .tile-art .hi *{ stroke:#fff; }
.js .tile-art *:not(g){ stroke-dasharray:1; stroke-dashoffset:1; }
.js .tile.in .tile-art *:not(g){ animation:draw 1.2s var(--e-out) forwards; animation-delay:calc(var(--dd,0s) + var(--d,0ms) + .25s); }

.tile-body{ position:relative; z-index:2; margin-top:auto; padding-top:clamp(14px,1.8vw,22px); display:block; }
.tile-body b{
  display:block; font-family:var(--f-display); font-weight:800; text-transform:uppercase;
  font-size:clamp(24px,2.4vw,34px); line-height:1; letter-spacing:-.025em; color:#fff;
  transition:transform .6s var(--e-out), color .4s var(--e-out);
}
.tile:hover .tile-body b{ transform:translateX(6px); }
.tile-desc{
  display:block; margin-top:10px; font-size:14px; line-height:1.55; color:rgba(255,255,255,.62);
  max-width:34ch; min-height:4.65em;
}
@media (max-width:620px){ .tile-desc{ min-height:0; } }
.tile-tags{
  display:flex; flex-wrap:wrap; gap:6px; margin-top:14px;
  opacity:.75; transform:translateY(4px);
  transition:opacity .5s var(--e-out), transform .6s var(--e-out);
}
.tile:hover .tile-tags{ opacity:1; transform:none; }
.tile-tags span{
  font-family:var(--f-mono); font-size:9.5px; letter-spacing:.16em; text-transform:uppercase;
  color:rgba(255,255,255,.7); border:1px solid rgba(255,255,255,.2); padding:5px 8px;
  transition:border-color .4s var(--e-out), color .4s var(--e-out);
}
.tile:hover .tile-tags span{ border-color:rgba(255,176,0,.55); color:#fff; }
.tile-arw{
  position:absolute; right:clamp(18px,2.2vw,30px); bottom:clamp(20px,2.4vw,30px); z-index:2;
  color:var(--hi); font-size:24px; line-height:1;
  opacity:0; transform:translate(-10px,0);
  transition:opacity .5s var(--e-out), transform .6s var(--e-out);
}
.tile:hover .tile-arw, .tile:focus-visible .tile-arw{ opacity:1; transform:none; }
@media (max-width:1024px){ .tiles{ grid-template-columns:repeat(2, minmax(0,1fr)); } .tile{ min-height:0; } }
@media (max-width:620px){ .tiles{ grid-template-columns:1fr; } .tile-art{ max-width:420px; } }

/* --- 21h. Schedule playhead --------------------------------------------- */
.gantt{ position:relative; }
.gantt-play{
  position:absolute; top:0; bottom:0; left:0; width:1px; z-index:3; pointer-events:none;
  background:var(--hi-deep); opacity:0; transition:opacity .4s var(--e-out);
  will-change:transform;
}
.gantt.is-playing .gantt-play{ opacity:1; }
.gantt-play i{
  position:absolute; top:-6px; left:50%; transform:translate(-50%,-100%);
  font-style:normal; font-family:var(--f-mono); font-weight:600; font-size:9px;
  letter-spacing:.2em; text-transform:uppercase; color:var(--ink);
  background:var(--hi); padding:3px 7px; white-space:nowrap;
}
.gantt-play::after{
  content:""; position:absolute; left:50%; top:-6px; width:7px; height:7px;
  background:var(--hi); transform:translate(-50%,-50%) rotate(45deg);
}
@media (max-width:860px){ .gantt-play{ display:none; } }

/* --- 21i. Footer wordmark fills with light ------------------------------ */
.foot-word{
  -webkit-text-stroke:1px rgba(255,255,255,.2);
  background:linear-gradient(90deg, rgba(255,255,255,.7) 0 calc(var(--fill,0%) - 8%), rgba(255,255,255,0) var(--fill,0%));
  -webkit-background-clip:text; background-clip:text;
}

/* --- 21j. Reduced motion ------------------------------------------------ */
@media (prefers-reduced-motion:reduce){
  .cursor{ display:none !important; }
  .js .split--chars .c{ transform:none !important; opacity:1 !important; }
  .hero--home :is(.sub,.btn-row,.eyebrow,.scroll-cue){ opacity:1 !important; filter:none !important; transform:none !important; }
  .hl .w::before{ transform:none !important; } .hl .c{ color:var(--ink) !important; }
  .js .lede .sub{ opacity:1; filter:none; transform:none; }
  .elev-scan, .gantt-play{ display:none; }
  .js .sheet-fig svg *, .js .tile-art *{ stroke-dasharray:none !important; stroke-dashoffset:0 !important; animation:none !important; }
  .js .sheet-fig .dash{ opacity:1; stroke-dasharray:.03 .025 !important; }
  .js .sheet .sheet-copy > *, .js .sheet .sheet-fig{ opacity:1 !important; transform:none !important; }
  .sheet-in{ transform:none !important; filter:none !important; }
}

/* ==========================================================================
   22. ABOUT — Sheet A-02 comes alive
   ========================================================================== */

/* --- 22a. Hero: exploded axonometric ------------------------------------
   Five layers of one building — foundation, structure, MEP/fire, envelope,
   roof — drawn line by line, then pulled apart as the visitor scrolls, each
   layer carrying its own label. --spread runs 0 (stacked) → 1 (exploded);
   it idles with a slow breath and is driven by scroll once the page moves. */
@property --spread{ syntax:'<number>'; inherits:true; initial-value:0; }
.hero-axon{
  /* fills the band between the masthead and the title block, never behind either */
  right:0; bottom:var(--tb-gap, 190px);
  width:auto; height:min(calc(100% - var(--head-h) - var(--tb-gap, 190px) - 24px), 34vw);
  opacity:.9;
  --spread:0;
  -webkit-mask-image:
    linear-gradient(180deg, transparent, #000 14%, #000 96%, transparent),
    linear-gradient(90deg, transparent 0%, #000 16%);
          mask-image:
    linear-gradient(180deg, transparent, #000 14%, #000 96%, transparent),
    linear-gradient(90deg, transparent 0%, #000 16%);
}
.intro-done .hero-axon{ animation:breathe 9s var(--e-io) 2.6s infinite; }
.hero-axon.is-driven{ animation:none; }
@keyframes breathe{ 0%,100%{ --spread:0 } 50%{ --spread:.24 } }
.hero-axon .layer{
  transform:translateY(calc(var(--spread, 0) * var(--k, 0) * -50px));
  transition:transform .35s var(--e-out);
  will-change:transform;
}
.hero-axon text.lbl{
  fill:rgba(255,255,255,.78); stroke:none; text-anchor:end;
  font-family:var(--f-mono); font-weight:500; font-size:12.5px; letter-spacing:.14em; text-transform:uppercase;
}
/* Labels only make sense once the layers have separated — they come up with
   the spread, so at rest the drawing reads as one building. */
.hero-axon .lab{ opacity:clamp(0, calc(var(--spread, 0) * 2.2 - .7), 1); transition:opacity .3s linear; }
.hero-axon .lab .hi{ opacity:1; }
.hero-axon .grade *{ opacity:.9; }
.axon-key{
  display:inline-flex; gap:16px; align-items:center; margin-top:26px;
  font-family:var(--f-mono); font-size:10.5px; letter-spacing:.2em; text-transform:uppercase;
  color:rgba(255,255,255,.5); opacity:0;
}
.axon-key em{ font-style:normal; color:var(--hi); position:relative; padding-left:16px; }
.axon-key em::before{
  content:""; position:absolute; left:0; top:50%; width:8px; height:8px; margin-top:-4px;
  border-right:1px solid var(--hi); border-bottom:1px solid var(--hi); transform:rotate(45deg);
  animation:nudge 1.8s var(--e-io) infinite;
}
@keyframes nudge{ 0%,100%{ transform:translateY(-2px) rotate(45deg) } 50%{ transform:translateY(2px) rotate(45deg) } }
.intro-done .axon-key{ animation:fadeIn 1s var(--e-out) 2.2s forwards; }
html:not(.js) .axon-key{ opacity:1; }
.hero--about .h1{ max-width:15ch; }
.hero--about .sub{ max-width:52ch; }
/* same entrance choreography as the home hero */
.hero--about .sub, .hero--about .page-tag{ opacity:0; }
.hero--about .sub{ filter:blur(6px); transform:translateY(10px); }
.intro-done .hero--about .sub{ animation:blurIn 1.2s var(--e-out) 1s forwards; }
.intro-done .hero--about .page-tag{ animation:fadeIn .8s var(--e-out) .3s forwards; }
html:not(.js) .hero--about :is(.sub,.page-tag){ opacity:1; filter:none; transform:none; }
@media (max-width:1100px){ .hero-axon{ height:min(calc(100% - var(--head-h) - var(--tb-gap, 190px) - 24px), 42vw); right:-8%; opacity:.6; } }
@media (max-width:860px){
  .hero-axon{ opacity:.35; width:120vw; height:auto; right:-30%; bottom:auto; top:var(--head-h); }
  .hero-axon text.lbl, .hero-axon text.lvl{ display:none; }
  .axon-key{ display:none; }
}

/* --- 22b. What we bring: spec cards on the paper band ------------------- */
.spec-cards{
  display:grid; grid-template-columns:repeat(3, minmax(0,1fr)); gap:1px;
  background:var(--line); border:1px solid var(--line);
}
.spec-card{
  position:relative; background:var(--paper); padding:22px clamp(20px,2.4vw,32px) clamp(24px,2.6vw,34px);
  display:flex; flex-direction:column; isolation:isolate; overflow:hidden;
  transition:transform .6s var(--e-out), box-shadow .6s var(--e-out), background .5s var(--e-out);
}
.spec-card::before{
  content:""; position:absolute; inset:0; z-index:0; pointer-events:none;
  background:radial-gradient(360px circle at var(--mx,50%) var(--my,30%), rgba(255,176,0,.10), transparent 62%);
  opacity:0; transition:opacity .5s var(--e-out);
}
.spec-card::after{
  content:""; position:absolute; left:0; top:0; height:2px; width:32px; z-index:2;
  background:var(--hi); transition:width .7s var(--e-out);
}
.spec-card:hover{ transform:translateY(-4px); box-shadow:var(--sh-3); z-index:2; }
.spec-card:hover::before{ opacity:1; }
.spec-card:hover::after{ width:100%; }
.sc-top{
  display:flex; justify-content:space-between; position:relative; z-index:1;
  font-family:var(--f-mono); font-weight:500; font-size:10.5px; letter-spacing:.2em;
  text-transform:uppercase; color:var(--steel-2);
}
.sc-idx{ color:var(--hi-deep); }
.sc-art{ position:relative; z-index:1; width:100%; height:auto; overflow:visible; margin:clamp(14px,1.8vw,24px) 0 clamp(14px,1.8vw,22px); display:block;
  transform:scale(.98); transition:transform .8s var(--e-out); }
.spec-card:hover .sc-art{ transform:scale(1.03) translateY(-3px); }
.sc-art *{ fill:none; vector-effect:non-scaling-stroke; stroke-linecap:square; transition:stroke .5s var(--e-out); }
.sc-art .ln   *{ stroke:rgba(10,10,10,.7); stroke-width:1.5; }
.sc-art .fade *{ stroke:rgba(10,10,10,.28); stroke-width:1.3; }
.sc-art .hi   *{ stroke:var(--hi-deep); stroke-width:1.7; }
.spec-card:hover .sc-art .ln *{ stroke:var(--hi-deep); }
.spec-card:hover .sc-art .hi *{ stroke:var(--ink); }
.js .sc-art *:not(g){ stroke-dasharray:1; stroke-dashoffset:1; }
.js .spec-card.in .sc-art *:not(g){ animation:draw 1.2s var(--e-out) forwards; animation-delay:calc(var(--dd,0s) + var(--d,0ms) + .3s); }
.spec-card h3{
  position:relative; z-index:1; font-family:var(--f-display); font-weight:800; text-transform:uppercase;
  font-size:clamp(20px,1.8vw,25px); line-height:1.05; letter-spacing:-.022em; color:var(--ink);
  transition:transform .6s var(--e-out);
}
.spec-card:hover h3{ transform:translateX(5px); }
.spec-card p{ position:relative; z-index:1; margin-top:12px; font-size:15px; line-height:1.6; color:var(--steel); }
.sc-tags{ position:relative; z-index:1; display:flex; flex-wrap:wrap; gap:6px; margin-top:auto; padding-top:18px; }
.sc-tags span{
  font-family:var(--f-mono); font-size:9.5px; letter-spacing:.16em; text-transform:uppercase;
  color:var(--steel); border:1px solid var(--line); padding:5px 8px;
  transition:border-color .4s var(--e-out), color .4s var(--e-out);
}
.spec-card:hover .sc-tags span{ border-color:rgba(224,148,0,.6); color:var(--ink); }
@media (max-width:900px){ .spec-cards{ grid-template-columns:1fr; } .sc-art{ max-width:420px; } }

/* --- 22c. Process: sticky live readout ---------------------------------- */
.stages-layout{
  display:grid; grid-template-columns:minmax(0,.9fr) minmax(0,1.6fr);
  gap:clamp(28px,5vw,80px); align-items:start;
}
.stage-readout{
  position:sticky; top:calc(var(--head-h-stuck) + 60px);
  padding-top:8px; border-top:1px solid var(--line);
}
.sr-lbl{
  display:block; font-family:var(--f-mono); font-weight:500; font-size:10.5px; letter-spacing:.22em;
  text-transform:uppercase; color:var(--steel-2); margin-bottom:6px;
}
.sr-no{
  display:block; font-family:var(--f-display); font-weight:900; line-height:.85; letter-spacing:-.06em;
  font-size:clamp(120px, 15vw, 220px); color:transparent; -webkit-text-stroke:1.5px rgba(10,10,10,.85);
  font-variant-numeric:tabular-nums;
  transition:-webkit-text-stroke-color .5s;
}
@supports not (-webkit-text-stroke:1px #000){ .sr-no{ color:var(--ink); } }
.sr-name{
  display:block; margin-top:14px; font-family:var(--f-display); font-weight:800; text-transform:uppercase;
  font-size:clamp(20px,2.1vw,28px); line-height:1.05; letter-spacing:-.024em; color:var(--ink);
}
.sr-bar{ display:block; height:2px; background:var(--line); margin-top:18px; position:relative; overflow:hidden; }
.sr-bar i{ position:absolute; inset:0; background:var(--hi); transform-origin:0 50%; transform:scaleX(var(--p,0)); transition:transform .25s linear; }
.sr-of{ display:block; margin-top:10px; font-family:var(--f-mono); font-size:10.5px; letter-spacing:.18em; text-transform:uppercase; color:var(--steel-2); }
.sr-of em{ font-style:normal; color:var(--hi-deep); }
.stage-readout.is-swapping .sr-no{ animation:srSwap .5s var(--e-out); }
.stage-readout.is-swapping .sr-name{ animation:srSwap .5s var(--e-out) .05s; }
@keyframes srSwap{ 0%{ opacity:0; transform:translateY(12px) } 100%{ opacity:1; transform:none } }
@media (max-width:900px){
  .stages-layout{ grid-template-columns:1fr; }
  .stage-readout{ display:none; }
}

/* --- 22d. Safety: stamp slams onto the sheet ---------------------------- */
.safety-grid{ position:relative; }
.stamp--slam{
  position:absolute; right:clamp(16px,4vw,48px); top:-58px; z-index:3; margin:0;
  transform:rotate(-8deg) scale(1); transform-origin:100% 50%;
  color:rgba(255,176,0,.9); border-color:rgba(255,176,0,.75);
  background:rgba(10,10,10,.6); backdrop-filter:blur(2px);
}
.js .stamp--slam[data-rv]{ transform:rotate(-8deg) scale(1.9); opacity:0; transition:transform .5s cubic-bezier(.2,1.4,.3,1), opacity .25s; }
.js .stamp--slam[data-rv].in{ transform:rotate(-8deg) scale(1); opacity:1; }
@media (max-width:1024px){ .stamp--slam{ display:none; } }

@media (prefers-reduced-motion:reduce){
  .hero-axon{ animation:none !important; }
  .hero-axon text.lbl, .hero-axon text.lvl, .axon-key{ opacity:1 !important; }
  .hero--about :is(.sub,.page-tag){ opacity:1 !important; filter:none !important; transform:none !important; }
  .js .sc-art *{ stroke-dasharray:none !important; stroke-dashoffset:0 !important; animation:none !important; }
  .stage-readout .sr-no, .stage-readout .sr-name{ animation:none !important; }
}

/* ==========================================================================
   23. SERVICES — Sheet A-03 comes alive
   ========================================================================== */
/* --- 23a. Hero: the plotter --------------------------------------------- */
.hero-plot{
  position:absolute; z-index:1; pointer-events:none; display:block;
  right:1%; bottom:var(--tb-gap, 190px);
  height:min(calc(100% - var(--head-h) - var(--tb-gap, 190px) - 24px), 27vw); width:auto;
  aspect-ratio:1000/620;
  translate:0 var(--dy, 0px); will-change:translate;
  -webkit-mask-image:linear-gradient(90deg, transparent 0%, #000 22%);
          mask-image:linear-gradient(90deg, transparent 0%, #000 22%);
  opacity:0; transition:opacity 1s var(--e-out) .3s;
}
.intro-done .hero-plot, html:not(.js) .hero-plot{ opacity:.95; }
.plot-key .plot-readout{ font-variant-numeric:tabular-nums; min-width:14ch; }
.plot-key em::before{ display:none; }
.plot-key em{ padding-left:0; }
.hero--services .h1{ max-width:19ch; }
.hero--services .sub{ max-width:50ch; }
.hero--services .sub, .hero--services .page-tag{ opacity:0; }
.hero--services .sub{ filter:blur(6px); transform:translateY(10px); }
.intro-done .hero--services .sub{ animation:blurIn 1.2s var(--e-out) 1s forwards; }
.intro-done .hero--services .page-tag{ animation:fadeIn .8s var(--e-out) .3s forwards; }
html:not(.js) .hero--services :is(.sub,.page-tag){ opacity:1; filter:none; transform:none; }
@media (max-width:1100px){ .hero-plot{ height:min(calc(100% - var(--head-h) - var(--tb-gap, 190px) - 24px), 38vw); right:-6%; opacity:.6; } .intro-done .hero-plot{ opacity:.6; } }
@media (max-width:860px){
  .hero-plot{ height:auto; width:120vw; right:-30%; bottom:auto; top:calc(var(--head-h) + 10px); opacity:.3; }
  .intro-done .hero-plot{ opacity:.3; }
  .plot-key{ display:none; }
}

/* --- 23b. Scope: sticky spec index + figures ---------------------------- */
.spec-index{
  position:sticky; top:calc(var(--head-h-stuck) + 8px); z-index:20;
  display:flex; flex-wrap:wrap; gap:6px 4px;
  margin:0 0 clamp(18px,2.4vw,30px); padding:10px 0;
  background:rgba(255,255,255,.82); -webkit-backdrop-filter:blur(14px); backdrop-filter:blur(14px);
  border-bottom:1px solid var(--line);
  transition:box-shadow .4s var(--e-out);
}
.spec-index.is-stuck{ box-shadow:var(--sh-2); }
.spec-index a{
  display:inline-flex; align-items:center; gap:10px; text-decoration:none;
  padding:9px 14px; border:1px solid transparent;
  font-family:var(--f-display); font-weight:600; font-size:12px; letter-spacing:.12em; text-transform:uppercase;
  color:var(--steel); position:relative;
  transition:color .35s var(--e-out), border-color .35s var(--e-out), background .35s var(--e-out);
}
.spec-index a i{ font-style:normal; font-family:var(--f-mono); font-weight:500; font-size:10.5px; letter-spacing:.14em; color:var(--steel-2); transition:color .35s; }
.spec-index a:hover{ color:var(--ink); border-color:var(--line); }
.spec-index a.is-current{ color:var(--ink); background:var(--ink); color:#fff; border-color:var(--ink); }
.spec-index a.is-current i{ color:var(--hi); }
.spec-fig{ margin:22px 0 0; max-width:300px; }
.spec-fig svg{ width:100%; height:auto; overflow:visible; display:block; }
.spec-fig figcaption{ margin-top:8px; padding-top:8px; border-top:1px solid var(--line); font-family:var(--f-mono); font-size:9.5px; letter-spacing:.16em; text-transform:uppercase; color:var(--steel-2); }
.spec-fig svg *{ fill:none; vector-effect:non-scaling-stroke; stroke-linecap:square; stroke-linejoin:miter; }
.spec-fig .ln  *{ stroke:rgba(10,10,10,.62); stroke-width:1.4; }
.spec-fig .fade *{ stroke:rgba(10,10,10,.26); stroke-width:1.2; }
.spec-fig .hi  *{ stroke:var(--hi-deep); stroke-width:1.6; }
.spec-fig .hi rect{ fill:rgba(255,176,0,.08); }
.spec-fig .dash{ stroke-dasharray:.03 .025 !important; }
.js .spec-fig svg *:not(g):not(.dash){ stroke-dasharray:1; stroke-dashoffset:1; }
.js .spec-sec.in .spec-fig svg *:not(g):not(.dash){ animation:draw 1.2s var(--e-out) forwards; animation-delay:calc(var(--dd,0s) + .35s); }
.js .spec-fig .dash{ opacity:0; transition:opacity .8s var(--e-out) 1.5s; }
.js .spec-sec.in .spec-fig .dash{ opacity:1; }
/* the section reading now gets its number in amber and its rule lit */
.spec-sec{ position:relative; }
.spec-sec::before{
  content:""; position:absolute; left:0; top:-1px; height:2px; width:0; background:var(--hi);
  transition:width .9s var(--e-out);
}
.spec-sec.in::before{ width:38px; }
.spec-sec h2{ transition:transform .6s var(--e-out); }
.spec-sec:hover h2{ transform:translateX(4px); }
@media (max-width:860px){ .spec-index{ display:none; } .spec-fig{ max-width:260px; } }

/* --- 23c. Matrix: column highlight -------------------------------------- */
.matrix thead th{ position:relative; transition:color .35s var(--e-out); }
.matrix thead th:not(:first-child)::after{
  content:""; position:absolute; left:clamp(12px,1.6vw,22px); right:clamp(12px,1.6vw,22px); bottom:8px; height:2px;
  background:var(--hi); transform:scaleX(0); transform-origin:0 50%; transition:transform .5s var(--e-out);
}
.matrix td, .matrix th{ transition:background .35s var(--e-out), color .35s var(--e-out); }
.matrix[data-col="1"] :is(td,th):nth-child(2),
.matrix[data-col="2"] :is(td,th):nth-child(3),
.matrix[data-col="3"] :is(td,th):nth-child(4){ background:rgba(255,176,0,.08); color:#fff; }
.matrix[data-col="1"] thead th:nth-child(2)::after,
.matrix[data-col="2"] thead th:nth-child(3)::after,
.matrix[data-col="3"] thead th:nth-child(4)::after{ transform:scaleX(1); }
.matrix[data-col] tbody tr:hover{ background:transparent; }
.matrix tbody th{ transition:color .35s var(--e-out); }
.matrix tbody tr:hover th{ color:var(--hi); }

/* --- 23d. Project types: four spec cards -------------------------------- */
.spec-cards--4{ grid-template-columns:repeat(4, minmax(0,1fr)); }
.spec-cards--4 .spec-card h3{ font-size:clamp(18px,1.5vw,21px); }
.spec-cards--4 .spec-card p{ font-size:14.5px; }
@media (max-width:1100px){ .spec-cards--4{ grid-template-columns:repeat(2, minmax(0,1fr)); } }
@media (max-width:620px){ .spec-cards--4{ grid-template-columns:1fr; } }

@media (prefers-reduced-motion:reduce){
  .hero--services :is(.sub,.page-tag){ opacity:1 !important; filter:none !important; transform:none !important; }
  .js .spec-fig svg *{ stroke-dasharray:none !important; stroke-dashoffset:0 !important; animation:none !important; opacity:1 !important; }
  .js .spec-fig .dash{ stroke-dasharray:.03 .025 !important; }
}

/* ==========================================================================
   24. PROJECTS — Sheet A-04 comes alive
   ========================================================================== */
/* --- 24a. Hero: the site map ------------------------------------------- */
.hero-map{
  position:absolute; z-index:1; pointer-events:none; display:block;
  right:2%; bottom:var(--tb-gap, 190px);
  height:min(calc(100% - var(--head-h) - var(--tb-gap, 190px) - 24px), 30vw); width:auto;
  aspect-ratio:1000/620;
  translate:0 var(--dy, 0px); will-change:translate;
  -webkit-mask-image:
    linear-gradient(90deg, transparent 0%, #000 18%),
    linear-gradient(180deg, transparent 0%, #000 12%, #000 90%, transparent);
  -webkit-mask-composite:source-in;
          mask-image:
    linear-gradient(90deg, transparent 0%, #000 18%),
    linear-gradient(180deg, transparent 0%, #000 12%, #000 90%, transparent);
          mask-composite:intersect;
  opacity:0; transition:opacity 1s var(--e-out) .3s;
}
.intro-done .hero-map, html:not(.js) .hero-map{ opacity:.95; }
.map-key em::before{ display:none; } .map-key em{ padding-left:0; min-width:22ch; }
.hero--projects .h1{ max-width:14ch; }
.hero--projects .sub{ max-width:50ch; }
.hero--projects .sub, .hero--projects .page-tag{ opacity:0; }
.hero--projects .sub{ filter:blur(6px); transform:translateY(10px); }
.intro-done .hero--projects .sub{ animation:blurIn 1.2s var(--e-out) 1s forwards; }
.intro-done .hero--projects .page-tag{ animation:fadeIn .8s var(--e-out) .3s forwards; }
html:not(.js) .hero--projects :is(.sub,.page-tag){ opacity:1; filter:none; transform:none; }
@media (max-width:1100px){ .hero-map{ height:min(calc(100% - var(--head-h) - var(--tb-gap, 190px) - 24px), 40vw); right:-4%; opacity:.6; } .intro-done .hero-map{ opacity:.6; } }
@media (max-width:860px){
  .hero-map{ height:auto; width:110vw; right:-20%; bottom:auto; top:calc(var(--head-h) + 10px); opacity:.3; }
  .intro-done .hero-map{ opacity:.3; }
  .map-key{ display:none; }
}

/* --- 24b. Register: drawn media, ignition, staggered refill ------------- */
.media-svg{ position:absolute; inset:0; z-index:1; width:100%; height:100%; padding:9% 8%; box-sizing:border-box; }
.media-svg{ transform:scale(.98); transition:transform .8s var(--e-out); }
.proj:hover .media-svg{ transform:scale(1.04) translateY(-3px); }
.js .media-svg *:not(g){ stroke-dasharray:1; stroke-dashoffset:1; }
.js .proj.in .media-svg *:not(g){ animation:draw 1.2s var(--e-out) forwards; animation-delay:calc(var(--dd,0s) + var(--d,0ms) + .45s); }
.proj:hover .media-svg .ln *{ stroke:var(--hi); }
.proj:hover .media-svg .fade *{ stroke:rgba(255,176,0,.45); }
.proj:hover .media-svg .hi *{ stroke:#fff; }
.media::after{                                  /* pointer glow inside the sheet */
  content:""; position:absolute; inset:0; z-index:1; pointer-events:none;
  background:radial-gradient(60% 60% at 50% 60%, rgba(255,176,0,.14), transparent 70%);
  opacity:0; transition:opacity .5s var(--e-out);
}
.proj:hover .media::after{ opacity:1; }
.proj .proj-no{ transition:color .4s var(--e-out), letter-spacing .5s var(--e-out); }
.proj:hover .proj-no{ color:var(--hi); letter-spacing:.24em; }
.proj h3{ transition:transform .5s var(--e-out); }
.proj:hover h3{ transform:translateX(4px); }
.js .refilling .proj{ transition-delay:var(--fd, 0ms); }
.js .refilling .proj:hover{ transition-delay:0ms; }
.reg-count{ transition:color .3s; }
.filters button[aria-pressed="true"] b{ color:var(--hi); opacity:1; }

/* --- 24c. Further experience: roster tiles ------------------------------ */
.tiles--roster .tile{ min-height:0; }
.tiles--roster .tile-body{ margin-top:0; padding-top:clamp(18px,2vw,26px); }
.tiles--roster .tile-desc{ min-height:0; }
.roster{ margin-top:18px; border-top:1px solid rgba(255,255,255,.14); }
.roster li{
  display:flex; align-items:center; gap:14px; padding:12px 0; border-bottom:1px solid rgba(255,255,255,.1);
  font-family:var(--f-display); font-weight:800; text-transform:uppercase; letter-spacing:-.012em;
  font-size:clamp(15px,1.25vw,18px); color:rgba(255,255,255,.86);
  transition:color .4s var(--e-out), padding-left .5s var(--e-out);
}
.roster li::before{ content:""; width:7px; height:7px; background:var(--hi); flex:none; transform:rotate(45deg); transition:transform .5s var(--e-out); }
.tile:hover .roster li{ color:#fff; }
.roster li:hover{ padding-left:8px; color:var(--hi); }
.roster li:hover::before{ transform:rotate(225deg); }

@media (prefers-reduced-motion:reduce){
  .hero--projects :is(.sub,.page-tag){ opacity:1 !important; filter:none !important; transform:none !important; }
  .js .media-svg *{ stroke-dasharray:none !important; stroke-dashoffset:0 !important; animation:none !important; }
}

/* --- 24d. The register proper: a ledger of sheets --------------------------
   Eleven lines, columned like a drawing register. A line lights under the
   pointer and a framed plate of that building type trails the cursor; click
   opens the line in place with scope, tags and (on touch) the plate itself. */
.register{ position:relative; border-top:1px solid var(--ink); }
.reg-cols, .reg-head{
  display:grid; align-items:center;
  grid-template-columns:64px minmax(0,1.6fr) minmax(0,1fr) minmax(0,.8fr) 132px 28px;
  gap:clamp(12px,2vw,28px);
}
.reg-cols{
  padding:12px 0; border-bottom:1px solid var(--line);
  font-family:var(--f-mono); font-weight:500; font-size:10px; letter-spacing:.2em;
  text-transform:uppercase; color:var(--steel-2);
}
.reg-row{ position:relative; border-bottom:1px solid var(--line); isolation:isolate; }
.reg-row::before{
  content:""; position:absolute; inset:0 calc(var(--gut) * -1); z-index:-1; pointer-events:none;
  background:linear-gradient(90deg, rgba(255,176,0,.12), transparent 60%);
  opacity:0; transition:opacity .5s var(--e-out);
}
.reg-row:hover::before, .reg-row.open::before, .reg-row:focus-within::before{ opacity:1; }
.reg-row::after{
  content:""; position:absolute; left:0; bottom:-1px; height:1px; width:100%; z-index:1;
  background:var(--hi); transform:scaleX(0); transform-origin:0 50%; transition:transform .7s var(--e-out);
}
.reg-row:hover::after, .reg-row.open::after{ transform:scaleX(1); }
.reg-head{
  width:100%; text-align:left; background:none; border:0; cursor:pointer;
  padding:clamp(18px,2.2vw,26px) 0; color:var(--ink);
  transition:padding-left .55s var(--e-out);
}
.reg-row:hover .reg-head, .reg-row.open .reg-head{ padding-left:clamp(8px,1.2vw,16px); }
.reg-no{ font-family:var(--f-mono); font-weight:500; font-size:11.5px; letter-spacing:.14em; color:var(--steel-2); transition:color .4s var(--e-out); }
.reg-row:hover .reg-no, .reg-row.open .reg-no{ color:var(--hi-deep); }
.reg-name{
  font-family:var(--f-display); font-weight:800; text-transform:uppercase;
  font-size:clamp(18px,2.2vw,30px); line-height:1.02; letter-spacing:-.028em; color:var(--ink);
  transition:transform .55s var(--e-out);
}
.reg-row:hover .reg-name, .reg-row.open .reg-name{ transform:translateX(4px); }
.reg-sector, .reg-scope{ font-family:var(--f-mono); font-weight:500; font-size:11px; letter-spacing:.14em; text-transform:uppercase; color:var(--steel); }
.reg-status{
  display:inline-flex; align-items:center; gap:9px;
  font-family:var(--f-mono); font-weight:500; font-size:10.5px; letter-spacing:.14em; text-transform:uppercase; color:var(--steel);
}
.reg-status i{ width:8px; height:8px; border:1.5px solid var(--steel-2); flex:none; }
.reg-status.is-live{ color:var(--ink); }
.reg-status.is-live i{ background:var(--hi); border-color:var(--hi); animation:blip 1.9s var(--e-io) infinite; }
.reg-plus{ position:relative; width:22px; height:22px; justify-self:end; }
.reg-plus::before, .reg-plus::after{ content:""; position:absolute; inset:0; margin:auto; background:var(--ink); transition:transform .5s var(--e-out), background .4s; }
.reg-plus::before{ width:18px; height:2px; } .reg-plus::after{ width:2px; height:18px; }
.reg-row.open .reg-plus::before{ transform:rotate(180deg); background:var(--hi-deep); }
.reg-row.open .reg-plus::after{ transform:rotate(90deg); background:var(--hi-deep); }

.reg-body{ display:grid; grid-template-rows:0fr; transition:grid-template-rows .7s var(--e-out); }
.reg-body > div{ overflow:hidden; }
.reg-row.open .reg-body{ grid-template-rows:1fr; }
html:not(.js) .reg-body{ grid-template-rows:1fr; }
.reg-detail{
  display:grid; grid-template-columns:minmax(0,.9fr) minmax(0,1.6fr); gap:clamp(20px,3vw,44px);
  padding:4px 0 clamp(26px,3vw,40px) calc(64px + clamp(12px,2vw,28px) + clamp(8px,1.2vw,16px));
  align-items:start;
}
.reg-fig{
  margin:0; background:var(--ink); padding:8% 7%; position:relative;
  background-image:linear-gradient(rgba(255,255,255,.05) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,.05) 1px, transparent 1px);
  background-size:26px 26px;
}
.reg-fig svg{ width:100%; height:auto; overflow:visible; display:block; margin:0; padding:0; transform:none; }
.reg-copy p{ font-size:15.5px; line-height:1.6; color:var(--steel); max-width:60ch; }
.reg-copy .meta{ margin-top:16px; padding-top:14px; border-top:1px solid var(--line); font-size:13px; color:var(--steel-2); display:flex; flex-wrap:wrap; gap:4px 10px; font-family:var(--f-mono); letter-spacing:.1em; text-transform:uppercase; font-size:10.5px; }
.reg-copy .meta span + span::before{ content:"/"; color:var(--line); margin-right:10px; }
/* the plate draws itself when the line opens */
.js .reg-fig svg *:not(g){ stroke-dasharray:1; stroke-dashoffset:1; }
.js .reg-row.open .reg-fig svg *:not(g){ animation:draw 1.1s var(--e-out) forwards; animation-delay:calc(var(--dd,0s) + .2s); }

/* --- the trailing plate --- */
.reg-preview{
  position:absolute; left:0; top:0; z-index:5; pointer-events:none;
  width:min(26vw, 340px); aspect-ratio:600/420;
  background:var(--ink); padding:7% 6% 12%;
  background-image:linear-gradient(rgba(255,255,255,.05) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,.05) 1px, transparent 1px);
  background-size:26px 26px;
  box-shadow:var(--sh-3), 0 0 0 1px rgba(255,176,0,.5);
  opacity:0; transform:translate3d(calc(var(--px,0px) + 28px), calc(var(--py,0px) - 100% - 26px), 0) scale(.94);
  transition:opacity .4s var(--e-out), transform .55s var(--e-out);
  will-change:transform;
}
.register.is-previewing .reg-preview{ opacity:1; transform:translate3d(calc(var(--px,0px) + 28px), calc(var(--py,0px) - 100% - 26px), 0) scale(1); }
.register.is-previewing.flip .reg-preview{ transform:translate3d(calc(var(--px,0px) - 100% - 28px), calc(var(--py,0px) - 100% - 26px), 0) scale(1); }
.reg-preview svg{ position:absolute; inset:7% 6% 14%; width:88%; height:auto; margin:0; padding:0; opacity:0; transform:scale(.96); transition:opacity .35s var(--e-out), transform .5s var(--e-out); }
.reg-preview svg.is-on{ opacity:1; transform:none; }
.reg-preview svg *{ stroke-dasharray:none !important; stroke-dashoffset:0 !important; animation:none !important; }
.reg-preview-cap{
  position:absolute; left:14px; right:14px; bottom:10px; display:flex; justify-content:space-between;
  font-family:var(--f-mono); font-size:9.5px; letter-spacing:.2em; text-transform:uppercase; color:rgba(255,255,255,.55);
}
.reg-preview-cap b{ font-weight:500; color:var(--hi); }
.js .filtering [data-cat]{ opacity:0; transform:translateY(12px); }
.reg-row{ transition:opacity .35s var(--e-out), transform .35s var(--e-out); }
.js .refilling [data-cat]{ transition-delay:var(--fd, 0ms); }
@media (max-width:1024px){
  .reg-cols, .reg-head{ grid-template-columns:52px minmax(0,1.6fr) minmax(0,1fr) 120px 24px; }
  .reg-scope, .reg-cols span:nth-child(4){ display:none; }
  .reg-preview{ display:none; }
  .reg-detail{ grid-template-columns:minmax(0,1fr) minmax(0,1.5fr); padding-left:calc(52px + clamp(12px,2vw,28px)); }
}
@media (max-width:760px){
  .reg-cols{ display:none; }
  .reg-head{ grid-template-columns:44px minmax(0,1fr) 22px; row-gap:6px; }
  .reg-sector{ grid-column:2; }
  .reg-status{ grid-column:2; }
  .reg-plus{ grid-row:1; grid-column:3; }
  .reg-detail{ grid-template-columns:1fr; padding-left:0; gap:18px; }
  .reg-fig{ max-width:420px; }
}
@media (pointer:coarse){ .reg-preview{ display:none; } }
@media (prefers-reduced-motion:reduce){
  .js .reg-fig svg *{ stroke-dasharray:none !important; stroke-dashoffset:0 !important; animation:none !important; }
  .reg-status.is-live i{ animation:none; }
}

/* --- 24e. THE PLAN TABLE — the register as a horizontal drawing set ------
   Desktop: the block pins for the length of the set and vertical scroll
   turns the sheets horizontally across the table, the sticky panel reading
   out whichever sheet is under the light. Touch / narrow: a native
   swipe-and-snap strip with the same panel above it. */
.section--ptable{ padding-bottom:0; }
.section--ptable .reg-bar{ margin-bottom:0; }
.ptable{
  position:relative; width:100vw; margin-left:calc(50% - 50vw);
  height:calc(100vh + var(--extra, 0px));
}
.pt-stage{
  position:sticky; top:0; height:100vh; overflow:hidden;
  display:grid; grid-template-columns:minmax(300px, 36%) minmax(0,1fr);
  padding-top:calc(var(--head-h-stuck) + 8px);
  background:var(--paper);
}
.pt-panel{
  position:relative; display:flex; flex-direction:column;
  padding:clamp(24px,4vh,48px) clamp(20px,2.4vw,36px) clamp(24px,4vh,44px)
          max(var(--gut), calc(50vw - var(--max) / 2 + var(--gut)));
  border-right:1px solid var(--line);
}
.pt-lbl{ font-family:var(--f-mono); font-weight:500; font-size:10.5px; letter-spacing:.22em; text-transform:uppercase; color:var(--steel-2); }
.pt-count{ display:flex; align-items:baseline; gap:10px; margin-top:8px; line-height:1; }
.pt-count b{
  font-family:var(--f-display); font-weight:900; font-size:clamp(88px,10vw,150px); letter-spacing:-.06em; line-height:.85;
  color:transparent; -webkit-text-stroke:1.5px rgba(10,10,10,.85); font-variant-numeric:tabular-nums;
}
@supports not (-webkit-text-stroke:1px #000){ .pt-count b{ color:var(--ink); } }
.pt-count em{ font-style:normal; font-family:var(--f-mono); font-size:13px; letter-spacing:.14em; color:var(--steel-2); }
.pt-count em span{ color:var(--hi-deep); }
.pt-items{ position:relative; margin-top:clamp(18px,3vh,30px); flex:1; min-height:220px; display:grid; }
.pt-item{
  grid-area:1/1; align-self:start;
  opacity:0; transform:translateY(14px); pointer-events:none;
  transition:opacity .5s var(--e-out), transform .6s var(--e-out);
}
.pt-item.is-on{ opacity:1; transform:none; pointer-events:auto; }
.pt-sector{ display:block; font-family:var(--f-mono); font-weight:500; font-size:10.5px; letter-spacing:.2em; text-transform:uppercase; color:var(--hi-deep); }
.pt-name{
  margin-top:10px; font-family:var(--f-display); font-weight:800; text-transform:uppercase;
  font-size:clamp(24px,2.4vw,36px); line-height:1; letter-spacing:-.03em; color:var(--ink);
}
.pt-desc{ margin-top:14px; font-size:15px; line-height:1.6; color:var(--steel); max-width:44ch; }
.pt-meta{ display:flex; flex-wrap:wrap; gap:8px 26px; margin-top:16px; padding-top:14px; border-top:1px solid var(--line); }
.pt-meta span{ font-family:var(--f-mono); font-size:11px; letter-spacing:.14em; text-transform:uppercase; color:var(--ink); }
.pt-meta i{ display:block; font-style:normal; font-size:9.5px; color:var(--steel-2); margin-bottom:4px; }
.pt-nav{ display:flex; align-items:center; gap:14px; margin-top:auto; padding-top:20px; }
.pt-btn{
  width:46px; height:46px; border:1px solid var(--line); background:none; cursor:pointer; display:grid; place-items:center;
  font-size:18px; color:var(--ink); transition:border-color .3s, background .3s, color .3s, transform .3s var(--e-out);
}
.pt-btn:hover{ border-color:var(--ink); background:var(--ink); color:#fff; }
.pt-btn:disabled{ opacity:.35; cursor:default; }
.pt-btn:disabled:hover{ border-color:var(--line); background:none; color:var(--ink); }
.pt-rule{ flex:1; height:2px; background:var(--line); position:relative; overflow:hidden; }
.pt-rule i{ position:absolute; inset:0; background:var(--hi); transform-origin:0 50%; transform:scaleX(var(--p,0)); transition:transform .5s var(--e-out); }
.pt-hint{ margin-top:14px; font-family:var(--f-mono); font-size:10px; letter-spacing:.2em; text-transform:uppercase; color:var(--steel-2); transition:opacity .5s; }
.ptable.is-moved .pt-hint{ opacity:0; }

.pt-view{ position:relative; overflow:hidden; }
.pt-view::before{                            /* table surface: paper grid */
  content:""; position:absolute; inset:0; pointer-events:none;
  background-image:linear-gradient(rgba(10,10,10,.035) 1px, transparent 1px), linear-gradient(90deg, rgba(10,10,10,.035) 1px, transparent 1px);
  background-size:38px 38px;
}
.pt-track{
  position:relative; display:flex; gap:clamp(18px,2vw,30px); height:100%;
  padding:clamp(16px,3vh,32px) 10vw clamp(16px,3vh,32px) clamp(20px,3vw,48px);
  will-change:transform;
}
.ps{ flex:0 0 clamp(360px, 42vw, 620px); height:100%; }
.ps-in{
  position:relative; height:100%; display:grid; grid-template-rows:auto minmax(0,1fr) auto;
  background:var(--ink); color:#fff; overflow:hidden; isolation:isolate;
  box-shadow:var(--sh-3);
  background-image:linear-gradient(rgba(255,255,255,.045) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,.045) 1px, transparent 1px);
  background-size:32px 32px;
  transform:scale(.96); opacity:.55;
  transition:transform .8s var(--e-out), opacity .6s var(--e-out), box-shadow .6s var(--e-out);
}
.ps.is-active .ps-in{ transform:none; opacity:1; box-shadow:var(--sh-3), 0 0 0 1px rgba(255,176,0,.55); }
.ps-in .reg{ opacity:1; animation:none; width:16px; height:16px; }
.ps-in .reg--tl{ top:12px; left:12px; } .ps-in .reg--tr{ top:12px; right:12px; }
.ps-in .reg--bl{ bottom:12px; left:12px; } .ps-in .reg--br{ bottom:12px; right:12px; }
.ps-in .reg::before, .ps-in .reg::after{ background:rgba(255,255,255,.35); }
.ps-head{
  display:flex; justify-content:space-between; gap:12px; padding:14px 22px 12px;
  border-bottom:1px solid rgba(255,255,255,.14);
  font-family:var(--f-mono); font-weight:500; font-size:10px; letter-spacing:.2em; text-transform:uppercase; color:rgba(255,255,255,.5);
}
.ps-head span:first-child{ color:var(--hi); }
.ps-head span:nth-child(2){ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.ps-plate{ margin:0; display:grid; place-items:center; padding:6% 9% 2%; min-height:0; }
.ps-plate svg{ width:100%; height:auto; max-height:100%; margin:0; padding:0; transform:none; overflow:visible; }
.js .ps .tile-art *:not(g){ stroke-dasharray:1; stroke-dashoffset:1; }
.js .ps.in .tile-art *:not(g){ animation:draw 1.2s var(--e-out) forwards; animation-delay:calc(var(--dd,0s) + .2s); }
.ps.is-active .tile-art .ln *{ stroke:rgba(255,255,255,.75); }
.ps-ghost{
  position:absolute; right:-.04em; bottom:-.16em; z-index:0; pointer-events:none;
  font-family:var(--f-display); font-weight:900; font-size:clamp(160px,18vw,260px); line-height:1; letter-spacing:-.06em;
  color:transparent; -webkit-text-stroke:1px rgba(255,255,255,.1);
}
.ps-foot{ position:relative; z-index:1; padding:16px 22px 22px; border-top:1px solid rgba(255,255,255,.14); }
.ps-no{ font-family:var(--f-mono); font-weight:500; font-size:10.5px; letter-spacing:.2em; color:var(--hi); }
.ps-foot h3{ margin-top:8px; font-family:var(--f-display); font-weight:800; text-transform:uppercase; font-size:clamp(20px,1.9vw,28px); line-height:1.02; letter-spacing:-.028em; color:#fff; }
.ps-tags{ display:flex; flex-wrap:wrap; gap:6px; margin-top:12px; }
.ps-tags span{ font-family:var(--f-mono); font-size:9.5px; letter-spacing:.14em; text-transform:uppercase; color:rgba(255,255,255,.7); border:1px solid rgba(255,255,255,.2); padding:4px 8px; }
.ps-status{ position:absolute; right:22px; top:18px; display:inline-flex; align-items:center; gap:8px; font-family:var(--f-mono); font-size:10px; letter-spacing:.16em; text-transform:uppercase; color:rgba(255,255,255,.55); }
.ps-status i{ width:8px; height:8px; border:1.5px solid rgba(255,255,255,.4); }
.ps-status.is-live{ color:#fff; }
.ps-status.is-live i{ background:var(--hi); border-color:var(--hi); animation:blip 1.9s var(--e-io) infinite; }
.js .filtering [data-cat]{ opacity:0; transform:translateY(12px); }
.ps{ transition:opacity .35s var(--e-out), transform .35s var(--e-out); }
.js .refilling [data-cat]{ transition-delay:var(--fd, 0ms); }

/* --- narrow / touch: native strip --- */
@media (max-width:1024px), (hover:none){
  .ptable{ height:auto; }
  .pt-stage{ position:static; height:auto; overflow:visible; display:block; padding-top:0; }
  .pt-panel{ border-right:0; border-bottom:1px solid var(--line); padding:clamp(22px,3vw,34px) var(--gut) clamp(18px,2.4vw,26px); }
  .pt-items{ min-height:0; }
  .pt-item{ position:relative; }
  .pt-item:not(.is-on){ display:none; }
  .pt-hint{ display:none; }
  .pt-view{ overflow-x:auto; overflow-y:hidden; scroll-snap-type:x mandatory; -webkit-overflow-scrolling:touch; scrollbar-width:none; }
  .pt-view::-webkit-scrollbar{ display:none; }
  .pt-track{ height:auto; padding:clamp(18px,3vw,30px) var(--gut); }
  .ps{ flex:0 0 min(78vw, 480px); height:auto; scroll-snap-align:center; }
  .ps-in{ aspect-ratio:4/4.6; height:auto; }
  .ps-ghost{ font-size:120px; }
}
@media (max-width:620px){ .pt-count b{ font-size:72px; } .ps{ flex-basis:84vw; } .ps-head span:nth-child(2){ display:none; } .ps-head span{ white-space:nowrap; } }
@media (prefers-reduced-motion:reduce){
  .ps-in{ transform:none !important; opacity:1 !important; }
  .js .ps .tile-art *{ stroke-dasharray:none !important; stroke-dashoffset:0 !important; animation:none !important; }
  .ps-status.is-live i{ animation:none; }
}

/* ==========================================================================
   25. CONTACT — Sheet A-05 comes alive
   ========================================================================== */
/* --- 25a. Hero: the beacon ---------------------------------------------- */
.hero-beacon{
  position:absolute; z-index:1; pointer-events:none; display:block;
  right:4%; bottom:var(--tb-gap, 190px);
  height:min(calc(100% - var(--head-h) - var(--tb-gap, 190px) - 24px), 34vw); width:auto; aspect-ratio:1/1;
  translate:0 var(--dy, 0px); will-change:translate;
  -webkit-mask-image:radial-gradient(50% 50% at 50% 50%, #000 78%, transparent 100%);
          mask-image:radial-gradient(50% 50% at 50% 50%, #000 78%, transparent 100%);
  opacity:0; transition:opacity 1s var(--e-out) .3s;
}
.intro-done .hero-beacon, html:not(.js) .hero-beacon{ opacity:1; }
.beacon-key em::before{ display:none; } .beacon-key em{ padding-left:0; font-variant-numeric:tabular-nums; }
.hero--contact .h1{ max-width:14ch; }
.hero--contact .sub{ max-width:50ch; }
.hero--contact .sub, .hero--contact .page-tag{ opacity:0; }
.hero--contact .sub{ filter:blur(6px); transform:translateY(10px); }
.intro-done .hero--contact .sub{ animation:blurIn 1.2s var(--e-out) 1s forwards; }
.intro-done .hero--contact .page-tag{ animation:fadeIn .8s var(--e-out) .3s forwards; }
html:not(.js) .hero--contact :is(.sub,.page-tag){ opacity:1; filter:none; transform:none; }
@media (max-width:1100px){ .hero-beacon{ height:min(calc(100% - var(--head-h) - var(--tb-gap, 190px) - 24px), 36vw); right:-2%; opacity:.6; } .intro-done .hero-beacon{ opacity:.6; } }
@media (max-width:860px){
  .hero-beacon{ height:auto; width:110vw; right:-30%; bottom:auto; top:var(--head-h); opacity:.25; }
  .intro-done .hero-beacon{ opacity:.25; }
  .beacon-key{ display:none; }
}

/* --- 25b. Talk to us: lines, station clock, the form as an instrument --- */
.cta-lines--light a{ color:var(--ink); border-bottom-color:var(--line); }
.cta-lines--light a span{ color:var(--steel-2); }
.cta-lines--light a:hover{ color:var(--hi-deep); }
.contact-lines .contact-dl{ margin-top:22px; }
.contact-lines .info-block:first-of-type{ border-top:0; padding-top:24px; }
.station{ margin-top:26px; padding:18px 20px; border:1px solid var(--line); background:var(--concrete); position:relative; }
.station::before{ content:""; position:absolute; left:-1px; top:-1px; width:32px; height:2px; background:var(--hi); }
.st-lbl{ display:block; font-family:var(--f-mono); font-size:10px; letter-spacing:.22em; text-transform:uppercase; color:var(--steel-2); }
.station b{ display:block; margin-top:6px; font-family:var(--f-display); font-weight:900; font-size:clamp(34px,3.2vw,46px); line-height:1; letter-spacing:-.03em; font-variant-numeric:tabular-nums; color:var(--ink); }
.st-sub{ display:block; margin-top:8px; font-family:var(--f-mono); font-size:10.5px; letter-spacing:.14em; text-transform:uppercase; color:var(--steel); }
.st-sub em{ font-style:normal; color:var(--hi-deep); }

.form-progress i{ font-style:normal; color:var(--hi-deep); font-variant-numeric:tabular-nums; }
.form-sheet{ position:relative; box-shadow:var(--sh-2); transition:box-shadow .5s var(--e-out); }
.form-sheet:focus-within{ box-shadow:var(--sh-3); }
.field{ position:relative; }
.field::after{                             /* amber rule that draws under the focused control */
  content:""; position:absolute; left:0; bottom:0; height:2px; width:100%; background:var(--hi);
  transform:scaleX(0); transform-origin:0 50%; transition:transform .5s var(--e-out); pointer-events:none;
}
.field:focus-within::after{ transform:scaleX(1); }
.field input:focus, .field select:focus, .field textarea:focus{ box-shadow:none; }
.field.is-filled label{ color:var(--ink); }
.field.is-filled label::after{ content:" ✓"; color:var(--hi-deep); }
.field-count{ position:absolute; right:12px; bottom:10px; font-family:var(--f-mono); font-size:9.5px; letter-spacing:.14em; text-transform:uppercase; color:var(--steel-2); pointer-events:none; font-variant-numeric:tabular-nums; }
.btn--send .arw{ transition:transform .5s var(--e-out); }
.btn--send:hover .arw{ transform:translateX(6px); }
.form.is-sent .btn--send{ background:var(--hi); border-color:var(--hi); color:var(--ink); }

/* --- 25c. After you send it: a three-node sequence ---------------------- */
.seq{ position:relative; display:grid; grid-template-columns:repeat(3, minmax(0,1fr)); gap:clamp(24px,3vw,48px); padding-top:26px; }
.seq-rule{ position:absolute; left:8px; right:8px; top:8px; height:1px; background:var(--line); overflow:hidden; }
.seq-rule i{ position:absolute; inset:0; background:var(--hi); transform-origin:0 50%; transform:scaleX(0); transition:transform 1.6s var(--e-out) .2s; }
.seq.in .seq-rule i{ transform:scaleX(1); }
.seq-step{ position:relative; }
.seq-node{ position:absolute; left:0; top:-26px; width:17px; height:17px; border-radius:50%; background:var(--concrete); border:1px solid var(--line); display:grid; place-items:center; transition:border-color .5s var(--e-out); }
.seq-node b{ width:5px; height:5px; border-radius:50%; background:var(--line); transition:background .5s var(--e-out), transform .5s var(--e-out); }
.seq-step.in .seq-node{ border-color:var(--hi); }
.seq-step.in .seq-node b{ background:var(--hi); transform:scale(1.5); }
.seq-key{ display:block; font-family:var(--f-mono); font-weight:500; font-size:10.5px; letter-spacing:.2em; text-transform:uppercase; color:var(--hi-deep); margin-top:6px; }
.seq-step h3{ margin-top:10px; font-family:var(--f-display); font-weight:800; text-transform:uppercase; font-size:clamp(19px,1.8vw,24px); line-height:1.05; letter-spacing:-.024em; }
.seq-step p{ margin-top:12px; font-size:15px; line-height:1.6; color:var(--steel); }
@media (max-width:860px){
  .seq{ grid-template-columns:1fr; padding-top:0; padding-left:34px; }
  .seq-rule{ left:8px; right:auto; top:8px; bottom:8px; width:1px; height:auto; }
  .seq-rule i{ transform-origin:50% 0; transform:scaleY(0); }
  .seq.in .seq-rule i{ transform:scaleY(1); }
  .seq-node{ left:-34px; top:2px; }
}
@media (prefers-reduced-motion:reduce){
  .hero--contact :is(.sub,.page-tag){ opacity:1 !important; filter:none !important; transform:none !important; }
  .seq-rule i{ transform:none !important; }
}

/* ==========================================================================
   26. CALL — a floating instrument in the corner of every sheet
   Dark disc, phone glyph, mono text orbiting it, a signal ring pulsing out.
   Hover: the disc goes amber, the glyph rings, and the number slides out.
   ========================================================================== */
.callfab{
  position:fixed; right:clamp(20px,2.4vw,34px); bottom:clamp(20px,2.6vh,30px); z-index:120;
  width:96px; height:96px; display:grid; place-items:center; text-decoration:none; color:#fff;
  opacity:0; transform:scale(.4) rotate(-20deg);
  transition:opacity .5s var(--e-out), transform .9s cubic-bezier(.2,1.6,.3,1);
}
.intro-done .callfab, html:not(.js) .callfab{ opacity:1; transform:none; transition-delay:1.6s; }
.callfab > *{ grid-area:1/1; }
.cf-orbit{
  width:100%; height:100%; overflow:visible; pointer-events:none;
  animation:orbit 16s linear infinite;
}
.cf-orbit text{
  font-family:var(--f-mono); font-weight:600; font-size:8.6px; letter-spacing:.24em;
  fill:var(--ink); transition:fill .4s var(--e-out);
}
/* the orbit reads on paper in ink and on black in white; the same JS switch
   the header and rail use flags which is beneath it (.on-dark) */
.callfab.on-dark .cf-orbit text{ fill:rgba(255,255,255,.85); }
/* a whisper of ground behind the orbit, so the ring of text always sits on
   something even when the band beneath is mid-tone */
.callfab::before{
  content:""; grid-area:1/1; width:100%; height:100%; border-radius:50%;
  background:radial-gradient(circle, rgba(244,243,240,.85) 55%, rgba(244,243,240,0) 72%);
  transition:background .4s var(--e-out);
}
.callfab.on-dark::before{ background:radial-gradient(circle, rgba(10,10,10,.85) 55%, rgba(10,10,10,0) 72%); }
@keyframes orbit{ to{ transform:rotate(360deg); } }
.callfab:hover .cf-orbit{ animation-duration:5s; }
.cf-ring{
  width:56px; height:56px; border-radius:50%; border:1px solid rgba(255,176,0,.9); pointer-events:none;
  animation:signal 2.8s var(--e-out) infinite;
}
.cf-ring--2{ animation-delay:1.4s; }
@keyframes signal{ 0%{ transform:scale(.9); opacity:.9 } 100%{ transform:scale(1.55); opacity:0 } }
.cf-disc{
  width:56px; height:56px; border-radius:50%; background:var(--ink); color:#fff;
  display:grid; place-items:center; position:relative;
  box-shadow:0 18px 40px -16px rgba(0,0,0,.65), 0 0 0 1px rgba(255,255,255,.14);
  transition:background .4s var(--e-out), color .4s var(--e-out), transform .5s var(--e-out), box-shadow .5s var(--e-out);
}
.cf-disc svg{ width:22px; height:22px; fill:none; stroke:currentColor; stroke-width:1.6; stroke-linejoin:round; stroke-linecap:round; }
.callfab:hover .cf-disc, .callfab:focus-visible .cf-disc{
  background:var(--hi); color:var(--ink); transform:scale(1.08);
  box-shadow:0 22px 46px -16px rgba(224,148,0,.7), 0 0 0 1px rgba(255,176,0,.6);
}
.callfab:hover .cf-disc svg{ animation:ringring .7s var(--e-io) infinite; transform-origin:50% 60%; }
@keyframes ringring{ 0%,100%{ transform:rotate(0) } 25%{ transform:rotate(-14deg) } 75%{ transform:rotate(14deg) } }
.callfab:active .cf-disc{ transform:scale(.96); }
.cf-label{
  position:absolute; right:calc(100% - 8px); top:50%; transform:translate(10px,-50%);
  display:flex; flex-direction:column; align-items:flex-end; white-space:nowrap;
  padding:10px 16px 11px; background:var(--ink); color:#fff;
  box-shadow:var(--sh-2); pointer-events:none;
  opacity:0; transition:opacity .35s var(--e-out), transform .5s var(--e-out);
}
.cf-label b{ font-family:var(--f-mono); font-weight:500; font-size:9.5px; letter-spacing:.22em; text-transform:uppercase; color:var(--hi); }
.cf-label span{ font-family:var(--f-display); font-weight:800; font-size:17px; letter-spacing:.02em; margin-top:2px; }
.callfab:hover .cf-label, .callfab:focus-visible .cf-label{ opacity:1; transform:translate(0,-50%); }
.callfab:focus-visible{ outline:none; }
.callfab:focus-visible .cf-disc{ box-shadow:0 0 0 3px var(--hi); }
.intro-active .callfab{ opacity:0 !important; }
.callfab.is-hidden{ opacity:0 !important; pointer-events:none; transition-delay:0s; }
@media (max-width:620px){
  .callfab{ width:78px; height:78px; right:16px; bottom:18px; }
  .cf-ring, .cf-disc{ width:50px; height:50px; }
  .cf-orbit text{ font-size:9.2px; }
  .cf-label{ display:none; }
}
@media print{ .callfab{ display:none; } }
@media (prefers-reduced-motion:reduce){
  .cf-orbit, .cf-ring, .callfab:hover .cf-disc svg{ animation:none !important; }
  .cf-ring{ opacity:.35; }
  .callfab{ opacity:1 !important; transform:none !important; }
}
