/* Iron Peak Construction — Salt Lake City residential construction & remodeling
   Palette from the logo, per intake.md. Structure per design-brief.md:
   black is an ANCHOR (header, hero, CTA band, footer), never the field. Reading happens on a
   near-white surface, which is what 18 of the 21 researched companies do.

   Contrast, measured, all pairings used below:
     #1A1A1A on #F7F6F5   15.8:1   body copy, the light field            AA + AAA
     #D5D3D2 on #000000   13.9:1   body copy on the dark bands           AA + AAA
     #817F7E on #000000    5.6:1   muted detail on dark, never primary   AA
     #9C753C on #000000    4.3:1   BELOW AA for normal text - headings, rules, icons ONLY
     #FFFFFF on #9C753C    4.0:1   large button label only (>=18.66px bold => 3:1 floor)  AA large
     #FFFFFF on #7A5A2C    5.3:1   the darker brass actually used for button fills        AA
   Brass never carries body copy anywhere on this site. */

/* ---------- self-hosted faces, latin subset, preloaded before this file ---------- */
@font-face{font-family:'Barlow Condensed';font-style:normal;font-weight:700;font-display:swap;
  src:url('fonts/barlow-condensed-700.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:'Barlow';font-style:normal;font-weight:400;font-display:swap;
  src:url('fonts/barlow-400.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:'Barlow';font-style:normal;font-weight:500;font-display:swap;
  src:url('fonts/barlow-500.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:'Barlow';font-style:normal;font-weight:600;font-display:swap;
  src:url('fonts/barlow-600.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}

:root{
  --black:#000000;
  --ink:#1A1A1A;              /* body on the light field, 15.8:1 */
  --ink-2:#4A4846;            /* muted on the light field, 8.1:1 */
  --steel:#817F7E;            /* muted on dark only */
  --steel-hi:#D5D3D2;         /* body on dark */
  --brass:#9C753C;            /* accents, headings, rules - never body */
  --brass-deep:#7A5A2C;       /* button fill: white on this is 5.3:1 */
  --brass-text:#6B4F26;       /* brass for TEXT on the light field, 6.9:1 */
  --brass-lite:#C79A58;       /* brass on the LIGHT field would fail, so this is dark-band only */
  --brass-onphoto:#E3BE8B;    /* one step lighter again, for brass over the blurred hero photo */
  /* Mid brass. Was the CTA band colour in round 8; now it only dresses the sixth services
     tile, which is not a CTA section and was not part of the darkening. */
  --brass-mid:#8A6733;
  /* CTA bands: the dark end of the logo's bronze. Taken by holding the logo brass's exact
     hue (35.6deg) and saturation (44%) and walking lightness down to 12%, so it is the same
     colour as the logo rather than a brown mixed to look like it. 1.33:1 from pure black -
     close to black as asked - while 44 33 17 keeps 27 points of channel spread, which is
     what stops it reading as a neutral charcoal. Below about 8% lightness that spread
     collapses and the colour does go neutral, so this is near the floor of 'still brown'. */
  --cta-dark:#2C2111;
  --field:#F7F6F5;            /* the near-white reading surface */
  --white:#FFFFFF;
  --line:#DEDBD8;
  --cond:"Barlow Condensed","Arial Narrow",Arial,sans-serif;
  --sans:"Barlow","Helvetica Neue",Arial,sans-serif;
  --header-h:66px;
  --max:1180px;
  --gutter:20px;
  --shadow:0 14px 34px rgba(0,0,0,.10);
  --shadow-lift:0 22px 48px rgba(0,0,0,.16);
  --ease:cubic-bezier(.22,.61,.36,1);
}
@media(min-width:900px){:root{--header-h:88px;--gutter:40px}}

*,*::before,*::after{box-sizing:border-box}
html{scroll-behavior:smooth;-webkit-text-size-adjust:100%;overflow-x:clip;background:var(--field)}
body{margin:0;overflow-x:clip;background:var(--field);color:var(--ink);
  font-family:var(--sans);font-size:1.0625rem;line-height:1.62;font-weight:400;
  -webkit-font-smoothing:antialiased}
img,svg,iframe{max-width:100%;display:block}
img{height:auto}
a{color:#6B4F26;text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:3px}
/* A generic a:hover out-specifies a button's own class colour, and iOS keeps a sticky hover after
   a tap, so a tapped button can repaint its label to its own fill and vanish. Buttons excluded. */
@media(hover:hover){a:not(.btn):not(.chip):hover{color:var(--black)}}
main p a:not(.btn),main li a:not(.btn),main address a,.form-note a{padding:10px 3px;margin:0 -3px}
:focus-visible{outline:3px solid var(--brass);outline-offset:3px;border-radius:2px}
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0,0,0,0);white-space:nowrap;border:0}
.skip{position:absolute;left:12px;top:-64px;z-index:200;background:var(--brass-deep);
  color:var(--white);padding:10px 16px;text-decoration:none;transition:transform .2s var(--ease)}
.skip:focus{top:12px}

/* ---------- type ---------- */
h1,h2,h3,h4{font-family:var(--cond);font-weight:700;line-height:1.06;color:var(--ink);
  margin:0 0 .45em;letter-spacing:.005em}
h1{font-size:clamp(2.3rem,6.2vw,4.1rem)}
h2{font-size:clamp(1.85rem,4vw,2.9rem)}
h3{font-size:clamp(1.3rem,2.3vw,1.7rem)}
p{margin:0 0 1.05em}
.lede{font-size:1.16rem;line-height:1.58;color:var(--ink-2)}
.lede--sm{font-size:1rem}
.fine{font-size:.92rem;color:var(--ink-2)}
/* 12px is body size, so this needs 4.5:1, and brass #9C753C on the light field is 3.87:1 -
   the intake's 4.3:1 was measured on black, where the same brass fares BETTER than it does
   here. --brass-text is the same hue taken deeper until it passes: 6.9:1 on the field.
   On the dark bands .band-dark .eyebrow overrides this with --brass-lite. */
.eyebrow{font-family:var(--sans);font-size:.75rem;letter-spacing:.17em;text-transform:uppercase;
  font-weight:600;color:var(--brass-text);margin:0 0 12px}
.measure{max-width:64ch}
.center{text-align:center}
.center .measure{margin-inline:auto}
.mt-8{margin-top:8px}.mt-16{margin-top:16px}.mt-24{margin-top:24px}.mt-32{margin-top:32px}
.mt-40{margin-top:40px}.mb-32{margin-bottom:32px}

/* ---------- layout ---------- */
.wrap{width:100%;max-width:var(--max);margin-inline:auto;padding-inline:var(--gutter)}
/* the trust strip supplies its own cell padding, so the wrap must not add a gutter */
.wrap--flush{padding-inline:0}
.section{padding:58px 0}
@media(min-width:900px){.section{padding:92px 0}}
.section--tight{padding-block:40px}
@media(min-width:900px){.section--tight{padding-block:64px}}
.band-dark{background:var(--black);color:var(--steel-hi)}
.band-dark h1,.band-dark h2,.band-dark h3{color:var(--white)}
.band-dark .eyebrow{color:var(--brass-lite)}
.band-dark .lede{color:var(--steel-hi)}
/* --brass-text exists to pass on the LIGHT field; on black it is 2.77:1. Dark bands need
   the lighter brass, which is 6.4:1 here. */
.band-dark a:not(.btn){color:var(--brass-lite)}
@media(hover:hover){.band-dark a:not(.btn):hover{color:var(--white)}}
.band-white{background:var(--white)}

/* ---------- header ---------- */
.site-header{position:sticky;top:0;z-index:100;background:var(--black);
  border-bottom:1px solid rgba(156,117,60,.38)}
/* The header runs wider than the 1180 content column and spreads: logo hard left, CTA hard
   right, nav links sharing the space between them. */
.header-inner{width:100%;max-width:1420px;margin-inline:auto;padding-inline:var(--gutter);
  min-height:var(--header-h);display:flex;align-items:center;gap:18px;
  justify-content:space-between}
/* the mobile logo is 43px, so the link it sits in came out 1px short of the 44px target */
.brand{display:inline-flex;align-items:center;gap:11px;text-decoration:none;flex:none;
  min-height:44px}
.brand img{height:43px;width:43px;border-radius:3px}
@media(min-width:900px){.brand img{height:72px;width:72px}}
.brand-name{font-family:var(--cond);font-weight:700;font-size:1.28rem;line-height:1;
  color:var(--white);letter-spacing:.01em}
.brand-name small{display:block;font-family:var(--sans);font-weight:500;font-size:.62rem;
  letter-spacing:.15em;text-transform:uppercase;color:var(--brass-lite);margin-top:4px}
@media(min-width:900px){.brand-name{font-size:1.55rem}.brand-name small{font-size:.66rem}}
.site-nav{margin-left:auto}
@media(min-width:1000px){
  /* The nav takes the whole span between the logo and the phone number and distributes the five
     items across it. space-between on the ul rather than a gap, so the spread grows with the
     window instead of leaving the items clustered in the middle of an over-wide nav. */
  .site-nav{flex:1 1 auto;margin-inline:32px;display:flex}
  .site-nav > ul{flex:1;justify-content:space-between;gap:0}
  /* The pill is scaled with the type: taller box and real horizontal padding, so the active
     indicator frames the word instead of hugging it at the new size. */
  .site-nav > ul > li > a,.site-nav > ul > li > .sub-row > a{padding:0 17px;min-height:48px}
}
.site-nav > ul{list-style:none;margin:0;padding:0;display:flex;align-items:center;gap:2px}
.site-nav a:not(.btn){display:inline-flex;align-items:center;min-height:44px;padding:0 11px;
  font-family:var(--sans);font-size:1.06rem;font-weight:500;color:var(--steel-hi);
  text-decoration:none;border-radius:999px;white-space:nowrap}
@media(hover:hover){.site-nav a:not(.btn):hover{color:var(--white);background:rgba(255,255,255,.08)}}
.site-nav a:not(.btn)[aria-current="page"]{background:rgba(156,117,60,.24);color:var(--white)}
/* min-width matters as much as min-height: the mobile variant is icon-only, so height alone
   left it 37px wide. A tap target has two dimensions. */
.hdr-call{display:inline-flex;align-items:center;justify-content:center;gap:7px;min-height:44px;
  min-width:44px;padding:0 10px;font-weight:600;font-size:.96rem;color:var(--brass-lite);
  text-decoration:none;white-space:nowrap}
@media(hover:hover){.hdr-call:hover{color:var(--white)}}
.hdr-call svg{width:17px;height:17px;flex:none}
.hdr-cta{flex:none}
.nav-toggle{display:inline-flex;flex-direction:column;justify-content:center;gap:5px;
  width:46px;height:46px;margin-left:auto;background:none;border:0;cursor:pointer;padding:0}
.nav-toggle .bar{display:block;width:24px;height:2px;background:var(--steel-hi);margin-inline:auto;
  transition:transform .25s var(--ease),opacity .2s var(--ease)}
.nav-toggle[aria-expanded="true"] .bar:nth-child(1){transform:translateY(7px) rotate(45deg)}
.nav-toggle[aria-expanded="true"] .bar:nth-child(2){opacity:0}
.nav-toggle[aria-expanded="true"] .bar:nth-child(3){transform:translateY(-7px) rotate(-45deg)}
@media(min-width:1000px){.nav-toggle{display:none}}
@media(max-width:999px){
  .site-nav{position:fixed;inset:var(--header-h) 0 0 0;background:var(--black);margin:0;
    padding:26px var(--gutter) 40px;overflow-y:auto;transform:translateX(100%);opacity:0;
    visibility:hidden;transition:transform .3s var(--ease),opacity .3s var(--ease),
    visibility 0s linear .3s}
  .site-nav[data-open="true"]{transform:none;opacity:1;visibility:visible;transition-delay:0s}
  .site-nav > ul{flex-direction:column;align-items:stretch;gap:2px}
  .site-nav a{min-height:54px;font-size:1.12rem;padding:0 14px;border-radius:4px}
  /* .btn{display:inline-flex} is declared later with equal specificity, so this needs the
     extra class to win on specificity rather than on source order. */
  .site-header .hdr-cta,.site-header .hdr-call--desk{display:none}
  .site-nav .btn{margin-top:18px;width:100%}
}
/* The drawer carries its own CTA so the mobile menu ends with one. At desktop the drawer is
   just the nav row, so that copy has to go or the header shows the button twice and wraps to
   a second row - measured at 94px tall with two buttons on different baselines. */
@media(min-width:1000px){.hdr-call--mob{display:none}.site-nav > .btn{display:none}}

/* ---------- buttons ---------- */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:9px;min-height:50px;
  padding:0 26px;border-radius:999px;font-family:var(--sans);font-size:.92rem;font-weight:600;
  letter-spacing:.03em;text-decoration:none;border:2px solid transparent;cursor:pointer;
  white-space:nowrap;transition:transform .18s var(--ease),background-color .18s var(--ease)}
.btn svg{width:17px;height:17px;flex:none}
.btn-primary{background:var(--brass-deep);color:var(--white);border-color:var(--brass-deep)}
/* On the photo hero the brass fill and the darkened photograph are both near-black, so the
   button needs a boundary that is not its fill. The 2px border already exists on .btn; here
   it carries the light on-photo brass instead of matching the fill. Measured 10.5:1 against
   the photo, against 2.91:1 for the fill it replaces. The fill and label are unchanged. */
.hero--img .btn-primary{border-color:var(--brass-onphoto)}
@media(hover:hover){.btn-primary:hover{background:#8C6832;border-color:#8C6832;color:var(--white);
  transform:translateY(-2px)}}
.btn-ghost{background:transparent;color:var(--white);border-color:rgba(213,211,210,.55)}
@media(hover:hover){.btn-ghost:hover{background:rgba(255,255,255,.1);color:var(--white);
  transform:translateY(-2px)}}
.btn-dark{background:var(--ink);color:var(--white);border-color:var(--ink)}
@media(hover:hover){.btn-dark:hover{background:#000;border-color:#000;color:var(--white);
  transform:translateY(-2px)}}
/* Safari/iOS paint a disabled button's label with a system colour that overrides the author's,
   so a white label on a brass fill disappears entirely. Chrome never shows this. */
.btn:disabled{opacity:.72;cursor:default;transform:none;
  color:var(--white);-webkit-text-fill-color:var(--white)}
.btn-row{display:flex;flex-wrap:wrap;gap:13px}
.btn-row--center{justify-content:center}

/* ---------- hero ---------- */
/* No photo. Every job photo is 206px square, so there is no hero-capable source in the set - see
   design-brief.md section 5. The LCP element is the H1, which is text. */
.hero{background:var(--black);color:var(--steel-hi);padding:56px 0 52px;position:relative;
  border-bottom:3px solid var(--brass)}
@media(min-width:900px){.hero{padding:96px 0 84px}}
.hero::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(120% 90% at 50% 0%,rgba(156,117,60,.16),transparent 62%)}
.hero .wrap{position:relative;z-index:1}
.hero h1{color:var(--white);max-width:16ch}
/* The service line is regular, the location line heavy - never all-caps condensed heavy for the
   whole headline, per build-prompt STEP 5. */
.hero h1 .h1-svc{display:block;font-family:var(--sans);font-weight:400;
  font-size:clamp(1.2rem,2.7vw,1.75rem);letter-spacing:.02em;color:var(--steel-hi);
  margin-bottom:12px;line-height:1.3}
.hero .lede{max-width:52ch;color:var(--steel-hi)}
.hero-cta{margin-top:30px}

/* trust chips — only credentials the intake confirms */
.chips{list-style:none;margin:30px 0 0;padding:0;display:flex;flex-wrap:wrap;gap:10px}
.chip{display:inline-flex;align-items:center;gap:8px;padding:9px 15px;border-radius:999px;
  border:1px solid rgba(156,117,60,.5);background:rgba(156,117,60,.1);
  font-size:.88rem;font-weight:600;color:var(--steel-hi)}
.chip svg{width:15px;height:15px;color:var(--brass-lite);flex:none}

/* A service page is not the home page: its hero is a heading section. Padding is halved, the
   H1 comes down a step so it stops wrapping to three lines, and the trust chips come off - they
   appear verbatim further down the same page in the estimate section's .facts list, so nothing
   is lost, only repeated less. The call and estimate buttons stay: every site in the research
   keeps a CTA above the fold. */
/* The three longest H1s ("Drywall Hanging and Repair in Salt Lake City, Utah" and friends) were
   wrapping one line more than the short ones, which is where the 55-58% cases came from. A
   slightly smaller floor on the clamp lets all six wrap the same way. */
.hero--page{padding:18px 0 20px}
@media(min-width:900px){.hero--page{padding:30px 0 30px}}
.hero--page h1{font-size:clamp(1.52rem,3.1vw,2.35rem);max-width:28ch;margin-bottom:.28em}
.hero--page .h1-svc{font-size:clamp(.95rem,1.7vw,1.1rem);margin-bottom:6px}
.hero--page .lede{font-size:1.02rem;max-width:58ch;margin-bottom:0}
.hero--page .hero-cta{margin-top:18px}
.hero--page .chips{display:none}
/* With the lede, chips and buttons gone, the H1 is the only thing in the band - so it can
   carry more size and air than it could when it was sharing the space. Still a heading
   section rather than a hero: no photo, no CTA, nothing beneath it. */
.hero--bare{padding:38px 0 36px}
@media(min-width:900px){.hero--bare{padding:62px 0 58px}}
.hero--bare h1{font-size:clamp(2rem,4.5vw,3.35rem);max-width:24ch;margin-bottom:0}


/* ---------- Our Services: 80vh blurred photo hero ----------
   The source is 206x206, which would be unusable stretched full-bleed - but a heavy blur is
   exactly the treatment that makes a low-resolution source work, because there is no detail left
   to be soft. scale(1.2) pushes the blurred edges off screen, where blur otherwise shows a
   feathered border.

   Contrast is not left to chance: the image is darkened by a brightness filter AND a scrim, and
   the resulting pixels behind the text are sampled and measured rather than assumed. */
.hero--photo{position:relative;min-height:80vh;display:flex;align-items:center;
  padding:48px 0;overflow:hidden;background:var(--black);border-bottom:3px solid var(--brass)}
.hero-bg{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;z-index:0;
  /* 26 -> 12 -> 2px. 2px is the floor set by the SOURCE, not by contrast: at 0 and 1px the
     206px original upscaled ~7x shows hard square blocks along every high-contrast edge, and
     2px is the first step where those disappear while the room stays fully readable. I
     rendered the ladder 0/1/2/3/4/6/9/12 and looked at it rather than picking a number.
     The global brightness crush is gone with it - darkening the whole photograph to protect
     text that occupies the left half was the thing making it read as flat colour. */
  filter:blur(2px) saturate(1.02);transform:scale(1.06)}
/* The contrast now lives here and only here. Mobile takes an even veil because at 375 the
   text spans the full width; desktop angles it so the half carrying the H1, lede and the
   stacked service list is protected and the other half is left as a photograph. */
.hero-scrim{position:absolute;inset:0;z-index:1;
  background:linear-gradient(180deg,rgba(0,0,0,.69) 0%,rgba(0,0,0,.61) 50%,rgba(0,0,0,.74) 100%)}
/* the last two stops sit beyond the text column, so opening them costs no contrast and is
   where the photograph actually becomes a photograph - re-measured after, not before */
@media(min-width:900px){.hero-scrim{background:
  linear-gradient(100deg,rgba(0,0,0,.9) 0%,rgba(0,0,0,.84) 38%,rgba(0,0,0,.38) 68%,
  rgba(0,0,0,.08) 100%)}}
.hero--photo > .wrap{position:relative;z-index:2;width:100%}
.hero--photo h1{color:var(--white);font-size:clamp(2.6rem,7vw,4.6rem);margin-bottom:.18em}
/* white rather than --steel-hi: the lede sets the ceiling on how bright the photograph is
   allowed to be, and white is worth roughly 1.5x the ratio of #D5D3D2 on the same pixels.
   Scoped .hero--photo .hero-photo-lede, not .hero-photo-lede alone: the element carries both
   .lede and .hero-photo-lede, and .hero .lede is two classes to this one's one, so the bare
   modifier lost and the lede kept rendering #D5D3D2. Measured, not assumed - the first run
   of this change reported the colour it actually had rather than the one I had written. */
.hero--photo .hero-photo-lede{color:#FFFFFF;max-width:46ch;margin-bottom:0}

.hero-svc{list-style:none;margin:30px 0 0;padding:0;display:grid;gap:0;
  border-top:1px solid rgba(213,211,210,.26)}
/* stacked, left-aligned, half width - not a two-column grid */
@media(min-width:820px){.hero-svc--stack{grid-template-columns:minmax(0,1fr);max-width:560px}}
.hero-svc li{border-bottom:1px solid rgba(213,211,210,.26)}

.hero-svc a{display:flex;align-items:center;gap:14px;min-height:58px;text-decoration:none;
  color:var(--white);font-family:var(--cond);font-weight:700;
  font-size:clamp(1.25rem,2.3vw,1.6rem);line-height:1.1;
  transition:padding-left .18s var(--ease)}
@media(hover:hover){.hero-svc a:hover{padding-left:10px;color:var(--brass-onphoto)}}
.hero-svc .n{font-family:var(--sans);font-size:.72rem;font-weight:600;letter-spacing:.12em;
  color:var(--brass-onphoto);flex:none;width:26px}
.hero-svc .t{flex:1;min-width:0}
.hero-svc .go{flex:none;width:26px;height:26px;display:grid;place-items:center;
  color:var(--brass-onphoto)}
.hero-svc .go svg{width:18px;height:18px;transition:transform .18s var(--ease)}
@media(hover:hover){.hero-svc a:hover .go svg{transform:translateX(4px)}}
@media(prefers-reduced-motion:reduce){.hero-svc a,.hero-svc .go svg{transition:none}}


/* ---------- home hero photograph ----------
   Every supplied photo is 206x206 and a full-bleed hero is roughly a 7x upscale, so some
   blur is forced by the asset. 2px is the floor: below it the upscale shows hard square
   blocks along the window frames. Above it nothing is gained. Ladder rendered and inspected
   at 0/1/2/3/4/6/9/12 rather than the number being guessed.
   The scrim is angled and heavier on the left than the Our Services one because this
   photograph has bright sky in its upper right, and the H1, lede and both buttons all sit on
   the left. Measured after the fact against real pixels, not assumed. */
.hero--img{overflow:hidden;background:var(--black)}
.hero--img .hero-bg{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  z-index:0;filter:blur(2px) saturate(1.04);transform:scale(1.06)}
/* mobile first: an even veil, because at 375 the text covers the whole hero and there is no
   empty side to open up */
.hero--img .hero-scrim{position:absolute;inset:0;z-index:1;background:
  linear-gradient(180deg,rgba(0,0,0,.66) 0%,rgba(0,0,0,.56) 50%,rgba(0,0,0,.72) 100%)}
/* desktop: the text sits in the left half, so the scrim is angled and the right half is left
   open for the photograph to actually read as one */
@media(min-width:900px){.hero--img .hero-scrim{background:
  linear-gradient(100deg,rgba(0,0,0,.9) 0%,rgba(0,0,0,.84) 36%,rgba(0,0,0,.38) 66%,
  rgba(0,0,0,.08) 100%)}}
/* white, not --steel-hi: the lede is the binding constraint on how light the photo can go,
   and white is worth roughly a 1.5x ratio over #D5D3D2 on the same field */
.hero--img .lede{color:#FFFFFF}
.hero--img > .wrap{position:relative;z-index:2}
/* the stock .hero::after vignette would stack on top of the scrim and mud the photo */
.hero--img::after{display:none}

/* ---------- trust ribbon ----------
   Rebuilt from research a second time. Still a ribbon, not cards, but the treatment is now what
   established contractor sites actually do with a trust strip:
     - the icon sits INSIDE a filled circular container rather than loose on the field, which is
       the one detail every reference shared (shadcn trust-strip, Re-Bath, Footprints Floors);
     - a quantity is stated as a quantity, at display size, on its own line (Findlay Roofing's
       counters). "20+" now reads before the word "years" does;
     - the four items are separated by real dividers so they read as four credentials rather than
       one run-on line;
     - the band is a distinct surface from the page, which is how contractor trust bars are
       usually set off.
   White was explicitly out: the sections above and below are white and the ribbon vanished into
   them. This uses --steel-hi #D5D3D2 straight from the intake palette, which separates from the
   black hero above and the white services section below without introducing a new colour.
   Measured on that field: label 11.67:1, detail 6.10:1, the brass number 5.08:1. */
.trust{background:var(--steel-hi);padding:0;
  border-top:3px solid var(--brass);border-bottom:3px solid var(--brass);
  background-image:linear-gradient(180deg,rgba(255,255,255,.5),rgba(255,255,255,0) 62%)}
.tp-grid{list-style:none;margin:0;padding:0;display:grid;
  grid-template-columns:repeat(auto-fit,minmax(min(250px,100%),1fr))}
.tp{display:flex;gap:14px;align-items:flex-start;padding:24px var(--gutter);
  border-right:1px solid rgba(26,26,26,.16)}
/* .wrap already supplies the page gutter; repeating it inside every cell cost ~100px of
   text width per column and the descriptions wrapped every four words */
@media(min-width:1010px){.tp{padding:24px 20px}.tp:first-child{padding-left:0}
  .tp:last-child{padding-right:0}}
.tp:last-child{border-right:0}
@media(max-width:1009px){.tp{border-right:0;border-bottom:1px solid rgba(26,26,26,.16)}
  .tp:last-child{border-bottom:0}}
.tp-ico{width:48px;height:48px;flex:none;display:grid;place-items:center;border-radius:50%;
  background:var(--white);color:var(--brass-text);box-shadow:0 2px 7px rgba(0,0,0,.13);
  border:1px solid rgba(156,117,60,.28)}
.tp-ico svg{width:22px;height:22px}
.tp-txt{min-width:0;padding-top:3px}
.tp-h{display:block;font-family:var(--cond);font-weight:700;font-size:1.2rem;line-height:1.12;
  color:var(--ink);margin-bottom:4px;letter-spacing:.005em}
/* the number is its own line at display size, not a prefix inside the label */
.tp-num{display:block;font-family:var(--cond);font-weight:700;font-size:2.3rem;line-height:.92;
  color:var(--brass-text);margin-bottom:1px}
.tp-d{display:block;font-size:.9rem;line-height:1.45;color:var(--ink-2)}

/* The sixth tile has no photograph, so it is a solid brass field with a centred label. It
   stretches to whatever height the photo tiles in its row reach rather than collapsing.
   Written .svc-box.svc-box--all, not .svc-box--all: the modifier sits ahead of .svc-box in
   this file, so at equal specificity the base class would win and the tile would stay white. */
.svc-box.svc-box--all{background:var(--brass-mid);border-color:var(--brass-mid);
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:9px;
  text-align:center;padding:34px 22px}
.svc-box--all .svc-box-t{color:#FFFFFF;font-size:clamp(1.34rem,2.2vw,1.62rem)}
.svc-box--all .svc-box-more{color:#FFFFFF;opacity:1;transform:none;justify-content:center}

/* ---------- six service tiles: photo on top, white bar beneath ----------
   The label moved off the photograph and onto a white bar, so its contrast is a fixed
   near-black-on-white pairing rather than something that has to be measured against whatever is
   in that corner of the image. Shorter than the previous boxes: the media is 16/10 instead of the
   whole tile being 4/3. */
.svc-boxes{display:grid;gap:18px;grid-template-columns:repeat(auto-fit,minmax(min(260px,100%),1fr))}
@media(min-width:620px){.svc-boxes{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media(min-width:960px){.svc-boxes{grid-template-columns:repeat(3,minmax(0,1fr))}}
.svc-box{display:block;overflow:hidden;border-radius:6px;text-decoration:none;
  background:var(--white);border:1px solid var(--line);
  transition:transform .2s var(--ease),box-shadow .2s var(--ease)}
.svc-box-media{display:block;aspect-ratio:16/10;overflow:hidden;background:#E6E3E0}
.svc-box-media img{width:100%;height:100%;object-fit:cover;
  transition:transform .35s var(--ease)}
.svc-box-body{display:flex;align-items:center;justify-content:space-between;gap:12px;
  padding:15px 16px;background:var(--white);min-height:60px}
.svc-box-t{font-family:var(--cond);font-weight:700;font-size:clamp(1.18rem,1.9vw,1.4rem);
  line-height:1.12;color:var(--ink)}
/* nothing shows by default; Learn More appears on hover, on keyboard focus, and on touch
   devices - a hover-only affordance is unreachable by keyboard and invisible on a phone */
.svc-box-more{display:inline-flex;align-items:center;gap:6px;font-family:var(--sans);
  font-size:.8rem;font-weight:600;letter-spacing:.05em;color:var(--brass-text);
  white-space:nowrap;opacity:0;transform:translateX(-6px);
  transition:opacity .2s var(--ease),transform .2s var(--ease)}
.svc-box-more svg{width:14px;height:14px}
@media(hover:hover){
  .svc-box:hover{transform:translateY(-4px);box-shadow:var(--shadow-lift)}
  .svc-box:hover .svc-box-media img{transform:scale(1.06)}
  .svc-box:hover .svc-box-more{opacity:1;transform:none}
}
.svc-box:focus-visible .svc-box-more{opacity:1;transform:none}
@media(hover:none){.svc-box-more{opacity:1;transform:none}}
@media(prefers-reduced-motion:reduce){
  .svc-box,.svc-box-media img,.svc-box-more{transition:none}}

/* Three steps want noticeably more room between them than four did. Doubled class selector on
   purpose: .steps is declared LATER in this file, and at equal specificity the later rule wins -
   so .steps--3 alone was being overridden back to the 26px four-up gap. */
.steps.steps--3{grid-template-columns:repeat(auto-fit,minmax(min(260px,100%),1fr));gap:44px}
@media(min-width:900px){.steps.steps--3{grid-template-columns:repeat(3,minmax(0,1fr));gap:76px}}
@media(min-width:1200px){.steps.steps--3{gap:96px}}
.steps.steps--3 li{padding-top:26px}

/* ---------- home quote band, laid out like the Dirt Pro home form ----------
   Full-bleed band, centred heading, then ONE centred card holding the whole form rather than a
   tall narrow column pushed to one side. 660px is the width Dirt Pro uses and it is the right
   one: wide enough to pair name/phone on a row, narrow enough that the inputs do not sprawl. */
.quote-band{background:var(--cta-dark);color:#FFFFFF;text-align:center;
  border-top:3px solid var(--brass-onphoto)}
.quote-band h2{color:var(--white)}
.quote-band .eyebrow{color:#FFFFFF}
.quote-sub{color:#FFFFFF;margin:0 auto 30px;max-width:52ch}
.quote-sub a{color:#FFFFFF;font-weight:600;text-decoration:underline}
@media(hover:hover){.quote-sub a:hover{text-decoration-thickness:2px}}
.quote-card{max-width:660px;margin:0 auto;background:var(--white);border-radius:14px;
  box-shadow:0 20px 48px rgba(0,0,0,.34);padding:30px 26px 32px;text-align:left}
@media(min-width:620px){.quote-card{padding:36px 34px 38px}}
.quote-card .form-note{text-align:center}

.hero-one-line{max-width:58ch;margin-bottom:0}
.hero--bare .hero-one-line{margin-top:16px}

/* ---------- trust strip under the hero ---------- */
.strip{background:var(--white);border-bottom:1px solid var(--line)}
.strip ul{list-style:none;margin:0;padding:0;display:grid;gap:0;
  grid-template-columns:repeat(auto-fit,minmax(min(260px,100%),1fr))}
.strip li{display:flex;gap:13px;align-items:flex-start;padding:24px var(--gutter);
  border-right:1px solid var(--line)}
.strip li:last-child{border-right:0}
@media(max-width:719px){.strip li{border-right:0;border-bottom:1px solid var(--line)}
  .strip li:last-child{border-bottom:0}}
.strip .ico{width:38px;height:38px;flex:none;display:grid;place-items:center;border-radius:50%;
  background:rgba(156,117,60,.13);color:var(--brass-deep)}
.strip .ico svg{width:19px;height:19px}
.strip strong{display:block;font-family:var(--cond);font-size:1.18rem;line-height:1.15;
  color:var(--ink)}
.strip span{font-size:.92rem;color:var(--ink-2);line-height:1.45}

/* ---------- service cards ---------- */
.svc-grid{display:grid;gap:26px;grid-template-columns:repeat(auto-fit,minmax(min(280px,100%),1fr))}
@media(min-width:760px){.svc-grid--2{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media(min-width:900px){.svc-grid--3{grid-template-columns:repeat(3,minmax(0,1fr))}}
.svc{background:var(--white);border:1px solid var(--line);border-radius:6px;overflow:hidden;
  display:flex;flex-direction:column;transition:transform .2s var(--ease),box-shadow .2s var(--ease)}
@media(hover:hover){.svc:hover{transform:translateY(-4px);box-shadow:var(--shadow-lift)}}
.svc-media{width:100%;aspect-ratio:3/2;background:#E6E3E0;overflow:hidden;position:relative}
.svc-media img{width:100%;height:100%;object-fit:cover;object-position:center}
.svc-media--feature{aspect-ratio:1;border-radius:6px;border:1px solid var(--line)}
.svc-body{padding:24px 22px 26px;display:flex;flex-direction:column;flex:1}
.svc-body h3{margin-bottom:10px}
.svc-body p{color:var(--ink-2);font-size:.98rem}
.svc-list{list-style:none;margin:0 0 20px;padding:0}
.svc-list li{position:relative;padding-left:22px;font-size:.95rem;line-height:1.5;
  margin-bottom:7px;color:var(--ink-2)}
.svc-list li::before{content:"";position:absolute;left:0;top:.52em;width:9px;height:5px;
  border-left:2px solid var(--brass-deep);border-bottom:2px solid var(--brass-deep);
  transform:rotate(-45deg)}
.svc-cta{margin-top:auto}
.link-more{display:inline-flex;align-items:center;gap:8px;min-height:44px;font-weight:600;
  font-size:.92rem;color:#6B4F26;text-decoration:none;background:none;border:0;padding:0;
  cursor:pointer;font-family:var(--sans)}
.link-more::after{content:"";width:22px;height:1.5px;background:currentColor;
  transition:width .2s var(--ease)}
@media(hover:hover){.link-more:hover::after{width:32px}}

/* ---------- the big hub cards, deliberately unlike the home grid ---------- */
.hub{display:grid;gap:0;border-top:1px solid var(--line)}
.hub-item{display:grid;gap:0;border-bottom:1px solid var(--line);
  grid-template-columns:minmax(0,1fr);align-items:stretch}
@media(min-width:820px){.hub-item{grid-template-columns:232px minmax(0,1fr)}}
.hub-media{background:#E6E3E0;overflow:hidden;min-height:180px}
@media(min-width:820px){.hub-media{min-height:100%}}
.hub-media img{width:100%;height:100%;object-fit:cover;min-height:180px}
.hub-body{padding:30px 0 34px}
@media(min-width:820px){.hub-body{padding:34px 0 38px 34px}}
.hub-num{font-family:var(--cond);font-size:.95rem;font-weight:700;letter-spacing:.14em;
  color:var(--brass-deep);margin-bottom:8px;display:block}
.hub-body h2{font-size:clamp(1.55rem,2.8vw,2.1rem);margin-bottom:12px}
.hub-body p{color:var(--ink-2)}
.hub-cols{display:grid;gap:4px 30px;margin:0 0 22px;padding:0;list-style:none}
@media(min-width:560px){.hub-cols{grid-template-columns:repeat(2,minmax(0,1fr))}}
.hub-cols li{position:relative;padding-left:22px;font-size:.95rem;color:var(--ink-2);
  line-height:1.5;margin-bottom:5px}
.hub-cols li::before{content:"";position:absolute;left:0;top:.52em;width:9px;height:5px;
  border-left:2px solid var(--brass-deep);border-bottom:2px solid var(--brass-deep);
  transform:rotate(-45deg)}

/* ---------- process ---------- */
.steps{list-style:none;margin:0;padding:0;display:grid;gap:26px;
  grid-template-columns:repeat(auto-fit,minmax(min(220px,100%),1fr))}
@media(min-width:720px){.steps{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media(min-width:1000px){.steps{grid-template-columns:repeat(4,minmax(0,1fr))}}
.steps li{position:relative;padding-top:22px;border-top:2px solid rgba(156,117,60,.4)}
.steps .n{font-family:var(--cond);font-size:2.3rem;font-weight:700;line-height:1;
  color:var(--brass-lite);display:block;margin-bottom:9px}
.steps h3{font-size:1.18rem;margin-bottom:7px;color:var(--white)}
.steps p{font-size:.95rem;color:var(--steel-hi);margin:0}

/* ---------- work strip: 206px sources shown at their true size ---------- */
.work{display:grid;gap:10px;grid-template-columns:repeat(2,minmax(0,1fr))}
@media(min-width:520px){.work{grid-template-columns:repeat(3,minmax(0,1fr))}}
@media(min-width:760px){.work{grid-template-columns:repeat(4,minmax(0,1fr))}}
@media(min-width:1020px){.work{grid-template-columns:repeat(6,minmax(0,1fr))}}
.work img{width:100%;aspect-ratio:1;object-fit:cover;border-radius:4px;background:#E6E3E0;
  transition:transform .25s var(--ease)}
@media(hover:hover){.work a:hover img{transform:scale(1.04)}}
.work a{display:block;overflow:hidden;border-radius:4px}

/* ---------- What We Do ----------
   Two-column split with the copy on one side and an OFFSET photo collage on the other, which is
   the layout the contractor teardowns converge on for an overview section. The stagger is a
   margin-top on the tall figure at desktop only - at 375 there is no room for it and it would
   just read as a gap.
   Deliberately shorter than the crew split below it: the research described these sections as
   positioning-focused rather than narrative-heavy, and the crew section is the narrative one. */
/* .split.split--wwd, not .split--wwd: .split sets align-items:start and is declared LATER in
   this file, so at equal specificity the base class won and the copy stayed pinned to the top
   of a much taller media column. Sixth time this exact collision has come up on this build. */
.split.split--wwd{align-items:center}
@media(min-width:900px){.split--wwd{grid-template-columns:minmax(0,1fr) minmax(0,.92fr);gap:56px}}
.wwd-media{display:grid;gap:14px;grid-template-columns:repeat(2,minmax(0,1fr))}
.wwd-fig{margin:0;overflow:hidden;border-radius:6px;border:1px solid var(--line);
  background:#E6E3E0;box-shadow:var(--shadow)}
.wwd-fig img{width:100%;height:100%;object-fit:cover}
/* The tall one holds the left column across both rows. It carries NO aspect-ratio of its own:
   its height has to be whatever the two stacked squares plus the gap come to, and a fixed ratio
   left it ~170px short of them with a ragged bottom edge. Grid stretch does it exactly, which
   also means .wwd-media must not set align-items - start there was what disabled the stretch. */
.wwd-fig--tall{grid-row:1/span 2}
.wwd-fig--sq{aspect-ratio:1/1}
@media(min-width:900px){.wwd-fig--tall{margin-top:40px}}

/* ---------- why-us split ---------- */
.split{display:grid;gap:34px;align-items:start}
@media(min-width:900px){.split{grid-template-columns:minmax(0,1.05fr) minmax(0,.95fr);gap:60px}}
.facts{list-style:none;margin:0;padding:0}
.facts li{padding:18px 0;border-bottom:1px solid var(--line);display:flex;gap:15px;
  align-items:flex-start}
.facts li:first-child{border-top:1px solid var(--line)}
.facts .ico{width:34px;height:34px;flex:none;display:grid;place-items:center;border-radius:50%;
  background:rgba(156,117,60,.13);color:var(--brass-deep)}
.facts .ico svg{width:17px;height:17px}
.facts strong{display:block;font-family:var(--cond);font-size:1.16rem;color:var(--ink);
  line-height:1.2;margin-bottom:3px}
.facts span{font-size:.95rem;color:var(--ink-2);line-height:1.5}

/* ---------- service area ---------- */
.cities{list-style:none;margin:0;padding:0;display:flex;flex-wrap:wrap;gap:10px}
.cities li{padding:10px 17px;border:1px solid var(--line);border-radius:999px;background:var(--white);
  font-weight:600;font-size:.93rem;color:var(--ink)}

/* ---------- FAQ ---------- */
.faq{border-top:1px solid var(--line);max-width:74ch}
.faq-item{border-bottom:1px solid var(--line)}
.faq-q{width:100%;display:flex;justify-content:space-between;align-items:center;gap:18px;
  text-align:left;background:none;border:0;cursor:pointer;padding:22px 0;font-family:var(--cond);
  font-size:1.22rem;font-weight:700;color:var(--ink);line-height:1.22}
.faq-icon{flex:none;width:28px;height:28px;border:1px solid var(--brass-deep);border-radius:50%;
  display:grid;place-items:center;color:var(--brass-deep);font-family:var(--sans);font-weight:600;
  transition:transform .25s var(--ease)}
.faq-q[aria-expanded="true"] .faq-icon{transform:rotate(45deg)}
/* Height is animated from a measured value; padding is a margin on the last child, not padding on
   this box, because max-height cannot shrink a box below its own padding and the collapse would
   floor there and then snap. */
.faq-a{max-width:68ch;overflow:hidden;max-height:0;padding:0;
  transition:max-height .34s var(--ease)}
.faq-a > :last-child{margin-bottom:22px}
.faq-a[hidden]{display:none}
.faq-a p{color:var(--ink-2)}
@media(prefers-reduced-motion:reduce){.faq-a{transition:none}}

/* ---------- CTA band ---------- */
.cta-band{background:var(--cta-dark);color:#FFFFFF;text-align:center;
  border-top:3px solid var(--brass-onphoto)}
.cta-band h2{color:var(--white)}
/* The band is brass now, so --brass-lite is nearly the band itself: 1.23:1. Every accent on
   these bands has to be off-white rather than brass. Same reasoning as before, new surface. */
.cta-band .eyebrow{color:#FFFFFF}
.cta-band .lede{color:#FFFFFF;max-width:54ch;margin-inline:auto}
.cta-call{display:inline-flex;align-items:center;gap:9px;font-weight:600;font-size:1.05rem;
  color:#FFFFFF;text-decoration:none;min-height:44px}
/* hover cannot go lighter than white, so it marks itself with an underline instead */
@media(hover:hover){.cta-call:hover{text-decoration:underline}}
.cta-call svg{width:18px;height:18px}

/* Grey rather than brass, on a grey from the intake palette rather than a new one.
   --steel-hi #D5D3D2 is the only palette grey that works as a solid button: --steel #817F7E
   fails its own label both ways (4.37:1 with ink, 3.98:1 with white), so a mid grey would
   have needed a colour that is not in the palette.
   .cta-band only. .quote-band was in this selector once and it was wrong: the only
   .btn-primary on that band is the form's submit, which sits inside .quote-card - a WHITE
   card - so a band-surface rule turned it invisible. The band's own surface is not the
   surface every button on it stands on. */
.cta-band .btn-primary{background:var(--steel-hi);border-color:var(--steel-hi);
  color:var(--ink)}
/* hover goes lighter, not warmer - a warm tint would put brass back on a grey button */
@media(hover:hover){.cta-band .btn-primary:hover{
  background:#FFFFFF;border-color:#FFFFFF;color:var(--ink)}}

/* The quote band's submit is the one genuinely BRASS button on any CTA section, so "grey rather
   than brass" applies to it too - but it stands on the white .quote-card, not on the band, and
   the two surfaces need opposite greys. --steel-hi on white is 1.49:1 and the button would have
   no edge at all, so this end of the pairing takes --ink-2 with a white label: 8.59:1 for the
   label and the same 8.59:1 for the fill against the card.
   Scoped through .quote-card so it is the CARD's surface driving the choice, and written with
   three classes so it cannot be undercut by a later .btn-primary rule at equal specificity. */
.quote-band .quote-card .btn-primary{background:var(--ink-2);border-color:var(--ink-2);
  color:var(--white)}
@media(hover:hover){.quote-band .quote-card .btn-primary:hover{
  background:var(--ink);border-color:var(--ink);color:var(--white)}}

/* ---------- forms ---------- */
.form-card{background:var(--white);border:1px solid var(--line);border-radius:18px;
  box-shadow:0 18px 44px rgba(0,0,0,.08);padding:26px 20px 28px}
@media(min-width:720px){.form-card{padding:30px}}
.form-card h2{font-size:clamp(1.6rem,2.6vw,2.05rem)}
.f-row{display:grid;gap:16px}
@media(min-width:560px){.f-row--2{grid-template-columns:repeat(2,minmax(0,1fr))}}
.field{display:flex;flex-direction:column;gap:6px;margin-bottom:16px}
.field label{font-size:.88rem;font-weight:600;color:var(--ink)}
.field .req{color:var(--brass-deep)}
.field input,.field select,.field textarea{font-family:var(--sans);font-size:1rem;
  color:var(--ink);background:var(--white);border:1px solid #C9C5C1;border-radius:5px;
  padding:13px 14px;min-height:50px;width:100%}
.field textarea{min-height:126px;resize:vertical;line-height:1.55}
.field input:focus-visible,.field select:focus-visible,.field textarea:focus-visible{
  outline:3px solid var(--brass);outline-offset:1px;border-color:var(--brass-deep)}
.form-note{font-size:.88rem;color:var(--ink-2);text-align:center;margin:14px 0 0}
.form-status{margin:16px 0 0;padding:14px 16px;border-radius:6px;font-size:.95rem;
  border:1px solid var(--line);background:#F1EFED;color:var(--ink)}
.form-status[hidden]{display:none}
.form-status.is-err{border-color:#B4342C;background:#FCEFEE;color:#7E231D}
.form-status.is-ok{border-color:#2F6B3A;background:#EEF6EF;color:#1F4A27}
.hp{position:absolute;left:-9999px}
.btn--full{width:100%}

/* ---------- contact split ---------- */
.contact-grid{display:grid;gap:26px;align-items:start}
@media(min-width:940px){.contact-grid{gap:52px}}
/* Dirt Pro's contact proportions: 1fr / 1.05fr from 900px, 52px gutter, aligned to start */
@media(min-width:900px){.contact-grid{grid-template-columns:minmax(0,1fr) minmax(0,1.05fr);gap:52px}}
.ic-list{list-style:none;margin:20px 0 0;padding:0}
.ic-list li{display:flex;gap:15px;align-items:flex-start;padding:13px 0;
  border-bottom:1px solid var(--line)}
.ic-list li:first-child{border-top:1px solid var(--line)}
.ic-list .ico{width:40px;height:40px;flex:none;display:grid;place-items:center;border-radius:50%;
  background:rgba(156,117,60,.13);color:var(--brass-deep)}
.ic-list .ico svg{width:19px;height:19px}
.ic-list strong{display:block;font-family:var(--cond);font-size:1.16rem;color:var(--ink);
  margin-bottom:2px;line-height:1.2}
/* This is a standalone control in a contact card, not a link inside a sentence, so the
   inline-prose exemption does not apply to it and it needs a real 44px target. */
.ic-list a{color:#6B4F26;font-weight:600;display:inline-flex;align-items:center;
  min-height:44px;min-width:44px}
.ic-list span{font-size:.95rem;color:var(--ink-2);line-height:1.5}
/* The map sits under both columns now rather than inside the left one, so on mobile it comes
   after the form instead of pushing it 340px further down the page. */
.map-block{max-width:100%}
.about-photo{border-radius:8px;overflow:hidden;border:1px solid rgba(0,0,0,.08);
  background:#E6E3E0;aspect-ratio:4/3}
.about-photo img{width:100%;height:100%;object-fit:cover}
.map-frame{border:1px solid var(--line);border-radius:8px;overflow:hidden;background:#E6E3E0}
.map-frame iframe{width:100%;height:340px;border:0;display:block}

/* ---------- footer ---------- */
.site-footer{background:var(--black);color:var(--steel-hi);padding:52px 0 26px;font-size:.95rem;
  border-top:3px solid var(--brass)}
.footer-grid{display:grid;gap:34px}
@media(min-width:760px){.footer-grid{grid-template-columns:1.35fr 1fr 1fr}}
@media(min-width:1040px){.footer-grid{grid-template-columns:1.5fr 1fr 1fr 1.1fr}}
.site-footer h2{font-family:var(--sans);font-size:.76rem;letter-spacing:.17em;
  text-transform:uppercase;color:var(--brass-lite);font-weight:600;margin:0 0 15px}
.site-footer ul{list-style:none;margin:0;padding:0}
.site-footer a{color:var(--steel-hi);text-decoration:none;display:inline-flex;align-items:center;
  min-height:44px;min-width:44px}
@media(hover:hover){.site-footer a:hover{color:var(--white);text-decoration:underline}}
.site-footer address{font-style:normal;color:var(--steel-hi);line-height:1.75}
.footer-brand{display:inline-flex;align-items:center;gap:11px;margin-bottom:14px}
.footer-brand img{height:52px;width:52px;border-radius:3px}
.footer-brand .brand-name{font-size:1.3rem}
.footer-tag{color:var(--steel);font-size:.93rem;margin:0 0 16px;max-width:34ch}
.footer-bottom{margin-top:38px;padding-top:20px;border-top:1px solid rgba(213,211,210,.16);
  display:flex;flex-wrap:wrap;gap:8px 22px;justify-content:space-between;font-size:.86rem;
  color:var(--steel)}
.footer-bottom a{color:var(--steel-hi);min-height:44px;align-items:center}


/* ---------- Our Services dropdown ----------
   Desktop opens on hover AND on focus-within, so a keyboard user tabbing from the "Our Services"
   link into the submenu keeps it open without needing the toggle button - which is why the button
   is hidden above 1000px rather than made to do double duty. Mobile turns the same markup into an
   expandable section inside the drawer, driven by the button and animated from a measured height. */
.sub-row{display:flex;align-items:center}
.sub-toggle{display:inline-flex;align-items:center;justify-content:center;width:44px;min-height:44px;
  background:none;border:0;cursor:pointer;color:var(--steel-hi);padding:0}
.sub-toggle svg{width:17px;height:17px;transition:transform .25s var(--ease)}
.sub-toggle[aria-expanded="true"] svg{transform:rotate(180deg)}
/* .site-nav > ul{display:flex} also matches this ul, which laid the panel out as a horizontal
   row 724px wide. It has to declare its own display rather than inherit that one. */
.subnav{list-style:none;margin:0;padding:0;display:block}
.subnav a{white-space:nowrap}
@media(min-width:1000px){.site-nav .subnav a{font-size:.98rem}}

@media(min-width:1000px){
  .sub-toggle{display:none}
  .has-sub{position:relative}
  /* an invisible bridge across the gap between the 44px nav item and the header edge, so the
     pointer can travel into the panel without the hover breaking on the way */
  .has-sub::after{content:"";position:absolute;left:0;right:0;top:100%;height:22px}
  .subnav{position:absolute;top:calc(100% + 22px);left:0;min-width:286px;background:var(--black);
    border:1px solid rgba(156,117,60,.45);border-top:2px solid var(--brass);
    box-shadow:0 22px 44px rgba(0,0,0,.5);padding:8px 0;z-index:130;
    opacity:0;visibility:hidden;transform:translateY(-8px);
    transition:opacity .18s var(--ease),transform .18s var(--ease),visibility 0s linear .18s}
  .has-sub:hover > .subnav,.has-sub:focus-within > .subnav{
    opacity:1;visibility:visible;transform:none;transition-delay:0s}
  .subnav li{display:block}
  .site-nav .subnav a{display:flex;align-items:center;min-height:44px;padding:0 18px;
    border-radius:0;font-size:.93rem;width:100%}
  .subnav-more{border-top:1px solid rgba(213,211,210,.16);margin-top:6px;padding-top:6px}
  .site-nav .subnav-more a{color:var(--brass-lite)}
  /* the parent keeps its pill while any of the six child pages is open */
  .has-sub.is-here > .sub-row > a{background:rgba(156,117,60,.24);color:var(--white)}
}

@media(max-width:999px){
  .sub-row{justify-content:space-between;gap:4px}
  .sub-row > a{flex:1}
  .subnav{overflow:hidden;max-height:0;padding-left:0;
    transition:max-height .3s var(--ease);border-left:1px solid rgba(156,117,60,.4);margin-left:14px}
  .subnav[hidden]{display:none}
  .site-nav .subnav a{min-height:48px;font-size:1.02rem;padding-left:14px}
  .site-nav .subnav-more a{color:var(--brass-lite)}
}
@media(prefers-reduced-motion:reduce){.subnav,.sub-toggle svg{transition:none}}

/* ---------- Our Services: one stacked list of six ---------- */
.svc-stack{list-style:none;margin:0;padding:0;border-top:1px solid var(--line)}
.svc-stack li{border-bottom:1px solid var(--line)}
.svc-stack a{display:flex;align-items:center;gap:18px;padding:26px 4px;text-decoration:none;
  color:var(--ink);transition:background-color .18s var(--ease),padding-left .18s var(--ease)}
@media(hover:hover){.svc-stack a:hover{background:rgba(156,117,60,.07);padding-left:14px}}
.svc-stack .n{font-family:var(--sans);font-size:.78rem;font-weight:600;letter-spacing:.12em;
  color:var(--brass-text);flex:none;width:28px}
.svc-stack .t{font-family:var(--cond);font-weight:700;font-size:clamp(1.5rem,3.4vw,2.3rem);
  line-height:1.1;flex:1;min-width:0}
.svc-stack .d{display:none}
@media(min-width:860px){.svc-stack .t{flex:0 0 300px}
  .svc-stack .d{display:block;flex:1;min-width:0;font-size:.98rem;color:var(--ink-2);line-height:1.5}}
.svc-stack .go{flex:none;width:30px;height:30px;display:grid;place-items:center;color:var(--brass-text)}
.svc-stack .go svg{width:20px;height:20px;transition:transform .18s var(--ease)}
@media(hover:hover){.svc-stack a:hover .go svg{transform:translateX(4px)}}

/* ---------- Our Services: rail + hub ---------- */
.hub-layout{display:grid;gap:36px}
@media(min-width:1000px){.hub-layout{grid-template-columns:238px minmax(0,1fr);gap:56px;
  align-items:start}}
@media(min-width:1000px){.svc-rail{position:sticky;top:calc(var(--header-h) + 24px)}}
.svc-rail-h{font-family:var(--sans);font-size:.76rem;letter-spacing:.17em;text-transform:uppercase;
  color:var(--brass-text);font-weight:600;margin:0 0 14px}
.svc-rail-list{list-style:none;margin:0;padding:0;border-top:1px solid var(--line)}
.svc-rail-list li{border-bottom:1px solid var(--line)}
.svc-rail-list a{display:flex;align-items:center;gap:12px;min-height:52px;text-decoration:none;
  font-family:var(--cond);font-size:1.2rem;font-weight:700;color:var(--ink)}
.svc-rail-list .svc-n{font-family:var(--sans);font-size:.72rem;font-weight:600;letter-spacing:.1em;
  color:var(--brass-text);flex:none}
@media(hover:hover){.svc-rail-list a:hover{color:var(--brass-text)}}
.svc-rail-note{font-size:.9rem;color:var(--ink-2);margin:16px 0 0}
.hub-body h2 a{color:inherit;text-decoration:none;display:inline-block;
  min-height:44px;padding-block:9px;margin-block:-9px}
@media(hover:hover){.hub-body h2 a:hover{color:var(--brass-text)}}

/* ---------- "don't see what you need" ---------- */
.ask-band{background:var(--black);color:var(--steel-hi);padding:32px 26px 34px;border-radius:6px;
  border-left:4px solid var(--brass)}
@media(min-width:760px){.ask-band{padding:40px 38px 42px}}
.ask-band h2{color:var(--white);font-size:clamp(1.6rem,2.8vw,2.2rem);margin-bottom:12px}
.ask-band p{color:var(--steel-hi);max-width:60ch;margin:0}

/* ---------- photo gallery ---------- */
.gal-group + .gal-group{margin-top:56px}
.gal-h{border-bottom:2px solid var(--brass);padding-bottom:12px;margin:0 0 22px;
  font-size:clamp(1.5rem,2.6vw,2rem)}
.gal-foot{margin:18px 0 0}
.gal-grid{display:grid;gap:14px;grid-template-columns:repeat(auto-fill,minmax(min(150px,100%),1fr))}
.gal-item{margin:0}
.gal-item img{width:100%;aspect-ratio:1;object-fit:cover;border-radius:4px;background:#E6E3E0}

.cities--dark li{background:transparent;border-color:rgba(156,117,60,.5);color:var(--steel-hi)}

/* ---------- reveal, transform + opacity only ----------
   Gated behind @media(scripting:enabled). The starting state is opacity:0, and only JS ever adds
   .in - so if the script fails to run, three service cards and six hub rows would be permanently
   invisible with no way for the reader to know. Gating it means the default state is VISIBLE and
   the animation is the enhancement, which is the right way round. */
@media(scripting:enabled){
  .rev{opacity:0;transform:translateY(16px);
    transition:opacity .5s var(--ease),transform .5s var(--ease)}
  .rev.in{opacity:1;transform:none}
}
@media(prefers-reduced-motion:reduce){
  .rev{opacity:1;transform:none;transition:none}
  .btn,.svc,.work img,.link-more::after{transition:none}
  html{scroll-behavior:auto}
}

/* ---------- 404 ---------- */
.nf{padding:76px 0 84px;text-align:center}
.nf h1{font-size:clamp(2.6rem,8vw,5rem)}
.nf ul{list-style:none;padding:0;margin:26px 0 0;display:flex;flex-wrap:wrap;gap:12px;
  justify-content:center}
