/* ═══════════════════════════════════════════════════════════════════════════
   main.css — Construction Santorini
   Art direction: "Industry" (light blueprint) — see DESIGN.md

   The page is a light technical ground. Objects are line drawings on it:
   transparent, square, bounded by a 1px hairline, with a "+" registration mark
   straddling each corner. One steel accent carries links, routes and focus. The
   only filled object on a page is the primary button; the only dark surface is
   the CTA plate. Photographs are duotoned into the accent so they belong to the
   drawing rather than sitting on top of it.

   All values come from tokens.css. No raw hex below this line.
   ═══════════════════════════════════════════════════════════════════════════ */

/* tokens.css is linked separately, before this file — see _tools/build.js.
   It is not @imported here, because an @import inside a deferred stylesheet
   chains a second request behind the first. */

/* ── 1. RESET + BASE ───────────────────────────────────────────────────── */

*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth}
@media (prefers-reduced-motion: reduce){html{scroll-behavior:auto}}

body{
  margin:0;
  background:var(--ground);
  color:var(--ink);
  font:400 var(--t-0)/var(--lh-body) var(--f-body);
  font-synthesis-weight:none;
  text-rendering:optimizeLegibility;
  overflow-x:hidden;
}

img,svg,video{max-width:100%;height:auto}
svg{display:block}

/* The route rail is retired with the dark theme. site.js still writes --scroll
   on <body>; nothing reads it, which costs one custom property and no layout. */

/* ── 2. TYPE ───────────────────────────────────────────────────────────────
   Headings are condensed 600, uppercase, tracked open — the way a drawing sheet
   sets a title, not the way a magazine sets a headline. One weight; hierarchy
   comes from size and tracking. */

h1,h2,h3,h4{
  font-family:var(--f-disp);font-weight:var(--w-disp);
  line-height:var(--lh-head);letter-spacing:var(--tr-head);
  text-transform:uppercase;
  margin:0 0 .5em;text-wrap:balance;
}
h1{font-size:var(--t-4);line-height:var(--lh-hero);letter-spacing:var(--tr-disp)}
h2{font-size:var(--t-3)}
h3{font-size:var(--t-2)}
h4{font-size:var(--t-1)}
p{margin:0 0 1.1em;max-width:var(--measure)}
a{color:var(--steel-700);text-decoration-thickness:1px;text-underline-offset:3px}
a:hover{color:var(--steel-900)}
strong{font-weight:600}
small{font-size:.86em}
hr{border:0;border-top:1px solid var(--hair);margin:var(--s4) 0}
abbr[title]{text-decoration:underline dotted;cursor:help}
::selection{background:color-mix(in srgb,var(--steel) 30%,transparent)}

/* `.mono` no longer names a face — the light theme has no third face. It still
   means what it always meant at the call site: these figures line up. */
.mono{font-variant-numeric:tabular-nums;font-feature-settings:'tnum' 1}
.lede{font-size:var(--t-1);color:var(--ink-2);max-width:60ch;margin-bottom:1.4em}

/* The kicker — the recurring wayfinding device. 13px, 600, uppercase, 0.08em,
   tabular figures so a "04 ·" prefix sets on the same rhythm everywhere. */
.kicker,.sign{
  display:block;font-size:var(--t--2);font-weight:600;line-height:1.2;
  text-transform:uppercase;letter-spacing:var(--tr-sign);
  color:var(--steel-700);font-variant-numeric:tabular-nums;
  font-feature-settings:'tnum' 1;margin:0 0 var(--s2);
}
/* A kicker that heads a section sits over a caption rule. */
.band__h .kicker,.sec>.kicker{padding-bottom:var(--s2);border-bottom:1px solid var(--hair)}

/* ── 3. THE FRAME — every framed object is the same object ─────────────────
   1px hairline, square, transparent, with a 15px "+" registration mark
   straddling each corner. Four marks are drawn by two pseudo-elements: a strip
   above the box carrying the top pair and one below carrying the bottom pair,
   each mark a crossed pair of 1px gradient bars.

   Doing it here rather than in the templates is the whole reason this is a
   reskin: not one of the 284 pages ships four spacer spans, and any object that
   should read as framed joins the list below. `.frame` is the generic hook;
   the rest are the site's existing framed objects, named. */

.frame,.route__i,.cta__in,.ph,.build__fig,.detail,.tool__fig,.caldera__fig,
.hero__meta,.spec{position:relative}
.frame{border:1px solid var(--hair);background:none}

.frame::before,.frame::after,
.route__i::before,.route__i::after,
.cta__in::before,.cta__in::after,
.ph::before,.ph::after,
.build__fig::before,.build__fig::after,
.detail::before,.detail::after,
.tool__fig::before,.tool__fig::after,
.caldera__fig::before,.caldera__fig::after,
.hero__meta::before,.hero__meta::after,
.spec::before,.spec::after{
  content:"";position:absolute;left:calc(var(--mark)/-2);right:calc(var(--mark)/-2);
  height:var(--mark);pointer-events:none;z-index:2;
  background-image:
    linear-gradient(var(--mark-ink),var(--mark-ink)),
    linear-gradient(var(--mark-ink),var(--mark-ink)),
    linear-gradient(var(--mark-ink),var(--mark-ink)),
    linear-gradient(var(--mark-ink),var(--mark-ink));
  background-size:var(--mark) 1px,1px var(--mark),var(--mark) 1px,1px var(--mark);
  background-position:
    left 0 top var(--mark-mid),left var(--mark-mid) top 0,
    right 0 top var(--mark-mid),right var(--mark-mid) top 0;
  background-repeat:no-repeat;
}
.frame::before,.route__i::before,.cta__in::before,.ph::before,.build__fig::before,
.detail::before,.tool__fig::before,.caldera__fig::before,.hero__meta::before,
.spec::before{top:calc(var(--mark)/-2)}
.frame::after,.route__i::after,.cta__in::after,.ph::after,.build__fig::after,
.detail::after,.tool__fig::after,.caldera__fig::after,.hero__meta::after,
.spec::after{bottom:calc(var(--mark)/-2)}

/* A frame whose marks would be clipped by a scroll parent drops them rather
   than showing half of each. */
.frame--nomark::before,.frame--nomark::after{display:none}

/* ── 4. FOCUS — instant, never animated, never lost ────────────────────── */

:focus{outline:none}
:focus-visible{outline:var(--focus-w) solid var(--steel);outline-offset:2px}
/* On the one dark surface the steel ring is too close in value to the field. */
.cta__in :focus-visible{outline-color:var(--steel-300)}

.skip{
  position:absolute;left:var(--s2);top:-100vh;z-index:99;
  background:var(--steel-700);color:var(--ground);
  padding:.7rem 1.1rem;font-size:var(--t--1);text-decoration:none;
}
.skip:focus{top:var(--s2)}

/* ── 5. LAYOUT ─────────────────────────────────────────────────────────── */

.wrap{width:min(100% - var(--gut)*2,var(--wrap));margin-inline:auto}
.wrap.narrow,.narrow{width:min(100% - var(--gut)*2,var(--wrap-n));margin-inline:auto}

main{display:block}

/* Document grid — asymmetric. Prose left and wide, apparatus right and narrow. */
.doc{padding:var(--sec) 0}
/* `minmax(0,1fr)` rather than a bare implicit track: an `auto` track takes its
   floor from the item's min-content contribution, and a wide drawn detail then
   pushes the column — and the document — past the viewport on a phone. */
.doc__grid{display:grid;grid-template-columns:minmax(0,1fr);gap:var(--s5) var(--s4);align-items:start}
.doc__main,.doc__side{min-width:0}
@media (min-width:62rem){
  .doc__grid{grid-template-columns:minmax(0,1fr) 17.5rem}
  .doc__side{order:2;position:sticky;top:var(--s4)}
  .doc__main{order:1}
}

/* The prose column. No panel, no fill — on a light ground the reading surface
   is the page. 15px is the system's body size and it is right for the chrome
   and the registers; it is not right for 264,000 words, so long-form sets one
   step up. */
.doc__main{font-size:var(--t-prose)}
.doc__main p,.doc__main li{max-width:var(--measure)}

/* Sections are separated by the line, never by cards. */
.sec{margin-bottom:var(--sec);scroll-margin-top:5rem}
.sec:last-child{margin-bottom:0}
.sec>h2{
  position:relative;padding-top:var(--s3);margin-top:0;
  border-top:1px solid var(--hair);
}
.sec>h3{margin-top:1.6em}

/* ── 6. HEADER + NAV ───────────────────────────────────────────────────── */

.site-head{
  position:relative;z-index:20;
  background:var(--ground);
  border-bottom:1px solid var(--hair);
}
/* The header carries brand + six links + four locales + two buttons, and the
   Greek labels are the long ones. It wraps to a second row rather than pushing
   the document wider — a header that overflows gives the whole page a
   horizontal scrollbar, which is the one failure mode worth designing out. */
.site-head__in{display:flex;align-items:center;flex-wrap:wrap;gap:var(--s2) var(--s3);min-height:4.25rem;padding-block:.5rem}

.brand{
  display:flex;align-items:center;gap:.55rem;
  color:var(--ink);text-decoration:none;flex:0 0 auto;
}
.brand__mark{color:var(--steel-700);display:block}
.brand__txt{display:flex;flex-direction:column;line-height:1.05}
.brand__l1,.brand__l2{
  font-family:var(--f-disp);font-weight:var(--w-disp);
  text-transform:uppercase;letter-spacing:var(--tr-name);
}
.brand__l1{font-size:var(--t--1);color:var(--ink-3)}
.brand__l2{font-size:1.125rem}

.navtoggle{
  margin-left:auto;display:flex;align-items:center;gap:.5rem;
  background:none;border:1px solid var(--hair);color:var(--ink);
  padding:.5rem .8rem;cursor:pointer;
  font:600 var(--t--2)/1.2 var(--f-body);
  text-transform:uppercase;letter-spacing:var(--tr-sign);
}
.navtoggle:hover{background:var(--tint);border-color:var(--steel)}
.navtoggle__bars{display:grid;gap:3px;width:15px}
.navtoggle__bars i{display:block;height:1.5px;background:currentColor;transition:transform var(--d-snap) var(--e-snap)}
[aria-expanded="true"] .navtoggle__bars i:nth-child(1){transform:translateY(4.5px) rotate(45deg)}
[aria-expanded="true"] .navtoggle__bars i:nth-child(2){transform:scaleX(0)}
[aria-expanded="true"] .navtoggle__bars i:nth-child(3){transform:translateY(-4.5px) rotate(-45deg)}
@media (min-width:62rem){.navtoggle{display:none}}

.nav{margin-left:auto;display:flex;align-items:center;flex-wrap:wrap;gap:var(--s2) var(--s3);min-width:0}
.nav__list{display:flex;flex-wrap:wrap;gap:var(--s1) var(--s3);list-style:none;margin:0;padding:0;min-width:0}
.nav__list a{
  color:var(--ink);text-decoration:none;font-size:var(--t--1);
  padding-bottom:2px;border-bottom:1px solid transparent;
  transition:color var(--d-snap) var(--e-snap),border-color var(--d-snap) var(--e-snap);
}
.nav__list a:hover,.nav__list a[aria-current]{color:var(--steel-700);border-bottom-color:var(--steel)}

.langs{display:flex;align-items:center;gap:.5rem}
.langs__label{
  font-size:var(--t--2);color:var(--ink-3);text-transform:uppercase;
  letter-spacing:var(--tr-sign);
}
.langs ul{display:flex;gap:.3rem;list-style:none;margin:0;padding:0}
.langs a{
  color:var(--ink-3);text-decoration:none;font-size:var(--t--2);font-weight:600;
  padding:.15rem .4rem;border:1px solid transparent;letter-spacing:.04em;
}
.langs a[aria-current]{color:var(--ground);background:var(--steel-700);border-color:var(--steel-700)}
.langs a:hover{color:var(--steel-700);border-color:var(--hair)}

.nav__cta{display:flex;align-items:center;gap:var(--s2)}

/* Between the point the full nav appears and the point the page is genuinely
   wide, everything in the header tightens a step so it holds one row. The
   "Language" label goes visually hidden rather than `display:none` — the
   locale list is labelled by it. */
@media (min-width:62rem) and (max-width:81.24rem){
  .site-head__in{gap:var(--s2)}
  .nav{gap:var(--s2)}
  .nav__list{gap:var(--s2)}
  .nav__list a{font-size:var(--t--2)}
  .nav__cta .btn{padding:.7rem .8rem;font-size:var(--t--2)}
  .langs{gap:.3rem}
  .langs__label{
    position:absolute;width:1px;height:1px;padding:0;margin:-1px;
    overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0;
  }
}

@media (max-width:61.99rem){
  .nav{
    position:absolute;inset:100% 0 auto;background:var(--ground);
    flex-direction:column;align-items:stretch;gap:var(--s3);
    padding:var(--s3) var(--gut) var(--s4);
    border-bottom:1px solid var(--hair);
    display:none;
  }
  /* site.js opens the menu with `nav.setAttribute('data-open','')`. The dark
     theme only ever styled `.is-open`, so the button set aria-expanded and
     nothing appeared — the mobile menu has never opened. Both selectors are
     honoured here rather than editing site.js, which is out of scope. */
  .nav.is-open,.nav[data-open]{display:flex}
  .nav__list{flex-direction:column;gap:var(--s2)}
  .nav__list a{font-size:var(--t-1);display:inline-block}
  .nav__cta{flex-direction:column;align-items:stretch}
}

/* ── 7. BUTTONS ────────────────────────────────────────────────────────────
   Square, hairline-bordered, condensed caps. The filled one is the only solid
   object on the page — and it is filled with steel-700, not the base steel:
   paper on #5980A6 is 3.71:1 and a 14px label needs 4.5:1. */

.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:.4rem;
  font-family:var(--f-disp);font-weight:var(--w-disp);font-size:var(--t--1);
  text-transform:uppercase;letter-spacing:var(--tr-head);white-space:nowrap;
  padding:.8rem 1.15rem;border:1px solid var(--hair);border-radius:var(--radius);
  text-decoration:none;cursor:pointer;background:none;color:var(--ink);
  transition:background-color var(--d-snap) var(--e-snap),
             color var(--d-snap) var(--e-snap),
             border-color var(--d-snap) var(--e-snap);
}
/* The chevron is retired: these are blueprint objects, not affordance stickers.
   `.btn--nochev` stays a valid class so no template needs editing. */
.btn--nochev::after{display:none}

.btn--mark{background:var(--steel-700);color:var(--ground);border-color:var(--steel-700)}
.btn--mark:hover{background:var(--steel-800);border-color:var(--steel-800);color:var(--ground)}
.btn--mark:active{background:var(--steel-900);border-color:var(--steel-900)}

.btn--ghost,.btn--out{border-color:var(--hair);color:var(--ink);background:none}
.btn--ghost:hover,.btn--out:hover{background:var(--tint);border-color:var(--steel);color:var(--steel-900)}
.btn--ghost:active,.btn--out:active{background:var(--steel-200)}

.btn--dark{background:var(--steel-900);color:var(--ground);border-color:var(--steel-900)}
.btn--dark:hover{background:var(--steel-800);border-color:var(--steel-800)}

.btn--lg{font-size:var(--t-0);padding:.9rem 1.4rem}

/* Inside the dark CTA plate the ghost button reverses. */
.cta__in .btn--ghost,.cta__in .btn--out{color:var(--rev);border-color:var(--rev-hair)}
.cta__in .btn--ghost:hover,.cta__in .btn--out:hover{
  background:color-mix(in srgb,var(--ground) 12%,transparent);border-color:var(--rev);color:var(--rev);
}

/* ── 8. BREADCRUMBS + PAGE HERO ────────────────────────────────────────── */

.crumbs{padding:.9rem 0 0}
.crumbs ol{
  display:flex;flex-wrap:wrap;gap:.5rem;list-style:none;margin:0;padding:0;
  font-size:var(--t--2);color:var(--ink-3);
}
.crumbs li+li::before{content:"/";margin-right:.5rem;color:var(--ink-4)}
.crumbs a{color:var(--ink-3);text-decoration:none}
.crumbs a:hover{color:var(--steel-700);text-decoration:underline}
.crumbs [aria-current]{color:var(--ink)}

.phero{padding:clamp(2rem,5vw,3.5rem) 0 clamp(1.5rem,3vw,2.5rem);border-bottom:1px solid var(--hair)}
.phero h1{max-width:20ch}
.phero__sub{font-size:var(--t-1);color:var(--ink-2);max-width:56ch}

.byline{font-size:var(--t--2);color:var(--ink-3);letter-spacing:.01em}

/* The 40–60 word direct answer. A ruled plate with an accent edge. */
.answer{
  border:1px solid var(--hair);border-left:3px solid var(--steel-700);
  padding:clamp(1rem,2.5vw,1.5rem) clamp(1.1rem,3vw,1.6rem);
  max-width:64ch;margin-top:var(--s3);
}
.answer__tag{
  font-size:var(--t--2);font-weight:600;text-transform:uppercase;
  letter-spacing:var(--tr-sign);color:var(--steel-700);margin:0 0 .45rem;
}
.answer__t{margin:0;font-size:var(--t-1);line-height:1.5;max-width:none}

/* ── 9. CONTENT BLOCKS ─────────────────────────────────────────────────── */

.list{margin:0 0 1.2em;padding:0;list-style:none;max-width:var(--measure)}
.list li{position:relative;padding-left:1.5rem;margin-bottom:.55em}
.list li::before{
  content:"";position:absolute;left:0;top:.7em;
  width:.7rem;height:1px;background:var(--steel);
}
.list--ord{counter-reset:n}
.list--ord li{counter-increment:n;padding-left:2.4rem}
.list--ord li::before{
  content:counter(n,decimal-leading-zero);
  width:auto;height:auto;background:none;top:0;
  font-size:var(--t--2);font-weight:600;letter-spacing:var(--tr-sign);
  color:var(--steel-700);font-variant-numeric:tabular-nums;
}

.deflist{margin:0 0 1.2em;max-width:var(--measure)}
.deflist dt{
  font-family:var(--f-disp);font-weight:var(--w-disp);font-size:var(--t-0);
  text-transform:uppercase;letter-spacing:var(--tr-name);
  padding-top:.7em;margin-top:.7em;border-top:1px solid var(--hair);
}
.deflist dd{margin:.25em 0 0;color:var(--ink-2)}

.note{
  margin:1.5em 0;padding:1rem 1.2rem;
  border:1px solid var(--hair);border-left:3px solid var(--hair-2);
  max-width:var(--measure);
}
.note p{margin:0}
.note__tag{
  display:block;font-size:var(--t--2);font-weight:600;text-transform:uppercase;
  letter-spacing:var(--tr-sign);color:var(--ink-3);margin-bottom:.35rem;
}
.note--warn{border-left-color:var(--steel-700);background:var(--tint)}
.note--warn .note__tag{color:var(--steel-700)}

/* Dimension lines — annotate real measurements. */
.dims{display:grid;gap:var(--s2);margin:1.5em 0;max-width:var(--measure)}
.dim{display:grid;grid-template-columns:5.5rem 1fr;align-items:baseline;gap:.8rem}
.dim__rule{position:relative;height:1px;background:var(--hair-2);align-self:center}
.dim__rule::before,.dim__rule::after{
  content:"";position:absolute;top:-3px;width:1px;height:7px;background:var(--hair-2);
}
.dim__rule::before{left:0}.dim__rule::after{right:0}
.dim__val{font-size:var(--t--1);color:var(--steel-700);font-weight:600;grid-column:1}
.dim__label{grid-column:2}

.tablewrap{overflow-x:auto;margin:1.5em 0;border-top:1px solid var(--hair-2)}
.dtable{width:100%;border-collapse:collapse;font-size:var(--t-0)}
.dtable caption{
  text-align:left;font-size:var(--t--2);font-weight:600;
  color:var(--ink-3);padding:.6em 0;text-transform:uppercase;letter-spacing:var(--tr-sign);
}
.dtable th,.dtable td{
  text-align:left;padding:.62em .8em;border-bottom:1px solid var(--hair);vertical-align:top;
}
.dtable thead th{
  font-size:var(--t--2);font-weight:600;text-transform:uppercase;
  letter-spacing:var(--tr-sign);white-space:nowrap;color:var(--ink-3);
}
.dtable tbody th{font-weight:600}
.dtable td{font-variant-numeric:tabular-nums;font-feature-settings:'tnum' 1}
.dtable tbody tr:hover{background:var(--tint)}
.tnote{font-size:var(--t--2);color:var(--ink-3);max-width:var(--measure)}

/* Steps — a numbered route down the page. */
.steps{list-style:none;margin:1.5em 0;padding:0}
.step{
  position:relative;display:grid;grid-template-columns:3rem 1fr;gap:var(--s2);
  padding:0 0 var(--s4) 0;
}
.step::before{
  content:"";position:absolute;left:1rem;top:2.2rem;bottom:0;width:1px;background:var(--hair);
}
.step:last-child{padding-bottom:0}
.step:last-child::before{display:none}
.step__n{
  grid-column:1;font-size:var(--t--2);color:var(--steel-700);font-weight:600;
  width:2rem;height:2rem;display:grid;place-items:center;
  border:1px solid var(--hair);background:var(--ground);position:relative;z-index:1;
  font-variant-numeric:tabular-nums;
}
.step__body{grid-column:2}
.step__body h3{margin-bottom:.25em}
.step__dur{font-size:var(--t--2);color:var(--ink-3);margin:0 0 .4em}

/* The drawn details — the site's explaining voice. Framed like everything else. */
.detail{margin:2.5em 0;padding:0;position:relative;border:1px solid var(--hair)}
.detail svg{width:100%;height:auto;background:var(--surface);display:block}

/* The linework of those drawings. assets/details.js marks 161 elements across 82
   pages with .dsvg-* classes and gives them geometry only — no stroke attribute.
   No stylesheet ever defined the classes, so SVG's initial `stroke: none` applied
   and every ground line, leader, dimension line and dashed indicator painted
   nothing: labels like "≥150 mm" pointed at arrows that were not there, and the
   paths, having no fill attribute either, filled black by default. The drawings
   have shipped that way since they were written; the light theme did not cause it
   but it is the visible face of the site on 29% of pages, so it is fixed here.

   `:not([fill])` matters: fourteen text groups carry a deliberate material colour
   as a presentation attribute, and a bare `fill` rule would overwrite them. */
.detail .dsvg-line{stroke:var(--ink);fill:none}
.detail .dsvg-thin{stroke:var(--ink-3);fill:none}
.detail .dsvg-mark{stroke:var(--steel-700);fill:none}
.detail .dsvg-t:not([fill]){fill:var(--ink-3)}
.detail .dsvg-tb:not([fill]){fill:var(--ink)}
.detail .dsvg-t,.detail .dsvg-tb{font-family:var(--f-body);font-size:11px}
.detail .dsvg-tb{font-weight:600;font-size:12px}
/* The arrowheads are separate <marker> elements filled by presentation attribute —
   #arm still carried the amber accent this palette retired. CSS outranks the
   attribute, so they follow the line they terminate. */
.detail marker#arm path{fill:var(--steel-700)}
.detail marker#ar path{fill:var(--ink-3)}
.detail figcaption{
  font-size:var(--t--2);line-height:1.55;color:var(--ink-3);
  padding:.6rem .8rem;border-top:1px solid var(--hair);max-width:none;
}
.detail__ref{color:var(--steel-700);font-weight:600;margin-right:.5rem;letter-spacing:var(--tr-sign)}

/* ── 10. APPARATUS: TOC + SPEC ─────────────────────────────────────────── */

.toc{margin-bottom:var(--s4)}
.toc__h,.spec__h{
  font-size:var(--t--2);font-weight:600;text-transform:uppercase;
  letter-spacing:var(--tr-sign);color:var(--ink-3);margin:0 0 .7rem;
  padding-bottom:.5rem;border-bottom:1px solid var(--hair);
}
.toc ul{list-style:none;margin:0;padding:0}
.toc li{margin-bottom:.4rem}
.toc a{
  color:var(--ink);text-decoration:none;font-size:var(--t--1);
  display:block;padding-left:.9rem;position:relative;
}
.toc a::before{
  content:"";position:absolute;left:0;top:.7em;width:.5rem;height:1px;
  background:var(--hair-2);
  transition:width var(--d-snap) var(--e-snap),background-color var(--d-snap) var(--e-snap);
}
.toc a:hover,.toc a.is-cur{color:var(--steel-700)}
.toc a:hover::before,.toc a.is-cur::before{width:.8rem;background:var(--steel)}

/* The spec table is a drawing-sheet title block: hairline frame, ruled rows. */
.spec{border:1px solid var(--hair);padding:var(--s2) var(--s3) var(--s3)}
.spec__h{margin-top:0}
.spec__t{width:100%;border-collapse:collapse;font-size:var(--t--1)}
.spec__t th,.spec__t td{text-align:left;padding:.55em 0;vertical-align:top;border-bottom:1px solid var(--hair)}
.spec__t tr:last-child th,.spec__t tr:last-child td{border-bottom:0}
.spec__t th{
  font-size:var(--t--2);font-weight:600;text-transform:uppercase;
  letter-spacing:var(--tr-sign);color:var(--ink-3);width:44%;
}
/* The contact page puts Info@ConstructionSantorini.com in this table. A table's
   min-content floor is its longest unbreakable token, so without this the
   sidebar — and the document — is 30 characters wide on a small phone. */
.spec__t td{color:var(--ink);padding-left:.6em;font-variant-numeric:tabular-nums;overflow-wrap:anywhere}
.spec__note{font-size:var(--t--2);color:var(--ink-3);margin:.7rem 0 0}

/* ── 11. FAQ ───────────────────────────────────────────────────────────── */

.acc{border-top:1px solid var(--hair-2)}
.acc__i{border-bottom:1px solid var(--hair)}
/* Questions sit in the body face, not the display face — a condensed uppercase
   heading reads as a statement, and these are questions. */
.acc__i summary{
  display:flex;align-items:flex-start;justify-content:space-between;gap:var(--s2);
  padding:.95em 0;cursor:pointer;list-style:none;
  font-family:var(--f-body);font-weight:600;font-size:var(--t-1);color:var(--ink);
}
.acc__i summary::-webkit-details-marker{display:none}
.acc__i summary:hover{color:var(--steel-700)}
.acc__x{position:relative;flex:0 0 auto;width:.9rem;height:.9rem;margin-top:.4em}
.acc__x::before,.acc__x::after{
  content:"";position:absolute;background:var(--steel-700);
  transition:transform var(--d-move) var(--e-snap);
}
.acc__x::before{left:0;top:50%;width:100%;height:1px;margin-top:-.5px}
.acc__x::after{top:0;left:50%;height:100%;width:1px;margin-left:-.5px}
.acc__i[open] .acc__x::after{transform:scaleY(0)}
.acc__b{padding:0 0 1.1em}
.acc__b p:last-child{margin-bottom:0}

/* ── 12. RELATED — routed links, not cards ─────────────────────────────── */

.rel__grid{list-style:none;margin:0;padding:0;border-top:1px solid var(--hair-2)}
.rel__i{border-bottom:1px solid var(--hair)}
.rel__i a{
  display:grid;gap:.15rem;padding:.9rem .5rem;text-decoration:none;
  color:var(--ink);transition:background-color var(--d-snap) var(--e-snap);
}
.rel__i a:hover{background:var(--tint)}
.rel__t{
  font-family:var(--f-disp);font-weight:var(--w-disp);font-size:var(--t-1);
  text-transform:uppercase;letter-spacing:var(--tr-name);color:var(--steel-700);
}
.rel__d{font-size:var(--t--2);line-height:1.5;color:var(--ink-3)}

/* ── 13. HOMEPAGE HERO ─────────────────────────────────────────────────── */

.hero{padding:clamp(2rem,5vw,4.5rem) 0 clamp(2rem,5vw,4rem)}
.hero__in{display:grid;gap:var(--s4);align-items:center}
.hero__kick{margin-bottom:var(--s3)}
/* The optical left shift: condensed caps leave a visible gap at the left margin
   that the smaller type does not, so the H1 is pulled back by half a stem to
   sit on the same vertical as the kicker and the sub. */
.hero h1,.hero__h{
  font-size:var(--t-6);letter-spacing:var(--tr-disp);line-height:var(--lh-hero);
  margin:0 0 var(--s3) -.052em;max-width:none;text-wrap:initial;
}
.hero__sub{font-size:var(--t-1);line-height:1.55;max-width:60ch;margin-bottom:var(--s3)}
.hero__sub strong{font-weight:600}
.hero__acts{display:flex;flex-wrap:wrap;gap:var(--s2);align-items:center;margin-bottom:var(--s3)}
.hero__tel{font-size:var(--t--1);color:var(--steel-700);text-decoration:none;font-variant-numeric:tabular-nums}
.hero__tel:hover{color:var(--steel-900);text-decoration:underline}

/* The spec-sheet plate. Four cells divided by hairlines, numerals in condensed
   600 at 44px with tabular figures — a drawing sheet's schedule of quantities.
   `.hero__txt` becomes `display:contents` at the two-column breakpoint so the
   plate can run the full width beneath both columns without touching a
   template: the drawing is an object beside the text, the numbers are a sheet
   under both. */
/* The cell dividers are the grid gap showing the container through, not borders
   on the cells: with `auto-fit` the number of columns is unknown, and a border
   per cell doubles up against the frame wherever a row happens to end. */
.hero__meta{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(11rem,1fr));
  list-style:none;margin:var(--s3) 0 0;padding:0;
  border:1px solid var(--hair);gap:1px;background:var(--hair);
}
.hero__stat{
  display:grid;gap:.35rem;align-content:start;
  padding:var(--s3);background:var(--ground);
}
.hero__stat b{
  font-family:var(--f-disp);font-weight:var(--w-disp);font-size:var(--t-stat);
  color:var(--ink);line-height:1.05;font-variant-numeric:tabular-nums;
  font-feature-settings:'tnum' 1;letter-spacing:var(--tr-disp);
}
.hero__stat span{font-size:var(--t--1);line-height:1.45;color:var(--ink-2)}
@media (min-width:62rem){
  .hero__in{grid-template-columns:minmax(0,52fr) minmax(0,48fr);gap:clamp(2rem,5vw,5rem) clamp(2rem,5vw,5rem)}
  .hero__txt{display:contents}
  .hero__kick,.hero__in>h1,.hero__sub,.hero__acts{grid-column:1}
  .hero__scene{grid-column:2;grid-row:1 / span 4;align-self:center}
  .hero__meta{grid-column:1 / -1;margin-top:var(--s4)}
}

/* ── 14. THE BUILD SEQUENCE — the drawing beside the hero ──────────────────
   Scroll-scrubbed by site.js, six stages, opacity only. The drawing itself is
   in content/connector.js and paints with the dark theme's token names; they
   are remapped here, scoped to the figure, so the sheet reads as a drawing on
   paper rather than a negative of one. */

.build{position:relative}
.build__fig{margin:0;border:1px solid var(--hair);background:var(--ground);position:relative}
.build__svg{
  width:100%;height:auto;display:block;background:var(--surface);
  --dust:var(--n-700);            /* ground line, structure, hatching        */
  --rule-d2:var(--hair-2);        /* setting-out dashes                      */
  --basalt:var(--steel-900);      /* openings: doors and windows are voids   */
  --chalk:var(--steel);           /* services, drawn                         */
  --chalk-up:var(--steel-700);    /* dimension lines and their figures       */
  /* --scoria-2 (the cut vault) and --whitewash (the render sweep) already hold
     the right values globally — see tokens.css §1b — so they are not repeated. */
}
.build__head{
  display:flex;justify-content:space-between;align-items:baseline;gap:var(--s2);
  padding:.6rem .9rem;border-bottom:1px solid var(--hair);
}
.build__title{
  font-size:var(--t--2);font-weight:600;text-transform:uppercase;
  letter-spacing:var(--tr-sign);color:var(--ink-3);margin:0;
}
.build__count{font-size:var(--t--2);font-weight:600;color:var(--steel-700);font-variant-numeric:tabular-nums}

/* Stage groups. Opacity only — driven by [data-stage] on the figure. */
.build__stage{opacity:0;transition:opacity var(--d-move) var(--e-lift)}
.build__stage.is-on{opacity:1}
.no-js .build__stage{opacity:1}

.build__labels{
  list-style:none;margin:0;padding:.9rem;display:flex;flex-wrap:wrap;gap:.4rem;
  border-top:1px solid var(--hair);
}
.build__label{
  display:inline-block;
  font-family:var(--f-disp);font-weight:var(--w-disp);font-size:var(--t--2);
  text-transform:uppercase;letter-spacing:var(--tr-name);
  padding:.3rem .55rem;border:1px solid var(--hair);color:var(--ink-3);
  text-decoration:none;
  transition:color var(--d-snap) var(--e-snap),border-color var(--d-snap) var(--e-snap),
             background-color var(--d-snap) var(--e-snap);
}
.build__label.is-on{color:var(--steel-700);border-color:var(--steel)}
.build__label:hover{background:var(--tint);border-color:var(--steel);color:var(--steel-900)}
.build__note{padding:.7rem .9rem;margin:0;font-size:var(--t--2);color:var(--ink-3);border-top:1px solid var(--hair);max-width:none}

/* ── 15. THE SNAP — symptom → trade. A ruled list you can read down. ───── */

/* Two columns of ruled rows, 64px apart, flowing row-major: symptom on the
   left in body text, the trade it routes to on the right in condensed caps. */
.symp{
  list-style:none;margin:0;padding:0;
  /* 22.5rem is 360px: with the 64px column gap a third column needs 1208px and
     the wrap is 1200px, so this holds at two columns exactly as drawn. The
     `min(…,100%)` is not optional — a bare 360px minimum is wider than a phone's
     content column and pushes the whole document sideways. */
  display:grid;grid-template-columns:repeat(auto-fit,minmax(min(22.5rem,100%),1fr));
  column-gap:4rem;border-top:1px solid var(--hair);
}
.symp__row{border-bottom:1px solid var(--hair)}
.symp__row a{
  display:flex;align-items:baseline;justify-content:space-between;gap:1.5rem;
  padding:.85rem .5rem;text-decoration:none;color:var(--ink);position:relative;
  transition:background-color var(--d-snap) var(--e-snap);
}
.symp__row a:hover,.symp__row a:focus-visible{background:var(--tint)}
.symp__q{font-size:var(--t-0);line-height:1.4}
/* The leader line belonged to the dark theme, where the chalk line snapping
   across was the signature. Here the two ends of the row are the whole idea and
   a rule between them is noise. site.js still adds `.is-snapped`; it now has
   nothing to draw, which is the correct resting state for a still design. */
.symp__line{display:none}
.symp__a{
  font-family:var(--f-disp);font-weight:var(--w-disp);font-size:var(--t-0);
  text-transform:uppercase;letter-spacing:var(--tr-name);color:var(--steel-700);
  white-space:nowrap;text-align:right;
}
@media (max-width:30rem){
  .symp__row a{flex-direction:column;gap:.2rem}
  .symp__a{text-align:left}
}

/* ── 16. TRADE BAND — the register, on rails ──────────────────────────────
   site.js still drives drag, arrows and keyboard; every card is still a real
   link. The perspective is gone: on a light sheet the cards are drawn objects
   in a row, not a carousel of tilted panels. The z-translate site.js writes
   simply has nothing to project onto. */

.band3d{position:relative}
.band3d__view{
  perspective:none;overflow:hidden;
  -webkit-mask-image:linear-gradient(90deg,#000 0,#000 92%,transparent);
  mask-image:linear-gradient(90deg,#000 0,#000 92%,transparent);
}
.band3d__track{
  display:flex;gap:var(--s3);padding:var(--s3) 0;
  transition:transform var(--d-move) var(--e-lift);
  will-change:transform;
}
.band3d__card{
  flex:0 0 auto;width:15rem;min-height:9rem;
  background:none;border:1px solid var(--hair);
  padding:var(--s3);text-decoration:none;color:var(--ink);
  display:grid;align-content:start;gap:.4rem;
  transition:border-color var(--d-snap) var(--e-snap),
             background-color var(--d-snap) var(--e-snap);
}
.band3d__card:hover,.band3d__card:focus-visible{border-color:var(--steel);background:var(--tint)}
.band3d__n{font-size:var(--t--2);font-weight:600;letter-spacing:var(--tr-sign);color:var(--steel-700);font-variant-numeric:tabular-nums}
.band3d__t{
  font-family:var(--f-disp);font-weight:var(--w-disp);font-size:var(--t-1);
  text-transform:uppercase;letter-spacing:var(--tr-name);line-height:1.12;
}
.band3d__d{font-size:var(--t--2);line-height:1.45;color:var(--ink-3)}
.band3d__nav{display:flex;gap:var(--s1);justify-content:flex-end;padding-top:var(--s2)}
.band3d__btn{
  width:2.6rem;height:2.6rem;display:grid;place-items:center;cursor:pointer;
  background:none;border:1px solid var(--hair);color:var(--ink);
  transition:border-color var(--d-snap) var(--e-snap),background-color var(--d-snap) var(--e-snap);
}
.band3d__btn:hover{border-color:var(--steel);background:var(--tint);color:var(--steel-900)}
.band3d__btn[disabled]{opacity:.35;cursor:not-allowed}
/* Mobile: a plain horizontal snap-scroll strip. No JS. */
@media (max-width:47.99rem){
  .band3d__view{overflow-x:auto;scroll-snap-type:x mandatory;-webkit-overflow-scrolling:touch;mask-image:none;-webkit-mask-image:none}
  .band3d__track{transform:none!important}
  .band3d__card{scroll-snap-align:start;width:13rem}
  .band3d__nav{display:none}
}
.no-js .band3d__view{overflow-x:auto}
.no-js .band3d__nav{display:none}

/* ── 17. ROUTE — the three how-it-works cells ─────────────────────────────
   Blueprint cells: 1px border, corner marks, 24px padding, no fill. */

.route{list-style:none;margin:0;padding:0;display:grid;gap:clamp(1.5rem,3vw,3rem)}
@media (min-width:48rem){.route{grid-template-columns:repeat(auto-fit,minmax(17rem,1fr))}}
.route__i{
  border:1px solid var(--hair);padding:var(--s3);
  display:grid;gap:.5rem;align-content:start;max-width:none;
}
.route__n{
  font-size:var(--t--2);font-weight:600;letter-spacing:var(--tr-sign);
  color:var(--steel-700);font-variant-numeric:tabular-nums;margin-bottom:.2rem;
}
.route__t{
  font-family:var(--f-disp);font-weight:var(--w-disp);font-size:var(--t-2);
  text-transform:uppercase;letter-spacing:var(--tr-head);margin:0;
}
.route__b{margin:0;color:var(--ink-2);max-width:46ch;font-size:var(--t-0);line-height:1.6}

/* ── 18. BANDS + SPLIT + REGISTER ──────────────────────────────────────────
   The dark theme alternated a dark band with a whitewash one. On a light
   ground there is one surface, so a band is a ruled interval: a hairline at the
   top and the section rhythm around it. `--dark` and `--lime` are kept as
   class names because content/*.js writes them; they no longer paint. */

.band{padding:var(--sec) 0;border-top:1px solid var(--hair)}
.band--dark,.band--lime,.wash{background:none;color:var(--ink)}
.band__h{margin-bottom:var(--s4)}
.band__h>h2{font-size:var(--t-5);line-height:1.06;max-width:22ch;margin-bottom:.3em}
.band__h>p{max-width:60ch}

.split{display:grid;grid-template-columns:minmax(0,1fr);gap:var(--s4)}
.split>*{min-width:0}
@media (min-width:56rem){.split{grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:clamp(2rem,5vw,6rem)}}

/* Register — the routed index, and the site's primary navigation surface. */
.reg{margin:0;padding:0}
.reg__group{margin-bottom:var(--s4)}
.reg__h{
  font-size:var(--t--2);font-weight:600;text-transform:uppercase;
  letter-spacing:var(--tr-sign);color:var(--ink-3);
  padding-bottom:.5rem;border-bottom:1px solid var(--hair-2);margin:0 0 0;
}
.reg__list{list-style:none;margin:0;padding:0}
@media (min-width:48rem){
  .reg__list{display:grid;grid-template-columns:repeat(auto-fill,minmax(16rem,1fr));column-gap:2.5rem}
}
.reg__i{border-top:1px solid var(--hair)}
.reg__i a{
  display:grid;grid-template-columns:auto minmax(0,1fr);gap:.2rem .7rem;
  padding:.85rem .5rem 1rem;text-decoration:none;color:var(--ink);
  position:relative;align-items:baseline;
  transition:background-color var(--d-snap) var(--e-snap);
}
.reg__i a:hover,.reg__i a:focus-visible{background:var(--tint)}
.reg__n,.reg__ref{
  font-size:var(--t--2);font-weight:600;letter-spacing:var(--tr-sign);
  color:var(--steel-700);grid-row:1;font-variant-numeric:tabular-nums;
}
.reg__t{
  font-family:var(--f-disp);font-weight:var(--w-disp);font-size:var(--t-1);
  text-transform:uppercase;letter-spacing:var(--tr-name);grid-row:1;
}
.reg__d{grid-column:2;font-size:var(--t--2);line-height:1.45;color:var(--ink-3);margin:0;max-width:44ch}

/* ── 19. FORMS ─────────────────────────────────────────────────────────── */

.form{max-width:44rem}
.field{margin-bottom:var(--s3);display:grid;gap:.4rem}
.field>label,.fieldset__l{
  font-size:var(--t--2);font-weight:600;
  text-transform:uppercase;letter-spacing:var(--tr-sign);color:var(--ink-2);
}
.req{color:var(--steel-700);font-size:var(--t--2);margin-left:.3rem}
.hint{font-size:var(--t--2);color:var(--ink-3);margin:0;max-width:56ch}

.input,input[type=text],input[type=email],input[type=tel],input[type=number],select,textarea{
  width:100%;font:400 var(--t-0)/1.5 var(--f-body);
  background:var(--surface);color:var(--ink);
  border:1px solid var(--hair);border-radius:var(--radius-field);
  padding:.7rem .85rem;caret-color:var(--steel);
  transition:border-color var(--d-snap) var(--e-snap),box-shadow var(--d-snap) var(--e-snap);
}
input:hover,select:hover,textarea:hover{border-color:var(--hair-2)}
textarea{min-height:7rem;resize:vertical}
select{
  appearance:none;
  background-image:linear-gradient(45deg,transparent 49%,var(--ink) 51%),
                   linear-gradient(-45deg,transparent 49%,var(--ink) 51%);
  background-size:6px 6px;
  background-position:right 1rem center,right .65rem center;
  background-repeat:no-repeat;padding-right:2.2rem;
}
input:focus-visible,select:focus-visible,textarea:focus-visible{
  border-color:var(--steel);box-shadow:0 0 0 1px var(--steel);outline:none;
}
input[aria-invalid="true"],textarea[aria-invalid="true"],select[aria-invalid="true"]{
  border-color:var(--steel-700);border-left-width:3px;
}
.err{display:flex;gap:.45rem;align-items:flex-start;font-size:var(--t--2);color:var(--steel-700);margin:.1rem 0 0;font-weight:600}
.err::before{content:"!"}
.err:empty{display:none}

/* Option lists — the "which trade" picker. Real radios, styled. */
.opts{display:grid;gap:.5rem;margin:0;padding:0;border:0}
.opts--2{grid-template-columns:repeat(auto-fit,minmax(13rem,1fr))}
.opts--3{grid-template-columns:repeat(auto-fit,minmax(9.5rem,1fr))}
.opt{position:relative;display:block}
.opt input{position:absolute;opacity:0;width:100%;height:100%;margin:0;cursor:pointer}
.opt span{
  display:block;padding:.7rem .85rem;cursor:pointer;
  border:1px solid var(--hair);background:none;
  font-family:var(--f-disp);font-weight:var(--w-disp);font-size:var(--t--1);
  text-transform:uppercase;letter-spacing:var(--tr-head);
  transition:border-color var(--d-snap) var(--e-snap),
             background-color var(--d-snap) var(--e-snap),color var(--d-snap) var(--e-snap);
}
.opt input:hover+span{border-color:var(--steel);background:var(--tint)}
.opt input:checked+span{background:var(--steel-700);border-color:var(--steel-700);color:var(--ground)}
.opt input:focus-visible+span{outline:var(--focus-w) solid var(--steel);outline-offset:2px}

/* ── THE SEASON BAND ────────────────────────────────────────────────────
   What month it is, and what that means for getting hold of anyone. */
.season{
  margin:0 0 var(--s4);padding:var(--s2) 0 var(--s2) var(--s3);
  border-left:3px solid var(--steel-700);
  max-width:60rem;
}
.season__tag{
  margin:0 0 .5rem;font-size:var(--t--2);font-weight:600;
  text-transform:uppercase;letter-spacing:var(--tr-sign);color:var(--ink-3);
}
.season__m{color:var(--steel-700)}
.season__m[hidden]{display:none}
.season__b{margin:0;font-size:var(--t-prose);line-height:var(--lh-body);max-width:66ch}
.season__l{margin:.7rem 0 0;font-size:var(--t--1)}

/* ── THE MATCHER ────────────────────────────────────────────────────────
   Typed symptom in, trade out. The answer arrives on a rule that runs out from
   the input, not inside a card. */
.match{margin:0 0 var(--s4);max-width:52rem}
.match[hidden]{display:none}
.match__l{
  display:block;margin-bottom:.5rem;
  font-size:var(--t--2);font-weight:600;
  text-transform:uppercase;letter-spacing:var(--tr-sign);color:var(--ink-2);
}
.match__q{
  width:100%;font:400 var(--t-1)/1.4 var(--f-body);
  background:none;color:var(--ink);
  border:0;border-bottom:1px solid var(--hair-2);border-radius:0;
  padding:.6rem 0;
  transition:border-color var(--d-snap) var(--e-snap);
}
.match__q::placeholder{color:var(--ink-4)}
.match__q:hover{border-bottom-color:var(--hair-2)}
.match__q:focus{border-bottom-color:var(--steel);outline:none}
.match__q:focus-visible{outline:none;box-shadow:none}

.match__out:empty{display:none}
.match__out{margin-top:var(--s3)}
.match__lead{
  font-size:var(--t--2);font-weight:600;letter-spacing:var(--tr-sign);
  text-transform:uppercase;color:var(--ink-3);margin:0 0 .6rem;
}
.match__list{list-style:none;margin:0;padding:0;display:grid;gap:0}
.match__i{
  display:grid;grid-template-columns:minmax(9rem,auto) 1fr;gap:.2rem var(--s3);
  align-items:baseline;
  padding:.85rem 0;border-top:1px solid var(--hair);
}
.match__i:last-child{border-bottom:1px solid var(--hair)}
.match__t{
  font-family:var(--f-disp);font-weight:var(--w-disp);font-size:var(--t-2);
  text-transform:uppercase;letter-spacing:var(--tr-name);
  color:var(--steel-700);text-decoration:none;
}
.match__t:hover{text-decoration:underline;text-underline-offset:.2em}
.match__b{font-size:var(--t--2);color:var(--ink-3)}
.match__go{margin-top:var(--s3)}
.match__none{font-size:var(--t-0);color:var(--ink-2);margin:0;max-width:56ch}
@media (max-width:38rem){
  .match__i{grid-template-columns:1fr}
  .match__t{font-size:var(--t-1)}
}

/* Photographs on a request. The file input is left as the browser's own control
   — a custom one is a well-known way to break drag-and-drop and screen readers —
   but the button inside it is given the site's button language. */
input[type=file]{
  width:100%;font:400 var(--t--1)/1.5 var(--f-body);color:var(--ink-2);
  padding:.55rem 0;
}
input[type=file]::file-selector-button{
  font:600 var(--t--1)/1 var(--f-disp);text-transform:uppercase;letter-spacing:var(--tr-head);
  background:none;color:var(--steel-700);
  border:1px solid var(--hair);border-radius:var(--radius-field);
  padding:.6rem .9rem;margin-right:var(--s2);cursor:pointer;
  transition:border-color var(--d-snap) var(--e-snap),background-color var(--d-snap) var(--e-snap);
}
input[type=file]::file-selector-button:hover{border-color:var(--steel);background:var(--tint)}
input[type=file]:focus-visible{outline:var(--focus-w) solid var(--steel);outline-offset:2px}

.shots{
  display:grid;grid-template-columns:repeat(auto-fill,minmax(7rem,1fr));
  gap:var(--s2);margin:var(--s2) 0 0;padding:0;list-style:none;
}
.shots[hidden]{display:none}
.shot{position:relative;display:block}
.shot img{
  display:block;width:100%;aspect-ratio:4/3;object-fit:cover;
  border:1px solid var(--hair);background:var(--surface);
}
.shot__n{display:block;font-size:var(--t--2);color:var(--ink-3);padding-top:.3rem}
.shot__x{
  position:absolute;top:0;right:0;width:2rem;height:2rem;
  display:grid;place-items:center;cursor:pointer;
  font:400 1.1rem/1 var(--f-body);
  background:var(--ground);color:var(--ink);
  border:1px solid var(--hair);border-top:0;border-right:0;
  transition:background-color var(--d-snap) var(--e-snap),color var(--d-snap) var(--e-snap);
}
.shot__x:hover{background:var(--steel-700);color:var(--ground);border-color:var(--steel-700)}
.shot__x:focus-visible{outline:var(--focus-w) solid var(--steel);outline-offset:2px}

/* Form-level response. Written by the Forms module after a fetch resolves. */
.formmsg:empty{display:none}
.formmsg{
  margin:0 0 var(--s3);padding:.85rem 0 .85rem var(--s2);
  border-left:3px solid var(--hair-2);
  font-size:var(--t-0);color:var(--ink-2);
}
.formmsg p{margin:0;max-width:56ch}
.formmsg[data-ok],.formmsg[data-err]{border-left-color:var(--steel-700);color:var(--ink)}
.formmsg[data-err]::before{
  content:"!";font-weight:600;color:var(--steel-700);
  float:left;margin:0 .45rem 0 -.1rem;
}

/* Honeypot — never visible, never announced. */
.hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}

/* Wizard. Without JS every step is visible and it is one long form. */
.wiz__bar{display:flex;align-items:stretch;gap:0;margin:0 0 var(--s4);padding:0;list-style:none}
.wiz__bar li{
  flex:1;display:grid;gap:.45rem;position:relative;padding-top:.8rem;
  font-size:var(--t--2);font-weight:600;
  text-transform:uppercase;letter-spacing:var(--tr-sign);color:var(--ink-3);
}
.wiz__bar li::before{content:"";position:absolute;top:0;left:0;right:1px;height:1px;background:var(--hair)}
.wiz__bar li::after{
  content:"";position:absolute;top:0;left:0;right:1px;height:1px;background:var(--steel);
  transform:scaleX(0);transform-origin:left;
  transition:transform var(--d-route) var(--e-draw);
}
.wiz__bar li.is-done::after,.wiz__bar li.is-cur::after{transform:scaleX(1)}
.wiz__bar li.is-cur{color:var(--steel-700)}
.wiz__step{margin-bottom:var(--s4)}
.wiz__nav{
  display:flex;gap:var(--s2);flex-wrap:wrap;align-items:center;
  padding-top:var(--s3);border-top:1px solid var(--hair);
}

/* ── 20. TOOLS (estimator, permit timeline) ────────────────────────────── */

.tool{margin:var(--s4) 0}
.tool__fig{border:1px solid var(--hair);padding:var(--s3);margin:0;background:none}
.tool__out{
  font-family:var(--f-disp);font-weight:var(--w-disp);font-size:var(--t-3);
  color:var(--ink);font-variant-numeric:tabular-nums;letter-spacing:var(--tr-disp);
  padding:var(--s2) 0;border-top:1px solid var(--hair-2);margin-top:var(--s2);
}
.tool__cap,.tool__caveat{font-size:var(--t--2);color:var(--ink-3);max-width:var(--measure)}
.tool__caveat{border-left:3px solid var(--hair-2);padding-left:var(--s2);margin-top:var(--s3)}

.tl{list-style:none;margin:var(--s3) 0;padding:0;position:relative}
.tl::before{content:"";position:absolute;left:.55rem;top:.5rem;bottom:.5rem;width:1px;background:var(--hair)}
.tl li{position:relative;padding:0 0 var(--s3) 2.2rem}
.tl li::before{
  content:"";position:absolute;left:0;top:.45rem;width:1.1rem;height:1.1rem;
  border:1px solid var(--steel);background:var(--ground);
}
.tl b{
  font-family:var(--f-disp);font-weight:var(--w-disp);text-transform:uppercase;
  letter-spacing:var(--tr-name);font-size:var(--t-0);display:block;
}
.tl .t{font-size:var(--t--2);font-weight:600;color:var(--steel-700);font-variant-numeric:tabular-nums}

/* Before/after, caldera section, strata — retained drawn components */
.ba{position:relative;margin:var(--s3) 0}
.ba__lbl{font-size:var(--t--2);font-weight:600;text-transform:uppercase;letter-spacing:var(--tr-sign)}
.ba__lbl--a{color:var(--ink-3)}
.ba__lbl--b{color:var(--steel-700)}

.caldera{margin:var(--s4) 0}
.caldera__in{display:grid;gap:var(--s3)}
@media (min-width:56rem){.caldera__in{grid-template-columns:minmax(0,1fr) 20rem}}
.caldera__fig{margin:0;border:1px solid var(--hair);background:var(--surface)}
.caldera__svg{width:100%;height:auto}
.caldera__tabs{list-style:none;margin:0;padding:0;display:grid;gap:0;border:1px solid var(--hair)}
.caldera__tab{
  background:none;border:0;border-bottom:1px solid var(--hair);width:100%;text-align:left;cursor:pointer;
  padding:.7rem .8rem;color:var(--ink);
  font:var(--w-disp) var(--t--1)/1.3 var(--f-disp);text-transform:uppercase;letter-spacing:var(--tr-name);
  transition:background-color var(--d-snap) var(--e-snap),color var(--d-snap) var(--e-snap);
}
.caldera__tabs li:last-child .caldera__tab{border-bottom:0}
.caldera__tab[aria-selected="true"]{background:var(--steel-700);color:var(--ground)}
.caldera__tab:hover{background:var(--tint);color:var(--steel-900)}
.caldera__tab[aria-selected="true"]:hover{background:var(--steel-800);color:var(--ground)}
.caldera__panel{padding:var(--s2) 0}
.caldera__leader{font-size:var(--t--2);font-weight:600;color:var(--steel-700)}
.caldera__fallback{border:1px solid var(--hair);padding:var(--s2)}
/* Written by site.js when a layer is selected. */
.caldera__ref{font-size:var(--t--2);font-weight:600;letter-spacing:var(--tr-sign);color:var(--steel-700);margin:0 0 .2rem}
.caldera__depth{font-size:var(--t--2);color:var(--ink-3);margin:0 0 .6rem;font-variant-numeric:tabular-nums}
.caldera__prob{margin:0 0 .6rem;font-size:var(--t-0)}
.caldera__link{margin:0;font-size:var(--t--1)}

.strata__fill{opacity:.9}
.strata__edge{stroke:var(--hair-2);stroke-width:1;fill:none}
.strata__lbl{font-size:11px;fill:var(--n-700)}
.strata__depth{font-size:10px;fill:var(--steel-700)}

.ci__meta{
  display:flex;flex-wrap:wrap;gap:var(--s3);
  font-size:var(--t--2);color:var(--ink-3);padding:var(--s2) 0;
  border-block:1px solid var(--hair);margin-bottom:var(--s3);
  font-variant-numeric:tabular-nums;
}
.ci__status{color:var(--steel-700);font-weight:600}

/* ── 21. CTA + FOOTER ──────────────────────────────────────────────────────
   The CTA plate is the one dark surface the system allows: accent-900, paper
   type, paper registration marks. Everything else on the page stays a drawing. */

.cta{padding:var(--sec) 0}
.cta__in{
  display:grid;gap:var(--s3);align-items:start;
  background:var(--steel-900);color:var(--rev);
  padding:clamp(2rem,5vw,4rem);
  --mark-ink:var(--rev-3);
}
.cta .kicker{
  color:var(--steel-300);border-bottom:1px solid var(--rev-hair);
  padding-bottom:var(--s2);margin-bottom:var(--s3);
}
.cta__txt h2{font-size:var(--t-5);line-height:1.06;max-width:18ch;color:var(--rev);margin-bottom:.3em}
.cta__txt p{color:var(--rev-2);max-width:60ch;margin:0}
.cta__acts{display:flex;flex-wrap:wrap;gap:var(--s2);align-items:center}
.cta__mail{font-size:var(--t--1);color:var(--steel-300);text-decoration:none}
.cta__mail:hover{color:var(--rev);text-decoration:underline}
.cta__in .btn--mark{background:var(--steel-300);color:var(--steel-900);border-color:var(--steel-300)}
.cta__in .btn--mark:hover{background:var(--rev);border-color:var(--rev);color:var(--steel-900)}

/* ── 21b. THE MESSAGE BLOCK ─────────────────────────────────────────────
   A contact form on every page that does not already carry one. Two columns:
   why you would write on the left with the ways to reach a person, the form on
   the right. It is a framed object like everything else, and the line naming the
   page you are on is the whole point of it — that context travels with the mail. */

.msg{padding:var(--sec) 0;border-top:1px solid var(--hair)}
.msg__in{display:grid;gap:var(--s4)}
@media (min-width:56rem){
  .msg__in{grid-template-columns:minmax(0,5fr) minmax(0,6fr);gap:clamp(2rem,5vw,5rem);align-items:start}
}
.msg__intro>h2{font-size:var(--t-3);margin-bottom:.4em}
.msg__lead{color:var(--ink-2);max-width:46ch;margin-bottom:var(--s3)}
/* The context line. Reads as a label and a value on a drawing, because that is
   exactly what it is: the sheet this enquiry refers to. */
.msg__ctx{
  display:grid;gap:.3rem;margin:0 0 var(--s3);padding:var(--s2) 0;
  border-top:1px solid var(--hair);border-bottom:1px solid var(--hair);max-width:none;
}
.msg__ctx-l{
  font-size:var(--t--2);font-weight:600;text-transform:uppercase;
  letter-spacing:var(--tr-sign);color:var(--ink-3);
}
.msg__ctx-v{
  font-family:var(--f-disp);font-weight:var(--w-disp);font-size:var(--t-2);
  text-transform:uppercase;letter-spacing:var(--tr-name);color:var(--steel-700);
}
.msg__alt{
  list-style:none;margin:0;padding:0;display:flex;flex-wrap:wrap;
  gap:.4rem var(--s3);font-size:var(--t--1);
}
.msg__alt a{color:var(--steel-700);text-decoration:none}
.msg__alt a:hover{color:var(--steel-900);text-decoration:underline}
.msg__form{max-width:none;border:1px solid var(--hair);padding:clamp(1.25rem,3vw,2rem)}
.msg__pair{display:grid;gap:0 var(--s3)}
@media (min-width:34rem){.msg__pair{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}}
.msg__form .field:last-of-type{margin-bottom:var(--s3)}
.msg__priv{margin:var(--s3) 0 0}
.hint-i{font-weight:400;text-transform:none;letter-spacing:0;color:var(--ink-3)}
/* The form's own status line sits above the fields, not floating at the top of
   the framed box. Forms module inserts it as the first child. */
.msg__form .formmsg{margin-bottom:var(--s3)}

.foot{background:none;border-top:1px solid var(--hair);padding:var(--sec) 0 var(--s4)}
.foot__grid{display:grid;gap:var(--s4)}
@media (min-width:56rem){.foot__grid{grid-template-columns:minmax(0,1.4fr) repeat(3,minmax(0,1fr))}}
.foot__brand .brand__mark{color:var(--steel-700);margin-bottom:var(--s2)}
.foot__claim{font-size:var(--t--2);line-height:1.55;color:var(--ink-3);max-width:36ch}
.foot__nap{font-size:var(--t--2);line-height:1.9;overflow-wrap:anywhere}
.foot__nap a{color:var(--ink);text-decoration:none}
.foot__nap a:hover{color:var(--steel-700);text-decoration:underline}
.foot__free{font-size:var(--t--2);font-weight:600;text-transform:uppercase;letter-spacing:var(--tr-sign);color:var(--steel-700)}
.foot__col h3{
  font-size:var(--t--2);font-weight:600;font-family:var(--f-body);
  text-transform:uppercase;letter-spacing:var(--tr-sign);color:var(--ink-3);
  margin:0 0 var(--s2);padding-bottom:.4rem;border-bottom:1px solid var(--hair);
}
.foot__col ul{list-style:none;margin:0;padding:0}
.foot__col li{margin-bottom:.4rem}
.foot__col a{color:var(--ink);text-decoration:none;font-size:var(--t--1)}
.foot__col a:hover{color:var(--steel-700);text-decoration:underline}
.foot__base{
  display:flex;flex-wrap:wrap;gap:var(--s2) var(--s3);justify-content:space-between;
  align-items:center;margin-top:var(--s5);padding-top:var(--s3);
  border-top:1px solid var(--hair);font-size:var(--t--2);color:var(--ink-3);
}
.foot__base p{max-width:none;margin:0}
.foot__legal-links{display:flex;gap:var(--s3);list-style:none;margin:0;padding:0}
.foot__legal-links a{color:var(--ink-3);font-size:var(--t--2)}

.wa{
  position:fixed;right:1rem;bottom:1rem;z-index:30;
  width:3rem;height:3rem;display:grid;place-items:center;
  background:var(--steel-700);color:var(--ground);border:1px solid var(--steel-700);
  transition:background-color var(--d-snap) var(--e-snap);
}
.wa:hover{background:var(--steel-900);border-color:var(--steel-900);color:var(--ground)}

/* ── 22. PHOTOGRAPHS ────────────────────────────────────────────────────
   Duotoned: the image is desaturated and washed in the steel accent, so a
   photograph belongs to the drawing rather than sitting on top of it. The wash
   is a blend layer, so it needs its own stacking context — `isolation` keeps it
   off the page behind. The frame and its registration marks live on the figure;
   the clip that the wash needs lives on the <picture> inside it. */

.ph{
  width:min(100% - var(--gut)*2,var(--wrap-n));
  margin:0 auto clamp(2rem,4vw,3rem);
  border:1px solid var(--hair);
}
.ph picture{display:block;position:relative;overflow:hidden;isolation:isolate}
.ph picture::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:var(--steel);mix-blend-mode:color;
}
.ph img{
  display:block;width:100%;height:auto;
  background:var(--surface);          /* holds the box before the bytes land */
  filter:grayscale(1) contrast(1.04);
}
.ph__cap{
  display:flex;justify-content:flex-end;
  padding:.5rem .7rem;border-top:1px solid var(--hair);
}
.ph__credit{font-size:var(--t--2);color:var(--ink-3);text-transform:uppercase;letter-spacing:.03em}
.ph__credit a{color:var(--ink-3);text-decoration:underline;text-underline-offset:.2em}
.ph__credit a:hover{color:var(--steel-700)}
@media print{.ph{break-inside:avoid}}
/* A duotone is a treatment, not information. In forced colours it is removed. */
@media (forced-colors: active){
  .ph picture::after{display:none}
  .ph img{filter:none}
}

/* ── 23. UTILITIES ─────────────────────────────────────────────────────── */

.vh{
  position:absolute!important;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0;
}
[hidden]{display:none!important}

/* Scroll reveals — opacity only. The light theme does not move things around. */
[data-reveal]{opacity:0;transition:opacity var(--d-move) var(--e-lift)}
[data-reveal].is-in{opacity:1}
.no-js [data-reveal]{opacity:1}

/* ── 24. REDUCED MOTION ────────────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{
    animation-duration:1ms!important;animation-iteration-count:1!important;
    transition-duration:1ms!important;scroll-behavior:auto!important;
  }
  /* Everything that would have animated in is simply present. */
  [data-reveal]{opacity:1}
  .symp__line::after{transform:scaleX(1)}
  .build__stage{opacity:1}
  .wiz__bar li::after{transform:scaleX(1)}
}

/* ── 25. PRINT ─────────────────────────────────────────────────────────── */

@media print{
  body{background:#fff;color:#000}
  .site-head,.wa,.cta,.foot,.band3d__nav,.toc{display:none!important}
  a{color:#000;text-decoration:underline}
  .answer{border-left:2px solid #000}
  .build__stage{opacity:1}
  .frame::before,.frame::after,.ph::before,.ph::after,
  .route__i::before,.route__i::after{display:none}
  .ph picture::after{display:none}
  .ph img{filter:none}
}
