/* ==========================================================================
   VanderWall Brothers — Spring Lake & Grand Rapids, MI

   PALETTE AND TYPE COME FROM THEIR OWN BRAND GUIDE, sent by Kurt Zink on
   5 Aug 2026 (24-VANDERWALLBROS-00552). This file previously ran a warm
   bark/brass/cream system sampled from their WordPress CSS. That was a
   reasonable inference and it was wrong: the real palette is cool and
   neutral, and contains no brown and no brass at all.

     #D83220 chili red · #2E2C2F raisin black · #E5E4E2 platinum
     #475B63 payne's gray · #000000 black

   The point of a neutral gray frame is that the fire is the only warm thing
   on the page. Their own printed materials do exactly this, and it serves
   the lookbook direction better than the warm system it replaces.

   THE RULE THAT SHAPES EVERYTHING BELOW: chili red measures 2.90:1 on raisin
   black, which fails even the 3:1 floor for large type, so red can never be
   text on a dark ground. Their guide never tries — red appears on light
   grounds and as a graphic mark (the flame in the logo), and dark grounds
   are white type only. So: RED ON LIGHT, WHITE ON DARK. That is why there is
   no dark-ground accent color here; on dark, hierarchy is carried by weight,
   letterspacing and size instead of hue.

   Red is also thin on the platinum step — 4.78:1 on white but only 3.76:1 on
   #E5E4E2 — so --accent is headings and graphics, and --accent-ink is the one
   that carries links and labels at 4.54:1 on the darkest light ground.

   Type is theirs too, and they already own it: Sentinel Medium (Hoefler & Co.)
   and Brother 1816 (TipoType) are the exact faces their live site has served
   since 2019. Both are single-weight, so the 500 and 600 steps below resolve
   to 400 and 700 by CSS font-matching rather than being synthesized.

   Square-shouldered controls (6px). This is a company that has been casting
   concrete block since 1922; pills would read as a consumer app.
   ========================================================================== */

/* Self-hosted from their own server's copies. Sentinel is Medium only and
   Brother ships regular + bold, so every weight the stylesheet asks for has
   to land on one of these three files. Per CSS font-matching, a request for
   500 checks 400 before anything above it, and a request for 600 checks 700 —
   so nothing is faux-bolded, which on a display serif looks obviously wrong. */
@font-face{
  font-family:"Sentinel";
  src:url("/css/fonts/sentinel-medium.woff") format("woff");
  font-weight:500;
  font-style:normal;
  font-display:swap;
}
@font-face{
  font-family:"Brother 1816";
  src:url("/css/fonts/brother-1816-regular.woff") format("woff");
  font-weight:400;
  font-style:normal;
  font-display:swap;
}
@font-face{
  font-family:"Brother 1816";
  src:url("/css/fonts/brother-1816-bold.woff") format("woff");
  font-weight:700;
  font-style:normal;
  font-display:swap;
}

:root{
  --bark:#2E2C2F;            /* raisin black — the dark ground */
  --bark-2:#363940;          /* lifted surfaces, drifting toward payne's gray */
  --bark-3:#3F464D;
  --line:#4E565D;            /* hairline on dark — borders only, never type */
  --line-pale:#D2D1CE;       /* hairline on light */

  --red:#D83220;             /* chili red, exact from the guide */
  --accent:#D83220;          /* graphic accent on LIGHT — rules, borders, hovers */
  --accent-ink:#C22A1A;      /* red as TYPE on light: 5.33:1 on paper, 4.54:1 on platinum */
  --quiet:#475B63;           /* payne's gray — secondary type/structure on light,
                                7.13:1 on white and 5.61:1 on platinum */
  --hi:#FFFFFF;              /* the accent on DARK: 13.84:1 on bark. There is no
                                colored alternative that passes — see the note above */

  --red-ink:#C22A1A;         /* alias of --accent-ink, kept so link rules read plainly */
  --red-btn:#D83220;         /* white on chili red measures 4.78:1 — the official
                                color is itself the button, no darkening needed */
  --red-btn-hover:#B42716;   /* 6.48:1 */

  /* The page ground is a light tint of platinum rather than platinum itself,
     so that #E5E4E2 stays available as a real alternating band instead of
     being spent on the background. */
  --paper:#F6F6F5;
  --paper-2:#EDEDEB;
  --paper-3:#E5E4E2;         /* platinum, exact from the guide */

  --ink:#FFFFFF;
  --ink-dark:#2E2C2F;        /* raisin black — 12.80:1 on paper, 10.90:1 on platinum */
  --body:#CFD2D4;            /* 9.11:1 on bark */
  /* Measured against --bark-2, not --bark. The preheader and the footer sit on
     the LIGHTER surface, so tuning this to the darkest ground was wrong: at
     #9AA0A6 it read 4.38:1 on bark-2 and quietly missed. 4.59:1 there now,
     5.50:1 on bark. */
  --muted:#9EA4AA;
  /* The hero lede needs its own value. Raisin black is a lighter scrim color
     than the bark it replaced, so the identical alpha stack darkens the
     photograph less and --body dropped to 3.94:1 on the brightest hero.
     Rather than thicken the wash — the whole point of the pooled scrim was to
     let their photograph show — the type gets lighter. Solved against the
     worst measured pixel: it needs relative luminance >= .739, and this is
     .774. Hierarchy against the white h1 is carried by size and face, which
     is where it should live anyway. */
  --hero-lede:#E2E4E6;
  --body-dark:#3C4247;       /* 9.42:1 on paper, 8.02:1 on platinum */
  --muted-dark:#5E666C;      /* 5.40:1 on paper, 4.60:1 on platinum */

  --shell:min(1180px,100% - 2.5rem);
  --r:6px;

  --display:"Sentinel",Georgia,"Times New Roman",serif;
  --text:"Brother 1816",system-ui,-apple-system,"Segoe UI",sans-serif;

  --tab-h:0px;
}

*,*::before,*::after{box-sizing:border-box}

html{
  -webkit-text-size-adjust:100%;   /* iOS inflates body text without this */
  scroll-behavior:smooth;
}
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{animation-duration:.01ms !important;transition-duration:.01ms !important}
}

/* No overflow-x on html/body. A fixed bottom tab bar unsticks and floats up
   while scrolling on iPhone Safari when the root carries overflow. The drawer
   below is hidden in place rather than slid off-screen precisely so the root
   never needs it. */
body{
  margin:0;
  background:var(--paper);
  color:var(--body-dark);
  font:400 17px/1.7 var(--text);
  -webkit-font-smoothing:antialiased;
}

h1,h2,h3,h4{margin:0;color:var(--ink-dark);font-family:var(--display);
  font-weight:500;letter-spacing:-.014em;line-height:1.14}
h2{margin-bottom:.72rem}
h1{font-size:clamp(2.3rem,1.55rem + 3.2vw,4.1rem)}
h2{font-size:clamp(1.8rem,1.3rem + 2vw,2.8rem)}
h3{font-size:clamp(1.16rem,1.02rem + .58vw,1.42rem)}
h4{font-size:1.05rem}
p{margin:0 0 1.05rem}
img{max-width:100%;height:auto;display:block}
a{color:var(--red-ink);text-underline-offset:3px}
a:hover{color:var(--red-btn-hover)}
hr{border:none;border-top:1px solid var(--line-pale);margin:2.4rem 0}

.shell{width:var(--shell);margin-inline:auto}
.narrow{width:min(46rem,100% - 2.5rem);margin-inline:auto}
.skip{position:absolute;left:-9999px;top:0;background:var(--red-btn);color:#fff;
  padding:.7rem 1.1rem;z-index:200;font-weight:600;border-radius:0 0 6px 0}
.skip:focus{left:0}
:focus-visible{outline:2.5px solid var(--accent);outline-offset:3px;border-radius:3px}
.dark :focus-visible,.hero :focus-visible,.strip :focus-visible,
.leadcard :focus-visible,.ftr :focus-visible{outline-color:var(--hi)}

.eyebrow{font:700 .72rem/1.5 var(--text);letter-spacing:.2em;text-transform:uppercase;
  color:var(--red-ink);margin:0 0 .9rem}
.lede{font-size:1.15rem;color:var(--body-dark);max-width:40em}
.ital{font-style:italic;color:var(--accent-ink)}   /* the single italic beat */
.hero .ital,.dark .ital,.strip .ital,.leadcard .ital{color:var(--hi)}

/* ---------- buttons ----------------------------------------------------- */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:.5rem;
  font:600 1rem/1 var(--text);padding:1.02rem 1.6rem;border-radius:var(--r);
  border:1px solid transparent;cursor:pointer;text-decoration:none;transition:.18s ease}
.btn-primary{background:var(--red-btn);color:#fff;border-color:var(--red-btn)}
.btn-primary:hover{background:var(--red-btn-hover);border-color:var(--red-btn-hover);color:#fff}
.btn-ghost{background:transparent;color:var(--ink);border-color:#565E64}
.btn-ghost:hover{border-color:var(--hi);color:var(--hi)}
.btn-block{width:100%}
.btn-sm{padding:.7rem 1.15rem;font-size:.9rem}
.pale .btn-ghost,.plain .btn-ghost{color:var(--ink-dark);border-color:#C6C9CB}
.pale .btn-ghost:hover,.plain .btn-ghost:hover{border-color:var(--red-ink);color:var(--red-ink)}

/* ---------- preheader utility bar ---------------------------------------
   Their current site has one and Alex wanted it kept: both showrooms' hours,
   the phone, the two links people reach for, and their social accounts. It
   scrolls away with the page rather than sticking, so the sticky masthead
   stays the same height once you start reading. */
.preheader{background:var(--bark-2);border-bottom:1px solid var(--line);
  font:500 .78rem/1 var(--text)}
.ph-in{display:flex;align-items:center;justify-content:space-between;
  gap:1rem;min-height:38px;padding:.35rem 0}
.ph-hours{display:flex;gap:1.4rem;color:var(--muted);flex-wrap:wrap;min-width:0}
.ph-loc b{color:var(--body);font-weight:600}
.ph-loc b::after{content:" ·";color:var(--line)}
.ph-right{display:flex;align-items:center;gap:1.1rem;flex:none}
.ph-link{color:var(--body);text-decoration:none}
.ph-link:hover{color:var(--hi)}
.ph-tel{color:var(--ink);text-decoration:none;font-weight:700;white-space:nowrap}
.ph-tel:hover{color:var(--hi);text-decoration:underline;text-underline-offset:3px}
.ph-social{display:flex;gap:.55rem;align-items:center}
.ph-social a{display:inline-flex;color:var(--muted)}
.ph-social a:hover{color:var(--hi)}
.ph-social svg{width:15px;height:15px;fill:currentColor}

/* ---------- header ------------------------------------------------------ */
.hdr{position:sticky;top:0;z-index:90;background:rgba(46,44,47,.94);
  backdrop-filter:blur(12px);border-bottom:1px solid var(--line)}
/* This gap separates three GROUPS (brand, nav, actions) and has to stay
   comfortably wider than the gap between links inside the nav, or the first
   link reads as part of the brand lockup. */
.hdr-in{display:flex;align-items:center;justify-content:space-between;
  gap:clamp(2rem,4vw,3.5rem);padding:.68rem 0}
.brand{display:flex;align-items:center;flex:none;text-decoration:none}
/* No typeset name beside the mark here, unlike the Moose River build. That
   rule exists for logos whose own lettering is illegible at header scale;
   VanderWall's horizontal lockup is a wide wordmark that reads cleanly at
   54px, so repeating the name in type beside it would be saying it twice.
   The mark gets the height instead. */
.brand img{width:auto;height:54px;flex:none}

/* ---------- mega menu ---------------------------------------------------
   Panels are opened by BUTTONS, not links: they reveal something rather than
   navigate, so they carry aria-expanded and answer to Enter, Space and Escape.
   Each column head is still a real link to the section landing page, so the
   menu never becomes the only route to a page. */
.mega{display:flex;align-items:center;gap:.35rem}
.mega-trigger,.mega-flat{background:none;border:0;cursor:pointer;
  display:inline-flex;align-items:center;gap:.3rem;
  color:var(--body);text-decoration:none;font:500 .94rem/1 var(--text);
  padding:.7rem .62rem;border-radius:var(--r)}
.mega-trigger svg{width:13px;height:13px;fill:none;stroke:currentColor;stroke-width:2.2;
  transition:transform .18s ease;opacity:.75}
.mega-trigger:hover,.mega-flat:hover,
.mega-trigger[aria-expanded="true"],.mega-flat[aria-current="page"]{color:var(--hi)}
.mega-trigger[aria-expanded="true"] svg{transform:rotate(180deg)}

/* The panel spans the viewport under the masthead. position:fixed rather than
   absolute so it is measured against the viewport and cannot be clipped by the
   header's own stacking context. */
.mega-panel{position:fixed;left:0;right:0;z-index:88;
  background:var(--bark-2);border-bottom:1px solid var(--line);
  box-shadow:0 24px 44px -28px rgba(0,0,0,.9)}
.mega-panel[hidden]{display:none}
.mega-grid{display:grid;gap:1.6rem;padding:1.7rem 0 2rem}
.mega-panel[data-cols="5"] .mega-grid{grid-template-columns:repeat(5,minmax(0,1fr))}
.mega-panel[data-cols="3"] .mega-grid{grid-template-columns:repeat(3,minmax(0,1fr));max-width:62rem}
.mega-panel[data-cols="2"] .mega-grid{grid-template-columns:repeat(2,minmax(0,1fr));max-width:42rem}
.mega-col{min-width:0}
.mega-thumb{display:block;border-radius:var(--r);overflow:hidden;margin-bottom:.75rem;
  border:1px solid var(--line)}
.mega-thumb img{width:100%;aspect-ratio:3/2;object-fit:cover;
  transition:transform .4s ease}
.mega-col:hover .mega-thumb img{transform:scale(1.05)}
.mega-col-head{display:block;font-family:var(--display);font-weight:500;font-size:1.06rem;
  color:var(--ink);text-decoration:none;margin-bottom:.5rem;
  padding-bottom:.5rem;border-bottom:1px solid var(--line)}
a.mega-col-head:hover{color:var(--hi)}
.mega-col ul{list-style:none;margin:0;padding:0}
.mega-col li{margin-bottom:.1rem}
.mega-col li a{display:block;color:var(--muted);text-decoration:none;
  font:400 .89rem/1.35 var(--text);padding:.35rem 0}
.mega-col li a:hover{color:var(--hi)}
.hdr-cta{display:flex;align-items:center;gap:.9rem;flex:none}
.tel{color:var(--ink);text-decoration:none;font:600 1.02rem/1 var(--text);white-space:nowrap}
.tel:hover{color:var(--hi);text-decoration:underline;text-underline-offset:3px}
.burger{display:none;background:none;border:1px solid #565E64;border-radius:6px;
  width:46px;height:46px;cursor:pointer;color:var(--ink);align-items:center;justify-content:center}
.burger span{display:block;width:19px;height:1.5px;background:currentColor;position:relative}
.burger span::before,.burger span::after{content:"";position:absolute;left:0;width:19px;
  height:1.5px;background:currentColor}
.burger span::before{top:-6px}.burger span::after{top:6px}

/* ---------- drawer (mobile) ---------------------------------------------
   Hidden IN PLACE, never translated off-screen. Sliding it out of the
   viewport forces overflow-x on the root to contain it, and that overflow is
   what unsticks the fixed tab bar on iPhone Safari. */
.drawer{position:fixed;inset:0;z-index:120;visibility:hidden;pointer-events:none}
.drawer[data-open="true"]{visibility:visible;pointer-events:auto}
.drawer-scrim{position:absolute;inset:0;background:rgba(23,22,24,.7);opacity:0;transition:opacity .25s}
.drawer[data-open="true"] .drawer-scrim{opacity:1}
.drawer-panel{position:absolute;top:0;right:0;height:100%;width:min(86vw,350px);
  background:var(--bark-2);border-left:1px solid var(--line);
  opacity:0;visibility:hidden;transform:scale(.97);
  transition:opacity .24s ease,transform .24s cubic-bezier(.4,0,.2,1),visibility .24s;
  display:flex;flex-direction:column;overflow-y:auto;
  /* Fourteen links plus the call button overrun an 812px screen by a little,
     so the panel scrolls. The bottom padding has to clear the iOS home
     indicator or the call button ends up half under it. */
  padding:1.1rem 1.3rem calc(2rem + env(safe-area-inset-bottom))}
.drawer[data-open="true"] .drawer-panel{opacity:1;visibility:visible;transform:none}
.drawer-top{display:flex;justify-content:flex-end;margin-bottom:.6rem}
.drawer-close{background:none;border:1px solid #565E64;border-radius:6px;width:44px;height:44px;
  color:var(--ink);font-size:1.3rem;cursor:pointer;line-height:1}
.drawer-panel a{color:var(--ink);text-decoration:none;font:500 1.05rem/1 var(--text);
  padding:.92rem 0;border-bottom:1px solid var(--line)}
.drawer-panel a:hover{color:var(--hi);text-decoration:underline;text-underline-offset:4px}
.drawer-panel .drawer-sub{font:500 .9rem/1 var(--text);color:var(--muted);padding-left:.9rem}
.drawer-panel .drawer-head{font:700 .68rem/1 var(--text);letter-spacing:.18em;
  text-transform:uppercase;color:var(--hi);padding:1.2rem 0 .5rem;border:none}
.drawer-panel .btn{margin-top:1.3rem}

/* ---------- bottom tab bar (mobile, app-like) ---------------------------
   Bark bar under a paper page, so the app chrome frames the light content top
   and bottom. The center item is a raised circular FAB pointing at the quote
   form, ringed in the bar color so it reads punched through. */
.tabbar{display:none;position:fixed;left:0;right:0;bottom:0;z-index:100;
  background:rgba(54,57,64,.97);backdrop-filter:blur(14px);border-top:1px solid var(--line);
  padding-bottom:env(safe-area-inset-bottom);
  transform:translateZ(0);will-change:transform}
.tabbar ul{display:flex;align-items:flex-end;margin:0;padding:0;list-style:none}
.tabbar li{flex:1;min-width:0}
.tabbar a{display:flex;flex-direction:column;align-items:center;gap:.22rem;
  padding:.6rem .15rem .55rem;color:var(--muted);text-decoration:none;
  font:500 .66rem/1.2 var(--text);text-align:center}
.tabbar a span{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tabbar a[aria-current="page"],.tabbar a:hover{color:var(--hi)}
.tabbar svg{width:21px;height:21px;stroke:currentColor;fill:none;stroke-width:1.6;flex:none}
.tabbar .tab-cta{flex:0 0 auto}
.tabbar .tab-cta a{
  transform:translateY(-15px);
  margin:0 .3rem;padding:.6rem 1rem .55rem;
  background:linear-gradient(160deg,var(--red),var(--red-btn-hover));color:#fff;
  border-radius:999px;font-weight:700;font-size:.68rem;gap:.14rem;
  box-shadow:0 9px 22px -7px rgba(216,50,32,.7),0 0 0 4px rgba(54,57,64,.97)}
.tabbar .tab-cta a svg{width:19px;height:19px;stroke-width:1.9}
.tabbar .tab-cta a:hover,.tabbar .tab-cta a[aria-current="page"]{color:#fff}
.tabbar .tab-cta a span{overflow:visible}
@media (max-width:359px){
  .tabbar a{font-size:.6rem}
  .tabbar .tab-cta a{padding:.58rem .72rem .52rem;font-size:.62rem}
  .tabbar svg{width:19px;height:19px}
}

/* ---------- hero -------------------------------------------------------- */
/* A wide, shortish photographic band. The bottom padding is generous because
   the cream form panel below overlaps into it. */
.hero{position:relative;
  padding:clamp(3.4rem,7vw,5.6rem) 0 clamp(6rem,11vw,9rem);
  overflow:hidden;background:var(--bark);color:var(--body)}
.hero h1,.hero h2,.hero h3{color:var(--ink)}
.hero .lede{color:var(--hero-lede)}
/* The scrim is deliberately LIGHT now. Their own Front-Page photograph is the
   hero, and burying it under an 80-94% wash defeats the point of using it.

   A uniform scrim could not do this: when this was tuned, the lightest flat
   wash that held the lede at 4.5:1 across the copy region measured 0.75 --
   barely lighter than the wash it was meant to replace. So the darkness is
   POOLED behind the text instead -- see .hero-copy::before -- and the base
   here only has to tie the photo to the dark chrome above and below it.

   NOTE: that 0.75 figure was measured against the old warm bark scrim and a
   dimmer lede. Both changed with the brand palette, so treat it as the reason
   the pool exists rather than as a current number. What IS current is
   check-hero-contrast.py, which re-measures the real stack over every hero at
   both breakpoints; the alphas below are unchanged from the bark version and
   the lede was lightened to --hero-lede to absorb the difference. */
/* --hero-size defaults to cover. The homepage overrides it to zoom in a little
   and anchor to the top, which slides the firebox DOWN the frame so the copy
   block above it has room to grow a second headline line without landing on
   the fire. It also crops off the bottom of the picture, which is wood floor. */
.hero::before{content:"";position:absolute;inset:0;z-index:1;
  background:
    linear-gradient(96deg,rgba(46,44,47,.62) 0%,rgba(46,44,47,.34) 34%,rgba(46,44,47,.26) 62%,rgba(46,44,47,.38) 100%),
    linear-gradient(180deg,rgba(46,44,47,.55) 0%,rgba(46,44,47,.12) 22%,rgba(46,44,47,.12) 72%,rgba(46,44,47,.58) 100%),
    var(--hero-bg,url("/images/hero-home.jpg")) var(--hero-pos,center 45%)/var(--hero-size,cover) no-repeat}
/* Red is a light-ground color: --accent-ink measures 2.6:1 on raisin black,
   so every panel sitting on a dark ground restates the accent as white. That
   is the brand's own rule, not a workaround — their materials never set red
   type on dark either.

   :not(.btn) matters — ".hero a" outranks ".btn-primary" on specificity, so
   without it the primary button's white label would be restyled as a link. */
.strip .eyebrow,.endcta .eyebrow,.leadcard .eyebrow,.dark .eyebrow{color:var(--hi)}
/* The hero eyebrow sits on a photograph. White is both the brand answer
   and the highest-contrast one, so it needs no separate hero value. */
.hero .eyebrow{color:var(--hi)}
.hero a:not(.btn),.leadcard a:not(.btn),.strip a:not(.btn),.dark a:not(.btn){color:var(--hi)}
.hero a:not(.btn):hover,.leadcard a:not(.btn):hover,.dark a:not(.btn):hover{
  color:var(--ink);text-decoration-thickness:2px}
.hero > .shell{position:relative;z-index:2}
/* One copy column, left, over a full-width photograph. The form used to sit
   beside it as an 890px card against a 240px copy block, which read as two
   unrelated things stacked at different heights. Lead capture now lives in
   .quickform below, straddling the bottom edge of this section. */
.hero-grid{display:grid;grid-template-columns:1fr;gap:clamp(2rem,4vw,3.4rem);align-items:center}
.hero-grid > *{min-width:0}
/* The hero headline is capped below the global h1 scale on purpose. It sits in
   a fixed band above the firebox, and at the global size it ran to two lines of
   62px and overflowed onto the fire. 48px still reads as a hero. */
.hero h1{margin-bottom:1rem;font-size:clamp(2.1rem,1.35rem + 2.3vw,3rem)}
.hero .lede{margin-bottom:1.45rem;max-width:32em}
.hero-actions{display:flex;gap:.8rem;flex-wrap:wrap}

/* The copy sits at the TOP of the hero, not centered against the form card.
   Measured on their photograph: the firebox occupies y 0.34 to 0.71 of the
   frame, and a vertically centered copy block landed at 0.38 to 0.63 -- exactly
   on the fire, which is the one thing in the picture worth seeing. Starting it
   at the top puts it on the stone above the opening and leaves the fire clear.
   That stone is bright (199/255 mean), so the pool below does the work; see
   check-hero-contrast.py, which models this position. */
.hero-copy{position:relative;isolation:isolate;align-self:start}

/* The pool. A soft radial anchored under the text, feathered to nothing well
   before the edge of the column so it reads as light falling off rather than
   as a panel with corners. Everything inside it stays above it on z. */
.hero-copy::before{content:"";position:absolute;z-index:-1;
  inset:-2.6rem -3.4rem -2.6rem -3.4rem;
  background:radial-gradient(118% 96% at 34% 50%,
    rgba(46,44,47,.84) 0%,rgba(46,44,47,.79) 42%,
    rgba(46,44,47,.52) 74%,rgba(46,44,47,0) 100%)}

/* Cap the COPY, not the shell. Putting max-width on .hero-grid also caps
   .shell, which carries margin-inline:auto -- so the block re-centered itself
   at x=409 and drifted straight onto the fireplace. The shell stays full
   width and centered; the copy is capped and sits at its left edge.
   33rem keeps type clear of the firebox, which starts at 44% of the frame. */
.hero .hero-copy{max-width:33rem}
.hero--tall{padding:clamp(4.5rem,10vw,8rem) 0 clamp(4rem,8vw,6.5rem)}
/* A hero with no form panel under it does not need the overlap reserve. */
.hero--tall,.hero--bare{padding-bottom:clamp(3rem,6vw,4.6rem)}

/* ---------- the lead panel ----------------------------------------------
   A cream card straddling the bottom edge of the hero. This is the house
   pattern (cream form card on a dark hero) and it solves the thing that was
   wrong: capture stays at the top of the page, but it is now one wide
   horizontal band instead of a tall column competing with the headline.

   Fields run in a single row on desktop and collapse to two, then one. */
.quickform{position:relative;z-index:5;
  margin-top:calc(-1 * clamp(3.2rem,6vw,5rem));
  margin-bottom:clamp(1rem,2vw,1.6rem)}
.qf-card{background:var(--paper);border:1px solid var(--line-pale);
  border-radius:var(--r);padding:clamp(1.3rem,2.6vw,2rem) clamp(1.3rem,2.6vw,2.1rem);
  box-shadow:0 34px 70px -34px rgba(46,44,47,.6),0 2px 0 rgba(255,255,255,.5) inset}
.qf-head{display:flex;flex-wrap:wrap;align-items:baseline;gap:.2rem 1rem;
  margin-bottom:1.1rem}
.qf-head h2{font-size:clamp(1.3rem,1.1rem + .7vw,1.7rem);margin:0}
.qf-head p{margin:0;color:var(--muted-dark);font-size:.94rem}
.qf-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr)) minmax(9.5rem,auto);
  gap:.85rem;align-items:end}
.qf-grid > *{min-width:0}
.qf .field{margin-bottom:0}
/* The card is light, so the form controls invert from the dark defaults. */
.qf .field label{color:var(--muted-dark)}
.qf .field .req{color:var(--red-ink)}
/* background-COLOR, not the `background` shorthand. The shorthand resets
   background-repeat to `repeat`, background-position to 0 0 and
   background-size to auto, which made the select's custom chevron tile into a
   grid of arrows across the whole control. */
.qf .field input,.qf .field select,.qf .field textarea{
  background-color:#fff;border-color:#C6C9CB;color:var(--ink-dark)}
.qf .field input:focus,.qf .field select:focus,.qf .field textarea:focus{
  border-color:var(--accent);box-shadow:0 0 0 3px rgba(216,50,32,.18)}
.qf .field select{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%235E666C' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E")}
.qf-go .btn{white-space:nowrap}
.qf-note{margin:1rem 0 0;font-size:.83rem;color:var(--muted-dark);line-height:1.55}
.qf-more{display:grid;grid-template-columns:1fr 1fr;gap:.85rem;margin-top:.95rem}
.qf-more > *{min-width:0}
.qf-more .field:nth-child(2){grid-column:1 / -1}
.qf-more .field:nth-child(3){grid-column:1 / -1}

/* The contact page uses a conventional single-column form instead of the wide
   panel: it is the content of that page, not an aside under a hero. */
/* The same panel used mid-page rather than straddling a hero, so it needs no
   negative pull and wants breathing room above it. */
.quickform--inline{margin-top:0;padding:clamp(2rem,4vw,3.2rem) 0}
.tallform{margin:0}
.tallform .field{margin-bottom:.9rem}
.tallform .two{gap:.9rem}
.contact-grid{display:grid;grid-template-columns:1.15fr .85fr;
  gap:clamp(2rem,4vw,3.4rem);align-items:start}
.contact-grid > *{min-width:0}
.contact-side h2{font-size:clamp(1.4rem,1.15rem + .8vw,1.8rem);margin-bottom:1rem}
.contact-side .loc{margin-bottom:1.2rem}

/* ---------- service-area map --------------------------------------------
   Inline SVG, drawn at build time from real boundary data. No tiles, no API
   key, no third-party script -- and every pin is a link, which the Google
   embed it replaces was not. */
.mapwrap{display:grid;grid-template-columns:1.05fr .95fr;gap:clamp(1.6rem,3.4vw,3rem);
  align-items:start}
.mapwrap > *{min-width:0}
.mapfig{background:var(--paper);border:1px solid var(--line-pale);border-radius:var(--r);
  overflow:hidden;padding:.5rem}
.svgmap{display:block;width:100%;height:auto}
.map-water{fill:#DFE4E3}          /* a cool flat tint so the lake reads as water */
.map-land{fill:var(--paper);stroke:var(--quiet);stroke-width:1.4;
  stroke-linejoin:round;paint-order:stroke fill}
.map-lake{fill:var(--muted-dark);font:600 15px/1 var(--text);letter-spacing:.22em;
  text-transform:uppercase;opacity:.55}

/* The halo is the tap target as well as the hover state. At 375px the map
   scales to about 0.59, so r=26 gives a ~30px target -- workable, and the town
   list beside it carries proper 44px rows as the primary route. */
.pin{cursor:pointer}
.pin image{transition:transform .18s ease;transform-box:fill-box;transform-origin:center bottom}
.pin-halo{fill:var(--red);opacity:0;transition:opacity .18s ease}
.pin:hover image,.pin:focus-visible image{transform:scale(1.22)}
.pin:hover .pin-halo,.pin:focus-visible .pin-halo{opacity:.14}
.pin:focus{outline:none}
.pin:focus-visible .pin-halo{opacity:.22}

/* Labels stay hidden until asked for; sixteen at once is a wall of text. The
   two showrooms are the exception, because those are the ones worth naming. */
.pin-tip{opacity:0;transition:opacity .18s ease;pointer-events:none}
.pin-tip rect{fill:var(--bark);stroke:var(--line)}
.pin-tip text{fill:var(--ink);font:600 12px/1 var(--text)}
.pin:hover .pin-tip,.pin:focus-visible .pin-tip,.pin.is-active .pin-tip{opacity:1}
.pin--showroom .pin-tip{opacity:1}
.pin--showroom .pin-tip rect{fill:var(--red-btn);stroke:var(--red-btn)}
.pin--showroom image{transform:scale(1.18)}
.pin.is-active image{transform:scale(1.3)}
.pin.is-active .pin-halo{opacity:.2}

.maplist{grid-template-columns:repeat(2,minmax(0,1fr));align-content:start}

/* ---------- careers: open roles -----------------------------------------
   Only renders once CAREERS_OPENINGS in sitecontent.py has entries. Styled
   ahead of time so adding a role is a data edit, not a design job. */
.openings{display:grid;gap:1.4rem}
.opening{background:#fff;border:1px solid var(--line-pale);border-radius:var(--r);
  border-left:3px solid var(--red);padding:clamp(1.2rem,2.4vw,1.7rem)}
.opening-head{display:flex;flex-wrap:wrap;align-items:baseline;gap:.4rem .9rem;
  margin-bottom:.5rem}
.opening-head h3{margin:0}
.pill-role{font:700 .68rem/1 var(--text);letter-spacing:.12em;text-transform:uppercase;
  color:var(--quiet);background:var(--paper-2);border:1px solid var(--line-pale);
  padding:.35rem .6rem;border-radius:3px}
.opening h4{font-family:var(--text);font-size:.72rem;font-weight:700;
  letter-spacing:.14em;text-transform:uppercase;color:var(--muted-dark);
  margin:1rem 0 .3rem}
.opening .list-tick{margin:.3rem 0 .6rem}
.opening .btn{margin-top:.8rem}

/* ---------- showroom cards ----------------------------------------------
   Both showroom pages were five sentences with no address, no hours and
   nothing about what is inside. This is the block that fixes that. */
.showrooms{display:grid;grid-template-columns:1fr 1fr;gap:clamp(1.6rem,3vw,2.4rem)}
.showrooms > *{min-width:0}
.showroom{background:#fff;border:1px solid var(--line-pale);border-radius:var(--r);
  overflow:hidden;display:flex;flex-direction:column}
.showroom figure{margin:0;aspect-ratio:16/10;overflow:hidden;background:var(--paper-3)}
.showroom figure img{width:100%;height:100%;object-fit:cover;object-position:center 50%}
.showroom-body{padding:clamp(1.2rem,2.2vw,1.7rem);display:flex;flex-direction:column;flex:1}
.showroom-body h3{margin-bottom:.5rem}
.showroom-blurb{color:var(--body-dark);font-size:.98rem}
.showroom-body address{font-style:normal;font-size:.98rem;line-height:1.7;
  color:var(--ink-dark);margin:0 0 1.2rem;padding-bottom:1.1rem;
  border-bottom:1px solid var(--line-pale)}
.showroom-body h4{font-family:var(--text);font-size:.72rem;font-weight:700;
  letter-spacing:.16em;text-transform:uppercase;color:var(--muted-dark);
  margin-bottom:.6rem}
.showroom-body .list-tick{margin:0 0 1.2rem}
.showroom-body .list-tick li{font-size:.95rem}
.showroom-body .hours{margin-top:auto}
.showroom-actions{display:flex;gap:.6rem;flex-wrap:wrap;margin-top:1.2rem}
.qf .field label.filedrop{background:#fff;border-color:#C6C9CB;color:var(--muted-dark)}
.qf .field label.filedrop:hover,.qf .field label.filedrop[data-over="true"]{
  border-color:var(--accent);color:var(--ink-dark)}
.qf .filedrop-list li{background:#fff;border-color:#C6C9CB;color:var(--body-dark)}

/* ---------- lead form, high on the page --------------------------------- */
.leadcard{background:linear-gradient(180deg,var(--bark-3),var(--bark-2));
  border:1px solid var(--line);border-radius:var(--r);padding:clamp(1.4rem,2.4vw,1.9rem);
  box-shadow:0 26px 60px -30px rgba(0,0,0,.8)}
.leadcard h2{font-size:1.42rem;margin-bottom:.35rem;color:var(--ink)}
.leadcard .sub{font-size:.93rem;color:var(--muted);margin-bottom:1.15rem}
/* The card keeps its dark panel wherever it lands, including inside a .pale
   section that restyles headings and links for a light ground. */
.pale .leadcard h2,.plain .leadcard h2{color:var(--ink)}
.pale .leadcard .sub,.pale .leadcard .formnote,
.plain .leadcard .sub,.plain .leadcard .formnote{color:var(--muted)}
.pale .leadcard .field label,.plain .leadcard .field label{color:var(--body)}
.pale .leadcard a,.plain .leadcard a{color:var(--hi)}
.pale .leadcard .field input,.pale .leadcard .field select,.pale .leadcard .field textarea,
.plain .leadcard .field input,.plain .leadcard .field select,.plain .leadcard .field textarea{color:var(--ink)}
.field{margin-bottom:.82rem}
.field label{display:block;font:700 .74rem/1.4 var(--text);letter-spacing:.07em;
  text-transform:uppercase;color:var(--body);margin-bottom:.35rem}
.field .req{color:var(--hi)}
/* 16px minimum on controls — anything smaller makes iOS zoom on focus and
   stay zoomed. min-width:0 stops a long <option> setting the select's
   intrinsic width and blowing out the grid column on a phone. */
.field input,.field select,.field textarea{
  width:100%;min-width:0;background:#232225;border:1px solid #484F55;border-radius:var(--r);
  padding:.85rem .9rem;color:var(--ink);font:400 16px/1.4 var(--text)}
.field textarea{min-height:96px;resize:vertical}
.field input:focus,.field select:focus,.field textarea:focus{border-color:var(--hi);outline:none}
.field select{appearance:none;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%239EA4AA' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right .8rem center;background-size:17px;padding-right:2.4rem}
.two{display:grid;grid-template-columns:1fr 1fr;gap:.82rem}
.two > *{min-width:0}
.formnote{font-size:.8rem;color:var(--muted);margin:.9rem 0 0;line-height:1.55}
.hp{position:absolute;left:-5000px}

/* photo uploader — click or drag. The label and the real input both sit
   inside a .field, so they are scoped by class or the generic .field rules
   out-specify them and the control goes full width and uppercase. */
.field label.filedrop{display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:.35rem;text-transform:none;letter-spacing:0;font:500 .92rem/1.4 var(--text);
  color:var(--muted);background:#232225;border:1.5px dashed #484F55;border-radius:var(--r);
  padding:1.15rem 1rem;cursor:pointer;text-align:center;margin:0}
.field label.filedrop:hover,.field label.filedrop[data-over="true"]{border-color:var(--hi);color:var(--body)}
.field label.filedrop svg{width:22px;height:22px;stroke:currentColor;fill:none;stroke-width:1.6}
.field input.filedrop-input{position:absolute;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
.filedrop-list{display:flex;flex-wrap:wrap;gap:.5rem;margin:.6rem 0 0;padding:0;list-style:none}
.filedrop-list li{display:flex;align-items:center;gap:.5rem;background:#232225;
  border:1px solid #484F55;border-radius:var(--r);padding:.35rem .55rem;
  font:500 .76rem/1.3 var(--text);color:var(--body)}
.filedrop-list img{width:34px;height:34px;object-fit:cover;border-radius:3px}
.filedrop-list span{color:var(--muted);font-size:.7rem}

/* ---------- sections ---------------------------------------------------- */
.sec{padding:clamp(3.2rem,6.5vw,5.4rem) 0}
.sec-sm{padding:clamp(2.2rem,4vw,3.4rem) 0}
section[id]{scroll-margin-top:5.5rem}
.sec-head{max-width:44em;margin-bottom:clamp(1.8rem,3.2vw,2.6rem)}
.sec-head p{color:var(--body-dark)}
.plain{background:var(--paper)}
.pale{background:var(--paper-2)}
.dark{background:var(--bark);color:var(--body)}
.dark h1,.dark h2,.dark h3,.dark h4{color:var(--ink)}
.dark .sec-head p,.dark .lede{color:var(--body)}
.dark a:hover{color:var(--ink);text-decoration-thickness:2px}

/* ---------- cards / grids ----------------------------------------------- */
.grid{display:grid;gap:1.4rem}
.g2{grid-template-columns:repeat(2,minmax(0,1fr))}
.g3{grid-template-columns:repeat(3,minmax(0,1fr))}
.g4{grid-template-columns:repeat(4,minmax(0,1fr))}

.card{background:#fff;border:1px solid var(--line-pale);border-radius:var(--r);
  overflow:hidden;display:flex;flex-direction:column;text-decoration:none;color:inherit;
  transition:.2s ease}
a.card:hover{border-color:var(--accent);transform:translateY(-3px);
  box-shadow:0 18px 34px -24px rgba(46,44,47,.55)}
.card figure{margin:0;aspect-ratio:4/3;overflow:hidden;background:var(--paper-3)}
.card figure img{width:100%;height:100%;object-fit:cover;object-position:center 45%}
.card-body{padding:1.1rem 1.2rem 1.35rem;flex:1;display:flex;flex-direction:column}
.card-body h3{margin-bottom:.4rem}
.card-body p{font-size:.95rem;color:var(--muted-dark);margin:0}
.card .more{margin-top:auto;padding-top:.9rem;font:700 .78rem/1 var(--text);
  letter-spacing:.08em;text-transform:uppercase;color:var(--red-ink)}
.dark .card{background:var(--bark-2);border-color:var(--line)}
.dark .card-body p{color:var(--muted)}
.dark .card .more{color:var(--hi)}
.dark a.card:hover{border-color:var(--hi)}

/* three pillars — fire, stone, supply. Their own division of the business. */
.pillar{position:relative;display:flex;flex-direction:column;justify-content:flex-end;
  min-height:clamp(17rem,26vw,22rem);border-radius:var(--r);overflow:hidden;
  text-decoration:none;color:#fff;isolation:isolate}
.pillar img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;z-index:-2;
  transition:transform .5s ease}
.pillar::after{content:"";position:absolute;inset:0;z-index:-1;
  background:linear-gradient(180deg,rgba(46,44,47,0) 0%,rgba(46,44,47,.10) 30%,
    rgba(46,44,47,.62) 52%,rgba(46,44,47,.88) 72%,rgba(46,44,47,.94) 100%)}
/* That ramp is measured, not styled by eye. The old two-stop version (.12 at
   30% to .82 at 100%) left only ~0.31-0.41 alpha behind the h3, and white type
   over a bright photograph at that alpha measured 1.89-3.07:1 across the five
   pillar images — i.e. the card headings were already failing WCAG before the
   palette change, on every pillar but stone. Raisin black being a lighter
   scrim than the old bark made it slightly worse, which is how it surfaced.
   Worst case now is 3.36:1 for the h3 (large, needs 3.0) and 5.12:1 for the
   paragraph (small, needs 4.5). The first 30% of the card is still untouched
   so the photograph reads. Re-measure with the pillar block in
   check-hero-contrast.py if the type sizes or the crop ever move. */
.pillar:hover img{transform:scale(1.045)}
.pillar-body{padding:1.5rem 1.5rem 1.4rem}
.pillar h3{color:#fff;font-size:clamp(1.4rem,1.1rem + .9vw,1.8rem);margin-bottom:.35rem}
.pillar p{color:rgba(255,255,255,.9);font-size:.95rem;margin:0}
.pillar .more{display:inline-block;margin-top:.85rem;font:700 .76rem/1 var(--text);
  letter-spacing:.1em;text-transform:uppercase;color:var(--hi)}

/* ---------- feature rows ------------------------------------------------ */
.split{display:grid;grid-template-columns:1fr 1fr;gap:clamp(2rem,4vw,3.4rem);align-items:center}
.split > *{min-width:0}
.split--top{align-items:start}
.readable > *{max-width:46rem}
.split.flip .split-media{order:2}
.split-media img{border-radius:var(--r);width:100%;max-height:min(30rem,70vh);
  object-fit:cover;object-position:center 42%}
.split-body h2{margin-bottom:1rem}

/* ---------- steps ------------------------------------------------------- */
/* No numerals in the markup and none drawn in. The order is the order. */
.steps{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:1.5rem}
.step{border-top:2px solid var(--accent);padding-top:1.1rem}
.step h3{font-size:1.1rem;margin-bottom:.45rem}
.step p{font-size:.94rem;color:var(--muted-dark);margin:0}
.dark .step p{color:var(--muted)}
.dark .step{border-top-color:var(--hi)}

/* ---------- proof strip ------------------------------------------------- */
.strip{border-block:1px solid var(--line);padding:2rem 0;background:var(--bark-2);color:var(--body)}
.strip-in{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:1.6rem;align-items:start}
.fact b{display:block;font:500 1.45rem/1.15 var(--display);color:var(--hi);letter-spacing:-.02em}
.fact span{display:block;font-size:.85rem;color:var(--muted);margin-top:.4rem}
.fact a{font-size:.85rem}

/* ---------- end-of-page CTA --------------------------------------------- */
.endcta{display:flex;flex-wrap:wrap;gap:1.5rem 2.4rem;align-items:center;
  justify-content:space-between;background:var(--bark-2);border:1px solid var(--line);
  border-radius:var(--r);padding:clamp(1.6rem,3vw,2.3rem);color:var(--body)}
.endcta h2{margin-bottom:.4rem;color:var(--ink)}
.endcta p{margin:0;color:var(--body);max-width:38em}
.endcta-actions{display:flex;gap:.7rem;flex-wrap:wrap;flex:none}
.endcta .btn-ghost{color:var(--ink);border-color:#565E64}
.endcta .btn-ghost:hover{border-color:var(--hi);color:var(--hi)}

/* ---------- chips / brands ---------------------------------------------- */
.brands{display:flex;flex-wrap:wrap;gap:.6rem}
.chip{display:inline-flex;align-items:center;padding:.55rem 1.05rem;border-radius:var(--r);
  border:1px solid var(--line-pale);background:#fff;color:var(--ink-dark);
  font:500 .9rem/1 var(--text);text-decoration:none}
a.chip:hover{border-color:var(--red-ink);color:var(--red-ink)}
.dark .chip{background:var(--bark-2);border-color:var(--line);color:var(--body)}
.dark a.chip:hover{border-color:var(--hi);color:var(--hi)}
.chip--flag{border-color:var(--accent);color:var(--quiet);font-weight:600}

/* ---------- testimonials ------------------------------------------------ */
.quotes{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:1.4rem}
.quote{background:#fff;border:1px solid var(--line-pale);border-left:3px solid var(--accent);
  border-radius:0 var(--r) var(--r) 0;padding:1.4rem 1.5rem}
.quote p{font-size:.98rem;color:var(--body-dark);margin-bottom:.9rem}
.quote cite{font:600 .86rem/1 var(--text);color:var(--muted-dark);font-style:normal}
.dark .quote{background:var(--bark-2);border-color:var(--line);border-left-color:var(--hi)}
.dark .quote p{color:var(--body)}
.dark .quote cite{color:var(--muted)}

/* ---------- articles ----------------------------------------------------
   Headings step down inside prose. The global scale is built for full-width
   section headers; dropped into a 44rem reading column it put a 66px H1 and a
   45px H2 into running text, which reads as a poster rather than an article.
   (Not visible until the clamp() syntax was fixed -- the whole scale had been
   falling back to browser defaults.) */
.prose{max-width:44rem}
.prose h1{font-size:clamp(2rem,1.4rem + 1.9vw,2.85rem);margin-bottom:.6rem}
.prose h2{font-size:clamp(1.45rem,1.15rem + 1.15vw,2rem)}
.prose h3{font-size:clamp(1.12rem,1.04rem + .38vw,1.3rem)}
.prose h2{margin-top:2.6rem}
.prose h3{margin-top:1.9rem;margin-bottom:.5rem}
.prose > :first-child{margin-top:0}
.prose ul,.prose ol{margin:0 0 1.2rem;padding-left:1.25rem}
.prose li{margin-bottom:.5rem}
.prose img{border-radius:var(--r);margin:1.8rem 0}
.prose blockquote{margin:1.8rem 0;padding:.2rem 0 .2rem 1.3rem;
  border-left:3px solid var(--accent);font-family:var(--display);font-size:1.2rem;
  font-style:italic;color:var(--ink-dark)}
.postmeta{font:500 .85rem/1 var(--text);color:var(--muted-dark);
  display:flex;flex-wrap:wrap;gap:.5rem 1rem;margin-bottom:1.6rem}
.postmeta .tag{color:var(--red-ink);text-transform:uppercase;letter-spacing:.1em;
  font-size:.72rem;font-weight:700}
.postcard{display:flex;flex-direction:column;background:#fff;border:1px solid var(--line-pale);
  border-radius:var(--r);padding:1.25rem 1.35rem 1.4rem;text-decoration:none;color:inherit;
  transition:.2s ease}
a.postcard:hover{border-color:var(--accent);transform:translateY(-3px);
  box-shadow:0 18px 34px -24px rgba(46,44,47,.55)}
.postcard .tag{font:700 .68rem/1 var(--text);letter-spacing:.14em;text-transform:uppercase;
  color:var(--red-ink);margin-bottom:.6rem}
.postcard h3{font-size:1.13rem;margin-bottom:.45rem}
.postcard p{font-size:.92rem;color:var(--muted-dark);margin:0 0 .9rem}
.postcard time{margin-top:auto;font:500 .8rem/1 var(--text);color:var(--muted-dark)}

/* ---------- help videos -------------------------------------------------
   Click-to-play facades. Fifteen live YouTube embeds would pull about a
   megabyte of third-party script and set cookies before anybody watched
   anything; nothing loads here until the button is pressed. */
.vidgrid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:1.2rem;
  margin:1.2rem 0 2.4rem}
.vidgrid > *{min-width:0}
.vid{display:flex;flex-direction:column;gap:.7rem}
.vid-play{position:relative;aspect-ratio:16/9;width:100%;padding:0;cursor:pointer;
  border:1px solid var(--line-pale);border-radius:var(--r);overflow:hidden;
  background:linear-gradient(150deg,var(--bark-3),var(--bark));
  display:flex;align-items:center;justify-content:center;transition:.2s ease}
.vid-play:hover{border-color:var(--accent);transform:translateY(-2px);
  box-shadow:0 18px 34px -24px rgba(46,44,47,.6)}
.vid-play svg{width:58px;height:41px;transition:transform .2s ease}
.vid-play:hover svg{transform:scale(1.08)}
.vid h3{font-size:1rem;margin:0;line-height:1.35}
.vid iframe{width:100%;aspect-ratio:16/9;border:0;border-radius:var(--r);display:block}
.prose .vidgrid h3{margin-top:0}

/* ---------- FAQ --------------------------------------------------------- */
.faq{border-top:1px solid var(--line-pale)}
.faq details{border-bottom:1px solid var(--line-pale)}
.faq summary{cursor:pointer;list-style:none;padding:1.15rem 2.5rem 1.15rem 0;position:relative;
  font-family:var(--display);font-size:1.1rem;font-weight:500;color:var(--ink-dark)}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{content:"";position:absolute;right:.4rem;top:1.55rem;width:.55rem;height:.55rem;
  border-right:2px solid var(--red-ink);border-bottom:2px solid var(--red-ink);
  transform:rotate(45deg);transition:transform .2s}
.faq details[open] summary::after{transform:rotate(-135deg)}
.faq .faq-body{padding:0 0 1.3rem;color:var(--body-dark)}
.faq .faq-body :last-child{margin-bottom:0}

/* ---------- service areas ----------------------------------------------- */
.arealist{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:.7rem;
  list-style:none;margin:0;padding:0}
.arealist a{display:block;padding:.85rem 1rem;background:#fff;border:1px solid var(--line-pale);
  border-radius:var(--r);text-decoration:none;color:var(--ink-dark);font:500 .95rem/1.3 var(--text)}
.arealist a:hover{border-color:var(--accent);color:var(--red-ink)}
.arealist .is-showroom{border-color:var(--accent);background:var(--paper-2)}
.dark .arealist a{background:var(--bark-2);border-color:var(--line);color:var(--body)}
.dark .arealist a:hover{border-color:var(--hi);color:var(--hi)}

/* ---------- locations --------------------------------------------------- */
.loc{background:#fff;border:1px solid var(--line-pale);border-radius:var(--r);padding:1.5rem 1.6rem}
.loc h3{margin-bottom:.6rem}
.loc address{font-style:normal;font-size:1rem;line-height:1.75;color:var(--body-dark)}
.loc .hours{margin-top:1rem}
.dark .loc{background:var(--bark-2);border-color:var(--line)}
.dark .loc address{color:var(--body)}
.hours{width:100%;border-collapse:collapse;font-size:.95rem}
.hours th,.hours td{text-align:left;padding:.55rem 0;border-bottom:1px solid var(--line-pale)}
.hours th{font-weight:500;color:var(--muted-dark)}
.hours td{color:var(--ink-dark);text-align:right}
.hours tr:last-child th,.hours tr:last-child td{border-bottom:none}
.dark .hours th,.dark .hours td{border-color:var(--line)}
.dark .hours th{color:var(--muted)}
.dark .hours td{color:var(--ink)}

/* ---------- footer ------------------------------------------------------
   The tab-bar reserve sits on the FOOTER, not the body. On the body it left a
   strip of paper between the dark footer and the dark tab bar, which read as
   a seam across the bottom of every page on a phone. */
.ftr{background:var(--bark);border-top:1px solid var(--line);
  padding:clamp(3rem,5vw,4.2rem) 0 calc(2rem + var(--tab-h));color:var(--body)}
.ftr-grid{display:grid;grid-template-columns:1.5fr 1fr 1fr 1.1fr;gap:2.2rem}
.ftr-grid > *{min-width:0}
.ftr h4{font-family:var(--text);font-size:.72rem;font-weight:700;letter-spacing:.18em;
  text-transform:uppercase;color:var(--hi);margin-bottom:1rem}
.ftr ul{list-style:none;margin:0;padding:0}
.ftr li{margin-bottom:.55rem}
.ftr a{color:var(--body);text-decoration:none;font-size:.94rem}
.ftr a:hover{color:var(--hi)}
.ftr .brand{margin-bottom:1rem}
.ftr .brand img{height:58px}
.ftr address{font-style:normal;font-size:.94rem;line-height:1.75}
.ftr address + address{margin-top:1rem}
.ftr-btm{margin-top:2.4rem;padding-top:1.5rem;border-top:1px solid var(--line);
  display:flex;flex-wrap:wrap;gap:1rem;justify-content:space-between;align-items:center;
  font-size:.85rem;color:var(--muted)}
.ftr-btm a{font-size:.85rem}

/* Website by Crutchfield Marketing — standard credit pill.
   color:inherit and no opacity fade. A 55% fade measured 2.0-3.5:1 on real
   client footers; inheriting lands at 5.9:1 here and still recedes, because
   it is small, muted and at the edge. Soften the border, never the text. */
.credit{display:inline-flex;align-items:center;gap:.45rem;padding:.4rem .85rem;
  border:1px solid color-mix(in srgb,currentColor 26%,transparent);
  border-radius:999px;color:inherit;text-decoration:none;font-size:.8rem}
.credit:hover{border-color:var(--hi);color:var(--hi)}
.credit svg{width:13px;height:13px;fill:#F97316;flex:none}

/* ---------- misc -------------------------------------------------------- */
.note{background:#fff;border:1px solid var(--line-pale);border-left:3px solid var(--red);
  border-radius:0 var(--r) var(--r) 0;padding:1.15rem 1.35rem;margin:1.6rem 0}
.note :last-child{margin-bottom:0}
.dark .note{background:var(--bark-2);border-color:var(--line);border-left-color:var(--hi)}
.crumbs{font-size:.84rem;color:var(--muted-dark);padding:1.1rem 0 0}
.crumbs a{color:var(--muted-dark);text-decoration:none}
.crumbs a:hover{color:var(--red-ink)}
.crumbs span{padding:0 .4rem;color:var(--line-pale)}
.dark .crumbs,.dark .crumbs a{color:var(--muted)}
/* Third-party recruiting award. The awarding body supplies black line art on a
   baked white background and a white version on transparency; the white was
   keyed out of the black one so it sits on --paper without showing a box. The
   mark's own color is untouched, which is what its usage terms expect. */
.award{display:flex;align-items:center;gap:1.1rem;margin:1.7rem 0 0;
  padding-top:1.4rem;border-top:1px solid var(--line-pale)}
/* 100px, not smaller. The "BEST AND BRIGHTEST" line is a fine serif and it
   starts to close up below about 95px. */
.award img{width:100px;height:auto;flex:none}
.award span{font-size:.93rem;color:var(--body-dark);max-width:22em}
@media (max-width:560px){
  .award{gap:.9rem}
  .award img{width:82px}
}

.list-tick{list-style:none;padding:0;margin:1.1rem 0}
.list-tick li{position:relative;padding-left:1.5rem;margin-bottom:.6rem}
.list-tick li::before{content:"";position:absolute;left:0;top:.68em;width:.42rem;height:.42rem;
  background:var(--red);border-radius:1px;transform:rotate(45deg)}
.dark .list-tick li::before{background:var(--hi)}
.figcap{font-size:.82rem;color:var(--muted-dark);line-height:1.5;margin:.6rem 0 0}
.dark .figcap{color:var(--muted)}
/* Their own photography, back on their own pages. A masonry column layout
   because the library mixes 3:2, 4:3 and portrait originals, and forcing a
   single crop on all of them loses the subject of half. break-inside stops a
   figure being split across a column. */
.gallery{columns:3;column-gap:1rem}
.gallery figure{margin:0 0 1rem;break-inside:avoid;border-radius:var(--r);
  overflow:hidden;border:1px solid var(--line-pale);background:var(--paper-3)}
.gallery img{width:100%;display:block;transition:transform .5s ease}
.gallery figure:hover img{transform:scale(1.03)}
.dark .gallery figure{border-color:var(--line);background:var(--bark-2)}

/* One wide image where a page has too few for a gallery. */
.leadfig{margin:0 0 1.8rem;border-radius:var(--r);overflow:hidden;
  border:1px solid var(--line-pale)}
.leadfig img{width:100%;display:block;max-height:26rem;object-fit:cover;
  object-position:center 45%}

/* Empty span carrying a legacy anchor id. It has to clear the sticky header
   the same way a heading does, or an old #people link lands with the section
   title hidden underneath the masthead. */
.anchor{display:block;position:relative;top:-5.5rem;visibility:hidden;height:0}
.tablewrap{overflow-x:auto;-webkit-overflow-scrolling:touch;margin:1.4rem 0}
.tablewrap table{min-width:34rem;width:100%;border-collapse:collapse;font-size:.95rem}
.tablewrap th,.tablewrap td{text-align:left;padding:.7rem .9rem;border-bottom:1px solid var(--line-pale)}
.tablewrap th{font-weight:600;color:var(--ink-dark);background:var(--paper-2)}

/* reveal on scroll */
.reveal{opacity:0;transform:translateY(14px);transition:opacity .6s ease,transform .6s ease}
.reveal.in{opacity:1;transform:none}
@media (prefers-reduced-motion:reduce){.reveal{opacity:1;transform:none}}

/* ---------- responsive --------------------------------------------------- */
@media (max-width:1000px){
  .hero-grid{grid-template-columns:1fr;gap:2.2rem}
  .g4,.steps,.arealist{grid-template-columns:repeat(2,minmax(0,1fr))}
  .quotes{grid-template-columns:repeat(2,minmax(0,1fr))}
  /* minmax(0,1fr), not 1fr — a bare fr track takes min-content as its floor,
     so the email address in the first column starves the ones beside it. */
  .ftr-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:2rem}
  .gallery{columns:2}
  /* The mega menu goes to the drawer here. Four panel triggers plus two flat
     links plus the logo and a button do not fit an 821px shell, and a mega
     panel is a pointer idiom anyway -- the drawer carries the same map. */
  .mega{display:none}
  .burger{display:inline-flex}
  /* The map has to take the full column once the layout is tight. Left in two
     columns it rendered 145px wide on a phone, with 12px pin targets. It also
     needs a ceiling once stacked: at 1000px it grew to 927x1321 and swamped
     the page it is supposed to introduce. */
  .mapwrap{grid-template-columns:1fr}
  /* justify-self, NOT margin-inline:auto. An auto inline margin on a grid item
     cancels the default stretch, so the figure shrank to fit-content and the
     SVG -- width:100% of an indefinite width -- fell back to its default 300px
     at every width below 1000. */
  .mapfig{width:100%;max-width:34rem;justify-self:center}
  .maplist{grid-template-columns:repeat(3,minmax(0,1fr))}
  /* `r` is a settable CSS property on SVG geometry in every current browser;
     the attribute stays as the fallback. Bigger halo, bigger thumb target. */
  .pin-halo{r:34}
  .mega-panel{display:none !important}
  /* The hours are the first thing to go: two showrooms wrap to three lines
     before the site has said anything. The phone and the links stay, since
     those are what the bar is for. */
  .ph-hours{display:none}
  .ph-in{justify-content:flex-end}
}
@media (max-width:860px){
  :root{--tab-h:60px}
  /* The hero stacks on a phone, so the left-to-right scrim is restacked top to
     bottom. It stays light for the same reason it does on desktop: the pool
     behind .hero-copy carries the legibility, so this only has to tie the photo
     to the chrome. */
  .hero::before{
    background:
      linear-gradient(180deg,rgba(46,44,47,.66) 0%,rgba(46,44,47,.30) 24%,rgba(46,44,47,.26) 66%,rgba(46,44,47,.70) 100%),
      var(--hero-bg,url("/images/hero-home.jpg")) var(--hero-pos,center 45%)/cover no-repeat}
  /* The form is first in SOURCE order so it lands left on desktop. On a phone
     that would put a form above the headline, asking for a phone number before
     saying whose site this is. Copy goes first here; the tab bar FAB is the
     one-tap route to the form from any scroll position. */
  .hero-grid{display:flex;flex-direction:column}
  .hero-copy{order:1}
  .hero-grid .leadcard{order:2}
  .hero-copy::before{inset:-1.6rem -1.5rem}
  /* backdrop-filter on the sticky header makes it the containing block for the
     fixed drawer inside it, capping the drawer at header height and cutting
     off the menu. Solid background on mobile is the fix. */
  .hdr{backdrop-filter:none;background:var(--bark)}
  .hdr-cta .btn{display:none}
  .tabbar{display:block}
  .g3,.g2,.quotes{grid-template-columns:1fr}
  .split,.split.flip .split-media{grid-template-columns:1fr;order:0}
  .strip-in{gap:1.5rem}
  /* Two-up before it collapses to one, so a tablet is not a column of five
     full-width inputs. The button takes the full row under them. */
  .qf-grid{grid-template-columns:repeat(2,minmax(0,1fr))}
  .qf-go{grid-column:1 / -1}
  .showrooms,.contact-grid{grid-template-columns:1fr}
  .vidgrid{grid-template-columns:repeat(2,minmax(0,1fr))}
  /* The phone number leaves the header on a phone. The tab bar carries a Call
     tab pinned to every screen, so the header copy duplicated an always-visible
     control, and that space is worth more spent saying whose site this is. */
  .hdr .tel{display:none}
  .brand img{height:40px}
  /* Touch targets. Chips measured 39px and the small buttons 38px; both are
     under the 44px a thumb wants, and there are 47 chips on /brands/. */
  .chip{padding:.72rem 1.1rem;min-height:44px}
  .btn-sm{min-height:44px}
  /* A list of 96 inline links on /site-map/ gave each one a 20px strike zone.
     Inline links inside a sentence are fine at text height; a LIST of links is
     a menu, so it gets menu-sized rows. */
  .prose ul li > a:only-child{display:block;padding:.5rem 0;min-height:44px}
  .vid h3{font-size:1.02rem}
  /* Form labels sat at 11.8px. Still small caps, but readable on a phone. */
  .field label{font-size:.79rem}
  .prose{max-width:none}
  .gallery{columns:2;column-gap:.8rem}
  .gallery figure{margin-bottom:.8rem}
  /* The preheader keeps the phone and the social row on a phone; Pinterest is
     the one that goes, because three icons plus a phone number plus two links
     is more than a 375px row holds. */
  .ph-social a:last-child{display:none}
  .ph-right{gap:.85rem}
  .preheader{font-size:.74rem}
}
@media (max-width:560px){
  body{font-size:16.5px}
  :root{--shell:min(1180px,100% - 1.6rem)}
  /* PHONE ONLY. These used to sit in the 860px block above, where they beat
     the two-up tablet steps declared alongside them -- so a 700px tablet got
     one full-width video and a one-column form for no reason. */
  .qf-grid,.qf-more{grid-template-columns:1fr}
  .qf-more .field{grid-column:auto !important}
  .vidgrid{grid-template-columns:1fr}
  .quickform{margin-top:calc(-1 * clamp(1.6rem,4vw,2.4rem))}
  .qf-head{margin-bottom:.9rem}
  .gallery{columns:2;column-gap:.7rem}
  .gallery figure{margin-bottom:.7rem}
  .two,.g4,.steps,.arealist{grid-template-columns:1fr}
  .card figure{aspect-ratio:16/10}
  .brand img{height:40px}
  .ftr .brand img{height:52px}
  .hero{padding-top:2.2rem}
  .endcta{flex-direction:column;align-items:flex-start}
  .ftr-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:1.6rem 1.2rem}
  .ftr-grid > :first-child{grid-column:1 / -1}
  .ftr address{font-size:.9rem}
  .strip-in{grid-template-columns:repeat(2,minmax(0,1fr));gap:1.4rem}
  .arealist a{padding:.95rem 1rem}
}

@media print{
  .hdr,.tabbar,.drawer,.leadcard,.skip,.endcta{display:none !important}
  body{background:#fff;color:#000}
  .ftr,.dark,.hero,.strip{background:#fff;color:#000;border-color:#ccc}
  .ftr h4,.ftr a,.ftr address,.ftr-btm,.dark h2,.dark h3,.hero h1,.hero .lede{color:#000}
  .hero::before{display:none}
  /* The page prints on white, where the light logo disappears. */
  .ftr .brand img,.hdr .brand img{content:url("/images/logo-for-light.png")}
}
