/* ============================================================
   TYPEFACES — self-hosted
   Served from this origin, not fonts.googleapis.com. Two fewer
   third-party connections, no render-block on a host we do not
   control, the site still sets type where Google is blocked, and
   the CSP no longer has to admit an external style and font host.
   Latin subset only; the five weights the design actually uses.
   ============================================================ */
@font-face{font-family:'Inter'; font-style:normal; font-weight:400; font-display:swap;
  src:url('/assets/fonts/inter-latin-400-normal.woff2') format('woff2')}
@font-face{font-family:'Inter'; font-style:normal; font-weight:500; font-display:swap;
  src:url('/assets/fonts/inter-latin-500-normal.woff2') format('woff2')}
@font-face{font-family:'Inter'; font-style:normal; font-weight:600; font-display:swap;
  src:url('/assets/fonts/inter-latin-600-normal.woff2') format('woff2')}
@font-face{font-family:'Archivo'; font-style:normal; font-weight:600; font-display:swap;
  src:url('/assets/fonts/archivo-latin-600-normal.woff2') format('woff2')}
@font-face{font-family:'Archivo'; font-style:normal; font-weight:700; font-display:swap;
  src:url('/assets/fonts/archivo-latin-700-normal.woff2') format('woff2')}

/* ============================================================
   TES — DRAFT DESIGN SYSTEM
   One direction, two skins. 8pt spacing. 2 typefaces, 3 sizes
   in the working scale. 3 colours + 1 accent. CTA colour is
   isolated: #E2701E appears ONLY on primary actions + the mark.
   ============================================================ */
:root{
  --accent:#E2701E; --accent-hi:#F0842F;
    --s1:4px; --s2:8px; --s3:16px; --s4:24px; --s5:32px; --s6:48px;
  --s7:64px; --s8:96px; --s9:128px; --s10:160px;
  /* squircle radius scale — one step per component size, nothing in between */
  --r-xs:8px; --r-sm:12px; --r-md:18px; --r-lg:26px; --r-xl:34px;
  /* The canvas is fluid, not a fixed 1240 column. On a phone the gutter is
     20px so the content owns the screen; on a large display it opens to 1680
     so the register and the project grids get the room they were built for.
     Prose never widens past its measure — that is handled per-element. */
  --maxw:1680px; --gutter:clamp(20px,4.4vw,64px);
  --ease:cubic-bezier(.16,.84,.34,1);
  --font-d:'Archivo',system-ui,-apple-system,'Segoe UI',sans-serif;
  --font-t:'Inter',system-ui,-apple-system,'Segoe UI',sans-serif;
}
/* ------------------------------------------------------------------
   ONE GROUND. The site is a drawing sheet: warm paper, graphite line,
   and a single accent. There is no dark skin — a drafting sheet is not
   black, and the brand is not either.

   The colour rule carries the whole argument:
     --draw    graphite   the building        (what the architect draws)
     --accent  #E2701E    the services        (what TES draws)
   Nothing else is ever orange.
   ------------------------------------------------------------------ */
:root{
  --bg:#FBFAF8; --surface:#FFFFFF; --surface2:#F4F2EE;
  --ink:#15171B; --ink-2:#3C4149; --muted:#666C75;
  --rule:rgba(0,0,0,.13); --rule-2:rgba(0,0,0,.07);
  --shadow:0 24px 64px rgba(20,22,26,.13);
  --draw:#2B2E33; --draw-2:rgba(43,46,51,.30); --draw-3:rgba(43,46,51,.14);
  --paper:#FBFAF8;
}
*,*::before,*::after{box-sizing:border-box}
html{scroll-behavior:smooth}
body{
  margin:0; background:var(--bg); color:var(--ink);
  font-family:var(--font-t); font-size:17px; line-height:1.62;
  -webkit-font-smoothing:antialiased; font-feature-settings:"tnum" 0;
}
img{display:block; max-width:100%}
a{color:inherit; text-decoration:none}
svg{display:block}

/* ---------- squircle geometry ----------
   Superellipse corners via corner-shape (Chromium 139+). border-radius is
   the base value and the graceful fallback; corner-shape only changes the
   curve's exponent, so nothing breaks where it is unsupported.
   Rules, dividers and type stay sharp — the softness is on containers only,
   so the page reads as precise rather than consumer-app. */
.btn{border-radius:var(--r-sm)}
.seg-card,.pcard,.panel{border-radius:var(--r-sm)}
/* ---------- squircle geometry ----------
   Superellipse corners, where the curvature is continuous instead of a circle
   spliced onto a straight edge. It is applied to CONTAINERS only — anything
   that holds something: buttons, cards, panels, plates, chips, controls.
   Rules, dividers, drawings and type stay sharp, so the page reads as precise
   rather than as a consumer app.

   A squircle reads visually tighter than a circular corner at the same radius,
   so each radius steps up one notch when the corner shape changes. Where
   corner-shape is unsupported the border-radius fallback is already correct
   and nothing about the layout moves. */
@supports (corner-shape: squircle){
  .btn,.chip,.navtoggle,.mobcta{corner-shape:squircle; border-radius:var(--r-md)}
  .seg-card,.pcard,.panel,.step{corner-shape:squircle; border-radius:var(--r-lg)}
  .plate-view,.hero-img{corner-shape:squircle; border-radius:var(--r-lg)}
  .pcard .ph{corner-shape:squircle; border-radius:var(--r-lg) var(--r-lg) 0 0}
}
.h2{font-family:var(--font-d); font-weight:600; letter-spacing:-.022em; line-height:1.1;
  font-size:clamp(1.85rem,3.5vw,2.95rem); margin:0}
.h3{font-family:var(--font-d); font-weight:600; letter-spacing:-.014em; line-height:1.2;
  font-size:1.24rem; margin:0}
.label{font-size:.695rem; letter-spacing:.17em; text-transform:uppercase; font-weight:600;
  color:var(--muted); margin:0 0 var(--s4)}
.lede{font-size:clamp(1.05rem,1.55vw,1.29rem); line-height:1.58; color:var(--ink-2); max-width:60ch; margin:0}
p{margin:0 0 var(--s3)}

/* ---------- layout ---------- */
.wrap{max-width:var(--maxw); margin:0 auto; padding:0 var(--gutter)}
section{padding:var(--s7) 0; position:relative}
@media(min-width:760px){section{padding:var(--s8) 0}}

.grid{display:grid; gap:var(--s3)}
.two,.three,.four{grid-template-columns:minmax(0,1fr)}
@media(min-width:600px){
  .grid{gap:var(--s4)}
  .two,.three,.four{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media(min-width:960px){
  .three{grid-template-columns:repeat(3,minmax(0,1fr))}
  .four{grid-template-columns:repeat(4,minmax(0,1fr))}
}
/* On the wide canvas the project grid earns a fourth column and the five
   disciplines line up as one row — the shape they actually are. */
@media(min-width:1400px){
  .three.g-wide{grid-template-columns:repeat(4,minmax(0,1fr))}
  .three.g-five{grid-template-columns:repeat(5,minmax(0,1fr))}
}

@media(min-width:900px){.split{grid-template-columns:minmax(0,.92fr) minmax(0,1.08fr); gap:var(--s8)}}

/* ---------- buttons: accent isolated here ---------- */
.btn{display:inline-flex; align-items:center; gap:var(--s2); font-family:var(--font-t);
  font-weight:600; font-size:.945rem; letter-spacing:-.005em; padding:15px var(--s4);
  border-radius:2px; border:1px solid transparent; cursor:pointer;
  transition:background .22s var(--ease), transform .22s var(--ease), border-color .22s var(--ease), color .22s var(--ease)}
/* White on #E2701E measures 3.05:1 — below the 4.5 AA floor for button text,
   and the first thing to fail on a phone in daylight. Ink on the same accent
   measures 5.89:1: the brand colour is untouched, the label is legible, and
   the button reads harder rather than softer. */
.btn-primary{background:var(--accent); color:#15171B}
.btn-primary:hover{background:var(--accent-hi); transform:translateY(-1px)}
.btn-primary:focus-visible{outline-color:#15171B; outline-offset:2px}
.btn-primary:active{transform:translateY(0)}
.btn-ghost{border-color:var(--rule); color:var(--ink); background:transparent}
.btn-ghost:hover{border-color:var(--ink); transform:translateY(-1px)}
.btn:focus-visible{outline:2px solid var(--accent); outline-offset:3px}
a:focus-visible,button:focus-visible{outline:2px solid var(--accent); outline-offset:3px; border-radius:2px}

.btn:hover .arrow{transform:translateX(3px)}

/* ---------- register ---------- */
.rg{border-top:1px solid var(--rule-2); padding:var(--s5) 0}
.rg-head{display:flex; align-items:center; gap:var(--s3); margin-bottom:var(--s3)}
.rg-n{margin-left:auto; font-family:var(--font-d); font-size:1.7rem; font-weight:600; letter-spacing:-.02em; color:var(--muted)}
.rg-list{list-style:none; margin:0; padding:0; columns:1; column-gap:var(--s5)}
@media(min-width:640px){.rg-list{columns:2}}
@media(min-width:1000px){.rg-list{columns:3}}
@media(min-width:1500px){.rg-list{columns:4}}
.rg-row{break-inside:avoid; padding:10px 0; border-bottom:1px solid var(--rule-2); display:flex; flex-direction:column; gap:2px; font-size:.92rem}
.rg-name{color:var(--ink); font-weight:500}
.rg-place{color:var(--muted); font-size:.82rem}

/* ---------- header ---------- */

.nav{display:flex; align-items:center; gap:var(--s5); height:76px}
/* NOTE: the existing lockup overprints the strapline through the letterforms,
   so it collapses below ~120px wide. Held at 25px here; a responsive logo
   system (full lockup / TES mark only / monochrome) is a build requirement. */
.mark{height:25px; width:auto; flex:none}
.nav ul{display:flex; gap:var(--s5); list-style:none; margin:0; padding:0; font-size:.925rem; font-weight:500}
.nav ul a{color:var(--ink-2); position:relative; padding:6px 0}
.nav ul a::after{content:""; position:absolute; left:0; right:100%; bottom:0; height:1px;
  background:var(--ink); transition:right .3s var(--ease)}
.nav ul a:hover{color:var(--ink)} .nav ul a:hover::after{right:0}
.nav .spacer{flex:1}
@media(max-width:900px){.nav ul{display:none}}
/* Mobile: the header CTA becomes a persistent bottom bar — same label,
   repeated verbatim (CTA variety reads as indecision). A real build also
   needs a mobile nav; out of scope for a look-and-feel draft. */
.mobcta{display:none}
@media(max-width:640px){
  header.site .btn-primary{display:none}
  .mobcta{display:block; opacity:0; pointer-events:none; transform:translateY(8px);
    transition:opacity .35s var(--ease), transform .35s var(--ease);
    position:fixed; left:0; right:0; bottom:0; z-index:150;
    padding:10px var(--s3) calc(10px + env(safe-area-inset-bottom));
    background:color-mix(in srgb,var(--bg) 90%,transparent); backdrop-filter:blur(14px);
    border-top:1px solid var(--rule)}
  .mobcta.show{opacity:1; pointer-events:auto; transform:none}
  .mobcta .btn{width:100%; justify-content:center}
  footer.site{padding-bottom:calc(var(--s6) + 68px)}
}

/* ---------- hero ----------
   The dark photographic hero is gone. There is no scrim to tune and no
   light-on-photograph contrast to defend: the type sits on paper, and the
   photograph lives inside the plate, beside the type rather than under it.
   Layout is in pages.css. */
.cta-row{display:flex; flex-wrap:wrap; gap:var(--s3); margin-top:var(--s4); align-items:center}

.trustline{display:flex; flex-wrap:wrap; gap:var(--s2) var(--s4); margin-top:var(--s4);
  padding-top:var(--s3); border-top:1px solid var(--rule); font-size:.845rem; color:var(--ink-2)}
.trustline span{display:inline-flex; align-items:center; gap:7px}

@media(max-width:640px){
  .trustline{font-size:.77rem; gap:5px var(--s3); margin-top:var(--s3); padding-top:var(--s2)}
}

/* ---------- reveal (the one interactive moment) ---------- */
/* ---------- segment router ---------- */
.seg-card{border:1px solid var(--rule-2); padding:var(--s4); background:var(--surface);
  display:flex; flex-direction:column; gap:var(--s2); min-height:172px;
  transition:border-color .28s var(--ease), transform .28s var(--ease), background .28s var(--ease)}
.seg-card:hover{border-color:var(--rule); transform:translateY(-3px); background:var(--surface2)}
.seg-card .count{font-family:var(--font-d); font-size:2.05rem; font-weight:600; letter-spacing:-.03em; line-height:1}
.seg-card .lst{font-size:.83rem; color:var(--muted); margin-top:auto}

/* ---------- project cards ---------- */
.pcard{display:block; position:relative; overflow:hidden; background:var(--surface); border:1px solid var(--rule-2)}
.pcard .ph{aspect-ratio:4/3; overflow:hidden; background:var(--surface2)}
.pcard img{width:100%; height:100%; object-fit:cover; transition:transform .8s var(--ease)}
.pcard:hover img{transform:scale(1.045)}
.pcard .meta{padding:var(--s3) var(--s3) var(--s4)}
.pcard .loc{font-size:.8rem; color:var(--muted); margin-top:2px}
.pcard .stats{display:flex; flex-wrap:wrap; gap:var(--s1) var(--s3); margin-top:var(--s3);
  padding-top:var(--s3); border-top:1px solid var(--rule-2); font-size:.775rem; color:var(--muted)}
.pcard.big .ph{aspect-ratio:16/10}

/* ---------- discipline list ---------- */

@media(min-width:820px){.disc-row{grid-template-columns:minmax(0,.42fr) minmax(0,1fr); gap:var(--s6)}}
.caps{columns:1; column-gap:var(--s5); margin:0; padding:0; list-style:none}
@media(min-width:640px){.caps{columns:2}}
@media(min-width:1400px){.caps{columns:3}}
.caps li{break-inside:avoid; padding:5px 0 5px 17px; position:relative; font-size:.925rem; color:var(--ink-2)}
.caps li::before{content:""; position:absolute; left:0; top:14px; width:7px; height:1px; background:var(--muted)}

/* ---------- data table (the differentiator, made visible) ---------- */

/* ---------- icon system (D10: one pack, locked) ----------
   24px grid · 1.5 stroke · round caps/joins · currentColor · outline only.
   Used strictly to encode building type and system type — the two things a
   silhouette communicates faster than a label. Never as decoration. */
.i{width:24px; height:24px; stroke:currentColor; stroke-width:1.5; fill:none;
   stroke-linecap:round; stroke-linejoin:round; flex:none}

.seg-card:hover .ico{color:var(--ink); border-color:var(--rule)}
.seg-card .ico{margin-bottom:var(--s2)}

/* ---------- diagram frame ---------- */

@media(max-width:640px){.dia{padding:var(--s3)}}

/* every diagram inherits the page's ink; no diagram-only colours exist */
  
  

/* ---------- system highlighting (contrast, never hue — CTA colour stays isolated) ---------- */

.chiprow{display:flex; flex-wrap:wrap; gap:var(--s2); margin-bottom:var(--s4)}
.chip{display:inline-flex; align-items:center; gap:7px; padding:8px 14px 8px 10px;
  border:1px solid var(--rule-2); background:var(--surface2); color:var(--ink-2);
  font:inherit; font-size:.855rem; font-weight:500; cursor:pointer;
  transition:border-color .24s var(--ease), color .24s var(--ease), background .24s var(--ease)}
.chip .i{width:18px; height:18px}
.chip:hover{border-color:var(--rule); color:var(--ink)}
.chip[aria-pressed="true"]{border-color:var(--ink); color:var(--ink); background:transparent}

/* ---------- flow diagram ---------- */

@media(max-width:900px){.flow{grid-template-columns:1fr; gap:var(--s3)}}

@media(max-width:900px){
  .node::after{right:auto; left:50%; top:auto; bottom:calc(var(--s3)*-1 - 1px);
    width:1px; height:var(--s3); transform:translateX(-50%)}
  .node::before{right:auto; left:50%; top:auto; bottom:-7px; transform:translateX(-50%) rotate(135deg)}
}

/* ---------- map ---------- */

 

/* ---------- misc ---------- */

@media(max-width:760px){.stat-row{grid-template-columns:repeat(2,1fr); gap:var(--s5)}}

.panel{background:var(--surface); border:1px solid var(--rule-2); padding:var(--s6)}
@media(max-width:640px){.panel{padding:var(--s4)}}
@media(min-width:1400px){.panel{padding:var(--s6)}}

@media(max-width:820px){.fgrid{grid-template-columns:1fr 1fr}}
@media(max-width:520px){.fgrid{grid-template-columns:1fr}}

/* ---------- motion: reveal on scroll (Y + opacity only) ---------- */
.rv{opacity:0; transform:translateY(22px); transition:opacity .85s var(--ease), transform .85s var(--ease)}
.rv.in{opacity:1; transform:none}

.stagger.in>*{opacity:1; transform:none}

@keyframes wordIn{to{opacity:1; transform:none}}
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.001ms!important; animation-delay:0s!important; transition-duration:.001ms!important}
  .rv,.stagger>*{opacity:1; transform:none}
  .word{opacity:1; transform:none}
  html{scroll-behavior:auto}
}
[hidden]{display:none!important}

/* ============================================================
   TES — SITE SHELL
   Layout the draft study did not contain: header, footer,
   section rhythm, register, empty states. Built on the draft's
   tokens. Accent still appears only on .btn-primary and .mark.
   ============================================================ */

/* ---------- base ---------- */
*,*::before,*::after{box-sizing:border-box}
.sprite{display:none}
html{-webkit-text-size-adjust:100%}
body{margin:0; background:var(--bg); color:var(--ink); font-family:var(--font-t);
  font-size:16px; line-height:1.6; overflow-x:hidden;
  -webkit-font-smoothing:antialiased; text-rendering:optimizeLegibility}
/* The width/height attributes on every <img> are presentational hints for the
   CSS width and height properties, not just an aspect-ratio source. Without an
   author height, the hint wins over `aspect-ratio` and the image paints at its
   intrinsic pixel height. `height:auto` is what lets aspect-ratio do its job. */
img{max-width:100%; display:block; height:auto}
a{color:inherit; text-decoration:none}
h1,h2,h3,p,ul,ol,figure{margin:0}
:focus-visible{outline:2px solid var(--accent); outline-offset:3px; border-radius:2px}
.skip{position:absolute; left:-9999px; top:0; z-index:999; background:var(--surface);
  color:var(--ink); padding:12px 18px; border-radius:var(--r-xs)}
.skip:focus{left:var(--s3); top:var(--s3)}

/* ---------- type scale (3 sizes in the working scale) ---------- */
.h1{font-family:var(--font-d); font-weight:700; letter-spacing:-.032em; line-height:1.03;
  font-size:clamp(2.35rem,5.4vw,4.05rem); margin:0}
.h1-sm{font-size:clamp(2rem,4vw,3.05rem)}
.h2{font-family:var(--font-d); font-weight:600; letter-spacing:-.024em; line-height:1.1;
  font-size:clamp(1.65rem,3vw,2.5rem); margin:0}
.h3{font-size:clamp(1.1rem,1.5vw,1.32rem)}
.lede-lg{font-size:clamp(1.12rem,1.75vw,1.4rem)}
.fine{font-size:.83rem; line-height:1.55; color:var(--muted); margin:0}
.claim{font-family:var(--font-d); font-weight:600; letter-spacing:-.01em;
  font-size:1.02rem; color:var(--ink); margin-top:var(--s3)}
.claim-lg{font-size:clamp(1.2rem,2vw,1.6rem); margin-top:var(--s4)}
/* The spine: every section on the page shares one left edge. The measure is
   applied to the text, not to the container, so prose stays readable at ~72ch
   while grids and plates still run the full page width. */
/* `.lede` zeroes the paragraph margin so it can sit tight under a heading.
   Two of them in a row then ran together as a single wall of text. */
.lede + .lede,.lede + .claim,.prose .lede + p{margin-top:var(--s4)}
.narrow{max-width:74ch}
.wrap.narrow{max-width:var(--maxw)}
/* The measure belongs to the prose. A display headline measured in its own
   `ch` is a different, much wider number — set separately so a project name
   is not broken across four lines to satisfy a body-copy rule. */
.wrap.narrow > *{max-width:68ch}
.wrap.narrow > .h1,.wrap.narrow > .h2{max-width:28ch}
.wrap.narrow > .lede-lg{max-width:60ch}
.wrap.narrow > .grid,.wrap.narrow > .steps,.wrap.narrow > figure,
.wrap.narrow > .rg,.wrap.narrow > .dtable,.wrap.narrow > .caps-lg{max-width:none}
.mt3{margin-top:var(--s3)} .mt4{margin-top:var(--s4)} .mt6{margin-top:var(--s6)}
.link{color:var(--ink); border-bottom:1px solid var(--rule); padding-bottom:1px;
  transition:border-color .25s var(--ease)}
/* A link that stands on its own is a control and gets a thumb-sized target;
   a link inside a sentence stays inline. */
.row-head .link,.pcard .link{display:inline-flex; align-items:center; min-height:44px}
@media(min-width:720px){.row-head .link{min-height:0}}
.link:hover{border-color:var(--ink)}

/* ---------- header ---------- */
.hdr{position:sticky; top:0; z-index:120; background:color-mix(in srgb,var(--bg) 88%,transparent);
  backdrop-filter:saturate(140%) blur(14px); border-bottom:1px solid var(--rule-2)}
.hdr-in{display:flex; align-items:center; gap:var(--s5); height:84px}
.brand{display:flex; align-items:center; flex:none}
/* logo-tes-mark.webp is the supplied lockup trimmed to its ink box and
   resampled to 418px. The browser was downscaling the 1600px original 13:1,
   which turned the strapline printed through the letterforms into fuzz.
   Trimmed, `height` is ink height: 46px of mark in an 84px bar. */
.mark{height:46px; width:auto; display:block}
.mark-sm{height:40px}
/* Base is the phone: the bar carries the mark and one control. The full nav
   is an enhancement the screen has to earn. */
.hdr .nav,.hdr-cta{display:none}
.hdr .nav{align-items:center; gap:var(--s4); height:auto; margin-left:auto;
  font-size:.925rem; font-weight:500}
.hdr .nav a{color:var(--ink-2); position:relative; padding:6px 0; transition:color .25s var(--ease)}
.hdr .nav a::after{content:""; position:absolute; left:0; right:100%; bottom:0; height:1px;
  background:var(--ink); transition:right .3s var(--ease)}
.hdr .nav a:hover{color:var(--ink)} .hdr .nav a:hover::after{right:0}
.hdr .nav a[aria-current="page"]{color:var(--ink)}
.hdr-cta{flex:none; margin-left:var(--s2)}
.navtoggle{display:flex; background:transparent; border:1px solid var(--rule); color:var(--ink);
  border-radius:var(--r-xs); width:46px; height:46px; align-items:center; justify-content:center;
  cursor:pointer; margin-left:auto; flex:none}
.navtoggle:hover{border-color:var(--ink)}
/* The mobile panel is the whole navigation on a phone, so it gets full rows,
   a rule between them, and the action as a full-width button — not a list of
   links a thumb has to aim at. */
.mnav{display:none; flex-direction:column; padding:var(--s2) 0 var(--s4);
  border-top:1px solid var(--rule-2); background:var(--bg)}
.mnav a:not(.btn){display:flex; align-items:center; min-height:52px; padding:0 var(--gutter);
  font-size:1.05rem; font-weight:500; color:var(--ink-2);
  border-bottom:1px solid var(--rule-2)}
.mnav a:not(.btn):active{background:var(--surface)}
.mnav a[aria-current="page"]{color:var(--ink)}
.mnav .btn{margin:var(--s4) var(--gutter) 0; justify-content:center; min-height:52px}
.mnav-meta{padding:var(--s4) var(--gutter) 0; font-size:.85rem; color:var(--muted); line-height:1.7}
.mnav-meta a{color:var(--ink-2); border-bottom:1px solid var(--rule)}
.mnav:not([hidden]){display:flex}

/* ---------- buttons ---------- */
.btn{padding:12px 20px; font-size:.925rem; font-weight:600; cursor:pointer; border:1px solid transparent;
  transition:background .25s var(--ease), border-color .25s var(--ease), transform .25s var(--ease)}
.btn-lg{padding:15px 26px; font-size:1rem}
.btn-ghost{border-color:var(--rule); color:var(--ink); background:transparent}
.btn-ghost:hover{border-color:var(--ink)}
.cta-row{display:flex; flex-wrap:wrap; gap:var(--s3); margin-top:var(--s5)}

/* ---------- hero ----------
   The hero is the site's own sentence, performed: the building as a drawing
   on the left of the seam, the building as built on the right. Scrolling
   advances the seam. There is no photograph behind the type, so the contrast
   floor is a property of the layout rather than something to be tuned against
   a photograph nobody controls.
   ------------------------------------------------------------------------ */
.hero{padding:var(--s6) 0 var(--s7); position:relative; overflow:hidden}
/* the drawing sheet the page is set on */
.hero::before{content:""; position:absolute; inset:0; z-index:-1; pointer-events:none;
  background-image:linear-gradient(var(--draw-3) 1px,transparent 1px),
                   linear-gradient(90deg,var(--draw-3) 1px,transparent 1px);
  background-size:96px 96px; opacity:.5;
  -webkit-mask-image:radial-gradient(120% 90% at 76% 42%,#000 0%,transparent 72%);
          mask-image:radial-gradient(120% 90% at 76% 42%,#000 0%,transparent 72%)}
.hero-in{display:grid; gap:var(--s6); align-items:center}
@media(min-width:1080px){
  .hero{padding:var(--s7) 0 var(--s8)}
  .hero-in{grid-template-columns:minmax(0,.86fr) minmax(0,1.14fr); gap:var(--s7); align-items:center}
}
@media(min-width:1500px){.hero-in{gap:var(--s8)}}
.hero-txt > *{max-width:56ch}
.hero .h1{margin-top:var(--s3); font-size:clamp(2.05rem,6.2vw,3.9rem); text-wrap:balance; max-width:19ch}
@media(min-width:720px){.hero .h1{font-size:clamp(2.4rem,3.5vw,3.9rem)}}
@media(min-width:1400px){.hero .h1{max-width:17ch}}
.hero .lede{margin-top:var(--s3); font-size:1.02rem}
@media(min-width:720px){.hero .lede{margin-top:var(--s4); font-size:clamp(1.05rem,1.4vw,1.26rem)}}
.hero .trustline{max-width:72ch}

/* ---------- the plate ---------- */
.plate{margin:0}
.plate-view{--reveal:64%; position:relative; overflow:hidden;
  border:1px solid var(--rule); border-radius:var(--r-md); background:var(--paper)}
/* 16:9 matches the source exactly, so nothing is cropped away horizontally and
   the drawing's content sits in frame rather than off the left edge. */
.plate-view img{display:block; width:100%; aspect-ratio:16/9; object-fit:cover; object-position:center}
/* The drawing is inline SVG here so it can be stroked on. It must cover the
   same box the photograph covers, with the same crop, or the seam lies. */
/* The SVG is transparent; the sheet it is drawn on is not. */
svg.plate-draw{display:block; width:100%; height:100%; background:var(--paper)}
/* It draws itself in three passes — the heavy members, then the edges, then the
   detail — which is the order a drafter blocks a drawing in, and the one piece
   of motion on this page that is telling the truth about the work. */
@keyframes plotIn{from{stroke-dashoffset:1} to{stroke-dashoffset:0}}
.plate-draw path{stroke-dasharray:1; stroke-dashoffset:1;
  animation:plotIn 1.25s var(--ease) both}
.plate-draw .lw-a{animation-delay:.15s}
.plate-draw .lw-b{animation-delay:.55s}
.plate-draw .lw-c{animation-delay:.90s}
.plate-draw{position:absolute; inset:0; height:100%;
  clip-path:inset(0 calc(100% - var(--reveal)) 0 0)}
/* The drawing side is a sheet, not an absence. The grid sits over the paper
   and disappears into the ink, so blank sky reads as unruled sheet rather
   than as a hole beside the photograph. */
.plate-grid{position:absolute; inset:0; pointer-events:none;
  clip-path:inset(0 calc(100% - var(--reveal)) 0 0);
  background-image:linear-gradient(var(--draw-3) 1px,transparent 1px),
                   linear-gradient(90deg,var(--draw-3) 1px,transparent 1px);
  background-size:44px 44px; mix-blend-mode:multiply; opacity:.9}
/* The seam is the only moving thing on the page, and it is the accent, because
   the accent means "what TES draws". */
.plate-edge{position:absolute; top:0; bottom:0; left:var(--reveal); width:1px;
  background:var(--accent); box-shadow:0 0 0 1px rgba(251,250,248,.5)}
.plate-edge::before,.plate-edge::after{content:""; position:absolute; left:50%; width:7px; height:7px;
  transform:translate(-50%,-50%) rotate(45deg); background:var(--accent)}
.plate-edge::before{top:1px} .plate-edge::after{top:calc(100% - 1px)}
/* registration marks, the way a drawing sheet is trimmed */
.plate-reg{position:absolute; inset:12px; pointer-events:none;
  background:
    linear-gradient(var(--draw-2),var(--draw-2)) 0 0/1px 15px no-repeat,
    linear-gradient(var(--draw-2),var(--draw-2)) 0 0/15px 1px no-repeat,
    linear-gradient(var(--draw-2),var(--draw-2)) 100% 0/1px 15px no-repeat,
    linear-gradient(var(--draw-2),var(--draw-2)) 100% 0/15px 1px no-repeat,
    linear-gradient(var(--draw-2),var(--draw-2)) 0 100%/1px 15px no-repeat,
    linear-gradient(var(--draw-2),var(--draw-2)) 0 100%/15px 1px no-repeat,
    linear-gradient(var(--draw-2),var(--draw-2)) 100% 100%/1px 15px no-repeat,
    linear-gradient(var(--draw-2),var(--draw-2)) 100% 100%/15px 1px no-repeat}
.plate-cap{display:flex; flex-wrap:wrap; align-items:baseline; gap:4px var(--s3);
  padding-top:var(--s3); font-size:.745rem; color:var(--muted); letter-spacing:.01em}
.pc-a,.pc-b{font-size:.655rem; letter-spacing:.17em; text-transform:uppercase; font-weight:600; flex:none}
.pc-a{color:var(--draw)} .pc-b{color:var(--muted)}
.pc-a::before,.pc-b::before{content:""; display:inline-block; width:16px; height:1px;
  margin-right:8px; vertical-align:.28em; background:currentColor}
.pc-c{flex:1 1 100%; min-width:0}
@media(min-width:900px){.pc-c{flex:1 1 26ch}}

/* ---------- sections ---------- */
.sec{padding:var(--s8) 0}
.sec-alt{background:var(--surface)}
.phead{padding:var(--s8) 0 var(--s6); border-bottom:1px solid var(--rule-2)}
.phead .label{margin-bottom:var(--s3)}
.phead .lede{margin-top:var(--s4)}
.sec .label{margin-bottom:var(--s3)}
.sec .h2 + .lede{margin-top:var(--s4)}
.row-head{display:flex; align-items:baseline; justify-content:space-between; gap:var(--s4); flex-wrap:wrap}
/* The plate is capped at the width the supplied photography can actually hold.
   Nine of these files are 760px wide; stretching them across a 1680px canvas
   makes good work look soft. */
.hero-img{margin-top:var(--s6); border-radius:var(--r-md); overflow:hidden;
  border:1px solid var(--rule); max-width:1240px; background:var(--paper)}
.hero-img img{width:100%; aspect-ratio:16/9; object-fit:cover}

/* ---------- cards ---------- */
.seg-card{display:flex; flex-direction:column; gap:var(--s2); text-align:left}
.seg-card .count{color:var(--ink)}
.seg-t{font-weight:600; font-size:.985rem; color:var(--ink); line-height:1.25}
.seg-m{font-size:.82rem; color:var(--muted); line-height:1.55; margin-top:auto; padding-top:var(--s2)}
/* Five disciplines in a two-up grid leave a hole. The last card takes the row. */
@media(min-width:600px){.grid.two > .panel:last-child:nth-child(odd){grid-column:1 / -1}}
.pcard{border-radius:var(--r-sm); display:flex; flex-direction:column}
.pcard .ph{aspect-ratio:4/3; overflow:hidden; background:var(--paper); flex:none; position:relative}
/* Every card carries the same argument as the hero: the drawing on the left of
   the seam, the building on the right. It rests as a split, completes to the
   photograph when it scrolls into view, and comes back on hover for anyone who
   wants to compare. With no JavaScript it simply stays a split — legible, not
   broken. */
.ph-draw,.hi-view .ph-draw{position:absolute; inset:0; width:100%; height:100%;
  object-fit:cover; object-position:center; clip-path:inset(0 62% 0 0);
  background:var(--paper); transition:clip-path 1.05s var(--ease)}
.pcard.seen .ph-draw{clip-path:inset(0 100% 0 0)}
.pcard:hover .ph-draw,.pcard:focus-within .ph-draw{clip-path:inset(0 34% 0 0)}
.hi-view{position:relative; overflow:hidden}
.hi-view.seen .ph-draw{clip-path:inset(0 100% 0 0)}
.hi-view:hover .ph-draw{clip-path:inset(0 46% 0 0)}
.ph-empty{display:grid; place-items:center; color:var(--muted); opacity:.45}
/* flex column + flex:1 makes every card in a row the same box, and pushes the
   render credit to a common bottom edge instead of letting it ride under
   whichever title happened to wrap. */
.pcard-b{padding:var(--s4); flex:1; display:flex; flex-direction:column}
.pcard-b .credit{margin-top:auto; padding-top:var(--s3)}
/* A card with no page does not pretend to be a link: no hover, no pointer,
   no arrow. It is a record, and it reads as one. */
.pcard-flat{cursor:default}
.pcard-flat:hover{border-color:var(--rule-2)}
.pcard-flat .pcard-t{color:var(--ink-2)}
.pcard-t{font-family:var(--font-d); font-weight:600; font-size:1.02rem; letter-spacing:-.012em;
  line-height:1.25; color:var(--ink)}
.pcard-m{font-size:.8rem; color:var(--muted); margin-top:6px}
/* A render is the developer's, and says so. Never presented as our photograph. */
.credit{font-family:var(--font-t); font-weight:400; font-size:.745rem; color:var(--muted);
  margin-top:8px; letter-spacing:.01em; line-height:1.45}
figure.hero-img{margin:var(--s6) 0 0}
figure.hero-img .credit{padding:var(--s3) 2px 0}
.pcard:hover{border-color:var(--rule)}
.panel{display:flex; flex-direction:column; gap:var(--s3); padding:var(--s5)}
/* The lead claim is the card's last line; pinning it to the bottom keeps a row
   of cards with unequal copy from looking like a bar chart. */
.panel .claim:last-child{margin-top:auto; padding-top:var(--s3)}
.panel .lede{font-size:1rem; line-height:1.6}
.panel-link{transition:border-color .25s var(--ease), transform .25s var(--ease)}
.panel-link:hover{border-color:var(--rule); transform:translateY(-2px)}
.minicard{display:flex; flex-direction:column; gap:3px; padding:var(--s3) 0;
  border-bottom:1px solid var(--rule-2); font-size:.925rem}
.minicard:hover{color:var(--ink)}
.i-lg{width:30px; height:30px}

/* ---------- lists ---------- */
/* A capability list is a schedule, not a paragraph: it wants columns as soon
   as the canvas can carry them. */
.caps-lg{columns:1; column-gap:var(--s6)}
@media(min-width:760px){.caps-lg{columns:2}}
@media(min-width:1300px){.caps-lg{columns:3}}
.caps-lg li{font-size:1rem; padding:8px 0 8px 19px; break-inside:avoid}
.steps{list-style:none; margin:0; padding:0; display:grid; gap:var(--s3);
  grid-template-columns:repeat(5,minmax(0,1fr))}
@media(max-width:1180px){.steps{grid-template-columns:repeat(3,minmax(0,1fr))}}
.step{background:var(--surface); border:1px solid var(--rule-2); border-radius:var(--r-sm);
  padding:var(--s4); display:flex; flex-direction:column; gap:var(--s2)}
.step .lede{font-size:.94rem; line-height:1.55}
.step-n{font-family:var(--font-d); font-size:.86rem; font-weight:600; color:var(--muted);
  letter-spacing:.06em}
.step .lede{font-size:.9rem}

/* ---------- register ---------- */
.rg{margin-bottom:var(--s7)}
.rg-head{border-bottom:1px solid var(--rule); padding-bottom:var(--s3)}
.rg-list{columns:3; column-gap:var(--s6)}
.rg-row a{display:flex; flex-direction:column; gap:2px; min-height:44px; justify-content:center}
.rg-row:hover .rg-name{color:var(--ink); border-bottom-color:var(--rule)}
.rg-name{border-bottom:1px solid transparent; transition:border-color .25s var(--ease)}
.rg-flat{display:flex; flex-direction:column; gap:2px}
/* The ten projects with a page get a quiet arrow. The rest are not lesser
   projects, so they are not dimmed — they simply have nothing more to open. */
.rg-row:not(.rg-flat) .rg-name::after{content:"\00a0\2192"; color:var(--muted);
  transition:color .25s var(--ease)}
.rg-row:not(.rg-flat):hover .rg-name::after{color:var(--ink)}
.chip{background:transparent; border:1px solid var(--rule); color:var(--ink-2);
  border-radius:var(--r-xs); font-family:var(--font-t); font-size:.875rem; cursor:pointer;
  min-height:44px; padding:0 var(--s3); display:inline-flex; align-items:center;
  transition:border-color .2s var(--ease), color .2s var(--ease), background .2s var(--ease)}
.chip:hover{border-color:var(--ink); color:var(--ink)}
.chip[aria-pressed="true"]{background:var(--ink); border-color:var(--ink); color:var(--bg); font-weight:600}

/* ---------- empty states + data ---------- */
.empty{border:1px dashed var(--rule); border-radius:var(--r-sm); padding:var(--s5);
  background:transparent; display:flex; flex-direction:column; gap:var(--s3)}
.empty .h3{color:var(--ink)}
.gap{color:var(--muted); font-style:italic}
.needs-list{margin-top:var(--s4); display:flex; flex-direction:column; gap:var(--s2)}
.prose > * + *{margin-top:var(--s4)}
.prose .h3{margin-top:var(--s6)}

/* ---------- the drawing ----------
   A section, a part plan and a riser diagram of the five systems. The services
   sit at a whisper until you ask for one: the site's argument expressed as an
   opacity, because the thing that makes a building work is the thing you do not
   see until you look for it. */
.sec-draw{background:var(--surface)}
.sysfig{display:grid; gap:var(--s5)}
/* The drawing takes the full canvas. Everything else on the page is measured;
   a drawing is not prose and does not want a measure. */
.sysfig-d{margin:0; position:relative}
/* No negative margin: the drawing carries its own margin inside the viewBox,
   and pulling it past the gutter clips the leaders. */
/* ---------- the drawing ----------
   Five weights with meaning, not two. Cut material is filled; everything else
   is drawn in the weight its importance earns. Each service carries its own
   line type, the way a drawing distinguishes them without colour. */
/* Three viewports need width. A phone gets the section alone — same drawing,
   same interaction, at a size where the poché and the datums are legible — and
   the full sheet is one tap away in the enlarged view. */
.sheet{width:100%;height:auto;overflow:visible}
.sheet-a{display:block} .sheet-full{display:none}
@media(min-width:900px){.sheet-a{display:none} .sheet-full{display:block}}
.sd-body .sheet-a{display:none} .sd-body .sheet-full{display:block}
.sheet text{font-family:var(--font-t),system-ui;fill:var(--muted)}
.sheet path,.sheet circle{fill:none}
/* Everything that is FILLED has to out-specify the blanket fill:none above, or
   the poché — the cut material, which is the first thing an engineer reads in a
   section — silently disappears. */

.sheet .d-poche{fill:var(--draw);stroke:none}                    /* cut material */
.d-e{stroke:var(--draw);stroke-width:1.1}
.d-o{stroke:var(--draw);stroke-width:1}
.d-o-t{stroke:var(--draw-2);stroke-width:.7}
.d-eq{stroke:var(--draw);stroke-width:1.25}
.d-eq-t{stroke:var(--draw-2);stroke-width:.8}
.sheet .d-eq-f{fill:var(--draw);stroke:none}
.d-gnd{stroke:var(--draw-2);stroke-width:1.1}
.d-fin{stroke:var(--draw-3);stroke-width:.8}
.d-lvl{stroke:var(--draw-3);stroke-width:.8;stroke-dasharray:9 6}
.d-grid{stroke:var(--draw-2);stroke-width:.7;stroke-dasharray:16 5 2.5 5}
.sheet .d-bub{stroke:var(--draw-2);stroke-width:.9;fill:var(--paper)}
.d-dat{stroke:var(--draw-2);stroke-width:.8}
.sheet .d-dat-f{fill:var(--draw);stroke:none}
.d-lead{stroke:var(--draw-2);stroke-width:.7}
.sheet .d-lead-d{fill:var(--draw);stroke:none}
.d-cut{stroke:var(--draw);stroke-width:1.6;stroke-dasharray:22 6 3 6}
.sheet .d-cut-f{stroke:var(--draw);stroke-width:1.6;fill:var(--draw)}
.d-rule{stroke:var(--rule);stroke-width:1}

.d-t{font-size:14px} .d-t-s{font-size:12.5px;letter-spacing:.04em}
.d-t-b{font-size:14px;font-weight:600;fill:var(--ink)}
.d-t-h{font-size:12px;letter-spacing:.16em;font-weight:600;fill:var(--ink-2)}
.d-t-n{font-size:13px;fill:var(--muted)}
.d-key{font-family:var(--font-d),system-ui;font-size:21px;font-weight:700;fill:var(--ink)}

/* a line type per service, so the drawing distinguishes them the way a drawing does */
.sheet .sys-line{stroke:var(--accent);stroke-width:2;fill:none;stroke-linecap:round;stroke-linejoin:round}
.sys-hvac{}
.sys-phe {stroke-dasharray:11 5}
.sys-fire{stroke-width:2.6}
.sys-elec{stroke-dasharray:.5 5.5}
.sys-elv {stroke-dasharray:7 3.5 1 3.5}
.sheet .sys-node{fill:var(--accent);stroke:none}

.sheet-bar{display:flex; flex-wrap:wrap; align-items:center; gap:var(--s3) var(--s4); margin-top:var(--s4)}
.sheet-bar .fine{flex:1 1 24ch}
@media(hover:none){.sheet-bar .fine{display:none}}

/* the key */
.syskey{list-style:none; margin:0; padding:0; display:grid; gap:0;
  border-top:1px solid var(--rule-2)}
@media(min-width:760px){.syskey{grid-template-columns:repeat(5,minmax(0,1fr)); gap:0 var(--s4); border-top:0}}
.sys-key{display:grid; grid-template-columns:22px minmax(0,1fr); gap:4px var(--s3);
  align-items:start; padding:var(--s3) 0; border-bottom:1px solid var(--rule-2);
  min-height:56px; transition:color .25s var(--ease)}
@media(min-width:760px){.sys-key{grid-template-columns:minmax(0,1fr); border-bottom:0; border-top:1px solid var(--rule)}}
.sys-key .i{width:22px; height:22px; color:var(--muted); transition:color .25s var(--ease)}
.sk-n{font-family:var(--font-d); font-weight:600; letter-spacing:-.012em; font-size:1rem; color:var(--ink)}
.sk-i{grid-column:2; font-size:.85rem; color:var(--muted); line-height:1.5}
@media(min-width:760px){.sk-i{grid-column:1}}
.sys-key:hover .i,.sys-key:focus-visible .i{color:var(--ink)}

/* hold one system, drop the rest */
.sys-run{opacity:.34; transition:opacity .34s var(--ease)}
.sysfig:has(.sys-key[data-sys="hvac"]:hover) .sys-run:not([data-sys="hvac"]),
.sysfig:has(.sys-key[data-sys="hvac"]:focus-visible) .sys-run:not([data-sys="hvac"]),
.sysfig:has(.sys-key[data-sys="elec"]:hover) .sys-run:not([data-sys="elec"]),
.sysfig:has(.sys-key[data-sys="elec"]:focus-visible) .sys-run:not([data-sys="elec"]),
.sysfig:has(.sys-key[data-sys="phe"]:hover) .sys-run:not([data-sys="phe"]),
.sysfig:has(.sys-key[data-sys="phe"]:focus-visible) .sys-run:not([data-sys="phe"]),
.sysfig:has(.sys-key[data-sys="fire"]:hover) .sys-run:not([data-sys="fire"]),
.sysfig:has(.sys-key[data-sys="fire"]:focus-visible) .sys-run:not([data-sys="fire"]),
.sysfig:has(.sys-key[data-sys="elv"]:hover) .sys-run:not([data-sys="elv"]),
.sysfig:has(.sys-key[data-sys="elv"]:focus-visible) .sys-run:not([data-sys="elv"]){opacity:.04}
.sysfig:has(.sys-key[data-sys="hvac"]:hover) [data-sys="hvac"],
.sysfig:has(.sys-key[data-sys="hvac"]:focus-visible) [data-sys="hvac"],
.sysfig:has(.sys-key[data-sys="elec"]:hover) [data-sys="elec"],
.sysfig:has(.sys-key[data-sys="elec"]:focus-visible) [data-sys="elec"],
.sysfig:has(.sys-key[data-sys="phe"]:hover) [data-sys="phe"],
.sysfig:has(.sys-key[data-sys="phe"]:focus-visible) [data-sys="phe"],
.sysfig:has(.sys-key[data-sys="fire"]:hover) [data-sys="fire"],
.sysfig:has(.sys-key[data-sys="fire"]:focus-visible) [data-sys="fire"],
.sysfig:has(.sys-key[data-sys="elv"]:hover) [data-sys="elv"],
.sysfig:has(.sys-key[data-sys="elv"]:focus-visible) [data-sys="elv"]{opacity:1}
@media(hover:none){.sys-run{opacity:.62}}

/* The drawing draws itself, once, so the interaction teaches itself and the
   page earns its one piece of motion. */
@keyframes sysDraw{from{stroke-dashoffset:1} to{stroke-dashoffset:0}}
@keyframes sysUp{0%{opacity:0} 30%,72%{opacity:1} 100%{opacity:.34}}
.sysfig.tour .sys-line{stroke-dasharray:1; animation:sysDraw 1.15s var(--ease) both}
.sysfig.tour .sys-run{animation:sysUp 1.9s var(--ease) both}
.sysfig.tour [data-sys="hvac"],.sysfig.tour [data-sys="hvac"] .sys-line{animation-delay:.10s}
.sysfig.tour [data-sys="elec"],.sysfig.tour [data-sys="elec"] .sys-line{animation-delay:.45s}
.sysfig.tour [data-sys="phe"], .sysfig.tour [data-sys="phe"]  .sys-line{animation-delay:.80s}
.sysfig.tour [data-sys="fire"],.sysfig.tour [data-sys="fire"] .sys-line{animation-delay:1.15s}
.sysfig.tour [data-sys="elv"], .sysfig.tour [data-sys="elv"]  .sys-line{animation-delay:1.50s}
.sysfig.tour:hover .sys-line,.sysfig.tour:hover .sys-run{animation:none}

/* ---------- the drawing, enlarged ---------- */
.sheet-dlg{width:min(96vw,1800px); max-width:none; max-height:92vh; padding:0; border:0;
  background:var(--paper); color:var(--ink); border-radius:var(--r-md); overflow:hidden}
@supports (corner-shape: squircle){.sheet-dlg{corner-shape:squircle; border-radius:var(--r-lg)}}
.sheet-dlg::backdrop{background:rgba(20,22,26,.62); backdrop-filter:blur(3px)}
.sd-bar{display:flex; gap:var(--s2); justify-content:flex-end; padding:var(--s3);
  border-bottom:1px solid var(--rule-2); background:var(--surface)}
.sd-body{overflow:auto; max-height:calc(92vh - 74px); padding:var(--s4);
  -webkit-overflow-scrolling:touch}
.sd-body .sheet{width:100%}
.sheet-dlg.zoom .sd-body .sheet{width:1900px; max-width:none}
.sd-body:focus-visible{outline:2px solid var(--accent); outline-offset:-4px}

/* ---------- project page: prev / next ---------- */
.pnav{border-top:1px solid var(--rule-2)}
.pnav-in{display:grid; grid-template-columns:minmax(0,1fr); gap:0}
@media(min-width:600px){.pnav-in{grid-template-columns:repeat(2,minmax(0,1fr))}}
.pnav-l{display:flex; flex-direction:column; gap:6px; padding:var(--s5) 0; min-height:44px;
  border-bottom:1px solid var(--rule-2); transition:color .25s var(--ease)}
@media(min-width:600px){
  .pnav-l{border-bottom:0; padding:var(--s6) var(--s5) var(--s6) 0}
  .pnav-r{text-align:right; align-items:flex-end; padding:var(--s6) 0 var(--s6) var(--s5);
    border-left:1px solid var(--rule-2)}
}
.pnav-k{font-size:.695rem; letter-spacing:.17em; text-transform:uppercase; font-weight:600; color:var(--muted)}
.pnav-t{font-family:var(--font-d); font-weight:600; letter-spacing:-.014em; font-size:1.16rem; color:var(--ink-2)}
.pnav-l:hover .pnav-t{color:var(--ink)}

/* ---------- contact ---------- */
.ct-col{display:flex; flex-direction:column; align-items:flex-start}
.ct-col .btn{align-self:stretch; justify-content:center; min-height:52px}
@media(min-width:600px){.ct-col .btn{align-self:flex-start; min-height:0}}
.ct-list{list-style:none; margin:var(--s4) 0 0; padding:0; display:flex; flex-direction:column;
  border-top:1px solid var(--rule-2); width:100%}
.ct-list li{display:grid; grid-template-columns:88px minmax(0,1fr); gap:var(--s3);
  padding:var(--s3) 0; border-bottom:1px solid var(--rule-2); align-items:start}
.ct-k{font-size:.695rem; letter-spacing:.17em; text-transform:uppercase; font-weight:600;
  color:var(--muted); padding-top:5px}
.ct-v{font-size:1.02rem; color:var(--ink); line-height:1.6}
a.ct-v{display:inline-flex; align-items:center; min-height:44px}
@media(min-width:720px){a.ct-v{min-height:0; display:inline}}
a.ct-v{border-bottom:1px solid var(--rule); padding-bottom:1px; transition:border-color .25s var(--ease)}
a.ct-v:hover{border-bottom-color:var(--ink)}

/* ---------- closing band + footer ---------- */
.band{background:var(--surface); border-top:1px solid var(--rule-2); padding:var(--s8) 0}
.band-in{display:flex; align-items:flex-end; justify-content:space-between; gap:var(--s5) var(--s6); flex-wrap:wrap}
.band-in > div{flex:1 1 34ch}
.band .lede{margin-top:var(--s3); max-width:56ch}
.ftr{background:var(--bg); border-top:1px solid var(--rule-2); padding:var(--s7) 0 var(--s5)}
.ftr-c .mark-sm{margin-bottom:var(--s3)}
.ftr-in{display:grid; grid-template-columns:1.5fr 1.1fr .8fr .7fr; gap:var(--s6)}
.ftr-h{font-size:.695rem; letter-spacing:.17em; text-transform:uppercase; font-weight:600;
  color:var(--muted); margin-bottom:var(--s3)}
.ftr-c p{font-size:.9rem; color:var(--ink-2); line-height:1.75}
.ftr-c a{border-bottom:1px solid transparent; transition:border-color .25s var(--ease)}
.ftr-c a:hover{border-bottom-color:var(--rule)}
.ftr-c a:hover{color:var(--ink)}
.ftr-b{margin-top:var(--s6); padding-top:var(--s4); border-top:1px solid var(--rule-2)}

/* ============================================================
   RESPONSIVE — mobile-first
   Base = phone. Every query below ADDS capability as the screen
   earns it. Nothing here takes anything away.
   ============================================================ */

/* ---------- persistent mobile CTA (base: on) ---------- */
/* The hero action scrolls away within one swipe on a phone. This puts it back,
   permanently, the moment it leaves — same label, so it reads as the same
   button rather than a second offer. */
.mobcta{display:none; position:fixed; left:var(--s3); right:var(--s3);
  bottom:calc(var(--s3) + env(safe-area-inset-bottom)); z-index:130;
  justify-content:center; min-height:52px; box-shadow:var(--shadow)}
.mobcta:not([hidden]){display:flex}
body:has(.mobcta:not([hidden])) .ftr{padding-bottom:96px}

/* ---------- base: phone ---------- */
.sec{padding:var(--s7) 0}
.phead{padding:var(--s6) 0 var(--s5)}
.steps{grid-template-columns:minmax(0,1fr)}
.ftr-in{grid-template-columns:minmax(0,1fr); gap:var(--s5)}
.caps-lg li{font-size:.97rem}
.trustline{margin-top:var(--s3); padding-top:var(--s3); font-size:.8rem}
.hero .label{font-size:.66rem}
.hero .cta-row{margin-top:var(--s4); gap:var(--s2)}
.hero .cta-row .btn{flex:1 1 auto; justify-content:center; min-height:52px}
.band-in{flex-direction:column; align-items:flex-start}
.row-head{gap:var(--s3)}
/* Footer links are a thumb target on a phone and a text link on a desktop. */
.ftr-c .ftr-nav{display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:0 var(--s4)}
.ftr-c .ftr-nav a{display:flex; align-items:center; min-height:44px;
  border-bottom:1px solid var(--rule-2)}
.ftr-c p a:not(.ftr-nav a){display:inline-block; min-height:40px; line-height:40px}

@media(min-width:600px){
  .ftr-in{grid-template-columns:repeat(2,minmax(0,1fr)); gap:var(--s6)}
  .steps{grid-template-columns:repeat(2,minmax(0,1fr))}
}

@media(min-width:720px){
  .sec{padding:var(--s8) 0}
  .phead{padding:var(--s8) 0 var(--s6)}
  .trustline{font-size:.83rem; margin-top:var(--s4)}
  .hero .cta-row{margin-top:var(--s5); gap:var(--s3)}
  .hero .cta-row .btn{flex:0 0 auto; min-height:0}
  .band-in{flex-direction:row; align-items:flex-end}
  .caps-lg li{font-size:1rem}
  .ftr-c .ftr-nav{display:block}
  .ftr-c .ftr-nav a{display:inline; min-height:0; border-bottom:1px solid transparent}
  .ftr-c .ftr-nav a:hover{border-bottom-color:var(--rule)}
  .ftr-c p a:not(.ftr-nav a){min-height:0; line-height:inherit}
  .mobcta{display:none!important}
  body:has(.mobcta) .ftr{padding-bottom:var(--s5)}
}

@media(min-width:960px){
  .steps{grid-template-columns:repeat(3,minmax(0,1fr))}
  .ftr-in{grid-template-columns:1.5fr 1.1fr .8fr .7fr}
}

/* ---------- desktop navigation ---------- */
/* Six links plus the action need ~1000px of bar. Below that the desktop nav
   wrapped "For architects" onto a second line and took the header with it. */
@media(min-width:1080px){
  .hdr .nav,.hdr-cta{display:flex}
  .navtoggle{display:none}
  .mnav{display:none!important}
}

@media(min-width:1180px){
  .steps{grid-template-columns:repeat(5,minmax(0,1fr))}
  /* On a wide canvas a measured section reads as a specification sheet: the
     section label moves into the left margin, aligned to the first line of the
     heading, and the prose keeps its measure. The left edge never moves. */
  /* Only where there IS a label to put in the margin — otherwise the heading
     would be indented against nothing and the spine would break. */
  .sec > .wrap.narrow:has(> .label){display:grid; grid-template-columns:190px minmax(0,1fr);
    column-gap:var(--s7); align-items:start}
  .sec > .wrap.narrow:has(> .label) > *{grid-column:2}
  .sec > .wrap.narrow > .label{grid-column:1; grid-row:1; margin:0; padding-top:.5em}
}

/* ---------- the wide canvas ---------- */
@media(min-width:1400px){
  .hdr-in{height:92px}
  .mark{height:50px}
  /* The section rhythm stays at s8 even on the widest canvas: two s9 paddings
     back to back put 256px of nothing between sections, which reads as a hole
     rather than as air. Only the closing band earns the larger measure. */
  .phead{padding:var(--s8) 0 var(--s7)}
  .band{padding:var(--s9) 0}
}

@media(prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.001ms!important; transition-duration:.001ms!important}
  .plate-draw path,.sysfig.tour .sys-line{stroke-dasharray:none!important; stroke-dashoffset:0!important}
  .rv{opacity:1!important; transform:none!important}
  html{scroll-behavior:auto}
}

/* ---------- print: the register is the document worth printing ---------- */
@media print{
  .hdr,.mnav,.mobcta,.band,.navtoggle,.skip{display:none!important}
  .rv{opacity:1!important; transform:none!important}
  body{background:#fff; color:#000; font-size:11pt}
  .wrap{max-width:none; padding:0}
  .rg-list{columns:2}
  a{text-decoration:none; color:#000}
}
