/* More Steel Inc — page below the scroll-cinematic hero.
   Kept in its own file because the site ships script-src/style-src discipline
   and because the hero engine owns everything inside #world. */

:root{
  --ink:#f2f4f7; --ink-soft:rgba(242,244,247,.72); --ink-faint:rgba(242,244,247,.58);
  /* Steel ramp. Same hue family as the logo's chrome (--steel), but held
     near 11% saturation instead of 21% so the darks read graphite rather than
     navy, and spaced far enough apart that a raised block is visibly raised. */
  --bg-2:#090A0C;        /* deepest - hero ground and footer */
  --bg:#0E1013;          /* the page */
  --bg-alt:#171A1F;      /* alternating band */
  --bg-card:#1D2127;     /* anything raised off the page */
  --bg-card-2:#262B33;   /* raised and hovered */
  --line:rgba(186,194,206,.20); --line-soft:rgba(186,194,206,.13);
  /* One pixel of light on a top edge is what separates plate from paint. */
  --edge:rgba(226,232,240,.09);
  --accent:#2265D2;
  --accent-ink:#7fb0f5;
  --steel:#BAC2CE; --steel-dim:#7F8894;
  --disp:'Saira Stencil One',system-ui,sans-serif;
  --disp-2:'Chakra Petch',system-ui,sans-serif;
  --body:'Chakra Petch',system-ui,sans-serif;
}
*{box-sizing:border-box}
html{scroll-behavior:smooth}
@media (prefers-reduced-motion: reduce){ html{scroll-behavior:auto} }
body{margin:0;background:var(--bg);color:var(--ink);font-family:var(--body);-webkit-font-smoothing:antialiased}
img{max-width:100%;height:auto}
a{color:#7fb0f5}

.wrap{max-width:1240px;margin:0 auto}
.sec{padding:clamp(64px,9vh,124px) 6vw}
/* The band now differs from the page by enough to see, and takes a soft
   light fall from its top edge so it reads as a plate rather than a fill. */
.sec--alt{
  background:linear-gradient(180deg,rgba(226,232,240,.030) 0,rgba(226,232,240,0) 140px),var(--bg-alt);
  border-block:1px solid var(--line-soft);
}
.rule{display:flex;align-items:center;gap:16px;margin:0 0 clamp(28px,4vh,48px)}
.rule .n{font:600 11px/1 ui-monospace,Menlo,monospace;letter-spacing:.24em;white-space:nowrap;color:var(--steel)}
.rule .dim{flex:1;display:flex;align-items:center;gap:0}
.rule .ln{flex:1;height:1px;background:var(--line)}
/* Extension ticks. Siblings of .ln, never children - .ln is scaled. */
.rule .t{width:1px;height:9px;background:var(--line);flex:none}
.anim [data-anim=draw] .t{opacity:0;transition:opacity .4s ease .55s}
.anim [data-anim=draw].is-in .t{opacity:1}
.rule a{font:600 13px/1 var(--body);letter-spacing:.08em;text-transform:uppercase;white-space:nowrap;color:var(--ink-soft);text-decoration:none}
.rule a:hover{color:var(--ink)}

h2.big{margin:0 0 18px;font:400 clamp(32px,5vw,62px)/1.02 var(--disp);text-transform:uppercase;letter-spacing:.005em;max-width:17ch}
p.lede{margin:0 0 clamp(34px,5vh,56px);font:700 clamp(20.5px,2.25vw,26px)/1.4 var(--body);color:rgba(242,244,247,.76);max-width:44ch;text-wrap:pretty}

/* stat strip */
.stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(190px,100%),1fr));gap:1px;background:var(--line-soft);border-block:1px solid var(--line-soft)}
.stats div{background:var(--bg-card);box-shadow:inset 0 1px 0 var(--edge);padding:32px 4vw;display:flex;flex-direction:column;gap:8px}
.stats b{font:400 clamp(36px,4.4vw,56px)/1 var(--disp);letter-spacing:.01em}
.stats span{font:500 12px/1.4 ui-monospace,Menlo,monospace;letter-spacing:.16em;text-transform:uppercase;color:var(--ink-faint)}

/* service cards */
.cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(250px,100%),1fr));gap:1px}
.card{background:var(--bg-card);outline:1px solid var(--line);box-shadow:inset 0 1px 0 var(--edge);padding:30px 28px 34px;display:flex;flex-direction:column;gap:13px;min-height:196px}
/* Each card now leads with a photo of that exact service, from the client's own
   jobs. Full-bleed to the card edge, so it reads as the card's subject rather
   than as decoration sitting inside a box. */
.card__img{display:block;width:calc(100% + 56px);max-width:none;margin:-30px -28px 4px;aspect-ratio:4/3;object-fit:cover;background:#0b0e13}
.card .n{font:600 11px/1 ui-monospace,Menlo,monospace;letter-spacing:.2em;color:var(--steel)}
.card h3{margin:0;font:700 clamp(20px,2.2vw,26px)/1.15 var(--disp-2);text-transform:uppercase;letter-spacing:.02em}
.card p{margin:0;font:700 19px/1.42 var(--body);color:rgba(242,244,247,.82);text-wrap:pretty}

/* work */
.work{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(300px,100%),1fr));gap:14px}
.work figure{margin:0;position:relative;overflow:hidden;background:var(--bg-card);border:1px solid var(--line)}
.work img{display:block;width:100%;aspect-ratio:4/3;object-fit:cover;background:#0b0e13}
.work figcaption{padding:14px 18px;font:500 11.5px/1.5 ui-monospace,Menlo,monospace;letter-spacing:.13em;color:var(--ink-faint)}
.work .badge{position:absolute;left:14px;top:14px;font:600 10px/1 ui-monospace,Menlo,monospace;letter-spacing:.16em;padding:7px 10px;background:rgba(5,7,11,.78);border:1px solid rgba(255,255,255,.18);color:rgba(242,244,247,.85)}

/* split */
.split{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(320px,100%),1fr));gap:clamp(30px,5vw,68px);align-items:center}
.split h2{margin:0 0 16px}
.split p{margin:0 0 20px;font:700 clamp(20px,2.1vw,24.5px)/1.45 var(--body);color:rgba(242,244,247,.78);max-width:42ch;text-wrap:pretty}
.sig{font:700 15px/1.5 var(--body);letter-spacing:.06em;color:rgba(242,244,247,.85)}

/* chips */
.logoband{background:#EEF1F6;border-block:1px solid rgba(0,0,0,.12);padding:clamp(30px,3.8vw,48px) 6vw}
.logoband__in{max-width:1240px;margin:0 auto}
.logoband__lab{margin:0 0 clamp(26px,3.4vw,44px);text-align:center;text-transform:uppercase;font:700 clamp(16px,2vw,22px)/1.3 var(--disp-2);letter-spacing:.13em;color:rgba(18,24,34,.62)}
.logos{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(2,1fr);align-items:center;justify-items:center;gap:clamp(20px,3vw,38px)}@media(min-width:1000px){.logos{grid-template-columns:repeat(4,1fr)}}
.logos li{display:flex;align-items:center;justify-content:center;min-height:84px;flex:0 1 auto}
.logos img{display:block;width:auto;height:auto;max-height:var(--lh,48px);max-width:min(var(--lw,240px),100%);object-fit:contain;opacity:.94;transition:opacity .2s ease}
@media(max-width:640px){.logos img{max-height:calc(var(--lh,48px)*.78)}}
.logos li:hover img{opacity:1}
.logos__wm{font:700 18px/1.3 var(--disp-2);letter-spacing:.02em;color:rgba(242,244,247,.8);text-align:center;text-wrap:balance}
@media (prefers-reduced-motion:reduce){.logos img{transition:none}}
.chips{display:flex;flex-wrap:wrap;gap:8px}
.chips span{font:600 15px/1 var(--body);letter-spacing:.04em;white-space:nowrap;padding:11px 14px;background:rgba(255,255,255,.05);border:1px solid var(--line);color:rgba(242,244,247,.78)}
.chips.mono span{font:600 10.5px/1 ui-monospace,Menlo,monospace;letter-spacing:.14em;padding:10px 13px}

/* buttons */
.btns{display:flex;flex-wrap:wrap;gap:12px}
.btn{display:inline-flex;align-items:center;justify-content:center;min-height:56px;padding:0 28px;text-decoration:none;font:700 17.5px/1 var(--body);letter-spacing:.02em;border:1px solid transparent}
.btn--p{background:var(--accent);color:#fff;text-transform:uppercase}
.btn--p:hover{background:#1b57bb;color:#fff}
.btn--g{border-color:rgba(242,244,247,.4);color:var(--ink);font:700 17.5px/1 var(--disp-2);letter-spacing:.04em}
.btn--g:hover{border-color:var(--ink);color:var(--ink)}
.btn--dark{background:#0b0d11;color:#fff;font:700 17.5px/1 var(--disp-2);letter-spacing:.04em}

/* closing CTA */
.cta{background:var(--accent);color:#fff;padding:clamp(72px,11vh,140px) 6vw}
.cta .in{max-width:1240px;margin:0 auto;display:flex;flex-wrap:wrap;gap:36px;align-items:flex-end;justify-content:space-between}
.cta .eye{font:600 11px/1 ui-monospace,Menlo,monospace;letter-spacing:.24em;color:rgba(255,255,255,.9)}
.cta h2{margin:16px 0;font:400 clamp(34px,5.6vw,72px)/0.98 var(--disp);text-transform:uppercase;letter-spacing:.005em}
.cta p{margin:0;font:700 clamp(20.5px,2.25vw,26px)/1.4 var(--body);color:rgba(255,255,255,.84);max-width:36ch;text-wrap:pretty}
.cta .col{display:flex;flex-direction:column;gap:12px}

/* disclosure + footer */
.disclose{background:var(--bg-2);border-top:1px solid var(--line-soft);padding:22px 6vw;font:500 14.5px/1.65 var(--body);color:var(--ink-faint)}
footer{background:var(--bg-2);border-top:1px solid var(--line-soft);padding:52px 6vw 36px;font:500 16px/1.7 var(--body);color:rgba(242,244,247,.62)}
footer .grid{max-width:1240px;margin:0 auto;display:grid;grid-template-columns:repeat(auto-fit,minmax(min(210px,100%),1fr));gap:40px}
footer .brand{font:700 20px/1.1 var(--disp-2);letter-spacing:.1em;color:var(--ink)}
/* Full lockup, no container: the nameplate already says the name. */
footer .brandmark{height:118px;width:auto;display:block;margin:0 0 16px}

/* One oversized ghost stamp on the blue band, off a 4K master, so it holds a
   clean edge at 660px instead of being a 298px file stretched four times over.
   The opacity was .1 only to hide that softness; a sharp mark reads as a
   deliberate watermark at .13.

   It is a background rather than an <img> because it is decorative and hidden
   below 820px, and a display:none <img> is still downloaded on most browsers.
   Inside a min-width query nothing requests it on a phone at all. */
.cta{position:relative;overflow:hidden;isolation:isolate}
@media (min-width:821px){
  .cta::before{
    content:'';position:absolute;z-index:-1;pointer-events:none;
    right:-5%;top:50%;translate:0 -50%;
    width:min(660px,58%);aspect-ratio:1320/761;
    background:url(/assets/img/logo-ghost.f8dca42e.webp) center/contain no-repeat;
    opacity:.13;
  }
}
footer h3{margin:0 0 4px;font:600 11px/1 ui-monospace,Menlo,monospace;letter-spacing:.22em;color:var(--steel)}
/* 44px minimum touch target (WCAG 2.5.8). These were 29px tall, which is a
   miss on a page whose whole conversion path is "tap the phone number". */
footer a{color:rgba(242,244,247,.72);text-decoration:none;display:flex;align-items:center;min-height:44px;padding:2px 0}
footer a:hover{color:var(--ink)}
footer .bot{max-width:1240px;margin:40px auto 0;padding-top:18px;border-top:1px solid rgba(255,255,255,.08);display:flex;flex-wrap:wrap;gap:12px;justify-content:space-between;font-size:12.5px}
footer .bot>span{white-space:nowrap}
footer .bot a{display:inline-flex;min-height:0;padding:0}
footer .phone{font:700 21px/1.1 var(--disp-2);letter-spacing:.04em;color:var(--ink)}

/* the page needs a way to convert before the film ends */
.railcta{position:fixed;right:18px;bottom:18px;z-index:80;display:inline-flex;align-items:center;gap:9px;min-height:50px;padding:0 20px;background:var(--accent);color:#fff;text-decoration:none;font:700 17px/1 var(--disp-2);letter-spacing:.03em;box-shadow:0 6px 26px rgba(0,0,0,.45)}
.railcta:hover{background:#1b57bb;color:#fff}
@media (max-width:640px){ .railcta{left:14px;right:14px;justify-content:center} }
@supports (padding:max(0px)){ .railcta{bottom:max(18px,env(safe-area-inset-bottom))} }

/* The who-you-are-hiring photo is a portrait phone shot of the crew. Cap the
   height so the split stays balanced, and hold the crop high so the hard hats
   stay in frame. */
#about img{width:100%;max-height:560px;object-fit:cover;object-position:center 26%}

/* ==========================================================================
   Multi-page components. The site used to be one page with anchor links, so
   none of this existed: every page below the home page needs its own header,
   and the service pages need a way to lay out scope, sequence and questions.
   ========================================================================== */

/* Compact page header. Home keeps the film; every other page gets a still. */
.phero{position:relative;min-height:clamp(340px,46vh,520px);display:flex;align-items:flex-end;overflow:hidden;isolation:isolate}
.phero__img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;z-index:-2}
.phero__scrim{position:absolute;inset:0;z-index:-1;background:linear-gradient(to right,rgba(5,7,11,.90) 0%,rgba(5,7,11,.64) 46%,rgba(5,7,11,.20) 82%,rgba(5,7,11,.12) 100%),linear-gradient(to top,rgba(5,7,11,.74) 0%,rgba(5,7,11,.10) 52%,rgba(5,7,11,.42) 100%)}
/* .wrap centres and caps; the inset comes from .sec, and .phero is not one.
   It cannot go on .phero either, because .phero__img and .phero__scrim are
   pinned with inset:0 and would inset with it. Widening the box by the same
   6vw it spends keeps this copy on the body text's left edge at every width. */
.phero__inner{max-width:calc(1240px + 12vw);padding-inline:6vw;padding-block:clamp(96px,13vh,150px) clamp(34px,6vh,58px)}
.phero__eyebrow{margin:0 0 10px;font:600 11px/1 ui-monospace,Menlo,monospace;letter-spacing:.24em;color:var(--steel)}
.phero__h1{margin:0;font:400 clamp(36px,6.4vw,78px)/0.97 var(--disp);text-transform:uppercase;letter-spacing:.005em;color:var(--ink);text-wrap:balance}
.phero__lede{margin:18px 0 0;max-width:44ch;font:700 clamp(20.5px,2.4vw,27px)/1.4 var(--body);color:rgba(242,244,247,.82);text-wrap:pretty}

.crumb{margin:0 0 20px;font:500 12px/1.5 ui-monospace,Menlo,monospace;letter-spacing:.1em;color:var(--ink-faint)}
/* Breadcrumb links get a full 44px tap height (WCAG 2.5.8) with the extra
   height taken back off the row, so they stay visually compact. */
.crumb{display:flex;flex-wrap:wrap;align-items:center;margin-block:-14px 6px}
.crumb a,.crumb [aria-current]{display:inline-flex;align-items:center;min-height:44px;padding-inline:2px}
.crumb a{color:rgba(242,244,247,.72);text-decoration:none}
.crumb a:hover{color:var(--ink)}
.crumb span{opacity:.5;padding:0 4px}
.crumb [aria-current]{color:var(--accent);opacity:1}

.wrap--narrow{max-width:860px}
.dual>p.lede{margin-bottom:0}
@media(min-width:920px){.dual{display:grid;grid-template-columns:1fr 1fr;gap:clamp(28px,3.4vw,56px)}}
.dual+.work{margin-top:clamp(34px,5vh,56px)}
p.lede--wide{max-width:78ch}

/* Service cards that are actual links to actual pages. */
.svcgrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(280px,100%),1fr));gap:1px;margin-top:34px}
.svccard{display:flex;flex-direction:column;background:var(--bg-card);outline:1px solid var(--line);text-decoration:none;color:inherit;transition:background .18s ease,outline-color .18s ease}
.svccard:hover{background:var(--bg-card-2);outline-color:rgba(34,101,210,.55)}
.svccard img{display:block;width:100%;aspect-ratio:4/3;object-fit:cover;background:var(--bg-alt)}
.svccard__body{padding:26px 26px 30px;display:flex;flex-direction:column;gap:11px;flex:1}
.svccard__body .n{font:600 11px/1 ui-monospace,Menlo,monospace;letter-spacing:.2em;color:var(--steel)}
.svccard__body h2,.svccard__body h3{margin:0;font:700 clamp(19px,2.1vw,25px)/1.15 var(--disp-2);text-transform:uppercase;letter-spacing:.02em}
.svccard__body p{margin:0;font:700 19px/1.42 var(--body);color:rgba(242,244,247,.8);text-wrap:pretty}
.svccard__go{margin-top:auto;padding-top:12px;font:600 12px/1 ui-monospace,Menlo,monospace;letter-spacing:.14em;color:var(--steel)}
.svccard:hover .svccard__go{color:#7fb0f5}

/* Scope: what a package actually includes. */
.scope{list-style:none;margin:30px 0 0;padding:0;display:grid;grid-template-columns:repeat(auto-fit,minmax(min(330px,100%),1fr));gap:1px;background:var(--line-soft)}
.scope li{background:var(--bg-card);box-shadow:inset 0 1px 0 var(--edge);padding:22px 24px 24px 52px;display:flex;flex-direction:column;gap:7px}
.scope strong{font:700 19px/1.25 var(--disp-2);letter-spacing:.02em;color:var(--ink)}
.scope span{font:700 19px/1.42 var(--body);color:rgba(242,244,247,.8)}

/* Sequence from award to handover. */
.steps{list-style:none;margin:32px 0 0;padding:0;display:flex;flex-direction:column;gap:1px;background:var(--line-soft)}
.steps li{background:var(--bg-card);box-shadow:inset 0 1px 0 var(--edge);display:flex;gap:22px;padding:24px 26px}
.steps__n{flex:none;font:700 clamp(22px,3vw,34px)/1 var(--disp-2);color:var(--steel-dim);min-width:56px}
.steps h3{margin:0 0 7px;font:700 clamp(18px,2.1vw,22px)/1.2 var(--disp-2);text-transform:uppercase;letter-spacing:.02em}
.steps p{margin:0;font:700 20.5px/1.45 var(--body);color:rgba(242,244,247,.82);max-width:52ch;text-wrap:pretty}

/* Three-up prose columns. */
.cols3{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(280px,100%),1fr));gap:clamp(24px,3vw,44px);margin-top:34px}
.cols3 h3{margin:0 0 12px;font:700 clamp(19px,2.2vw,24px)/1.15 var(--disp-2);text-transform:uppercase;letter-spacing:.02em}
.cols3 p{margin:0;font:700 20.5px/1.45 var(--body);color:rgba(242,244,247,.76);text-wrap:pretty}

/* Service areas. */
.areas{display:grid;grid-template-columns:1fr;gap:1px;background:var(--line-soft);margin-top:30px}
@media(min-width:520px){.areas{grid-template-columns:repeat(2,1fr)}}
@media(min-width:760px){.areas{grid-template-columns:repeat(3,1fr)}}
@media(min-width:1060px){.areas{grid-template-columns:repeat(4,1fr)}}
.area{background:var(--bg-card);box-shadow:inset 0 1px 0 var(--edge);padding:20px 22px}
.area h3{margin:0 0 7px;font:700 20px/1.15 var(--disp-2);text-transform:uppercase;letter-spacing:.03em}
.area p{margin:0;font:700 19.5px/1.4 var(--body);color:rgba(242,244,247,.82);text-wrap:pretty}

/* FAQ. <details> keeps this working with script-src 'self' and no JS at all. */
.faq{margin-top:28px;display:flex;flex-direction:column;gap:1px;background:var(--line-soft)}
.faq details{background:var(--bg-card);box-shadow:inset 0 1px 0 var(--edge)}
.faq summary{cursor:pointer;list-style:none;padding:21px 24px;font:700 20px/1.35 var(--body);color:var(--ink);display:flex;justify-content:space-between;gap:18px;align-items:center;min-height:44px}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{content:"+";font:700 22px/1 var(--disp-2);color:var(--steel);flex:none}
.faq details[open] summary::after{content:"–"}
.faq p{margin:0;padding:0 24px 24px;font:700 20.5px/1.45 var(--body);color:rgba(242,244,247,.82);max-width:54ch;text-wrap:pretty}

/* Contact rows. */
.contactlist{margin-top:26px;display:flex;flex-direction:column;gap:1px;background:var(--line-soft)}
.contactlist__row{background:var(--bg);display:flex;align-items:center;gap:18px;padding:16px 20px;min-height:44px;text-decoration:none;color:inherit}
a.contactlist__row:hover{background:#0e131b}
.contactlist__k{flex:none;min-width:92px;font:600 11px/1 ui-monospace,Menlo,monospace;letter-spacing:.18em;color:var(--steel)}
.contactlist__v{font:700 clamp(17px,2vw,22px)/1.2 var(--disp-2);letter-spacing:.03em;color:var(--ink)}

/* Active nav item. */
.nav__links a[aria-current="page"]{color:var(--ink)}
.nav__links a[aria-current="page"]::after{content:"";display:block;height:2px;margin-top:5px;background:var(--accent)}

@media (max-width:760px){
  .steps li{flex-direction:column;gap:10px}
  .steps__n{min-width:0}
  .phero{min-height:300px}
}

/* Their mark, sitting with the eyebrow on every page header. */
.phero__eyebrow{display:flex;align-items:center;gap:11px}
.phero__mark{width:auto;height:22px;flex:none;display:block;filter:drop-shadow(0 2px 7px rgba(0,0,0,.6))}

/* Service intro sits beside a short at-a-glance panel, so the page does not
   open with one narrow column of prose and a lot of empty space. */
.intro2{display:grid;grid-template-columns:minmax(0,1.55fr) minmax(0,1fr);gap:clamp(28px,4vw,60px);align-items:start}
.glance{background:var(--bg-card);outline:1px solid var(--line);padding:26px 26px 28px}
.glance h2{margin:0 0 16px;font:600 13px/1 ui-monospace,Menlo,monospace;letter-spacing:.2em;text-transform:uppercase;color:var(--steel)}
.glance dl{margin:0 0 26px;display:flex;flex-direction:column;gap:26px}
.glance dt{font:600 11px/1 ui-monospace,Menlo,monospace;letter-spacing:.16em;text-transform:uppercase;color:rgba(242,244,247,.5)}
.glance dd{margin:6px 0 0;font:700 19.5px/1.4 var(--body);color:rgba(242,244,247,.86)}
@media (max-width:900px){.intro2{grid-template-columns:1fr}}



/* Lead form, matching the pattern on the other client sites. Inputs are 48px so
   they clear the 44px touch minimum, because these get filled in on a phone. */
.lead{margin:0 0 26px;display:flex;flex-direction:column;gap:14px}
.lead__row{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(210px,100%),1fr));gap:14px}
.lead label{display:flex;flex-direction:column;gap:7px;font:600 11px/1 ui-monospace,Menlo,monospace;letter-spacing:.16em;text-transform:uppercase;color:rgba(242,244,247,.6)}
.lead input,.lead select,.lead textarea{
  width:100%;min-height:48px;padding:12px 14px;background:#0b0e13;color:var(--ink);
  border:1px solid var(--line);border-radius:0;font:600 18px/1.4 var(--body);
  text-transform:none;letter-spacing:0}
.lead textarea{min-height:110px;resize:vertical}
.lead input:focus-visible,.lead select:focus-visible,.lead textarea:focus-visible{
  outline:2px solid var(--accent-ink);outline-offset:1px;border-color:transparent}
.lead input::placeholder,.lead textarea::placeholder{color:rgba(242,244,247,.34)}
.lead [aria-invalid="true"]{border-color:#e0776c}
.lead button{align-self:flex-start;min-height:48px;cursor:pointer;border:0}
.lead button[disabled]{opacity:.6;cursor:default}
/* Honeypot sits off-screen rather than display:none, so bots that check
   computed style still fill it in. */
.lead__hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
/* Consent is a checkbox beside running text, so it must not inherit the
   uppercase mono label styling. */
.lead label.lead__consent{flex-direction:row;align-items:flex-start;gap:11px;
  font:500 15px/1.6 var(--body);letter-spacing:0;text-transform:none;color:rgba(242,244,247,.62)}
.lead label.lead__consent input{width:20px;height:20px;min-height:0;flex:none;margin-top:2px;padding:0}
.lead label.lead__consent a{color:var(--accent-ink)}
.lead__alt{margin:0;font:600 17px/1.5 var(--body);color:rgba(242,244,247,.75)}
.lead__alt a{color:var(--accent-ink);display:inline-flex;align-items:center;min-height:44px;padding-inline:2px}
.lead__status{margin:0;padding:13px 15px;font:600 16px/1.5 var(--body);border:1px solid}
.lead__status--ok{color:#c8e6c9;border-color:rgba(120,200,130,.5);background:rgba(60,120,70,.16)}
.lead__status--err{color:#ffd7d2;border-color:rgba(230,120,110,.55);background:rgba(150,50,45,.18)}

/* Legal pages: long-form running text. */
.story h2,.legal h2{margin:34px 0 10px;font:700 clamp(19px,2.2vw,24px)/1.2 var(--disp-2);text-transform:uppercase;letter-spacing:.02em}
.legal p{margin:0 0 15px;font:500 17px/1.68 var(--body);color:var(--ink-soft);max-width:62ch;text-wrap:pretty}
.wrap--narrow.story{max-width:50ch}
.story p{margin:0 0 20px;font:700 clamp(20px,2.1vw,24.5px)/1.45 var(--body);color:rgba(242,244,247,.79);text-wrap:pretty}
.story a,.legal a{color:var(--accent-ink)}
.legal__updated{font:600 11px/1 ui-monospace,Menlo,monospace;letter-spacing:.16em;text-transform:uppercase;color:rgba(242,244,247,.45)}

/* Consent links are inline inside a sentence, so the WCAG inline exception
   applies, but they are legally required links: give them a bigger hit area
   than 13px without breaking the run of text. */
.lead label.lead__consent a{padding-block:6px;display:inline-block}

/* Coverage map. Three tiers, and the legend repeats the palette baked into the
   SVG because the map is an <img> and cannot inherit page colours. */
.cvblock{margin-top:30px;display:grid;grid-template-columns:minmax(0,1.5fr) minmax(0,1fr);gap:clamp(24px,3vw,44px);align-items:center}
.cvblock__map{display:block;width:100%;height:auto;background:#0b0e13;border:1px solid var(--line)}
.cvlegend{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:20px}
.cvlegend li{display:grid;grid-template-columns:18px 1fr;gap:6px 12px;align-items:start}
.cvlegend strong{font:700 19px/1.25 var(--disp-2);letter-spacing:.02em;color:var(--ink)}
.cvlegend__d{grid-column:2;font:700 18.5px/1.4 var(--body);color:rgba(242,244,247,.8);text-wrap:pretty}
.sw{width:18px;height:18px;margin-top:2px;border:1px solid}
.sw--home{background:#2265D2;border-color:#9cc4fb}
.sw--se{background:#1d4f9e;border-color:#3b7ad4}
.sw--reach{background:#1a2a41;border-color:#7fb0f5;border-style:dashed}
.sw--pin{border:0;background:none;color:#fff;font-size:19px;line-height:17px;text-align:center}
@media (max-width:900px){.cvblock{grid-template-columns:1fr}}

/* ============================================================ motion
 * Every start state below is gated on .anim, which assets/anim.js adds to
 * <html>. No script, blocked script, or reduced-motion preference means the
 * class never lands and the page renders in its finished state. Nothing here
 * is allowed to hide content on its own.
 *
 * One effect per kind of block. A rule draws, a headline wipes, a photo
 * uncovers, a scope cell catches a light sweep, a step latches in from the
 * left. Using one motion everywhere is what makes a site feel templated.
 * Only transform, opacity, filter and clip-path move, so none of this
 * triggers layout. */

/* section rule: the hairline runs out from the left, the number lifts after it */
.anim [data-anim=draw] .ln{transform:scaleX(0);transform-origin:left;transition:transform .9s cubic-bezier(.16,.84,.44,1)}
.anim [data-anim=draw].is-in .ln{transform:scaleX(1)}
.anim [data-anim=draw] .n{opacity:0;transform:translateY(7px);transition:opacity .5s ease .12s,transform .5s ease .12s}
.anim [data-anim=draw].is-in .n{opacity:1;transform:none}

/* display headline: uncovers upward behind its own baseline */
.anim [data-anim=wipe]{clip-path:inset(0 0 108% 0);transform:translateY(12px);transition:clip-path 1s cubic-bezier(.16,.84,.44,1),transform 1s cubic-bezier(.16,.84,.44,1)}
.anim [data-anim=wipe].is-in{clip-path:inset(0);transform:none}

/* running prose: rises out of focus */
.anim [data-anim=defog]{opacity:0;transform:translateY(18px);transition:opacity .7s ease,transform .8s cubic-bezier(.16,.84,.44,1)}
.anim [data-anim=defog].is-in{opacity:1;transform:none}

/* client marks: lift and settle in sequence */
.anim [data-anim=pop]{opacity:0;transform:translateY(15px) scale(.93);transition:opacity .5s ease,transform .65s cubic-bezier(.2,.9,.3,1);transition-delay:calc(var(--i,0)*70ms)}
.anim [data-anim=pop].is-in{opacity:1;transform:none}

/* credential chips: widen from their left edge */
.anim [data-anim=latch]{opacity:0;transform:scaleX(.72);transform-origin:left;transition:opacity .4s ease,transform .55s cubic-bezier(.2,.9,.3,1);transition-delay:calc(var(--i,0)*45ms)}
.anim [data-anim=latch].is-in{opacity:1;transform:none}

/* stat cells: rise, then the figure decodes (assets/anim.js) */
.anim [data-anim=tally]{opacity:0;transform:translateY(20px);transition:opacity .5s ease,transform .65s cubic-bezier(.2,.9,.3,1);transition-delay:calc(var(--i,0)*90ms)}
.anim [data-anim=tally].is-in{opacity:1;transform:none}
.anim [data-anim=tally] b{font-variant-numeric:tabular-nums}

/* service cards: tip up onto their front edge */
.anim [data-anim=deal]{opacity:0;transform:perspective(1000px) rotateX(7deg) translateY(32px);transform-origin:50% 100%;transition:opacity .6s ease,transform .85s cubic-bezier(.16,.84,.44,1);transition-delay:calc(var(--i,0)*95ms)}
.anim [data-anim=deal].is-in{opacity:1;transform:none}

/* photographs: a panel pulls off the frame while the image eases back to size */
.anim [data-anim=curtain]::after{content:"";position:absolute;inset:0;z-index:3;background:var(--bg-card);transform:scaleY(1);transform-origin:top;transition:transform .85s cubic-bezier(.7,0,.2,1);transition-delay:calc(var(--i,0)*75ms)}
.anim [data-anim=curtain].is-in::after{transform:scaleY(0);transform-origin:bottom}
.anim [data-anim=curtain] img{transform:scale(1.14);transition:transform 1.3s cubic-bezier(.16,.84,.44,1);transition-delay:calc(var(--i,0)*75ms)}
.anim [data-anim=curtain].is-in img{transform:none}

/* two-column blocks: the halves come in from opposite sides */
.anim [data-anim=part]{opacity:0;transform:translateX(-30px);transition:opacity .7s ease,transform .9s cubic-bezier(.16,.84,.44,1)}
.anim [data-anim=part]:nth-child(even){transform:translateX(30px)}
.anim [data-anim=part].is-in{opacity:1;transform:none}

/* scope cells: a light passes across each one in turn */
.anim [data-anim=sweep]{opacity:0;position:relative;overflow:hidden;transition:opacity .45s ease;transition-delay:calc(var(--i,0)*55ms)}
.anim [data-anim=sweep].is-in{opacity:1}
.anim [data-anim=sweep]::before{content:"";position:absolute;inset:0;z-index:2;pointer-events:none;transform:translateX(-130%);
  background:linear-gradient(100deg,transparent 34%,rgba(127,176,245,.15) 50%,transparent 66%)}
.anim [data-anim=sweep].is-in::before{animation:ms-sweep 1.15s cubic-bezier(.3,0,.2,1) forwards;animation-delay:calc(var(--i,0)*55ms + 120ms)}
@keyframes ms-sweep{to{transform:translateX(130%)}}

/* numbered steps: the row latches in, then its figure snaps to size */
.anim [data-anim=ladder]{opacity:0;transform:translateX(-28px);transition:opacity .5s ease,transform .7s cubic-bezier(.16,.84,.44,1);transition-delay:calc(var(--i,0)*110ms)}
.anim [data-anim=ladder].is-in{opacity:1;transform:none}
.anim [data-anim=ladder] .steps__n{display:inline-block;opacity:0;transform:scale(.55);transition:opacity .35s ease,transform .5s cubic-bezier(.22,1,.36,1);transition-delay:calc(var(--i,0)*110ms + 130ms)}
.anim [data-anim=ladder].is-in .steps__n{opacity:1;transform:none}

/* three-column blocks: rise and straighten */
.anim [data-anim=settle]{opacity:0;transform:translateY(28px) rotate(-.9deg);transform-origin:left bottom;transition:opacity .6s ease,transform .85s cubic-bezier(.16,.84,.44,1);transition-delay:calc(var(--i,0)*120ms)}
.anim [data-anim=settle].is-in{opacity:1;transform:none}

/* coverage map: powers up out of the dark */
.anim [data-anim=bloom]{opacity:0;transform:scale(.975);transition:opacity .8s ease,transform 1.1s cubic-bezier(.16,.84,.44,1)}
.anim [data-anim=bloom].is-in{opacity:1;transform:none}
.anim [data-anim=bloom] .cvblock__map{opacity:.35;transition:opacity 1.2s ease .15s}
.anim [data-anim=bloom].is-in .cvblock__map{opacity:1}

/* city cards and map legend: hinge down from their top edge */
.anim [data-anim=wave]{opacity:0;transform:perspective(760px) rotateX(-14deg);transform-origin:top center;transition:opacity .5s ease,transform .7s cubic-bezier(.2,.9,.3,1);transition-delay:calc(var(--i,0)*50ms)}
.anim [data-anim=wave].is-in{opacity:1;transform:none}

/* stacked rows: slide in from the right */
.anim [data-anim=shunt]{opacity:0;transform:translateX(32px);transition:opacity .5s ease,transform .68s cubic-bezier(.16,.84,.44,1);transition-delay:calc(var(--i,0)*70ms)}
.anim [data-anim=shunt].is-in{opacity:1;transform:none}

/* form fields: quiet on purpose, this is the part people have to use */
.anim [data-anim=stack]{opacity:0;transform:translateY(12px);transition:opacity .45s ease,transform .55s ease;transition-delay:calc(var(--i,0)*70ms)}
.anim [data-anim=stack].is-in{opacity:1;transform:none}

/* home hero: the copy arrives on load, it is already in view */
.anim .hero__inner > *{opacity:0;transform:translateY(24px);transition:opacity .85s ease,transform .95s cubic-bezier(.16,.84,.44,1)}
.anim .hero__inner > *:nth-child(1){transition-delay:.2s}
.anim .hero__inner > *:nth-child(2){transition-delay:.36s}
.anim .hero__inner > *:nth-child(3){transition-delay:.52s}
.anim .hero__inner > *:nth-child(4){transition-delay:.68s}
.anim .hero__inner.is-in > *{opacity:1;transform:none}

/* inner page headers: the photograph drifts back to true over the first look */
.anim .phero__img{animation:ms-ken 20s cubic-bezier(.2,.6,.3,1) forwards}
@keyframes ms-ken{from{transform:scale(1.09)}to{transform:scale(1)}}

/* ---- hover, which is motion the visitor asks for ---- */
.svccard{overflow:hidden}
.svccard img{transition:transform .55s cubic-bezier(.16,.84,.44,1)}
.svccard:hover img{transform:scale(1.05)}
.svccard__go{transition:transform .3s ease,color .18s ease}
.svccard:hover .svccard__go{transform:translateX(6px)}

.work figure img{transition:transform .6s cubic-bezier(.16,.84,.44,1)}
.work figure:hover img{transform:scale(1.045)}

.btn{position:relative;overflow:hidden;isolation:isolate}
.btn::after{content:"";position:absolute;inset:0;z-index:-1;background:currentColor;opacity:0;transform:translateX(-101%);
  transition:transform .45s cubic-bezier(.16,.84,.44,1),opacity .45s ease}
.btn:hover::after{opacity:.1;transform:none}

.nav__links a{position:relative}
.nav__links a::before{content:"";position:absolute;left:0;right:0;bottom:-5px;height:2px;background:var(--accent);
  transform:scaleX(0);transform-origin:right;transition:transform .35s cubic-bezier(.16,.84,.44,1)}
.nav__links a:hover::before{transform:scaleX(1);transform-origin:left}
.nav__links a[aria-current="page"]::before{display:none}

.area{transition:background .25s ease}
.area:hover{background:var(--bg-card)}

.railcta{transition:background .18s ease,transform .25s cubic-bezier(.2,.9,.3,1)}
.railcta:hover{transform:translateY(-3px)}

/* One switch turns all of it off, including the hover work above. */
@media (prefers-reduced-motion:reduce){
  .anim [data-anim],.anim [data-anim] *,.anim .hero__inner > *{transition:none!important;animation:none!important}
  .svccard img,.svccard__go,.work figure img,.btn::after,.nav__links a::before,.railcta,.phero__img{transition:none!important;animation:none!important}
  .svccard:hover img,.work figure:hover img,.railcta:hover{transform:none}
}

.hl{color:#fff}
.anim .hl{color:inherit;transition:color .75s ease .25s}
.anim .hl.is-in{color:#fff}
@media (prefers-reduced-motion:reduce){.anim .hl{color:#fff;transition:none}}



/* ========================================================== lightbox
 * A native <dialog>, so the focus trap, Escape and background inerting come
 * from the platform. Only the appearance is ours. */
.lb{
  width:100%;max-width:100%;height:100dvh;max-height:100dvh;
  margin:0;padding:0;border:0;background:rgba(6,8,12,.97);color:var(--ink);
  overflow:hidden;
}
.lb::backdrop{background:rgba(4,6,9,.9)}
.lb__fig{
  margin:0;height:100%;display:flex;flex-direction:column;
  align-items:center;justify-content:center;gap:16px;padding:clamp(52px,7vw,72px) clamp(14px,4vw,64px);
}
.lb__img{
  max-width:100%;max-height:calc(100dvh - 190px);
  width:auto;height:auto;object-fit:contain;display:block;
  border:1px solid var(--line);background:#0b0e13;
}
.lb__cap{
  display:flex;flex-wrap:wrap;align-items:baseline;justify-content:center;gap:8px 16px;
  text-align:center;max-width:70ch;
}
.lb__text{font:600 12px/1.5 ui-monospace,Menlo,monospace;letter-spacing:.15em;color:var(--steel)}
.lb__count{font:600 12px/1.5 ui-monospace,Menlo,monospace;letter-spacing:.15em;color:var(--ink-faint)}

/* Controls: 48px minimum so a thumb can hit them. */
.lb__x,.lb__nav{
  position:absolute;z-index:2;cursor:pointer;
  min-width:48px;min-height:48px;display:flex;align-items:center;justify-content:center;
  background:rgba(255,255,255,.07);border:1px solid var(--line);color:var(--ink);
  font:400 26px/1 var(--body);
  transition:background .18s ease,border-color .18s ease;
}
.lb__x:hover,.lb__nav:hover{background:rgba(255,255,255,.14);border-color:var(--ink)}
.lb__x{top:14px;right:14px;font-size:30px}
.lb__nav{top:50%;transform:translateY(-50%);font-size:32px}
.lb__prev{left:14px}
.lb__next{right:14px}
@media (max-width:640px){
  /* Thumbs sit at the bottom of a phone, not the middle of the screen. */
  .lb__nav{top:auto;bottom:16px;transform:none;min-width:64px}
  .lb__prev{left:16px}
  .lb__next{right:16px}
  .lb__img{max-height:calc(100dvh - 230px)}
}
@media (prefers-reduced-motion:reduce){.lb__x,.lb__nav{transition:none}}

/* The photographs advertise themselves as openable only once the script has
   run and made them so. */
.anim .work figure{cursor:zoom-in}
.work figure[role="button"]:focus-visible{outline:2px solid var(--accent-ink);outline-offset:3px}

/* ==================================================== phone layout
 * Measured before this block: the work page ran 21,843px at 390 wide, which is
 * 26 phone screens of scrolling, and the home page 12.9. Every grid on the site
 * collapsed to one column, so a set of four cards became four screens.
 *
 * The fix is not smaller type. It is refusing to let a set become a stack:
 * card sets swipe sideways one screen at a time, the photo grids go two up with
 * their captions moved onto the image, and the tall portrait photographs stop
 * eating a whole screen each. Section padding comes down to match.
 *
 * Everything here is scoped to phones. The desktop layout is untouched. */
@media (max-width:700px){

  /* Bands were built for a laptop. On a phone that padding is dead scroll. */
  .sec{padding:clamp(40px,6.5vh,64px) 6vw}
  .logoband{padding:clamp(24px,4vw,34px) 6vw}

  /* ---- card sets swipe instead of stacking ----
     Four service cards were four screens. Now they are one, and the row bleeds
     to both edges so the cut-off card at the right announces there is more. */
  .svcgrid,.cols3{
    display:grid;grid-auto-flow:column;grid-template-columns:none;
    grid-auto-columns:80%;
    overflow-x:auto;overscroll-behavior-x:contain;
    scroll-snap-type:x mandatory;
    margin-inline:-6vw;padding:0 6vw 14px;
    scrollbar-width:none;
  }
  .svcgrid{gap:10px;margin-top:26px}
  .cols3{gap:14px;margin-top:26px}
  .svcgrid::-webkit-scrollbar,.cols3::-webkit-scrollbar{display:none}
  .svcgrid>*,.cols3>*{scroll-snap-align:start}
  /* A grid item with an image needs a floor or the track collapses. */
  .svccard{min-width:0}
  .svccard img{aspect-ratio:16/10}

  /* ---- photographs go two up, captions move onto the image ----
     57 captions below 57 photos was 2,000px of text nobody reads while
     scrolling. On the image it costs nothing and reads better. */
  .work{grid-template-columns:1fr 1fr;gap:6px;margin-top:24px}
  .work img{aspect-ratio:1/1}
  /* Every third one runs full width, so the grid has a rhythm instead of being
     a wall of squares. */
  .work figure:nth-child(7n+1){grid-column:1 / -1}
  .work figure:nth-child(7n+1) img{aspect-ratio:4/3}
  .work figcaption{
    position:absolute;left:0;right:0;bottom:0;z-index:2;
    padding:22px 10px 8px;font-size:9.5px;letter-spacing:.08em;line-height:1.35;
    color:rgba(242,244,247,.92);
    background:linear-gradient(to top,rgba(5,7,11,.92),rgba(5,7,11,0));
  }
  .work .badge{display:none}

  /* ---- scope and area lists go two up ---- */
  .scope{grid-template-columns:1fr 1fr;margin-top:24px}
  .scope li{padding:15px 14px 17px}
  .scope strong{font-size:15px;line-height:1.2}
  .scope span{font-size:14px;line-height:1.35}

  /* ---- the tall portrait photo in split sections ----
     900x1200 at full width is most of a screen on its own. */
  .split{gap:24px}
  .split img{max-height:46vh;width:100%;object-fit:cover;object-position:center}

  /* ---- numbered steps stay a sequence, just tighter ---- */
  .steps li{padding:16px 16px 18px;gap:6px}
  .steps p{font-size:17px;line-height:1.4}

  /* ---- everything else that was sized for a desk ---- */
  p.lede{margin-bottom:26px;font-size:19px;line-height:1.35}
  .split p,.story p{font-size:18px;line-height:1.4;margin-bottom:14px}
  .cols3 p{font-size:17px;line-height:1.4}
  .area p{font-size:14.5px;line-height:1.35}
  .faq p{font-size:17px;line-height:1.45}
  .faq summary{font-size:17px;padding:16px 16px}
  .faq p{padding:0 16px 18px}
  .cvlegend{gap:14px}
  .cvlegend__d{font-size:14.5px;line-height:1.35}
  .glance{padding:20px 20px 22px}
  .glance dl{gap:18px}
  .cta{padding:clamp(48px,7vh,72px) 6vw}

  /* The two-column prose block is a stack on a phone, so it needs its gap back. */
  .dual>p.lede:not(:last-child){margin-bottom:22px}
}

/* A swipeable row is only obvious if something is cut off at the edge. Below
   this width the cards are wide enough that one and a bit always shows. */
@media (max-width:420px){
  .svcgrid{grid-auto-columns:84%}
  .cols3{grid-auto-columns:86%}
}

@media (prefers-reduced-motion:reduce){
  .svcgrid,.cols3{scroll-behavior:auto}
}

/* Phone performance. 3D transforms and long image lists are where an iPhone
   actually struggles, so both are simplified below 700px. */
@media (max-width:700px){
  .anim [data-anim=deal]{transform:translateY(24px)}
  .anim [data-anim=wave]{transform:translateY(16px)}
  .anim [data-anim=settle]{transform:translateY(20px)}
  .work figure{content-visibility:auto;contain-intrinsic-size:auto 220px}
}


/* ==========================================================================
   DRAFTING LAYER
   Borrowed from erection drawings, which is the document this trade runs on.
   All of it is background-image or pseudo-element work: no extra DOM, no
   requests, and nothing animated except transform and opacity.
   ========================================================================== */

/* Drafting paper. A fine grid under the whole page and a heavier one, with
   major gridlines, on the alternating bands - so the alternation reads as a
   change of sheet rather than a change of paint. Two gradients, painted once,
   no image decode. */
body{
  background-image:
    repeating-linear-gradient(to right, rgba(186,194,206,.035) 0 1px, transparent 1px 28px),
    repeating-linear-gradient(to bottom, rgba(186,194,206,.035) 0 1px, transparent 1px 28px);
}
.sec--alt{
  background-image:
    /* major gridlines every fifth square, as on a real sheet */
    repeating-linear-gradient(to right, rgba(186,194,206,.055) 0 1px, transparent 1px 140px),
    repeating-linear-gradient(to bottom, rgba(186,194,206,.055) 0 1px, transparent 1px 140px),
    repeating-linear-gradient(to right, rgba(186,194,206,.03) 0 1px, transparent 1px 28px),
    repeating-linear-gradient(to bottom, rgba(186,194,206,.03) 0 1px, transparent 1px 28px),
    linear-gradient(180deg,rgba(226,232,240,.030) 0,rgba(226,232,240,0) 140px);
}

/* Registration targets at the corners of every section, the way a drawing
   sheet is cropped and aligned. One background-image, four positions, no DOM. */
.sec{
  position:relative;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='19' height='19'%3E%3Cg fill='none' stroke='%23BAC2CE' stroke-width='1' opacity='.42'%3E%3Cpath d='M9.5 0v5.4M9.5 13.6V19M0 9.5h5.4M13.6 9.5H19'/%3E%3Ccircle cx='9.5' cy='9.5' r='3.1'/%3E%3C/g%3E%3C/svg%3E");
  background-repeat:no-repeat;
  background-position:
    2.1vw 26px,
    calc(100% - 2.1vw) 26px,
    2.1vw calc(100% - 26px),
    calc(100% - 2.1vw) calc(100% - 26px);
}
/* The bands carry their own grid, so their marks ride on top of it. */
.sec--alt{
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='19' height='19'%3E%3Cg fill='none' stroke='%23BAC2CE' stroke-width='1' opacity='.42'%3E%3Cpath d='M9.5 0v5.4M9.5 13.6V19M0 9.5h5.4M13.6 9.5H19'/%3E%3Ccircle cx='9.5' cy='9.5' r='3.1'/%3E%3C/g%3E%3C/svg%3E"),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='19' height='19'%3E%3Cg fill='none' stroke='%23BAC2CE' stroke-width='1' opacity='.42'%3E%3Cpath d='M9.5 0v5.4M9.5 13.6V19M0 9.5h5.4M13.6 9.5H19'/%3E%3Ccircle cx='9.5' cy='9.5' r='3.1'/%3E%3C/g%3E%3C/svg%3E"),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='19' height='19'%3E%3Cg fill='none' stroke='%23BAC2CE' stroke-width='1' opacity='.42'%3E%3Cpath d='M9.5 0v5.4M9.5 13.6V19M0 9.5h5.4M13.6 9.5H19'/%3E%3Ccircle cx='9.5' cy='9.5' r='3.1'/%3E%3C/g%3E%3C/svg%3E"),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='19' height='19'%3E%3Cg fill='none' stroke='%23BAC2CE' stroke-width='1' opacity='.42'%3E%3Cpath d='M9.5 0v5.4M9.5 13.6V19M0 9.5h5.4M13.6 9.5H19'/%3E%3Ccircle cx='9.5' cy='9.5' r='3.1'/%3E%3C/g%3E%3C/svg%3E"),
    repeating-linear-gradient(to right, rgba(186,194,206,.055) 0 1px, transparent 1px 140px),
    repeating-linear-gradient(to bottom, rgba(186,194,206,.055) 0 1px, transparent 1px 140px),
    repeating-linear-gradient(to right, rgba(186,194,206,.03) 0 1px, transparent 1px 28px),
    repeating-linear-gradient(to bottom, rgba(186,194,206,.03) 0 1px, transparent 1px 28px),
    linear-gradient(180deg,rgba(226,232,240,.030) 0,rgba(226,232,240,0) 140px);
  background-repeat:no-repeat,no-repeat,no-repeat,no-repeat,repeat,repeat,repeat,repeat,no-repeat;
  background-position:
    2.1vw 26px,
    calc(100% - 2.1vw) 26px,
    2.1vw calc(100% - 26px),
    calc(100% - 2.1vw) calc(100% - 26px),
    0 0,0 0,0 0,0 0,0 0;
}

/* The wide-flange section. The cut end of nearly every member on one of his
   jobs, so it is the one shape that belongs here. It replaces the bullet in
   the scope lists, where the old markup had none. */
.scope li{position:relative}
.scope li strong{display:block}
.scope li strong::before{
  content:'';position:absolute;left:24px;top:26px;width:14px;height:12px;
  background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='12'%3E%3Cpath fill='%23BAC2CE' d='M0 0h14v2.6H8.3v6.8H14V12H0V9.4h5.7V2.6H0z'/%3E%3C/svg%3E") no-repeat center/contain;
  opacity:.62;
}
@media (max-width:700px){ .scope li strong::before{top:24px} }

/* Card art. Drafting corner ticks on the service cards, so a card reads as a
   detail drawn on the sheet rather than a tile. Drawn with one gradient set on
   a pseudo-element, so it costs no extra element and no request. */
.svccard{position:relative}
.svccard::after{
  content:'';position:absolute;inset:9px;pointer-events:none;z-index:2;
  background:
    linear-gradient(to right, var(--steel-dim) 0 11px, transparent 11px) 0 0/100% 1px no-repeat,
    linear-gradient(to bottom, var(--steel-dim) 0 11px, transparent 11px) 0 0/1px 100% no-repeat,
    linear-gradient(to left, var(--steel-dim) 0 11px, transparent 11px) 100% 0/100% 1px no-repeat,
    linear-gradient(to bottom, var(--steel-dim) 0 11px, transparent 11px) 100% 0/1px 100% no-repeat,
    linear-gradient(to right, var(--steel-dim) 0 11px, transparent 11px) 0 100%/100% 1px no-repeat,
    linear-gradient(to top, var(--steel-dim) 0 11px, transparent 11px) 0 100%/1px 100% no-repeat,
    linear-gradient(to left, var(--steel-dim) 0 11px, transparent 11px) 100% 100%/100% 1px no-repeat,
    linear-gradient(to top, var(--steel-dim) 0 11px, transparent 11px) 100% 100%/1px 100% no-repeat;
  opacity:.34;transition:opacity .22s ease;
}
.svccard:hover::after{opacity:.8}

/* The number on a service card becomes a piece mark, the way a fabricator
   tags a member, sitting against a W-shape. */
.svccard__body .n{display:inline-flex;align-items:center;gap:7px}
.svccard__body .n::before{
  content:'';width:14px;height:12px;flex:none;
  background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='12'%3E%3Cpath fill='%23BAC2CE' d='M0 0h14v2.6H8.3v6.8H14V12H0V9.4h5.7V2.6H0z'/%3E%3C/svg%3E") no-repeat center/contain;
  opacity:.75;
}

/* Leader line. The elbow that ties a note to the thing it points at - here,
   the caption to the photograph above it. */
.work figcaption{position:relative;padding-left:30px}
.work figcaption::before{
  content:'';position:absolute;left:14px;top:0;width:9px;height:19px;
  border-left:1px solid var(--steel-dim);
  border-bottom:1px solid var(--steel-dim);
  opacity:.5;
}

/* Reduced motion is already handled by anim.js never adding .anim, so none of
   the transitions above ever engage. The linework itself stays. */


/* The title block that closes a drawing sheet. Every value here is true; a
   drawing with invented fields is worse than no drawing. */
.titleblock{
  max-width:1240px;margin:40px auto 0;
  border:1px solid var(--line);
  display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));
  background:var(--bg-card);box-shadow:inset 0 1px 0 var(--edge);
}
.titleblock > div{
  padding:13px 16px 14px;
  border-right:1px solid var(--line-soft);
  display:flex;flex-direction:column;gap:5px;min-width:0;
}
.titleblock > div:last-child{border-right:0}
.tb__k{
  font:600 9.5px/1 ui-monospace,Menlo,monospace;letter-spacing:.22em;
  color:var(--steel-dim);text-transform:uppercase;
}
.tb__v{
  font:700 14.5px/1.25 var(--disp-2);letter-spacing:.045em;
  color:var(--ink);text-transform:uppercase;overflow-wrap:anywhere;
}
.tb__v a{color:inherit;text-decoration:none}
.tb__v a:hover{color:var(--accent-ink)}
/* On a phone the cells stack two-up, and the right border becomes a bottom
   one so the block still reads as ruled cells rather than a list. */
@media (max-width:640px){
  .titleblock{grid-template-columns:repeat(2,1fr)}
  .titleblock > div{border-bottom:1px solid var(--line-soft)}
  .titleblock > div:nth-child(2n){border-right:0}
}
.anim .titleblock{opacity:0;transform:translateY(14px);transition:opacity .6s ease,transform .7s cubic-bezier(.16,.84,.44,1)}
.anim .titleblock.is-in{opacity:1;transform:none}
