/* ============================================================================
   BASE — identical on every Pittsburgh IT build. The visitor never sees any of it.
   Token NAMES are fixed; only the VALUES change per client. Everything below the
   token block is structural: the accessibility floor, the form skeleton, tap
   targets, the motion contract. Roughly 20 lines get rewritten per client and
   several hundred lines of quality are inherited.
   MOBILE FIRST — every rule here is the small-screen rule. Breakpoints add.
   ========================================================================== */
:root{
  --surface:#F4F2EC;
  --surface-2:#E8E4D9;
  --band:#16232B;
  --band-ink:#EFEDE6;
  --band-ink-2:#A6B4BB;
  --accent-on-band:#F0A882;
  --ink:#14181B;
  --ink-2:#4A5257;
  --ink-3:#586064;
  --accent:#A32F16;
  --accent-2:#7E2410;
  --accent-ink:#FFF6F1;
  --line:#CFCABC;
  --maxw:1240px;
  --gutter:22px;
  --radius:0px;
  --font-display:'Archivo','Helvetica Neue',Helvetica,Arial,sans-serif;
  --font-body:'IBM Plex Sans',system-ui,-apple-system,'Segoe UI',sans-serif;
}

*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth}
@media(prefers-reduced-motion:reduce){html{scroll-behavior:auto}}
body{margin:0;background:var(--surface);color:var(--ink);
  font-family:var(--font-body);font-size:17px;line-height:1.62;
  -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;
  overflow-x:hidden}
img,svg,video{max-width:100%;height:auto;display:block}
h1,h2,h3,h4{font-family:var(--font-display);margin:0;line-height:1.08;
  font-weight:700;letter-spacing:-.03em}
p{margin:0 0 1em}
a{color:inherit}
ul{margin:0;padding:0;list-style:none}

/* --- container ------------------------------------------------------------ */
.container{width:100%;max-width:var(--maxw);margin:0 auto;padding:0 var(--gutter)}
@media(min-width:760px){:root{--gutter:34px}}
@media(min-width:1180px){:root{--gutter:48px}}

/* --- accessibility floor -------------------------------------------------- */
.skip{position:absolute;left:-9999px;top:0;z-index:200;background:var(--accent);
  color:var(--accent-ink);padding:12px 18px;border-radius:0 0 var(--radius) 0;
  font-weight:700;text-decoration:none}
.skip:focus{left:0}
:focus-visible{outline:3px solid var(--accent);outline-offset:3px;border-radius:2px}
.vh{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);
  clip-path:inset(50%);white-space:nowrap}
/* honeypot: OFF-SCREEN, never display:none — a hidden field some bots skip,
   and a screen reader is told to leave it alone. */
.hp{position:absolute!important;left:-9999px;top:-9999px;width:1px;height:1px;
  opacity:0;pointer-events:none}

/* --- tap targets ---------------------------------------------------------- */
a,button,input,select,textarea,summary{font-family:inherit}
.btn,button,input[type=submit]{min-height:48px}
nav a,footer a{display:inline-block;min-height:24px}

/* --- button skeleton (templates restyle the skin, not the mechanics) ------- */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:.55em;
  padding:14px 26px;border:1px solid transparent;border-radius:var(--radius);
  font-weight:650;font-size:16px;line-height:1.1;text-decoration:none;cursor:pointer;
  transition:transform .18s ease,background .18s ease,color .18s ease,border-color .18s ease,box-shadow .18s ease}
.btn:active{transform:translateY(1px)}
.btn-primary{background:var(--accent);color:var(--accent-ink);border-color:var(--accent)}
.btn-ghost{background:transparent;color:var(--ink);border-color:var(--line)}

/* --- form skeleton -------------------------------------------------------- */
.form{display:grid;gap:16px}
.field{display:grid;gap:7px}
.field label{font-size:12.5px;font-weight:700;letter-spacing:.09em;
  text-transform:uppercase;color:var(--ink-2)}
.field input,.field select,.field textarea{
  width:100%;min-height:50px;padding:13px 15px;border:1px solid var(--line);
  border-radius:var(--radius);background:var(--surface);color:var(--ink);
  font-size:16px;/* 16px stops iOS zooming the page on focus */
  font-family:inherit;transition:border-color .18s ease,box-shadow .18s ease}
.field textarea{min-height:140px;resize:vertical;line-height:1.55}
.field input:focus,.field select:focus,.field textarea:focus{
  outline:none;border-color:var(--accent);box-shadow:0 0 0 3px rgba(163,47,22,.24)}
.field ::placeholder{color:var(--ink-3);opacity:1}
.frow{display:grid;gap:16px}
@media(min-width:680px){.frow{grid-template-columns:1fr 1fr}}
.thanks{display:none;border:1px solid var(--line);border-radius:var(--radius);
  padding:28px;background:var(--surface-2)}
.thanks.show{display:block}
.thanks h3{font-size:24px;margin-bottom:10px}
.formerror{color:#8C2712;font-size:15px;font-weight:600;margin-top:10px}

/* --- MOTION CONTRACT ------------------------------------------------------
   Nothing starts hidden unless JavaScript has already run. The `js` class is set
   by an inline <head> script, and ONLY when prefers-reduced-motion is not set.
   No JS, blocked JS, old browser, or reduced motion => the page is simply visible.
   This is the inverse of how most sites do it, and it is why a script failure
   here cannot produce a blank page on a lead-generating site. */
html.js .reveal{opacity:0;transform:translateY(18px);
  transition:opacity .7s cubic-bezier(.22,.61,.36,1),transform .7s cubic-bezier(.22,.61,.36,1)}
html.js .reveal.in{opacity:1;transform:none}
html.js .reveal.d1{transition-delay:.08s}
html.js .reveal.d2{transition-delay:.16s}
html.js .reveal.d3{transition-delay:.24s}
@media(prefers-reduced-motion:reduce){
  html.js .reveal,html.js .reveal.in{opacity:1!important;transform:none!important;transition:none!important}
  *{animation-duration:.001ms!important;animation-iteration-count:1!important;
    transition-duration:.001ms!important}
}

/* --- nav skeleton --------------------------------------------------------- */
#nav{position:fixed;top:0;left:0;right:0;z-index:100;
  transition:background .25s ease,box-shadow .25s ease,border-color .25s ease}
.nav-inner{display:flex;align-items:center;justify-content:space-between;
  gap:16px;min-height:64px}
.navtoggle{display:inline-flex;align-items:center;justify-content:center;
  width:48px;height:48px;margin-right:-10px;background:none;border:0;
  color:inherit;cursor:pointer}
@media(min-width:940px){.navtoggle{display:none}}
.nav-links{display:none}
.nav-links.open{display:flex}
.nav-links{gap:0}
/* Desktop nav reset. Deliberately scoped to #nav so its specificity (1,1,0) beats any
   later `.nav-links{position:absolute…}` a template writes for its mobile drawer —
   equal specificity later in the file wins over a media query, which silently left the
   drawer stacked at the left edge on six of seven templates before this was scoped.
   It sets ONLY the structural properties that must not leak from mobile to desktop;
   gap, colour and type stay the template's business. */
@media(min-width:940px){
  #nav .nav-links,#nav .nav-links.open{display:flex;position:static;inset:auto;
    flex-direction:row;align-items:center;padding:0;margin:0;border:0;background:none;
    width:auto;height:auto;min-height:0;max-height:none;box-shadow:none;transform:none;
    visibility:visible;opacity:1;overflow:visible;
    gap:var(--nav-gap,32px)}
}
html.menu-open,html.menu-open body{overflow:hidden}

/* --- footer skeleton ------------------------------------------------------ */
footer a{text-decoration:none}
.credit{font-size:13.5px}
.credit a{text-decoration:underline;text-underline-offset:3px}

/* --- button rows ----------------------------------------------------------
   On a phone two CTAs sitting side by side at different intrinsic widths look
   accidental, and neither is a comfortable thumb target. They go full width until
   there is room for a row. Scoped as `.btnrow > .btn` (0,2,0) so a template's own
   `.btn{}` rule later in the file cannot silently undo it — the same cascade trap
   that left the desktop nav stacked. */
.btnrow{display:flex;flex-wrap:wrap;gap:12px}
.btnrow > .btn{flex:1 1 100%}
@media(min-width:560px){.btnrow > .btn{flex:0 0 auto}}

/* --- long-string guard ----------------------------------------------------
   A client email address or a compound word set in a heavy display face at
   20px uppercase does not wrap, and pushes a 390px page sideways. Found on the
   Ironworks contact page: dispatch@vantagemechanical.com forced the document to
   462px. Plumbing, so every template inherits the fix. */
/* Headings are deliberately NOT in this guard. break-word on a display heading
   shatters a word mid-syllable the moment its container is narrower than the word —
   it turned "Everything we make," into "Everyth / ing we / make," on Marquee. A
   heading that does not fit is a LAYOUT bug; fix the column, do not hyphenate it. */
h1,h2,h3,h4{overflow-wrap:normal;word-break:normal}
a[href^="mailto:"],a[href^="tel:"]{overflow-wrap:anywhere}
.crow span,.crow b,.cinfo span,address{overflow-wrap:anywhere}

/* --- utility -------------------------------------------------------------- */
.sec{padding:64px 0}
@media(min-width:760px){.sec{padding:96px 0}}
@media(min-width:1180px){.sec{padding:124px 0}}
.eyebrow{font-size:12px;font-weight:750;letter-spacing:.16em;text-transform:uppercase;
  color:var(--accent);margin:0 0 14px}
.lead{font-size:19px;line-height:1.6;color:var(--ink-2)}
@media(min-width:760px){.lead{font-size:21px}}


/* ============================================================================
   OPEN — the shop's own week, drawn to scale.

   LIGHT LOGIC: FLAT, EVEN, MIDDAY — and it is enforced by SUBTRACTION. Search this
   file for `box-shadow` and you will find none. Search it for a gradient used as a
   SURFACE and you will find none. There is no vignette, no glow, no raking rim, no
   translucency and no blur anywhere in it. Every separation on this page is a 1px
   rule or a change of paper (--surface / --surface-2 / --band). 01-nightwork earns
   its keep on atmosphere; this one earns it on information density and precision,
   the way a well-set timetable does, and one soft shadow would drag it into 01.

   The single gradient in the file rules the clock lanes into hours. That is a
   measuring instrument, not a background.

   THE INSTRUMENT: template.js writes --s / --e / --m / --ticks from the client's
   own hours[] and services[].tag. Everything below reads those four numbers. A shop
   open three days and a shop open six produce different pages from the same markup.

   MOBILE FIRST. Every rule here is the phone rule; breakpoints only add.
   ========================================================================== */

:root{
  --font-mono:'IBM Plex Mono',ui-monospace,SFMono-Regular,Menlo,monospace;
  --grade:saturate(.76) contrast(.92) brightness(1.10) sepia(.07);
  --nav-h:64px;
  --nav-gap:30px;
  --lane-bg:var(--surface-2);   /* the paper a clock lane is ruled onto        */
  --lane:18px;                  /* lane height; the large clock re-declares it */
  --hair:1px solid var(--line);
  --hair-hard:1px solid var(--ink);
}

/* A 28-inch display is where Jon works, and a 1240px column centred in 2560px of
   paper reads as a phone layout that stopped growing. The measure opens up once,
   at 1700, and the full-bleed contact strip and ink band do the rest. */
@media(min-width:1700px){:root{--maxw:1400px;--gutter:64px}}

/* ---------------------------------------------------------------- type ----- */
body{background:var(--surface)}
h1{font-size:clamp(46px,5.4vw,68px);line-height:1.02;letter-spacing:-.034em;margin:0}
.h-lg{font-size:clamp(28px,3.6vw,42px);line-height:1.06;letter-spacing:-.028em}
.h-md{font-size:clamp(23px,2.8vw,30px);line-height:1.12;letter-spacing:-.022em}
h3{font-size:18px;line-height:1.25;letter-spacing:-.012em;font-weight:700}
.measure{max-width:62ch}
.lead{color:var(--ink-2)}

/* the mono is the page's instrument face: every time, price, duration, index and
   label is set in it, and NOTHING else is. That is the whole typographic system. */
.eyebrow,.wklab,.wt,.wkscale li,.smt,.plate figcaption span,.dl-k,.dl-tel,
.dateline,.mark,.fnum,.rn,.fh,.drawlab,.mgh,.mnote,.towns span,.field label{
  font-family:var(--font-mono)}
.eyebrow{font-size:11px;font-weight:500;letter-spacing:.18em;color:var(--accent);
  margin:0 0 16px}
.eyebrow.onband{color:var(--accent-on-band)}

/* -------------------------------------------------------------- imagery ---- */
/* ONE grade, one rule, every photograph on the page. There is no second filter in
   this file and there must never be one. */
.heroplate img,.frame img{filter:var(--grade)}
.frame{display:block;position:relative;overflow:hidden;background:var(--surface-2);
  aspect-ratio:1400 / 933}
.frame img{width:100%;height:100%;object-fit:cover;object-position:50% 50%}

/* ------------------------------------------------------------ preview bar --
   Demo-only chrome, and it has to get out of the masthead's way — in normal flow
   the fixed nav simply covers it and the wordmark prints on top of the bar's own
   words (the defect 05-plate shipped). The bar is pinned above the nav and the nav
   is given a matching padding-top, published as --tpl-h. No `top` and no `position`
   is declared on #nav: the shared floor owns those and houserules.py enforces it. */
.tplbar{position:fixed;top:0;left:0;right:0;z-index:130;
  background:var(--band);color:var(--band-ink-2);font-family:var(--font-mono);
  font-size:11.5px;line-height:1.4;letter-spacing:.02em;
  padding:8px var(--gutter);text-align:center}
.tplbar b{color:var(--band-ink)}
:root:has(.tplbar){--tpl-h:54px}
@media(min-width:760px){:root:has(.tplbar){--tpl-h:32px}}
#nav{padding-top:var(--tpl-h,0px)}

/* -------------------------------------------------------------------- nav -- */
/* A printed running head, not a bar floating over a picture: paper, one hairline
   under it, and the dateline set in the instrument face. Nothing is translucent,
   blurred or shadowed; scrolling darkens the hairline and nothing else. */
#nav{background:var(--surface);border-bottom:1px solid transparent}
#nav.scrolled{border-bottom-color:var(--line)}
.nav-inner{gap:12px;flex-wrap:wrap}
.brand{display:inline-flex;align-items:center;gap:12px;text-decoration:none;
  color:var(--ink);min-height:44px}
.mark{display:inline-flex;align-items:center;justify-content:center;
  width:30px;height:30px;font-size:11.5px;font-weight:500;letter-spacing:.02em;
  color:var(--accent);border:1px solid var(--accent)}
.brandtype{font-family:var(--font-display);font-size:19px;font-weight:700;
  letter-spacing:-.028em;white-space:nowrap}
/* The shop's number, in the masthead, in the instrument face. It is the one thing
   a person looking at a barber's site at 6pm actually wants, and it is a link on
   a phone and a printed line on a desktop. Hidden below 940 because the drawer
   carries it there at thumb size. */
.navtel{display:none}
.navtoggle .bars{display:block;width:22px}
.navtoggle .bars i{display:block;height:1px;margin:6px 0;background:var(--ink)}
.navtoggle .bars i:nth-child(2){width:14px}
.nav-links{flex:1 0 100%;flex-direction:column;align-items:stretch;gap:0;
  width:100%;padding:4px 0 14px;margin-top:6px;border-top:var(--hair)}
.nav-links a{color:var(--ink-2);text-decoration:none;font-size:16px;font-weight:500;
  padding:11px 0;min-height:44px;display:flex;align-items:center;
  border-bottom:var(--hair)}
.nav-links a:hover{color:var(--accent)}
.drawlab{font-size:10.5px;letter-spacing:.18em;color:var(--accent);margin:10px 0 2px}
.drawhours{font-size:14px;color:var(--ink-2);margin:0 0 8px}
.drawtel{font-family:var(--font-mono);font-size:19px!important;color:var(--ink)!important}
.navcta{background:var(--accent);color:var(--accent-ink)!important;
  justify-content:center!important;border-bottom:0!important;margin-top:12px;
  font-family:var(--font-mono)!important;font-size:12.5px!important;font-weight:500;
  letter-spacing:.14em;text-transform:uppercase}
html.menu-open #nav{border-bottom-color:var(--line)}

@media(min-width:940px){
  .nav-inner{flex-wrap:nowrap;gap:26px}
  .navtel{display:inline-flex;align-items:center;min-height:44px;margin-left:auto;
    padding-right:26px;border-right:var(--hair);
    font-family:var(--font-mono);font-size:14px;letter-spacing:-.01em;
    color:var(--ink);text-decoration:none}
  .navtel:hover{color:var(--accent)}
  .nav-links{flex:0 0 auto;width:auto;padding:0;margin:0;border:0}
  .nav-links a{width:auto;padding:0;border-bottom:0;font-family:var(--font-mono);
    font-size:11.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-2)}
  /* two classes, not one: `.nav-links a` is (0,1,1) and beat a bare `.drawtel`
     (0,1,0), so the drawer's 19px telephone number printed in the desktop
     masthead. Found on the render, not in the file. */
  .nav-links .drawlab,.nav-links .drawhours,.nav-links .drawtel{display:none}
  .navcta{height:40px;margin-top:0;padding:0 18px!important;font-size:11.5px!important}
}

/* ------------------------------------------------------------------- hero -- */
.hero{background:var(--surface);padding-top:calc(var(--nav-h) + var(--tpl-h,0px) + 2px);
  padding-bottom:0}
/* The dateline is a DESKTOP running line. On a phone the address wrapped to two
   lines, collided with the kicker and stole 28px from the photograph — measured on
   the render. The phone gets the picture instead and the address is in the footer,
   the close and the schema. */
.dateline-row{display:none;justify-content:space-between;align-items:baseline;
  gap:16px;margin:0 0 6px;padding-bottom:6px;border-bottom:var(--hair)}
@media(min-width:700px){.dateline-row{display:flex}}
.dl-k{font-size:11px;letter-spacing:.18em;text-transform:uppercase;color:var(--accent);
  white-space:nowrap}
.dl-a{font-size:11px;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-3);
  text-align:right}
/* THE PHONE PLATE goes full bleed to the viewport edges while every other thing on
   the page keeps the gutter — the one place the measure is deliberately broken, and
   the reason the phone hero is its own composition rather than the desktop one
   shrunk. The statement block then cuts UP into it from below. No shadow, no radius
   and no border: it is a rectangle of the page removed from the picture. */
.heroplate{position:relative;margin:0 calc(var(--gutter) * -1)}
.heroplate picture{display:block}
.heroplate img{display:block;width:100%;aspect-ratio:1000 / 660;object-fit:cover;
  object-position:50% 46%}
/* the paper runs flush to the viewport edge on the left while the TYPE stays on the
   page's measure, so the block reads as cut in from the edge rather than floating
   with a hairline of photograph showing down its left side. */
.herosay{position:relative;background:var(--surface);margin-top:-68px;
  margin-left:calc(var(--gutter) * -1);padding:16px 20px 0 var(--gutter);
  max-width:none;width:calc(100% + var(--gutter))}
h1 .h1a{color:var(--ink)}
/* the mono runs wider and sits lower than Archivo, so it is set a step down to
   match it optically rather than metrically. */
h1 .h1b{font-family:var(--font-mono);font-style:normal;font-weight:500;
  font-size:.88em;color:var(--accent);letter-spacing:-.03em}
.herosay .lead{margin:14px 0 0;font-size:17px;line-height:1.5;max-width:46ch}
.herosay .btnrow{margin-top:18px}

@media(min-width:560px){.herosay .lead{font-size:18px}}
/* From 820 the plate and the statement share ONE grid cell. The block is punched
   into the picture — inset 60px from its top, 62% of the way across — so the
   daylight frames it above, to the right and below. The plate keeps its own aspect
   (DESIGN-FLOOR D2) and never stretches: if the block grows taller than the picture
   at a narrow desktop or with a long headline, it runs on past the bottom edge onto
   the paper, which is the phone treatment and is still one composition. */
@media(min-width:820px){
  .herotop{display:grid;grid-template-columns:1fr}
  .heroplate{grid-area:1 / 1;align-self:start;margin:0}
  .heroplate img{aspect-ratio:2400 / 1200}
  .herosay{grid-area:1 / 1;align-self:start;margin-top:44px;margin-left:0;
    width:min(680px,62%);max-width:none;padding:28px 40px 28px 0}
  .herosay .lead{margin-top:20px;font-size:19px;line-height:1.55}
  .herosay .btnrow{margin-top:24px}
}
@media(min-width:1180px){
  .herosay{margin-top:48px;padding:32px 46px 32px 0;width:min(720px,60%)}
  .close .wk-lg{--lane:32px}
}

/* ------------------------------------------------------------- THE CLOCK ---
   One lane per hours[] row, ruled into the client's own hours. --s and --e come
   from template.js; --ticks is the number of hours in the window it computed.
   A closed day is an EMPTY LANE. The lane is drawn only on a row the script
   resolved, so with no JavaScript this is a ruled two-column hours table. */
.wk{margin-top:20px;padding-top:12px;border-top:var(--hair-hard)}
.wkhead,.wrow{display:grid;grid-template-columns:1fr auto;column-gap:16px;row-gap:6px;
  align-items:center}
.wkhead{padding-bottom:6px}
.wklab{grid-column:1;font-size:10.5px;font-weight:500;letter-spacing:.18em;
  text-transform:uppercase;color:var(--ink-3)}
/* list-style:none — base.css only resets <ul>, and this <ol> printed "1. 8a
   2. 11a 3. 2p" straight down the middle of the clock on the deployed page. */
.wkscale{grid-column:1 / -1;grid-row:2;position:relative;height:14px;margin:2px 0 0;
  list-style:none;padding:0}
.wkscale:empty{display:none}
.wkscale li{position:absolute;top:0;left:calc(var(--p,0) * 100%);
  font-size:10px;font-weight:500;letter-spacing:.04em;color:var(--ink-3);
  padding-left:3px;white-space:nowrap}
.wkscale li.end{left:auto;right:0;padding:0 3px 0 0}
.wkrows{border-top:var(--hair)}
.wrow{padding:6px 0;border-bottom:var(--hair)}
.wd{grid-column:1;font-size:14.5px;font-weight:500;color:var(--ink)}
.wt{grid-column:2;justify-self:end;font-size:12px;letter-spacing:.04em;
  color:var(--ink-2);white-space:nowrap}
.wtrack{display:none;grid-column:1 / -1;grid-row:2;position:relative;
  height:var(--lane);border:var(--hair);background-color:var(--lane-bg);
  background-image:repeating-linear-gradient(90deg,var(--line) 0 1px,
    transparent 1px calc(100% / var(--ticks,8)))}
.wrow[data-open] .wtrack{display:block}
.wbar{position:absolute;top:0;bottom:0;left:calc(var(--s,0) * 100%);
  width:calc((var(--e,0) - var(--s,0)) * 100%);background:var(--accent)}
.wrow[data-open="0"] .wd{color:var(--ink-3)}
.wrow[data-open="0"] .wbar{display:none}

@media(min-width:760px){
  .wkhead,.wrow{grid-template-columns:180px 1fr 118px;row-gap:0}
  .wkscale{grid-column:2;grid-row:1;margin:0}
  .wtrack{grid-column:2;grid-row:1}
  .wt{grid-column:3}
  .wrow{padding:7px 0}
}
.wk-lg{--lane:28px;margin-top:30px;padding-top:18px}
.wk-lg .wd{font-size:15.5px}
.wk-lg .wrow{padding:10px 0}
@media(min-width:760px){.wk-lg .wrow{padding:9px 0}}

/* --------------------------------------------------- section furniture ------ */
/* base.css's mobile .sec is 64px; six of those put the phone page near the
   contract's 7,500px ceiling. Trimmed here, and the two desktop steps are restated
   because base's media queries sit EARLIER in the built file and would otherwise
   lose to this rule on equal specificity. */
.sec{padding:52px 0;background:var(--surface)}
@media(min-width:760px){.sec{padding:88px 0}}
@media(min-width:1180px){.sec{padding:110px 0}}
.shead,.fhead,.bhead,.ahead,.chead{max-width:820px}
.shead .h-lg,.fhead .h-lg,.bhead .h-lg,.chead .h-lg{margin-bottom:14px}
.shead .lead,.fhead .lead,.bhead .lead,.chead .lead{margin:0}

/* ------------------------------------------------- THE BOARD (paper, dense) --
   Rows on hairlines, no cards. The second axis is DRAWN: services[].tag measured
   against the longest job on the page, on a lane ruled to the same tick pattern as
   the clock, because it is the same instrument on a different kind of time. */
.rows{margin-top:28px;border-top:var(--hair-hard)}
.srow{display:grid;grid-template-columns:1fr auto;column-gap:18px;row-gap:6px;
  padding:16px 0;border-bottom:var(--hair)}
.sn{grid-column:1;grid-row:1;color:var(--ink);align-self:center}
.sp{grid-column:2;grid-row:1;font-family:var(--font-display);font-size:22px;
  font-weight:700;letter-spacing:-.03em;color:var(--ink);white-space:nowrap;
  font-variant-numeric:tabular-nums;align-self:center}
.sb{grid-column:1 / -1;grid-row:2;margin:0;font-size:14.5px;line-height:1.55;
  color:var(--ink-2);max-width:60ch}
.sm{grid-column:1 / -1;grid-row:3;display:flex;align-items:center;gap:12px;
  margin-top:4px}
.smlane{display:none;position:relative;flex:0 1 190px;height:8px;
  border:var(--hair);background-color:var(--surface-2);
  background-image:repeating-linear-gradient(90deg,var(--line) 0 1px,
    transparent 1px calc(100% / var(--ticks,4)))}
.sm[data-m] .smlane{display:block}
.smbar{position:absolute;top:0;bottom:0;left:0;width:calc(var(--m,1) * 100%);
  background:var(--accent)}
.smt{font-size:10.5px;font-weight:500;letter-spacing:.16em;text-transform:uppercase;
  color:var(--ink-3)}
.bfoot{margin:24px 0 0;font-size:14px;color:var(--ink-3);max-width:62ch}
.mgroup{margin-top:34px}
.mgh{font-size:10.5px;font-weight:500;letter-spacing:.18em;text-transform:uppercase;
  color:var(--accent);padding-bottom:9px;border-bottom:var(--hair-hard)}
.mrow{display:grid;grid-template-columns:1fr auto;column-gap:16px;padding:11px 0;
  border-bottom:var(--hair)}
.mn{color:var(--ink);font-weight:600;font-size:15px}
.mnote{grid-column:1;font-size:12px;letter-spacing:.04em;color:var(--ink-3)}
.mp{grid-column:2;grid-row:1 / span 2;align-self:center;font-family:var(--font-display);
  font-size:18px;font-weight:700;color:var(--ink);font-variant-numeric:tabular-nums}

@media(min-width:760px){
  .srow{grid-template-columns:1fr 230px 96px;column-gap:30px;row-gap:5px;padding:18px 0}
  .sn{font-size:20px}
  .sb{grid-column:1;grid-row:2;font-size:15px}
  .sm{grid-column:2;grid-row:1 / span 2;flex-direction:column;align-items:flex-start;
    justify-content:center;gap:8px;margin:0}
  .smlane{flex:0 0 auto;width:100%}
  .sp{grid-column:3;grid-row:1 / span 2;justify-self:end;font-size:26px}
}

/* ---------------------------------------------- THE FLOOR (the contact strip) --
   Full bleed and the four plates BUTT: no gutter, a 1px paper hairline between
   them, one aspect for all four. A contact strip, not a grid of cards. */
.floor .fhead{margin-bottom:30px}
.strip{display:grid;grid-template-columns:1fr 1fr;gap:1px;background:var(--surface);
  border-top:var(--hair-hard);border-bottom:var(--hair-hard);
  padding:1px 0;margin:0}
.plate{margin:0;background:var(--surface)}
.plate figcaption{display:flex;justify-content:space-between;align-items:baseline;
  gap:10px;padding:8px 10px 9px;border-top:var(--hair)}
.plate figcaption b{font-size:13px;font-weight:600;color:var(--ink);
  letter-spacing:-.01em}
.plate figcaption span{font-size:10px;font-weight:500;letter-spacing:.12em;
  text-transform:uppercase;color:var(--ink-3);white-space:nowrap}
.facts{margin-top:36px;border-top:var(--hair-hard)}
.fact{display:grid;grid-template-columns:34px 1fr;column-gap:14px;padding:16px 0;
  border-bottom:var(--hair)}
.fnum{grid-row:1 / span 2;font-size:11px;font-weight:500;letter-spacing:.1em;
  color:var(--accent);padding-top:4px}
.fact h3{color:var(--ink)}
.fact p{margin:5px 0 0;font-size:14.5px;color:var(--ink-2);max-width:60ch}

@media(min-width:760px){
  .strip{grid-template-columns:repeat(4,1fr)}
  .plate figcaption{padding:10px 14px 11px}
  .facts{display:grid;grid-template-columns:repeat(3,1fr);column-gap:30px;margin-top:52px}
  .fact{border-bottom:0;border-right:var(--hair);padding:18px 24px 4px 0}
  .fact:last-child{border-right:0}
}

/* ------------------------------------------------ THE INK BAND (the breath) --
   The one dark surface on the page and the only change of paper. A ruled register,
   not three cards. Flat ink against flat paper; nothing fades between them. */
.band{background:var(--band);color:var(--band-ink)}
.band h2,.band h3{color:var(--band-ink)}
.band .lead{color:var(--band-ink-2)}
.reg{margin-top:30px;border-top:1px solid rgba(239,237,230,.28)}
.regrow{display:grid;grid-template-columns:34px 1fr;column-gap:14px;padding:18px 0;
  border-bottom:1px solid rgba(239,237,230,.18)}
.rn{grid-row:1 / span 2;font-size:11px;font-weight:500;letter-spacing:.1em;
  color:var(--accent-on-band);padding-top:4px}
.regrow p{margin:6px 0 0;font-size:15px;line-height:1.6;color:var(--band-ink-2);
  max-width:70ch}
/* the quote block draws its own rule, so the register must not draw a second one
   26px above it -- two hairlines with a gap between them, seen on the render. */
.regrow:last-child{border-bottom:0}
.qt{margin:34px 0 0;padding-top:26px;border-top:1px solid rgba(239,237,230,.28)}
.qt blockquote{margin:0;font-family:var(--font-display);font-weight:600;
  font-size:clamp(19px,2.2vw,27px);line-height:1.36;letter-spacing:-.022em;
  color:var(--band-ink);max-width:34ch}
.qt figcaption{margin-top:16px;font-family:var(--font-mono);font-size:10.5px;
  font-weight:500;letter-spacing:.16em;text-transform:uppercase;
  color:var(--accent-on-band)}

@media(min-width:760px){
  .reg{margin-top:44px}
  .regrow{grid-template-columns:56px 300px 1fr;column-gap:30px;align-items:baseline}
  .regrow h3{grid-column:2;font-size:19px}
  .regrow p{grid-column:3;margin:0}
  .rn{grid-row:1}
  .qt{margin-top:52px;display:grid;grid-template-columns:1fr 220px;
    column-gap:40px;align-items:end}
  .qt blockquote{max-width:44ch}
  .qt figcaption{margin:0;text-align:right}
}

/* -------------------------------------------------- WHAT PEOPLE ASK ---------- */
.asks{background:var(--surface)}
.asklist{margin-top:20px;border-top:var(--hair-hard)}
.ask{border-bottom:var(--hair)}
.ask summary{display:flex;align-items:center;justify-content:space-between;gap:18px;
  padding:15px 0;min-height:54px;cursor:pointer;list-style:none;
  font-weight:600;font-size:15.5px;color:var(--ink)}
.ask summary::-webkit-details-marker{display:none}
.ask summary:hover{color:var(--accent)}
.ask summary i{flex:0 0 auto;width:11px;height:11px;position:relative}
.ask summary i::before,.ask summary i::after{content:"";position:absolute;
  background:var(--accent)}
.ask summary i::before{left:0;top:5px;width:11px;height:1px}
.ask summary i::after{left:5px;top:0;width:1px;height:11px}
.ask[open] summary i::after{opacity:0}
.ask p{margin:0;padding:0 0 18px;font-size:14.5px;line-height:1.62;color:var(--ink-2);
  max-width:66ch}
.askcall{margin:14px 0 0;font-size:14px;line-height:1.6;color:var(--ink-3);max-width:36ch}
.askcall a{display:inline-flex;align-items:center;min-height:44px;
  font-family:var(--font-mono);font-size:19px;color:var(--ink);text-decoration:none}
.askcall a:hover{color:var(--accent)}
/* A narrow column beside its own heading from 900px. Run full width, four short
   rows across a 1144px measure is restraint that reads as unfinished, which is a
   D5 deduction rather than minimalism. */
@media(min-width:900px){
  .asks .container{display:grid;grid-template-columns:.8fr 1.2fr;column-gap:60px;
    align-items:start}
  .asklist{margin-top:0}
}

/* --------------------------------------------------------- THE COUNTER ------ */
.close{background:var(--surface-2);--lane-bg:var(--surface)}
.close .wk-lg{margin-top:34px}
.cgrid{display:grid;gap:34px;margin-top:38px}
.crow{display:flex;flex-direction:column;gap:4px}
.cbig{display:inline-flex;align-items:center;min-height:44px;align-self:flex-start;
  font-family:var(--font-mono);font-size:clamp(18px,2.2vw,22px);color:var(--ink);
  text-decoration:none;letter-spacing:-.01em;border-bottom:1px solid transparent}
.cbig:hover{color:var(--accent);border-bottom-color:var(--accent)}
.crow address{font-style:normal;font-size:14px;color:var(--ink-3);margin-top:6px}
.area{margin-top:24px;padding-top:18px;border-top:var(--hair)}
.area h3{color:var(--ink)}
.area p{margin:7px 0 0;font-size:14.5px;color:var(--ink-2)}
.towns{display:flex;flex-wrap:wrap;gap:6px}
.towns span{font-size:11px;letter-spacing:.1em;text-transform:uppercase;
  color:var(--ink-3);padding:5px 9px;border:var(--hair)}
.formpanel{background:var(--surface);border:var(--hair-hard);padding:22px 20px}
.field label{font-size:10.5px;font-weight:500;letter-spacing:.16em;color:var(--ink-3)}
.field input,.field select,.field textarea{background:var(--surface);
  border-color:var(--line);color:var(--ink)}
.field input:focus,.field select:focus,.field textarea:focus{border-color:var(--accent)}
.fineprint{margin:14px 0 0;font-size:12.5px;line-height:1.55;color:var(--ink-3)}
.thanks{background:var(--surface);border:var(--hair-hard);border-radius:0}
.thanks h3{font-family:var(--font-display);font-size:23px;color:var(--ink)}
.thanks p{margin:0;color:var(--ink-2)}
@media(min-width:900px){
  .cgrid{grid-template-columns:.82fr 1.18fr;column-gap:56px;align-items:start}
  .formpanel{padding:30px 28px}
}
@media(min-width:1180px){
  .cgrid{grid-template-columns:.78fr 1.22fr;column-gap:72px}
}

/* ----------------------------------------------------------------- BUTTONS -- */
.btn{border-radius:0;letter-spacing:.02em;font-family:var(--font-mono);
  font-size:12.5px;font-weight:500;text-transform:uppercase;letter-spacing:.14em;
  padding:15px 24px}
.btn-primary{background:var(--accent);border-color:var(--accent);color:var(--accent-ink)}
.btn-primary:hover{background:var(--accent-2);border-color:var(--accent-2)}
.btn-ghost{background:transparent;color:var(--ink);border-color:var(--ink)}
.btn-ghost:hover{color:var(--accent);border-color:var(--accent)}

/* ------------------------------------------------------------------ FOOTER -- */
footer{background:var(--surface-2);border-top:var(--hair-hard);padding:44px 0 26px}
.fgrid{display:grid;gap:30px}
.mark.big{width:40px;height:40px;font-size:14px}
.fname{font-family:var(--font-display);font-size:21px;font-weight:700;
  letter-spacing:-.028em;color:var(--ink);margin:14px 0 6px}
.fabout{margin:0;font-size:14px;color:var(--ink-2);max-width:44ch}
.fh{font-size:10.5px;font-weight:500;letter-spacing:.18em;text-transform:uppercase;
  color:var(--accent);margin-bottom:10px;padding-bottom:8px;border-bottom:var(--hair)}
.fcol{display:flex;flex-direction:column;gap:4px}
.fcol a,.fplain{color:var(--ink-2);font-size:14px;text-decoration:none}
.fcol a{display:inline-flex;align-items:center;min-height:44px}
.fcol a:hover{color:var(--accent)}
.fcol address{font-style:normal;font-size:14px;color:var(--ink-3)}
.fnav{display:flex;flex-wrap:wrap;gap:6px 26px;margin-top:32px;padding-top:16px;
  border-top:var(--hair)}
.fnav a{display:inline-flex;align-items:center;min-height:44px;
  font-family:var(--font-mono);font-size:11px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--ink-3)}
.fnav a:hover{color:var(--accent)}
.fbase{display:flex;flex-wrap:wrap;justify-content:space-between;gap:8px 24px;
  margin-top:18px;font-size:12.5px;color:var(--ink-3)}
.credit a{color:var(--ink-2)}
@media(min-width:760px){
  .fgrid{grid-template-columns:1.6fr 1fr 1fr;gap:40px}
  .fcol a,.fnav a{min-height:26px}
  footer{padding:64px 0 30px}
}

/* --------------------------------------------------------------------- 404 -- */
.nf{padding-top:calc(var(--nav-h) + var(--tpl-h,0px) + 52px)}
.nfgrid{display:grid;gap:32px;align-items:start}
/* .h-lg tops out at 42px, which is 2.47x a 17px body — DESIGN-FLOOR C2 wants 2.5,
   and the 404 failed it at 1440 on the render while the homepage passed. The 404
   gets its own step so it clears at 390 as well as at 2560. */
.nf h1{font-size:clamp(44px,4.4vw,54px);line-height:1.04;letter-spacing:-.03em;
  margin-bottom:0}
.nfsay .lead{margin:16px 0 26px}
.nfline{display:flex;flex-direction:column;gap:4px;margin:26px 0 0;padding-top:16px;
  border-top:var(--hair-hard)}
.nfline span{font-size:14px;color:var(--ink-3)}
/* On the phone the 404's picture is a SMALL PRINT, not a backdrop. At full width it
   is a full-bleed image with the headline stacked above it and sliced by the fold —
   DESIGN-FLOOR A1 and A2, both measured failing on the deployed page. At 190px it is
   an object sitting on the paper and neither rule applies to it. */
.nfplate{margin:0 0 0 auto;max-width:190px}
@media(min-width:860px){
  .nf{padding-top:calc(var(--nav-h) + var(--tpl-h,0px) + 72px)}
  .nfgrid{grid-template-columns:1.1fr .9fr;column-gap:56px}
  .nfplate{max-width:none;margin:0}
}

/* ------------------------------------------------------------------ MOTION --
   Two moments and they say the same thing the layout says.
   1. every clock lane DRAWS from its opening time when the section arrives —
      the shop's week filling in, left to right, one row after another;
   2. every duration measure on the board draws the same way, because it is the
      same instrument.
   Both are gated behind html.js, which the head script only sets when the visitor
   has NOT asked for reduced motion, and base.css neutralises the reveal entirely
   in that case. The clock itself is drawn by template.js with no such gate, so a
   reduced-motion visitor gets the whole instrument, just not the sweep. */
@keyframes opendraw{from{transform:scaleX(0)}to{transform:scaleX(1)}}
html.js .reveal.in .wbar,html.js .reveal.in .smbar{transform-origin:left center;
  animation:opendraw .7s cubic-bezier(.22,.61,.36,1) both}
html.js .reveal.in .wrow:nth-child(2) .wbar{animation-delay:.10s}
html.js .reveal.in .wrow:nth-child(3) .wbar{animation-delay:.20s}
html.js .reveal.in .wrow:nth-child(4) .wbar{animation-delay:.30s}
html.js .reveal.in .wrow:nth-child(5) .wbar{animation-delay:.40s}
html.js .reveal.in .wrow:nth-child(6) .wbar{animation-delay:.50s}
html.js .reveal.in .wrow:nth-child(7) .wbar{animation-delay:.60s}
html.js .reveal.in .srow:nth-child(2) .smbar{animation-delay:.06s}
html.js .reveal.in .srow:nth-child(3) .smbar{animation-delay:.12s}
html.js .reveal.in .srow:nth-child(4) .smbar{animation-delay:.18s}
html.js .reveal.in .srow:nth-child(5) .smbar{animation-delay:.24s}
html.js .reveal.in .srow:nth-child(6) .smbar{animation-delay:.30s}
@media(prefers-reduced-motion:reduce){
  html.js .reveal.in .wbar,html.js .reveal.in .smbar{animation:none;transform:none}
}
