:root{
  --paper:#f5f3ee;
  --paper2:#edeae2;
  --ink:#22261f;
  --muted:#5b6152;
  --faint:#656a5d;   /* was #84897a: 3.24:1 on paper, below AA for text under 18.66px */
  --line:rgba(34,38,31,.16);
  --line-soft:rgba(34,38,31,.09);
  /* accent tokens - Sedona terracotta, signed off with Rafal.
     Values tuned so every text pairing clears WCAG AA 4.5:1; the previous
     #b25a24 sat at 4.32 on paper and 4.11 under white button labels. */
  --green:#a04f1e;
  --green-deep:#8a411a;
  --green-ink:#f6ece1;
  --acc-rgb:160,79,30;
  --accD-rgb:138,65,26;
  --onacc-rgb:246,236,225;
  --onacc-key:#f6ece1;
  --onacc-strong:#f0e2d4;
  --onacc-soft:#eadac9;
  --onacc-faint:#e0c9b3;
  --serif:"Iowan Old Style","Palatino Linotype",Palatino,Georgia,serif;
  --sans:"Seravek","Gill Sans","Segoe UI","Helvetica Neue",Arial,sans-serif;
  --navh:84px;
  /* Type scale. The sheet carried 56 distinct font-size values and 28 line
     heights; four variants of the same step differing by half a pixel are not
     a hierarchy, they are drift. Everything now snaps to these. */
  --t-nano:10.5px;   /* badges over photos */
  --t-micro:12px;    /* eyebrows, uppercase labels */
  --t-cap:13.5px;    /* captions, legal, footnotes */
  --t-sm:15px;       /* card copy, table cells */
  --t-base:16px;     /* UI text, buttons, nav */
  --t-read:18px;     /* prose */
  --t-lede:20px;     /* hero lede and standfirst */
  --h-sm:clamp(1.2rem,1.7vw,1.4rem);    /* h3, card titles, faq summary */
  --h-md:clamp(1.45rem,2.3vw,1.9rem);   /* h3 that opens a section, prose h2 */
  --h-lg:clamp(1.8rem,3.1vw,2.7rem);    /* h2 */
  --lh-read:1.7;
  --lh-head:1.2;
  /* Vertical rhythm. The sheet carried 43 distinct clamp() triples for 59 uses,
     including pairs that differed by 0.1vh. Five steps replace them. */
  --flow-xs:clamp(18px,2.4vh,32px);
  --flow-sm:clamp(22px,3vh,44px);
  --flow-md:clamp(30px,4vh,58px);
  --flow-lg:clamp(40px,6vh,78px);
  --flow-xl:clamp(72px,10vh,118px);
  /* Horizontal gutters. clamp(20px,4vw,52px) is deliberately absent: that one
     defines the content band itself and must not be folded into a scale. */
  --gut-sm:clamp(18px,2.4vw,32px);
  --gut-md:clamp(26px,3.4vw,46px);
  --gut-lg:clamp(36px,5vw,72px);
  /* One shading base instead of four near-blacks (34,38,31 / 26,22,18 /
     28,34,26 / 0,0,0) and two greenish whites that did not belong to the
     terracotta family. */
  --shade-rgb:26,22,18;
  --elev-1:0 1px 2px rgba(var(--shade-rgb),.08), 0 6px 14px rgba(var(--shade-rgb),.07);
  --elev-2:0 2px 4px rgba(var(--shade-rgb),.10), 0 12px 26px rgba(var(--shade-rgb),.10);
  --elev-3:0 3px 6px rgba(var(--shade-rgb),.14), 0 20px 44px rgba(var(--shade-rgb),.16);
  /* Content band. Every block runs the full width of .wrap, which is exactly
     the band between the left edge of the logo and the right edge of the
     "Visit Our Showroom" button - 142..1298 at a 1440 viewport. Nothing on the
     page is allowed to stop short of it. */
  --measure:100%;
  --wide:100%;
}
*{margin:0;padding:0;box-sizing:border-box}
h1,h2,h3{text-wrap:balance}
.est-alt,.lede{text-wrap:pretty}
html{scroll-behavior:smooth}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}}
body{
  background:var(--paper);
  color:var(--ink);
  font-family:var(--sans);
  font-size:var(--t-base);line-height:1.65;
  -webkit-font-smoothing:antialiased;
}
img{max-width:100%;display:block}
a{color:var(--green);text-decoration:none}
a:hover{color:var(--ink)}
:focus-visible{
  outline:2px solid var(--ink);outline-offset:3px;
  /* The light halo fills the offset gap, so one of the two rings always
     clears 3:1 against whatever sits underneath. A single terracotta ring
     measured 1.00:1 on the accent bands and 1.27:1 on the deep ones. */
  box-shadow:0 0 0 3px var(--onacc-key);
}
.wrap{max-width:1260px;margin:0 auto;padding:0 clamp(20px,4vw,52px)}
section{scroll-margin-top:110px}
/* Table-of-contents links point at <h2 id>, not at <section>, so the rule
   above never covered them and the heading parked under the sticky header. */
.prose [id],.readcol [id],.readwide [id]{scroll-margin-top:calc(var(--navh) + 26px)}

/* ---------- utility bar ---------- */
.util{background:var(--green-deep);color:var(--onacc-soft);font-size:var(--t-micro);position:relative;z-index:41}
.util .wrap{display:flex;justify-content:space-between;align-items:center;gap:16px;min-height:38px}
.util-left{display:flex;align-items:center;gap:14px;flex-wrap:wrap}
.util-left span + span{border-left:1px solid rgba(var(--onacc-rgb),.25);padding-left:14px}
.util-right{display:flex;align-items:center;gap:18px;white-space:nowrap}
.util-right a{color:var(--onacc-strong)}
.util-right a:hover{color:#fff}
/* D09: the estimate page was reachable from the footer and the mobile bar only,
   so the homepage body never once linked to it. */
.util-right .util-cta{color:var(--onacc-key);font-weight:700;
  border-bottom:1px solid rgba(var(--onacc-rgb),.55);padding-bottom:1px}
.util-right .util-cta:hover{color:#fff;border-bottom-color:#fff}
@media (max-width:900px){
  .util .wrap{justify-content:center;gap:0;padding-top:7px;padding-bottom:7px;min-height:0}
  .util-left{flex-direction:column;align-items:center;text-align:center;gap:3px}
  /* the vertical rule between items only reads as a divider on one line */
  .util-left span + span{border-left:0;padding-left:0}
  .util-left span:nth-child(3){display:none}
}
/* The phone used to vanish at 900 while the bottom bar only appeared at 760,
   leaving 761-900 (iPad portrait is 768) with no phone and no call to action. */
@media (max-width:640px){.util-right{display:none}}

/* ---------- nav: solid from the start, shadow after scroll ---------- */
header.site{
  position:sticky;top:0;z-index:40;
  background:rgba(245,243,238,.96);
  backdrop-filter:blur(14px);
  -webkit-backdrop-filter:blur(14px);
  border-bottom:1px solid var(--line-soft);
  transition:box-shadow .35s ease;
}
header.site.scrolled,
header.site.open{
  box-shadow:var(--elev-2);
}
.nav{display:flex;align-items:center;gap:18px;min-height:var(--navh);transition:min-height .35s ease}
header.site.scrolled .nav{min-height:70px}
.brand img{height:56px;width:auto;transition:height .35s ease}
header.site.scrolled .brand img{height:42px}
.menu{display:flex;align-items:center;gap:2px;list-style:none;margin-left:8px}
.menu > li{position:relative}
.menu > li > a{display:block;position:relative;white-space:nowrap;padding:14px 13px;color:var(--ink);font-size:var(--t-base);font-weight:600;letter-spacing:.01em}
.menu > li > a::after{
  content:"";position:absolute;left:13px;right:13px;bottom:8px;height:2px;
  background:var(--green);transform:scaleX(0);transform-origin:left center;
  transition:transform .28s cubic-bezier(.16,1,.3,1);
}
.menu > li > a:hover::after,
.menu > li > a:focus-visible::after,
.menu > li > a.active::after{transform:scaleX(1)}
.menu > li > a:hover,.menu > li > a.active{color:var(--green)}
/* site.js marks every matching link, but only the top level was ever styled,
   so 13 of 20 pages showed no "you are here" at all and the mobile panel never did. */
.sub a.active,.mobile-panel a.active{
  color:var(--green);font-weight:600;
  background:rgba(var(--acc-rgb),.10);
  box-shadow:inset 3px 0 0 var(--green);
}
.menu > li:has(.sub a.active) > a{color:var(--green)}
.menu > li:has(.sub a.active) > a::after{transform:scaleX(1);opacity:.45}
.menu .caret{font-size:var(--t-nano);color:var(--faint);margin-left:4px;vertical-align:2px}
.sub{
  position:absolute;top:100%;left:6px;min-width:255px;
  background:#fbfaf6;border:1px solid var(--line-soft);border-radius:10px;
  padding:8px;list-style:none;
  opacity:0;visibility:hidden;transform:translateY(6px);
  transition:opacity .18s ease,transform .18s ease,visibility .18s;
  box-shadow:var(--elev-3);
}
.menu li:hover > .sub,
.menu li:focus-within > .sub{opacity:1;visibility:visible;transform:translateY(0)}
.sub a{display:block;padding:10px 12px;color:var(--ink);font-size:var(--t-sm);border-radius:7px}
.sub a:hover{background:rgba(var(--acc-rgb),.08);color:var(--green)}
.sub .star{color:var(--green);font-size:var(--t-micro);margin-left:6px}
.nav-cta{margin-left:auto;display:flex;align-items:center;gap:18px}
.nav-phone{text-align:right;line-height:1.25}
.nav-phone a{display:block;white-space:nowrap;color:var(--ink);font-weight:700;font-size:var(--t-base);letter-spacing:.02em}
.nav-phone a:hover{color:var(--green)}
.nav-phone small{display:block;color:var(--faint);font-size:var(--t-micro);letter-spacing:.05em}
.btn{
  display:inline-block;background:var(--green);color:var(--green-ink);
  font-family:var(--sans);font-weight:600;font-size:var(--t-sm);letter-spacing:.02em;
  padding:14px 28px;border-radius:999px;border:1px solid var(--green);
  transition:transform .18s ease,background .18s ease,box-shadow .18s ease;white-space:nowrap;
}
.btn:hover{background:var(--green-deep);color:#fff;transform:translateY(-1px);box-shadow:var(--elev-1)}
.btn:active{transform:translateY(1px);box-shadow:none}
.btn.ghost{background:transparent;color:var(--green);border:1px solid rgba(var(--acc-rgb),.45)}
.btn.ghost:hover{border-color:var(--green);background:rgba(var(--acc-rgb),.07);color:var(--green);box-shadow:none}
.btn.onGreen{background:var(--paper);color:var(--green-deep);border-color:var(--paper)}
.btn.onGreen:hover{background:#fff;color:var(--green-deep)}
.btn.onGreenGhost{background:transparent;color:var(--green-ink);border:1px solid rgba(var(--onacc-rgb),.5)}
.btn.onGreenGhost:hover{border-color:var(--green-ink);color:#fff;background:transparent;box-shadow:none}
.progress{
  position:absolute;left:0;right:0;bottom:-1px;height:2px;background:var(--green);
  transform:scaleX(0);transform-origin:0 50%;opacity:0;transition:opacity .3s ease;
}
header.site.scrolled .progress{opacity:1}
@supports (animation-timeline: scroll()){
  @media (prefers-reduced-motion:no-preference){
    .progress{animation:pageProgress linear both;animation-timeline:scroll(root)}
  }
}
@keyframes pageProgress{from{transform:scaleX(0)}to{transform:scaleX(1)}}
.burger{
  display:none;margin-left:auto;background:var(--green);border:1px solid var(--green);
  border-radius:999px;color:var(--green-ink);padding:11px 20px;cursor:pointer;
  font-family:var(--sans);font-size:var(--t-cap);font-weight:600;letter-spacing:.04em;
}
header.site.open .burger{background:var(--green-deep);border-color:var(--green-deep)}
.mobile-panel{display:none}
@media (max-width:1020px){
  .menu,.nav-cta{display:none}
  .burger{display:block}
  /* The panel lives inside a position:sticky header, so page scrolling never
     revealed its bottom. With submenus open it ran to 1197px on an 844px screen
     and the last nav items were unreachable. It now scrolls inside itself. */
  header.site.open{display:flex;flex-direction:column;max-height:100dvh}
  body:has(header.site.open) .util{display:none}
  header.site.open ~ .sticky-bar{display:none}
  .mobile-panel.open{
    display:block;border-top:1px solid var(--line-soft);
    background:#fbfaf6;padding:8px 0 22px;
    flex:1 1 auto;min-height:0;
    overflow-y:auto;overscroll-behavior:contain;-webkit-overflow-scrolling:touch;
    padding-bottom:calc(22px + env(safe-area-inset-bottom));
  }
  .mobile-panel a{display:block;padding:14px clamp(20px,4vw,52px);color:var(--ink);font-size:var(--t-base);font-weight:600}
  .mobile-panel a:hover{color:var(--green)}
  .mobile-panel details{border-bottom:1px solid var(--line-soft)}
  .mobile-panel summary{
    padding:14px clamp(20px,4vw,52px);cursor:pointer;font-size:var(--t-base);font-weight:600;list-style:none;
    display:flex;justify-content:space-between;align-items:center;
  }
  .mobile-panel summary::after{content:"+";color:var(--green);font-size:var(--t-read);line-height:1}
  .mobile-panel details[open]{background:rgba(var(--acc-rgb),.045)}
  .mobile-panel details[open] summary::after{content:"\2212"}
  .mobile-panel details a{
    padding-left:calc(clamp(20px,4vw,52px) + 16px);color:var(--muted);
    font-weight:500;font-size:var(--t-sm);
  }
  .mobile-panel .m-plain,
  .mobile-panel .m-links > a{border-bottom:1px solid var(--line-soft)}
  .mobile-panel .m-cta{padding:18px clamp(20px,4vw,52px) 0;display:flex;flex-direction:column;gap:12px}
  /* .mobile-panel a wins on specificity over .btn, so restate the button colours */
  .mobile-panel .m-cta .btn{text-align:center;color:var(--green-ink);font-weight:600}
  .mobile-panel .m-cta .btn:hover{color:#fff}
  .mobile-panel .m-cta .btn.ghost{color:var(--green);background:transparent}
  .mobile-panel .m-cta .btn.ghost:hover{color:var(--green)}
}

/* ---------- hero: full-bleed photo behind type ---------- */
.hero{
  position:relative;z-index:0;overflow:hidden;
  min-height:min(84dvh,820px);
  display:flex;flex-direction:column;
}
.hero-media{position:absolute;inset:0;z-index:0}
.hero-media img{
  width:100%;height:114%;object-fit:cover;object-position:62% 74%;
  background:var(--paper2);
}
@supports (animation-timeline: view()){
  @media (prefers-reduced-motion:no-preference){
    .hero-media img{animation:heroPar linear both;animation-timeline:view()}
  }
}
@keyframes heroPar{from{transform:translateY(0)}to{transform:translateY(-8%)}}
.hero-media .scrim{
  position:absolute;inset:0;z-index:2;
  background:
    linear-gradient(90deg,rgba(245,243,238,.97) 0%,rgba(245,243,238,.88) 30%,rgba(245,243,238,.44) 58%,rgba(245,243,238,.05) 82%),
    linear-gradient(180deg,rgba(245,243,238,.72) 0%,rgba(245,243,238,0) 24%);
}
.planks{
  position:absolute;inset:0;z-index:3;pointer-events:none;
  display:grid;grid-template-columns:repeat(6,1fr);
}
.planks i{background:var(--paper);transform:translateY(-101%)}
@media (prefers-reduced-motion:no-preference){
  .js .planks i{animation:plankAway .85s cubic-bezier(.65,0,.35,1) both}
  .js .planks i:nth-child(1){animation-delay:.10s}
  .js .planks i:nth-child(2){animation-delay:.20s}
  .js .planks i:nth-child(3){animation-delay:.30s}
  .js .planks i:nth-child(4){animation-delay:.40s}
  .js .planks i:nth-child(5){animation-delay:.50s}
  .js .planks i:nth-child(6){animation-delay:.60s}
}
@keyframes plankAway{from{transform:translateY(0)}to{transform:translateY(-101%)}}
.hero-inner{
  position:relative;z-index:2;flex:1;width:100%;
  display:flex;align-items:center;
}
.hero-copy{max-width:680px;padding:var(--flow-lg) 0}
.kicker{
  font-size:var(--t-micro);letter-spacing:.22em;text-transform:uppercase;
  color:var(--green);font-weight:600;margin-bottom:20px;
}
h1{
  font-family:var(--serif);font-weight:500;
  font-size:clamp(2.35rem,5vw,4.4rem);
  line-height:1.08;letter-spacing:-.01em;
}
h1 br{display:none}
@media (min-width:761px){h1 br{display:inline}}
h1 i{font-style:italic;color:var(--green);line-height:1.1;padding-bottom:4px}
.hero-sub{color:var(--muted);font-size:var(--t-read);max-width:44ch;margin-top:24px}
.hero-ctas{display:flex;gap:13px;margin-top:30px;flex-wrap:wrap}
@media (prefers-reduced-motion:no-preference){
  .js .hero-rise{opacity:0;transform:translateY(22px);animation:rise .75s cubic-bezier(.16,1,.3,1) both}
  .js .hero-rise.r2{animation-delay:.14s}
  .js .hero-rise.r3{animation-delay:.26s}
  .js .hero-rise.r4{animation-delay:.38s}
  .js .hero-band{opacity:0;animation:fadeIn .8s ease .55s both}
}
@keyframes rise{to{opacity:1;transform:none}}
@keyframes fadeIn{to{opacity:1}}
.hero-band{
  position:relative;z-index:2;
  border-top:1px solid var(--line);
  background:rgba(245,243,238,.72);
  backdrop-filter:blur(10px);
  -webkit-backdrop-filter:blur(10px);
}
.hero-band ul{
  list-style:none;display:grid;grid-template-columns:repeat(4,minmax(0,1fr));
  gap:14px 24px;padding-top:18px;padding-bottom:18px;
}
.hero-band li{font-size:var(--t-cap);color:var(--muted)}
.hero-band strong{
  font-family:var(--serif);font-size:24px;color:var(--ink);
  font-weight:600;margin-right:8px;letter-spacing:0;
}
@media (max-width:760px){
  .hero{min-height:min(88dvh,760px)}
  .hero-media img{object-position:56% 78%}
  .hero-media .scrim{
    background:
      linear-gradient(180deg,rgba(245,243,238,.94) 0%,rgba(245,243,238,.84) 42%,rgba(245,243,238,.6) 72%,rgba(245,243,238,.4) 100%);
  }
  .hero-band ul{grid-template-columns:repeat(2,minmax(0,1fr));gap:10px 18px}
  .hero-band strong{font-size:20px}
}

/* ---------- shared ---------- */
.section{padding:var(--flow-xl) 0}
.section.tint{background:var(--paper2)}
h2{
  font-family:var(--serif);font-weight:500;
  font-size:var(--h-lg);line-height:1.12;letter-spacing:-.005em;
}
.section-head{max-width:var(--measure);margin-bottom:var(--flow-md)}

/* The intro beside a heading is a STANDFIRST, not body copy. Left unstyled it
   read as a paragraph shoved into the spare column - no size difference, no
   colour difference, nothing marking where it starts. It now carries a short
   accent rule, sits a step larger than body text and, on wide screens, starts
   on the same optical line as the heading's cap height. */
.section-head > p:not(.eyebrow){
  font-family:var(--serif);font-weight:400;
  color:var(--ink);margin-top:20px;max-width:var(--measure);
  font-size:clamp(1.12rem,1.5vw,1.3rem);line-height:1.5;
  letter-spacing:-.003em;text-wrap:pretty;
}
.section-head > p:not(.eyebrow) b,
.section-head > p:not(.eyebrow) strong{font-weight:600}
.section-head > p:not(.eyebrow)::before{
  content:"";display:block;width:44px;height:2px;background:var(--green);
  margin-bottom:18px;
}

/* On wide screens the heading and its standfirst sit side by side instead of
   leaving half the row empty. The eyebrow takes its own row so the standfirst
   can align to the h2 rather than to the eyebrow above it.
   Heads that are just an <h2> keep the narrow measure - nothing to pair. */
@media (min-width:1080px){
  .wrap > .section-head:has(> p:not(.eyebrow)){
    max-width:none;display:grid;
    grid-template-columns:minmax(0,1.05fr) minmax(0,1fr);
    column-gap:var(--gut-lg);
    align-items:start;
  }
  .wrap > .section-head:has(> p:not(.eyebrow)) > .eyebrow{
    grid-column:1;grid-row:1;max-width:none;
  }
  .wrap > .section-head:has(> p:not(.eyebrow)) > h2{grid-column:1;grid-row:2}
  .wrap > .section-head:has(> p:not(.eyebrow)) > p:not(.eyebrow){
    grid-column:2;grid-row:2;margin-top:0;max-width:44ch;
  }
  /* nudge the rule down onto the heading's cap line, not its em box */
  .wrap > .section-head:has(> p:not(.eyebrow)) > p:not(.eyebrow)::before{
    margin-top:7px;
  }
}
.arrow-link{font-weight:500;font-size:var(--t-sm);color:var(--green);letter-spacing:.02em}
.arrow-link:hover{color:var(--ink)}

/* ---------- full-bleed photo chapters ---------- */
.chapter{
  position:relative;overflow:hidden;color:var(--onacc-key);
  min-height:clamp(430px,64vh,660px);
  display:flex;align-items:center;
}
.ch-bg{position:absolute;left:0;right:0;top:-9%;bottom:-9%;z-index:0}
.ch-bg img{width:100%;height:100%;object-fit:cover}
.ch-bg::after{
  content:"";position:absolute;inset:0;
  /* light overall knock-back plus a soft left-anchored pool under the type,
     instead of a flat dark sheet across the whole photo */
  background:
    linear-gradient(100deg,rgba(26,22,18,.62) 0%,rgba(26,22,18,.44) 34%,rgba(26,22,18,.14) 62%,rgba(26,22,18,.06) 100%),
    linear-gradient(to top,rgba(26,22,18,.34) 0%,rgba(26,22,18,.10) 40%,rgba(26,22,18,0) 72%);
}
.chapter.right .ch-bg::after{
  background:
    linear-gradient(260deg,rgba(26,22,18,.62) 0%,rgba(26,22,18,.44) 34%,rgba(26,22,18,.14) 62%,rgba(26,22,18,.06) 100%),
    linear-gradient(to top,rgba(26,22,18,.34) 0%,rgba(26,22,18,.10) 40%,rgba(26,22,18,0) 72%);
}
@media (max-width:760px){
  .ch-bg::after,.chapter.right .ch-bg::after{
    background:linear-gradient(to top,rgba(26,22,18,.68) 0%,rgba(26,22,18,.42) 46%,rgba(26,22,18,.24) 100%);
  }
}
/* Parallax is driven from site.js, not by animation-timeline:view(). The CSS
   version attached an animation but never moved the image (translateY stayed at
   0 through the whole scroll range), and it has no support in Safari or Firefox.
   The band is 118% tall (.ch-bg is inset -9% top and bottom), so the image can
   travel +/-8% without ever showing an edge. */
.ch-bg img{will-change:transform}
.ch-inner{position:relative;z-index:1;width:100%}
.ch-line{
  font-family:var(--serif);font-weight:500;
  font-size:clamp(1.9rem,4.2vw,3.4rem);line-height:1.14;letter-spacing:-.005em;
  max-width:21ch;text-wrap:balance;
  text-shadow:0 2px 26px rgba(0,0,0,.3);
}
.ch-line i{font-style:italic}
.ch-note{color:var(--onacc-soft);margin-top:16px;font-size:var(--t-sm);max-width:44ch;text-shadow:0 1px 14px rgba(0,0,0,.3)}
.chapter.right .ch-inner{display:flex;justify-content:flex-end}
.chapter.right .ch-block{text-align:right}
.chapter.right .ch-note{margin-left:auto}
@media (max-width:760px){
  .chapter{min-height:min(72vh,520px)}
  .chapter .ch-bg img{object-position:center 70%}
  .chapter.right .ch-inner{justify-content:flex-start}
  .chapter.right .ch-block{text-align:left}
  .chapter.right .ch-note{margin-left:0}
}

/* ---------- services (asymmetric trio) ---------- */
/* Services: one lead card at full width, two supporting cards beneath it at half
   the visual weight. Installation is the thing Rafal wants the page to sell, so
   it gets the photograph, the larger type and the only solid button. */
.svc-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:22px}

.svc-lead{
  /* 1fr 1fr, not 1.08fr 1fr: the photo column then measures exactly the same
     as one .svc-minor card underneath, so the three photos line up. */
  grid-column:1 / -1;display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  background:#fbfaf6;border:1px solid var(--line-soft);overflow:hidden;
}
/* the text block sets the row height and the photo fills it. Letting the
   photo drive it stretched the card to ~800 px and left the text floating in
   a sea of empty paper. */
.svc-lead .ph{overflow:hidden;aspect-ratio:4/3}
.svc-lead{column-gap:22px}
.svc-lead .ph img{width:100%;height:100%;object-fit:cover;transition:transform .7s cubic-bezier(.16,1,.3,1)}
.svc-lead:hover .ph img{transform:scale(1.04)}
.svc-lead .tx{padding:var(--gut-md);display:flex;flex-direction:column;justify-content:center}
.svc-lead h3{font-family:var(--serif);font-weight:600;font-size:var(--h-md);line-height:1.14;margin-top:12px}
.svc-lead p{color:var(--muted);font-size:var(--t-base);line-height:1.68;margin-top:12px;max-width:48ch}
.svc-lead .btn{align-self:flex-start;margin-top:22px}

.svc-minor{display:flex;flex-direction:column;background:#fbfaf6;border:1px solid var(--line-soft);overflow:hidden}
.svc-minor .ph{overflow:hidden;aspect-ratio:7/3}
.svc-minor .ph img{width:100%;height:100%;object-fit:cover;transition:transform .7s cubic-bezier(.16,1,.3,1)}
.svc-minor:hover .ph img{transform:scale(1.04)}
.svc-minor .tx{padding:24px 26px 26px;display:flex;flex-direction:column;flex:1}
.svc-minor h3{font-family:var(--serif);font-weight:600;font-size:var(--h-sm);line-height:1.2}
.svc-minor p{color:var(--muted);font-size:var(--t-sm);line-height:1.62;margin-top:9px;flex:1}
.svc-minor .arrow-link{margin-top:16px}

.svc-grid h3 a{color:var(--ink)}
.svc-grid h3 a:hover{color:var(--green)}
.svc-grid p b{color:var(--ink);font-weight:600}
@media (max-width:900px){
  .svc-grid{grid-template-columns:1fr}
  .svc-lead{grid-template-columns:1fr}
  .svc-lead .ph{aspect-ratio:16/9}
}

/* ---------- floors: tight overlay cards ---------- */
.floor-cards{display:grid;grid-template-columns:1fr 1fr;gap:20px}
/* Floor cards: the caption used to sit ON the photo behind a gradient. On a pale
   oak floor that gave the heading 3.09:1 and the badge 2.56:1, and it buried the
   lower half of every image. Photo on top, caption on a solid panel below - the
   contrast is then fixed for any photograph we ever drop in. */
.fcard{
  position:relative;display:flex;flex-direction:column;overflow:hidden;
  background:#fbfaf6;border:1px solid var(--line-soft);color:var(--ink);
  transition:transform .24s cubic-bezier(.16,1,.3,1),box-shadow .24s ease,border-color .24s ease;
}
.fcard > img{
  width:100%;height:auto;aspect-ratio:5/2;object-fit:cover;display:block;
  transition:transform .8s cubic-bezier(.16,1,.3,1);
}
.fcard .imgwrap{overflow:hidden;position:relative}
.fcard:hover > img,.fcard:hover .imgwrap > img{transform:scale(1.04)}
.fcard:hover{transform:translateY(-3px);box-shadow:var(--elev-1);border-color:rgba(var(--acc-rgb),.35)}
.fcard .fx{position:relative;z-index:1;padding:24px 28px 28px;display:flex;flex-direction:column;flex:1}
.fcard h3{font-family:var(--serif);font-weight:600;font-size:var(--h-md);line-height:1.15;color:var(--ink)}
.fcard p{color:var(--muted);font-size:var(--t-sm);line-height:1.66;margin-top:10px;flex:1}
.fcard .arrow-link{display:inline-block;margin-top:18px;color:var(--green)}
.fcard:hover .arrow-link{color:var(--green-deep)}

/* The one thing that stays on the photo is a solid pill, so its contrast
   never depends on what is underneath it. */
.spec-flag{
  position:absolute;top:16px;left:16px;z-index:2;
  display:inline-block;font-size:var(--t-micro);letter-spacing:.16em;text-transform:uppercase;
  color:var(--green-ink);background:var(--green-deep);border-radius:999px;
  padding:6px 13px;font-weight:600;
}
@media (max-width:860px){
  .floor-cards{grid-template-columns:1fr}
}

/* ---------- how we work (rail timeline + photo) ---------- */
.about-grid{
  display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  gap:var(--gut-lg);align-items:center;
}
.about-media{position:relative}
.about-media::after{
  content:"";position:absolute;inset:16px -16px 74px 16px;
  border:1px solid rgba(var(--acc-rgb),.35);z-index:0;
}
.about-media img{
  position:relative;z-index:1;width:100%;height:auto;aspect-ratio:1/1;object-fit:cover;
}
/* The caption used to float on the photograph. It sits under it now, so a group
   shot never has a panel across somebody's face. */
.about-media figcaption{
  position:relative;z-index:2;margin-top:16px;font-size:var(--t-cap);color:var(--muted);line-height:1.6;
}
.about-media figcaption b{display:block;color:var(--ink);font-family:var(--serif);font-size:var(--t-base);font-weight:500;margin-bottom:4px}
@media (max-width:900px){
  .about-grid{grid-template-columns:1fr}
  .about-media{max-width:560px}
  .about-media::after{display:none}
  .about-media img{aspect-ratio:4/3}
}
.about-note{color:var(--muted);max-width:var(--measure);margin-top:14px}
.about-note b{color:var(--ink);font-weight:600}
.rail{list-style:none;max-width:var(--measure);position:relative;margin-top:10px}
.rail::before{
  content:"";position:absolute;left:17px;top:14px;bottom:14px;width:1px;background:var(--line);
}
.rail li{position:relative;padding:0 0 40px 66px}
.rail li:last-child{padding-bottom:0}
.rail .dot{
  position:absolute;left:0;top:0;width:35px;height:35px;border-radius:50%;
  background:var(--paper);border:1px solid var(--green);color:var(--green);
  display:flex;align-items:center;justify-content:center;
  font-family:var(--serif);font-size:var(--t-base);font-weight:600;
}
.rail h3{font-family:var(--serif);font-weight:600;font-size:var(--h-sm);line-height:1.25}
.rail p{color:var(--muted);margin-top:8px;font-size:var(--t-sm);max-width:52ch}
.rail p b{color:var(--ink);font-weight:600}

/* ---------- gallery mosaic ---------- */
.mosaic-head{display:flex;justify-content:space-between;align-items:flex-end;gap:24px;margin-bottom:34px}
.mosaic{
  display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  grid-auto-rows:215px;grid-auto-flow:dense;gap:14px;
}
.mosaic figure{overflow:hidden;position:relative}
.mosaic figure.tall{grid-row:span 2}
.mosaic img{width:100%;height:100%;object-fit:cover;transition:transform .7s cubic-bezier(.16,1,.3,1);object-position:50% 62%}
.mosaic a:hover img,.mosaic a:focus-visible img{transform:scale(1.05)}
.mosaic figure::after{
  content:"";position:absolute;inset:0;background:rgba(var(--accD-rgb),0);
  transition:background .4s ease;pointer-events:none;
}
.mosaic a:hover::after,.mosaic a:focus-visible::after{background:rgba(var(--accD-rgb),.12)}
@media (max-width:860px){
  .mosaic{grid-template-columns:repeat(2,minmax(0,1fr));grid-auto-rows:170px}
}
@media (max-width:520px){
  .mosaic{grid-auto-rows:130px}
}

/* ---------- reviews ---------- */
.rev-feature{max-width:var(--wide)}
.rev-feature blockquote{
  font-family:var(--serif);font-weight:500;
  font-size:clamp(1.4rem,2.5vw,2.05rem);line-height:1.35;letter-spacing:-.005em;
}
.rev-feature blockquote::before{content:"\201C";color:var(--green)}
.rev-feature blockquote::after{content:"\201D";color:var(--green)}
cite{display:block;font-style:normal;color:var(--faint);font-size:var(--t-cap);margin-top:16px;letter-spacing:.03em}
.rev-head{display:flex;justify-content:space-between;align-items:flex-end;gap:24px}
.rev-nav{display:flex;gap:10px;flex-shrink:0}
.rev-nav button{
  width:46px;height:46px;border-radius:50%;cursor:pointer;
  background:transparent;border:1px solid rgba(var(--acc-rgb),.45);color:var(--green);
  font-size:var(--t-read);line-height:1;transition:background .2s ease,color .2s ease,border-color .2s ease;
}
.rev-nav button:hover{background:var(--green);color:var(--green-ink);border-color:var(--green)}
.rev-track{
  display:grid;grid-auto-flow:column;grid-auto-columns:min(400px,82%);
  gap:18px;margin-top:var(--flow-md);
  overflow-x:auto;scroll-snap-type:x mandatory;scroll-behavior:smooth;
  padding:2px 2px 10px;
  scrollbar-width:none;
  -webkit-mask-image:linear-gradient(90deg,#000 92%,transparent);
  mask-image:linear-gradient(90deg,#000 92%,transparent);
}
.rev-track::-webkit-scrollbar{display:none}
.rev-card{
  scroll-snap-align:start;
  background:#fbfaf6;border:1px solid var(--line-soft);
  padding:26px 28px;display:flex;flex-direction:column;
}
.rev-card blockquote{color:var(--muted);font-size:var(--t-sm);flex:1}
.rev-card blockquote::before{content:"\201C"}
.rev-card blockquote::after{content:"\201D"}
.rev-card cite{margin-top:18px}
.rev-card .stars{display:block;font-size:var(--t-cap);margin-bottom:12px}
.google-badge{display:inline-flex;align-items:baseline;gap:10px;margin-top:26px;color:var(--muted);font-size:var(--t-cap)}
.google-badge strong{font-family:var(--serif);font-size:30px;color:var(--ink);font-weight:600}
.stars{color:var(--green);letter-spacing:2px;font-size:var(--t-sm)}
@media (max-width:760px){.rev-head{flex-direction:column;align-items:flex-start}.rev-track{grid-auto-columns:88%}}

/* ---------- showroom (green color block) ---------- */
.visit{background:var(--green-deep);color:var(--green-ink)}
.visit .wrap{padding-top:var(--flow-xl);padding-bottom:var(--flow-xl)}
.visit-grid{display:grid;grid-template-columns:minmax(0,6fr) minmax(0,6fr);gap:var(--gut-lg);align-items:center}
.visit h2{color:var(--onacc-key);max-width:15ch}
.visit-info > p{color:var(--onacc-soft);margin-top:16px;max-width:48ch}
.visit-facts{list-style:none;margin-top:30px;border-top:1px solid rgba(var(--onacc-rgb),.2)}
.visit-facts li{
  display:grid;grid-template-columns:130px 1fr;gap:18px;
  padding:14px 0;border-bottom:1px solid rgba(var(--onacc-rgb),.2);font-size:var(--t-sm);
}
.visit-facts .k{color:var(--onacc-faint);font-size:var(--t-micro);letter-spacing:.14em;text-transform:uppercase;padding-top:2px;font-weight:500}
.visit-facts .v{color:var(--onacc-key);min-width:0;overflow-wrap:anywhere}
.visit-facts .v small{display:block;color:var(--onacc-soft);font-size:var(--t-cap);margin-top:2px}
.visit-facts a{color:var(--onacc-strong);text-decoration:underline;text-underline-offset:3px}
.visit-facts a:hover{color:#fff}
.visit-ctas{display:flex;gap:14px;margin-top:28px;flex-wrap:wrap}
.visit-media{position:relative}
.visit-media::after{
  content:"";position:absolute;inset:14px -14px -14px 14px;
  border:1px solid rgba(var(--onacc-rgb),.3);z-index:0;
}
.visit-media img{position:relative;z-index:1;width:100%;height:auto;aspect-ratio:4/5;object-fit:cover}
@media (max-width:900px){
  .visit-grid{grid-template-columns:1fr}
  .visit-media::after{display:none}
  .visit-media img{aspect-ratio:4/3}
}

/* ---------- contact form ---------- */
/* .estimate is used together with .section, so zero the section padding -
   otherwise the two stack and the block gets ~200px of dead space each side */
.estimate.section{padding-top:0;padding-bottom:0}
.estimate .wrap{padding-top:var(--flow-lg);padding-bottom:var(--flow-lg)}
/* same column split and gap as .visit-grid above, so the form card sits on
   exactly the same axis as the showroom photograph */
.est-grid{display:grid;grid-template-columns:minmax(0,6fr) minmax(0,6fr);gap:var(--gut-lg);align-items:start}
.est-intro p{color:var(--muted);margin-top:14px;max-width:44ch}
.est-alt{margin-top:26px;padding-top:22px;border-top:1px solid var(--line);font-size:var(--t-sm);color:var(--muted)}
.est-alt a{font-weight:500}
.form-card{
  background:#fbfaf6;border:1px solid var(--line-soft);
  padding:var(--gut-md);
  box-shadow:var(--elev-2);
}
.form-grid{display:grid;grid-template-columns:1fr 1fr;gap:18px}
.form-grid .full{grid-column:1/-1}
.field label{display:block;font-size:var(--t-micro);letter-spacing:.12em;text-transform:uppercase;color:var(--faint);font-weight:500;margin-bottom:7px}
.field input,.field select,.field textarea{
  width:100%;background:#fff;border:1px solid var(--line);
  padding:13px 14px;font-family:var(--sans);font-size:var(--t-sm);color:var(--ink);
  border-radius:0;appearance:none;-webkit-appearance:none;
  transition:border-color .2s ease,box-shadow .2s ease;
}
.field select{
  background-image:linear-gradient(45deg,transparent 50%,var(--muted) 50%),linear-gradient(135deg,var(--muted) 50%,transparent 50%);
  background-position:calc(100% - 20px) 50%,calc(100% - 15px) 50%;
  background-size:5px 5px;background-repeat:no-repeat;
}
.field textarea{min-height:120px;resize:vertical}
.field input:focus,.field select:focus,.field textarea:focus{
  border-color:var(--green);
}
.field input:focus-visible,.field select:focus-visible,.field textarea:focus-visible{
  outline:2px solid var(--ink);outline-offset:3px;box-shadow:0 0 0 3px var(--onacc-key);
}
.form-foot{display:flex;align-items:center;justify-content:space-between;gap:18px;margin-top:22px;flex-wrap:wrap}
.form-foot small{color:var(--faint);font-size:var(--t-cap);max-width:34ch}
.form-ok{
  display:none;margin-top:18px;padding:14px 18px;font-size:var(--t-sm);
  background:rgba(var(--acc-rgb),.1);border:1px solid rgba(var(--acc-rgb),.3);color:var(--green-deep);
}
.form-ok.show{display:block}

/* Nothing in the sheet reacted to :disabled, so after sending, the button kept
   the full accent background and read as still clickable. */
button.btn{cursor:pointer}
.btn:disabled,.btn[disabled]{
  background:transparent;color:var(--faint);border-color:var(--line);
  box-shadow:none;transform:none;cursor:not-allowed;
}
.btn[data-state="busy"]{
  background:var(--green-deep);border-color:var(--green-deep);
  cursor:progress;pointer-events:none;
}
.btn[data-state="busy"]::before{
  content:"";display:inline-block;width:12px;height:12px;
  border:2px solid rgba(var(--onacc-rgb),.45);border-top-color:var(--onacc-key);
  border-radius:50%;margin-right:9px;vertical-align:-1px;
  animation:btnSpin .7s linear infinite;
}
@keyframes btnSpin{to{transform:rotate(360deg)}}
@media (prefers-reduced-motion:reduce){
  /* the spinner is information, not decoration, so it slows rather than stops */
  .btn[data-state="busy"]::before{animation-duration:2.4s}
}

/* D07: which fields are required, and one consistent rule across all three forms */
.field label .req{color:var(--green);font-weight:700;margin-left:3px}
.form-legend{font-size:var(--t-cap);color:var(--faint);margin-bottom:18px}
.form-legend .req{color:var(--green);font-weight:700}
/* N-02: the empty first option must read as a prompt, not as a chosen answer.
   Both selects used to default to "New floor installation", so anyone who
   never touched the field filed a job they had not asked for. */
.field select:has(option[value=""]:checked){color:var(--faint)}
@media (max-width:900px){
  .est-grid{grid-template-columns:1fr}
  .form-grid{grid-template-columns:1fr}
}

/* ---------- service area ---------- */
.area .wrap{padding-top:var(--flow-md);padding-bottom:var(--flow-lg)}
.area h2{font-size:var(--h-md)}
.area ul{list-style:none;display:flex;flex-wrap:wrap;gap:10px 0;margin-top:18px}
.area li{color:var(--muted);font-size:var(--t-sm)}
.area li + li{border-left:1px solid var(--line);margin-left:16px;padding-left:16px}
.area .tail{color:var(--faint);font-size:var(--t-cap);margin-top:12px}

/* ---------- footer ---------- */
footer{border-top:1px solid var(--line-soft);background:var(--paper2);padding:var(--flow-lg) 0 0}
.foot-grid{display:grid;grid-template-columns:minmax(0,4fr) repeat(3,minmax(0,2.4fr));gap:36px}
.foot-brand img{height:38px;width:auto}
.foot-brand address{font-style:normal;color:var(--muted);font-size:var(--t-sm);margin-top:18px;line-height:1.75}
.foot-brand a{color:var(--green)}
/* D14: the sheet styled footer h4 while build.py emits h3, so this rule was dead
   and 60 footer column headings across 20 pages fell back to the browser default:
   sans-serif 18.72px at weight 700, the loudest thing in the footer. */
footer h3{font-size:var(--t-micro);letter-spacing:.16em;text-transform:uppercase;color:var(--faint);margin-bottom:16px;font-weight:500}
footer ul{list-style:none}
footer ul li{margin-bottom:10px}
footer ul a{color:var(--muted);font-size:var(--t-sm)}
footer ul a:hover{color:var(--green)}
.foot-legal{border-top:1px solid var(--line-soft);margin-top:var(--flow-md);padding:20px 0;color:var(--faint);font-size:var(--t-cap)}
.foot-legal .wrap{display:flex;justify-content:space-between;gap:14px;flex-wrap:wrap}
@media (max-width:860px){.foot-grid{grid-template-columns:1fr 1fr}}
@media (max-width:560px){.foot-grid{grid-template-columns:1fr}}

/* ---------- mobile sticky bar ---------- */
.sticky-bar{display:none}
@media (max-width:1020px){
  body{padding-bottom:64px}
  .sticky-bar{
    display:grid;grid-template-columns:1fr 1fr;
    position:fixed;left:0;right:0;bottom:0;z-index:60;
    border-top:1px solid var(--line);
    padding-bottom:env(safe-area-inset-bottom);
    background:#fbfaf6;
  }
  .sticky-bar a{
    display:flex;align-items:center;justify-content:center;
    min-height:56px;font-weight:600;font-size:var(--t-cap);letter-spacing:.03em;
  }
  .sticky-bar .call{background:var(--green);color:var(--green-ink)}
  .sticky-bar .est{color:var(--green-deep)}
}

/* ---------- reveal motion ---------- */
@media (prefers-reduced-motion:no-preference){
  .js .reveal{opacity:0;transform:translateY(20px);transition:opacity .7s cubic-bezier(.16,1,.3,1),transform .7s cubic-bezier(.16,1,.3,1)}
  .js .reveal.in{opacity:1;transform:none}
  .js .mosaic .reveal:nth-child(2){transition-delay:.07s}
  .js .mosaic .reveal:nth-child(3){transition-delay:.14s}
  .js .mosaic .reveal:nth-child(4){transition-delay:.21s}
  .js .mosaic .reveal:nth-child(5){transition-delay:.28s}
  .js .mosaic .reveal:nth-child(6){transition-delay:.35s}
}

/* ============================================================
   INNER PAGES - components added on top of the taste-2b system
   ============================================================ */

/* ---------- compact page hero ---------- */
.pagehero{
  position:relative;overflow:hidden;
  /* Heights ranged 327-627px across 11 different values with no floor, so the
     same component read as a banner on one page and a strip on the next. */
  min-height:clamp(480px,52vh,566px);
  display:flex;align-items:center;
  background:var(--paper2);
  border-bottom:1px solid var(--line-soft);
}
.pagehero .ph-media{position:absolute;inset:0;z-index:0}
/* Vertical 3:4 photographs sat in horizontal frames and object-fit cropped from
   the centre, which on an interior shot means ceiling. Aim lower. */
.pagehero .ph-media img{width:100%;height:100%;object-fit:cover;object-position:50% 72%}
.pagehero .ph-media::after{
  content:"";position:absolute;inset:0;
  background:linear-gradient(90deg,rgba(245,243,238,.97) 0%,rgba(245,243,238,.9) 34%,rgba(245,243,238,.55) 64%,rgba(245,243,238,.18) 100%);
}
.pagehero > .wrap{width:100%}
.pagehero .wrap{position:relative;z-index:1;padding-top:var(--flow-lg);padding-bottom:var(--flow-lg)}
.pagehero h1{
  font-family:var(--serif);font-weight:500;
  font-size:clamp(2rem,4.1vw,3.5rem);line-height:1.1;letter-spacing:-.01em;
  max-width:min(19ch,var(--measure));text-wrap:balance;
}
.pagehero h1 i{font-style:italic;color:var(--green)}
.pagehero .lede{color:var(--ink);font-size:var(--t-lede);line-height:1.7;max-width:min(62ch,var(--measure));margin-top:20px}
.pagehero .hero-ctas{margin-top:28px}
.pagehero.plain{background:var(--paper2);min-height:clamp(400px,40vh,470px)}
.pagehero.plain .ph-media{display:none}
@media (max-width:760px){
  .pagehero .ph-media::after{
    background:linear-gradient(180deg,rgba(245,243,238,.95) 0%,rgba(245,243,238,.88) 55%,rgba(245,243,238,.72) 100%);
  }
  .pagehero h1{max-width:none}
}

/* ---------- breadcrumbs ---------- */
.crumbs{font-size:var(--t-cap);color:var(--faint);margin-bottom:18px}
.crumbs ol{list-style:none;display:flex;flex-wrap:wrap;gap:8px;align-items:center}
.crumbs a{color:var(--muted)}
.crumbs a:hover{color:var(--green)}
.crumbs li + li::before{content:"/";color:var(--line);margin-right:8px}
.crumbs [aria-current]{color:var(--faint)}

/* ---------- long-form prose ---------- */
/* Full band, by the client's decision. The audit measured 128-153 characters per
   line here and a narrowed column fixed that, but it left the right half of the
   page empty, which reads worse than a long line. Consistency wins. */
.prose{max-width:var(--measure);min-width:0}
.prose > * + *{margin-top:1.1em}
.prose h2{
  font-family:var(--serif);font-weight:500;
  font-size:var(--h-md);line-height:1.18;letter-spacing:-.005em;
  margin-top:2em;
}
.prose h2:first-child{margin-top:0}
.prose h3{
  font-family:var(--serif);font-weight:600;font-size:var(--h-sm);line-height:1.3;
  margin-top:1.7em;
}
.prose p,.prose li{color:var(--muted);font-size:var(--t-read);line-height:var(--lh-read);text-wrap:pretty}
.prose p b,.prose li b,.prose strong{color:var(--ink);font-weight:600}
.prose ul,.prose ol{padding-left:1.15em}
.prose li + li{margin-top:.5em}
.prose ul li::marker{color:var(--green)}
.prose ol li::marker{color:var(--green);font-weight:600}
.prose a{text-decoration:underline;text-underline-offset:3px;text-decoration-thickness:1px;font-weight:500}
.prose blockquote{
  border-left:2px solid var(--green);padding:4px 0 4px 22px;
  font-family:var(--serif);font-size:var(--h-sm);line-height:1.5;color:var(--ink);
}
.prose blockquote cite{margin-top:10px}
.prose figure{margin-top:2em}
.prose figure img{width:100%;height:auto}
.prose figcaption{font-size:var(--t-cap);color:var(--faint);margin-top:10px}
.prose hr{border:0;border-top:1px solid var(--line-soft);margin:2.4em 0}

/* ---------- content + sticky aside ---------- */
.split{
  display:grid;grid-template-columns:minmax(0,7.2fr) minmax(0,4fr);
  gap:var(--gut-lg);align-items:start;
}
/* grid items default to min-width:auto, which lets a wide child (the
   comparison tables) push the whole track past the viewport on mobile */
.split > *{min-width:0}
.aside-stack{position:sticky;top:calc(var(--navh) + 18px);display:flex;flex-direction:column;gap:20px}
.aside-card{
  background:#fbfaf6;border:1px solid var(--line-soft);padding:26px 26px 28px;
  box-shadow:var(--elev-1);
}
.aside-card.green{background:var(--green-deep);color:var(--green-ink);border-color:var(--green-deep);box-shadow:none}
.aside-card h3{font-family:var(--serif);font-weight:600;font-size:var(--h-sm);line-height:1.25}
.aside-card.green h3{color:var(--onacc-key)}
.aside-card p{color:var(--muted);font-size:var(--t-sm);margin-top:10px}
.aside-card.green p{color:var(--onacc-soft)}
.aside-card .btn{margin-top:18px;width:100%;text-align:center}
.aside-card ul{list-style:none;margin-top:16px}
.aside-card li{font-size:var(--t-sm);color:var(--muted);padding:9px 0;border-top:1px solid var(--line-soft)}
.aside-card.green li{color:var(--onacc-strong);border-top-color:rgba(var(--onacc-rgb),.2)}
.aside-card li b{display:block;color:var(--ink);font-weight:600;font-size:var(--t-micro);letter-spacing:.12em;text-transform:uppercase;margin-bottom:3px}
.aside-card.green li b{color:var(--onacc-faint)}
.aside-card a:not(.btn){font-weight:500}
.aside-card.green a:not(.btn){color:var(--onacc-strong);text-decoration:underline;text-underline-offset:3px}
.aside-card.green a:not(.btn):hover{color:#fff}
@media (max-width:960px){
  .split{grid-template-columns:minmax(0,1fr)}
  .aside-stack{position:static}
}

/* ---------- single-column reading layout (replaced the old sidebar split) ----------
   The text column keeps a comfortable measure; tables, photo pairs and sliders
   break out wider, centred on the same axis. */
.readcol{display:block}
/* Left-aligned, NOT centred. Centring the measure put the body text on a
   different left edge from the page hero, the FAQ and the CTA band - which is
   exactly the "three different left edges" the .readwide attempt died of.
   One left edge for the whole page; only the right edge steps out. */
.readcol > .prose{max-width:var(--measure);margin-inline:0;font-size:var(--t-read)}
.readcol > .prose > .tablewrap,
.readcol > .prose > .photoduo,
.readcol > .prose > .phgrid,
.readcol > .prose > .ba-wrap,
.readcol > .prose > figure,
.readcol > .prose > .teamgrid{
  width:min(var(--wide),100%);max-width:none;
}
.endnote{
  max-width:var(--wide);margin:70px 0 0;display:grid;
  grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:22px;align-items:stretch;
}
.endnote > .aside-card{display:flex;flex-direction:column}
.endnote > .aside-card > ul:last-child{margin-top:auto;padding-top:16px}
@media (max-width:760px){
  .endnote{grid-template-columns:minmax(0,1fr)}
  .readcol > .prose > .tablewrap,
  .readcol > .prose > .photoduo,
  .readcol > .prose > .phgrid,
  .readcol > .prose > .ba-wrap,
  .readcol > .prose > figure,
  .readcol > .prose > .teamgrid{width:100%}
}

@media (max-width:1320px){
  .menu > li > a{font-size:var(--t-sm);padding:14px 10px}
  .menu > li > a::after{left:10px;right:10px}
  .nav-cta{gap:14px}
}
@media (max-width:1140px){
  .nav-phone{display:none}
}

/* ---------- homepage: brand strip + education cards ---------- */
/* Brand marquee: two rows drifting in opposite directions. Each track holds the
   names twice so translateX(-50%) loops seamlessly; the second copy is
   aria-hidden and is dropped when the visitor asks for reduced motion, where
   the track becomes an ordinary wrapping list instead. */
.brandmarquee{display:flex;flex-direction:column;gap:14px;margin:28px 0 40px}
.bm-row{overflow:hidden;border-block:1px solid var(--line-soft);padding:15px 0}
.bm-track{display:flex;width:max-content;animation:bmDrift 46s linear infinite}
.bm-row.rev .bm-track{animation-direction:reverse;animation-duration:56s}
.bm-track span{
  font-family:var(--serif);font-size:clamp(1.15rem,1.9vw,1.5rem);color:var(--muted);
  white-space:nowrap;padding:0 var(--gut-sm);line-height:1.25;
  border-right:1px solid var(--line-soft);
}
.brandmarquee:hover .bm-track,.brandmarquee:focus-within .bm-track{animation-play-state:paused}
@keyframes bmDrift{from{transform:translateX(0)}to{transform:translateX(-50%)}}
@media (prefers-reduced-motion:reduce){
  .bm-track{animation:none;width:auto;flex-wrap:wrap;gap:8px var(--gut-md)}
  .bm-track span[aria-hidden="true"]{display:none}
  /* separators go entirely: :last-of-type would land on a hidden duplicate and
     leave a rule dangling after the final visible name */
  .bm-track span{border-right:0;padding:0}
}

.learngrid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:20px;margin-top:8px}
.lcard{
  display:flex;flex-direction:column;background:var(--paper);
  border:1px solid var(--line-soft);padding:28px 26px 26px;
  transition:transform .22s cubic-bezier(.16,1,.3,1),box-shadow .22s ease,border-color .22s ease;
}
.lcard h3{font-family:var(--serif);font-weight:600;font-size:var(--h-sm);line-height:1.2;margin-top:12px;color:var(--ink)}
.lcard p{color:var(--muted);font-size:var(--t-sm);line-height:1.66;margin-top:12px;flex:1}
.lcard .arrow-link{margin-top:20px}
a.lcard:hover{transform:translateY(-3px);box-shadow:var(--elev-1);border-color:rgba(var(--acc-rgb),.35)}
@media (max-width:900px){
  .learngrid{grid-template-columns:1fr}
}

/* ---------- "the wall runs to 1,000+ samples" ---------- */
.wallcta{
  display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;
  gap:24px 40px;margin-top:40px;padding:30px 0 0;border-top:1px solid var(--line);
}
.wallcta h3{font-family:var(--serif);font-weight:600;font-size:var(--h-md);line-height:1.18;color:var(--ink)}
.wallcta p{color:var(--muted);font-size:var(--t-base);line-height:1.65;margin-top:10px;max-width:56ch}
.wallcta .btn{flex-shrink:0}
@media (max-width:640px){.wallcta .btn{width:100%;text-align:center}}

/* ---------- product page: three-up photo rows, wide shots, NAP line ---------- */
.floor-cards.three{grid-template-columns:repeat(3,minmax(0,1fr))}
.floor-cards.three .fcard > img{aspect-ratio:4/3}
@media (max-width:900px){.floor-cards.three{grid-template-columns:1fr}}

.photorow{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:18px;margin-top:2em}
.photorow figure{margin:0}
.photorow img{width:100%;height:auto;aspect-ratio:4/3;object-fit:cover;display:block}
.photorow figcaption{font-size:var(--t-cap);color:var(--faint);margin-top:10px;line-height:1.5}
@media (max-width:820px){.photorow{grid-template-columns:1fr 1fr}}
@media (max-width:540px){.photorow{grid-template-columns:1fr}}

.wideshot{margin-top:2.2em}
.wideshot img{width:100%;height:auto;aspect-ratio:16/9;object-fit:cover;display:block}
.wideshot figcaption{font-size:var(--t-cap);color:var(--faint);margin-top:10px;line-height:1.5}

/* the address sentence carried in the copy, not just in the footer */
.napline{
  margin-top:2.2em;padding-top:20px;border-top:1px solid var(--line);
  font-size:var(--t-sm);color:var(--muted);line-height:1.7;
}
.napline b{color:var(--ink)}
.napline a{color:var(--green);font-weight:600}

/* ---------- showroom gallery ----------
   A masonry-ish grid: the page's job is to show the room, so the photographs
   are the content rather than decoration for it. */
.srgrid{
  display:grid;grid-template-columns:repeat(4,minmax(0,1fr));
  grid-auto-rows:clamp(150px,13vw,200px);gap:12px;margin-top:var(--flow-sm);
}
.srgrid figure{margin:0;overflow:hidden;position:relative}
.srgrid img{width:100%;height:100%;object-fit:cover;display:block;transition:transform .7s cubic-bezier(.16,1,.3,1);object-position:50% 68%}
.srgrid a:hover img,.srgrid a:focus-visible img{transform:scale(1.04)}
.srgrid .w2{grid-column:span 2;grid-row:span 2}
.srgrid .h2{grid-row:span 2}
@media (max-width:900px){
  .srgrid{grid-template-columns:repeat(2,minmax(0,1fr));grid-auto-rows:clamp(130px,26vw,180px)}
  .srgrid .w2{grid-column:span 2}
}
@media (max-width:520px){
  .srgrid{grid-template-columns:1fr;grid-auto-rows:auto}
  .srgrid figure{aspect-ratio:4/3}
  .srgrid .w2,.srgrid .h2{grid-column:auto;grid-row:auto}
}

/* brand signage: proof the names on the list are physically on the wall */
.brandshots{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:16px;margin-top:var(--flow-sm)}
.brandshots figure{margin:0}
.brandshots img{width:100%;height:auto;aspect-ratio:4/3;object-fit:cover;display:block}
.brandshots figcaption{font-size:var(--t-cap);color:var(--faint);margin-top:9px}
@media (max-width:760px){.brandshots{grid-template-columns:1fr 1fr}}

/* visit facts on the light background of the showroom page */
.visitcard{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:2px;
  background:var(--line-soft);border:1px solid var(--line-soft);margin-top:var(--flow-sm);
}
.visitcard > div{background:var(--paper);padding:22px 24px}
.visitcard + .mapwrap{margin-top:var(--flow-xs)}
.visitcard dt{font-size:var(--t-micro);letter-spacing:.14em;text-transform:uppercase;color:var(--green);font-weight:500}
.visitcard dd{margin-top:8px;font-size:var(--t-base);line-height:1.55;color:var(--ink)}
.visitcard dd small{display:block;color:var(--muted);font-size:var(--t-cap);margin-top:4px}
.visitcard a{color:var(--green);font-weight:600}

/* ---------- alternating text / image blocks ----------
   Long product copy is broken into blocks of one heading, one or two
   paragraphs and one photograph, alternating sides down the page. The pair
   still spans the full content band, but each text column measures about
   60 characters instead of 108, which is what stops it reading as a wall. */
.fsplit{
  display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  gap:var(--gut-lg);align-items:center;
  margin-top:var(--flow-md);
}
.fsplit:first-of-type{margin-top:var(--flow-sm)}
.fsplit > .fx > * + *{margin-top:1em}
.fsplit h3{
  font-family:var(--serif);font-weight:600;
  font-size:var(--h-md);line-height:1.2;color:var(--ink);
}
.fsplit p{color:var(--muted);font-size:var(--t-read);line-height:1.75;text-wrap:pretty}
.fsplit p b{color:var(--ink);font-weight:600}
.fsplit figure{margin:0}
.fsplit img{width:100%;height:auto;aspect-ratio:4/3;object-fit:cover;display:block}
.fsplit figcaption{font-size:var(--t-cap);color:var(--faint);margin-top:10px;line-height:1.5}
.fsplit.rev > .fx{order:2}
.fsplit.tall img{aspect-ratio:3/4}
@media (max-width:860px){
  .fsplit{grid-template-columns:1fr;gap:20px}
  .fsplit.rev > .fx{order:0}
  .fsplit img,.fsplit.tall img{aspect-ratio:16/10}
}

/* a before/after slider used as the image half of a split block */
.fsplit .ba{margin:0}
.fsplit .ba-wrap{aspect-ratio:4/3}

/* trade: what's in scope, as a list that reads like a spec */
.tradelist{list-style:none;margin-top:var(--flow-xs);border-top:1px solid var(--line)}
.tradelist li{padding:14px 0;border-bottom:1px solid var(--line-soft);color:var(--muted);font-size:var(--t-base);line-height:1.6}
.tradelist li b{color:var(--ink);font-weight:600}

/* ---------- service areas: place plus what we did there ---------- */
.prooflist{border-top:1px solid var(--line);margin-top:var(--flow-xs)}
.proofrow{
  display:grid;grid-template-columns:200px minmax(0,1fr);gap:20px;
  padding:16px 0;border-bottom:1px solid var(--line-soft);
}
.proofrow b{font-family:var(--serif);font-weight:600;font-size:var(--h-sm);line-height:1.25;color:var(--ink)}
.proofrow span{color:var(--muted);font-size:var(--t-base);line-height:1.65}
@media (max-width:640px){.proofrow{grid-template-columns:1fr;gap:5px}}

/* ---------- contact page: details beside the form ---------- */
.map-acts{margin-top:var(--flow-xs)}
.contact-details h2{font-family:var(--serif);font-weight:600;font-size:var(--h-md);line-height:1.18}
.cd-lede{color:var(--muted);font-size:var(--t-base);line-height:1.7;margin-top:12px;max-width:44ch}
.cd-list{margin-top:var(--flow-xs);border-top:1px solid var(--line)}
.cd-list > div{padding:16px 0;border-bottom:1px solid var(--line-soft);display:grid;grid-template-columns:132px minmax(0,1fr);gap:16px}
.cd-list dt{font-size:var(--t-micro);letter-spacing:.14em;text-transform:uppercase;color:var(--green);font-weight:500;padding-top:3px}
.cd-list dd{font-size:var(--t-base);line-height:1.55;color:var(--ink)}
.cd-list dd small{display:block;color:var(--muted);font-size:var(--t-cap);margin-top:5px;line-height:1.5}
.cd-list a{color:var(--green);font-weight:600}
.contact-details .hero-ctas{margin-top:var(--flow-xs)}
@media (max-width:520px){.cd-list > div{grid-template-columns:1fr;gap:5px}}

/* the form card carries its own heading on the contact page */
.form-card .form-head{font-family:var(--serif);font-weight:600;font-size:var(--h-md);line-height:1.2}
.form-card .form-sub{color:var(--muted);font-size:var(--t-sm);line-height:1.6;margin-top:8px;margin-bottom:var(--flow-xs)}

/* a small heading between blocks in a full-width section */
.subhead{
  font-family:var(--serif);font-weight:600;font-size:var(--h-sm);line-height:1.2;
  margin-top:var(--flow-md);padding-top:22px;border-top:1px solid var(--line);
}

/* a pull quote that carries a section rather than decorating one */
.bigquote{
  max-width:60ch;margin:var(--flow-lg) 0 0;
  padding-left:var(--gut-sm);border-left:3px solid var(--green);
}
.bigquote p{
  font-family:var(--serif);font-weight:500;
  font-size:clamp(1.3rem,2.4vw,1.9rem);line-height:1.34;color:var(--ink);text-wrap:pretty;
}
.bigquote.wide{max-width:none}
.bigquote.wide p{font-size:clamp(1.25rem,2.05vw,1.65rem);line-height:1.4}
.bigquote cite{display:block;font-style:normal;color:var(--faint);font-size:var(--t-cap);margin-top:14px;letter-spacing:.03em}

/* full-band pieces that sit between the split blocks */
.bandnote{margin-top:var(--flow-sm)}
.bandnote p{color:var(--muted);font-size:var(--t-read);line-height:var(--lh-read);text-wrap:pretty}
.bandnote p b{color:var(--ink);font-weight:600}
.bandnote p + p{margin-top:1em}
.callout.bandnote{max-width:none}
/* A spec-style list is a full-band block, not a paragraph: it reads as columns
   of items, so constraining it to the prose measure defeats the point. */
.bandnote:has(> .tradelist){max-width:none}

/* ---------- steps, laid out across instead of down ---------- */
.steprow{
  display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  gap:var(--gut-md);margin-top:var(--flow-sm);
  counter-reset:step;
}
.steprow li{list-style:none;padding-top:22px;border-top:2px solid rgba(var(--acc-rgb),.3)}
.steprow .dot{
  display:inline-flex;align-items:center;justify-content:center;
  width:34px;height:34px;border-radius:50%;
  border:1px solid var(--green);color:var(--green);
  font-size:var(--t-sm);font-weight:600;
}
.steprow h3{font-family:var(--serif);font-weight:600;font-size:var(--h-sm);line-height:1.2;margin-top:14px;color:var(--ink)}
.steprow p{color:var(--muted);font-size:var(--t-sm);line-height:1.65;margin-top:8px}
/* four-step variant for the installation process */
.steprow.four{grid-template-columns:repeat(4,minmax(0,1fr));gap:var(--gut-sm)}
@media (max-width:1000px){.steprow.four{grid-template-columns:1fr 1fr}}
@media (max-width:780px){.steprow,.steprow.four{grid-template-columns:1fr;gap:26px}}

/* ---------- mid-page call to action ---------- */
.midcta{
  display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;
  gap:22px 40px;margin-top:var(--flow-lg);
  background:var(--green-deep);color:var(--green-ink);
  padding:var(--gut-md) var(--gut-md);
}
.midcta h3{font-family:var(--serif);font-weight:600;font-size:var(--h-md);line-height:1.18;color:var(--onacc-key)}
.midcta p{color:var(--onacc-soft);font-size:var(--t-base);line-height:1.6;margin-top:10px;max-width:52ch}
.midcta .acts{display:flex;gap:12px;flex-wrap:wrap;flex-shrink:0}
@media (max-width:640px){
  .midcta{flex-direction:column;align-items:flex-start}
  .midcta .acts,.midcta .btn{width:100%;text-align:center}
}

/* ---------- brand grid (the 50 makers on the showroom wall) ---------- */
.brandgrid{
  display:grid;grid-template-columns:repeat(auto-fill,minmax(212px,1fr));
  gap:14px;margin-top:8px;
}
/* 20 tiles fill four rows of five; the call to action then sat alone in a
   fifth. Spanning the full row makes it close the grid instead of orphaning. */
.brandgrid .brandtile.more{grid-column:1 / -1;text-align:center}
.brandtile{
  display:flex;flex-direction:column;justify-content:center;gap:5px;
  min-height:94px;padding:18px 20px;background:#fbfaf6;
  border:1px solid var(--line-soft);
  transition:border-color .18s ease,transform .18s ease,box-shadow .18s ease;
}
.brandtile b{font-family:var(--serif);font-weight:600;font-size:var(--t-sm);line-height:1.2;color:var(--ink)}
.brandtile span{font-size:var(--t-cap);color:var(--faint);line-height:1.35}
.brandtile.more{background:var(--green-deep);border-color:var(--green-deep);text-decoration:none}
.brandtile.more b{color:var(--onacc-key)}
.brandtile.more span{color:var(--onacc-soft)}
a.brandtile:hover{transform:translateY(-2px);box-shadow:var(--elev-1)}
a.brandtile:hover{border-color:rgba(var(--acc-rgb),.45)}
@media (max-width:560px){
  .brandgrid{grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:10px}
  .brandtile{min-height:80px;padding:14px 15px}
  .brandtile b{font-size:var(--t-sm)}
}

/* ---------- team portraits ---------- */
.teamgrid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:18px;margin-top:2em}
.teamgrid figure{margin:0}
.teamgrid img{width:100%;height:auto;aspect-ratio:3/4;object-fit:cover}
.teamgrid figcaption{margin-top:11px}
.teamgrid figcaption b{display:block;font-size:var(--t-micro);letter-spacing:.12em;text-transform:uppercase;color:var(--green);font-weight:600}
.teamgrid figcaption span{display:block;font-size:var(--t-cap);color:var(--muted);margin-top:3px}
@media (max-width:620px){.teamgrid{grid-template-columns:1fr 1fr;gap:12px}}

/* ---------- text + photo feature band ---------- */
.split-feature{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:var(--gut-lg);align-items:center}
.split-feature .tx h2{font-family:var(--serif);font-weight:600;font-size:var(--h-md);line-height:1.15;margin-top:12px}
.split-feature .tx p{color:var(--muted);font-size:var(--t-base);line-height:1.72;margin-top:16px;max-width:52ch}
.split-feature .hero-ctas{margin-top:26px}
.split-feature figure{margin:0}
.split-feature img{width:100%;height:auto;aspect-ratio:4/3;object-fit:cover}
@media (max-width:860px){.split-feature{grid-template-columns:1fr}}

/* ---------- FAQ accordion ---------- */
.faq{max-width:var(--wide);border-top:1px solid var(--line)}
.faq details{border-bottom:1px solid var(--line)}
.faq summary{
  cursor:pointer;list-style:none;padding:22px 44px 22px 0;position:relative;
  font-family:var(--serif);font-size:var(--h-sm);font-weight:600;line-height:1.35;color:var(--ink);
}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{
  content:"";position:absolute;right:8px;top:50%;width:13px;height:13px;
  border-right:1.5px solid var(--green);border-bottom:1.5px solid var(--green);
  transform:translateY(-70%) rotate(45deg);transition:transform .25s ease;
}
.faq details[open] summary::after{transform:translateY(-30%) rotate(-135deg)}
.faq summary:hover{color:var(--green)}
.faq .answer{padding:0 0 24px}
/* the longest block on the page used to sit at the smallest size with no measure */
.faq .answer p,.faq .answer li{color:var(--muted);font-size:var(--t-base);line-height:var(--lh-read)}
.faq .answer > * + *{margin-top:.9em}
.faq .answer ul{padding-left:1.1em}
.faq .answer ul li::marker{color:var(--green)}

/* ---------- generic card grids ---------- */
.tiles{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:20px}
/* UI-07: a three-column grid leaves a single orphan whenever the count is 2 or 4.
   Match the columns to the count instead of leaving a hole in the last row. */
.tiles:has(> :last-child:nth-child(2)),
.tiles:has(> :last-child:nth-child(4)){grid-template-columns:repeat(2,minmax(0,1fr))}
.tiles.two{grid-template-columns:repeat(2,minmax(0,1fr))}
.tile{
  background:#fbfaf6;border:1px solid var(--line-soft);
  display:flex;flex-direction:column;overflow:hidden;
  transition:transform .3s cubic-bezier(.16,1,.3,1),box-shadow .3s ease;
}
a.tile:hover{transform:translateY(-3px);box-shadow:var(--elev-2)}
.tile .ph{aspect-ratio:4/3;overflow:hidden}
.tile .ph img{width:100%;height:100%;object-fit:cover;transition:transform .7s cubic-bezier(.16,1,.3,1)}
a.tile:hover .ph img{transform:scale(1.045)}
.tile .tx{padding:24px 26px 28px;display:flex;flex-direction:column;flex:1}
.tile h3{font-family:var(--serif);font-weight:600;font-size:var(--h-sm);line-height:1.24;color:var(--ink)}
.tile p{color:var(--muted);font-size:var(--t-sm);margin-top:10px;flex:1}
.tile .arrow-link{margin-top:16px}
.tile .eyebrow{
  font-size:var(--t-micro);letter-spacing:.16em;text-transform:uppercase;
  color:var(--green);font-weight:600;margin-bottom:9px;
}
@media (max-width:900px){.tiles,.tiles.two{grid-template-columns:1fr 1fr}}
@media (max-width:620px){.tiles,.tiles.two{grid-template-columns:1fr}}

/* ---------- comparison / spec table ---------- */
.tablewrap{overflow-x:auto;max-width:100%;margin-top:1.4em;-webkit-overflow-scrolling:touch}
table.spec{width:100%;border-collapse:collapse;min-width:520px;font-size:var(--t-sm)}
table.spec th,table.spec td{text-align:left;padding:14px 18px;border-bottom:1px solid var(--line-soft);vertical-align:top}
table.spec thead th{
  font-size:var(--t-micro);letter-spacing:.14em;text-transform:uppercase;color:var(--faint);
  font-weight:500;border-bottom:1px solid var(--line);
}
table.spec tbody th{font-weight:600;color:var(--ink);width:30%}
table.spec td{color:var(--muted)}
table.spec tbody tr:hover{background:rgba(var(--acc-rgb),.035)}

/* ---------- key/value fact strip ---------- */
.factbar{
  display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:2px;
  background:var(--line-soft);border:1px solid var(--line-soft);
}
.factbar div{background:var(--paper);padding:22px 24px}
.factbar b{display:block;font-family:var(--serif);font-size:1.7rem;color:var(--ink);font-weight:600;line-height:1.1}
.factbar span{display:block;color:var(--muted);font-size:var(--t-cap);margin-top:6px}
@media (max-width:820px){.factbar{grid-template-columns:1fr 1fr}}

/* ---------- callout ---------- */
.callout{
  background:rgba(var(--acc-rgb),.06);border-left:2px solid var(--green);
  padding:22px 26px;margin-top:1.6em;
}
.callout .callout-h,.callout h3{font-family:var(--serif);font-size:var(--h-sm);font-weight:600;margin-bottom:8px;margin-top:0}
.callout p,.callout li{color:var(--muted);font-size:var(--t-base);line-height:var(--lh-read)}
.callout > * + *{margin-top:.7em}

/* ---------- mid-page CTA band ---------- */
.ctaband{background:var(--green-deep);color:var(--green-ink)}
.ctaband .wrap{
  padding-top:var(--flow-lg);padding-bottom:var(--flow-lg);
  display:flex;align-items:center;justify-content:space-between;gap:34px;flex-wrap:wrap;
}
.ctaband h2{color:var(--onacc-key);max-width:20ch}
.ctaband p{color:var(--onacc-soft);margin-top:12px;max-width:48ch}
.ctaband .acts{display:flex;gap:14px;flex-wrap:wrap}

/* ---------- projects grid with captions ---------- */
.projgrid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:22px}
.projcard{display:flex;flex-direction:column;background:#fbfaf6;border:1px solid var(--line-soft);overflow:hidden}
.projcard .ph{aspect-ratio:4/3;overflow:hidden}
.projcard .ph img{width:100%;height:100%;object-fit:cover;transition:transform .7s cubic-bezier(.16,1,.3,1)}
a.projcard:hover .ph img{transform:scale(1.05)}
.projcard .tx{padding:20px 22px 24px}
.projcard h3{font-family:var(--serif);font-weight:600;font-size:var(--h-sm);line-height:1.28;color:var(--ink)}
.projcard .meta{font-size:var(--t-micro);letter-spacing:.13em;text-transform:uppercase;color:var(--green);font-weight:600;margin-bottom:8px}
.projcard p{color:var(--muted);font-size:var(--t-sm);margin-top:9px}
@media (max-width:900px){.projgrid{grid-template-columns:1fr 1fr}}
@media (max-width:600px){.projgrid{grid-template-columns:1fr}}

/* ---------- full-length reviews ---------- */
.revlist{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:22px}
.revlong{background:#fbfaf6;border:1px solid var(--line-soft);padding:28px 30px 30px;display:flex;flex-direction:column}
.revlong .stars{margin-bottom:14px}
.revlong h3{font-family:var(--serif);font-weight:600;font-size:var(--h-sm);line-height:1.3;margin-bottom:10px}
.revlong blockquote{color:var(--muted);font-size:var(--t-sm);line-height:1.7;flex:1}
.revlong blockquote::before{content:"\201C"}
.revlong blockquote::after{content:"\201D"}
.revlong cite{margin-top:18px}
@media (max-width:820px){.revlist{grid-template-columns:1fr}}

/* ---------- link columns (service areas, brands) ---------- */
.linkgrid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:2px;background:var(--line-soft);border:1px solid var(--line-soft)}
.linkgrid a,.linkgrid span{
  background:var(--paper);padding:18px 20px;font-size:var(--t-sm);color:var(--ink);
  display:block;transition:background .2s ease;
}
.linkgrid a:hover{background:rgba(var(--acc-rgb),.07);color:var(--green)}
.linkgrid span{color:var(--muted)}
.linkgrid small{display:block;color:var(--faint);font-size:var(--t-micro);margin-top:3px}
@media (max-width:900px){.linkgrid{grid-template-columns:1fr 1fr}}
@media (max-width:520px){.linkgrid{grid-template-columns:1fr}}

/* ---------- inline photo duo ---------- */
.photoduo{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin-top:2em}
.photoduo figure{margin:0}
.photoduo img{width:100%;height:auto;aspect-ratio:4/3;object-fit:cover}
.photoduo figcaption{font-size:var(--t-cap);color:var(--faint);margin-top:9px}
@media (max-width:620px){.photoduo{grid-template-columns:1fr}}

/* ---------- misc helpers ---------- */
.section.narrow .wrap{max-width:960px}
.lede-lg{font-family:var(--serif);font-size:clamp(1.2rem,2vw,1.5rem);line-height:1.5;color:var(--ink);max-width:60ch}
.eyebrow{font-size:var(--t-micro);letter-spacing:.22em;text-transform:uppercase;color:var(--green);font-weight:500}
.mt0{margin-top:0}
.center{text-align:center;margin-left:auto;margin-right:auto}

/* ---------- blog ---------- */
.postmeta{
  font-size:var(--t-micro);letter-spacing:.1em;text-transform:uppercase;color:var(--faint);
  margin-top:16px;padding-top:14px;border-top:1px solid var(--line-soft);
}
.tile .postmeta{flex:0 0 auto}
.post-head{max-width:var(--measure)}
.post-head .postmeta{border-top:0;padding-top:0;margin-top:0;margin-bottom:16px}
.post-toc{
  background:#fbfaf6;border:1px solid var(--line-soft);
  padding:22px 26px;margin-top:2em;
}
.post-toc h2{font-family:var(--serif);font-size:var(--t-micro);font-weight:600;margin:0 0 12px;
  letter-spacing:.02em;text-transform:none}
.post-toc ol{list-style:none;padding-left:0;counter-reset:toc}
.post-toc li{counter-increment:toc;margin-top:0;padding:7px 0;border-top:1px solid var(--line-soft)}
.post-toc li:first-child{border-top:0;padding-top:0}
.post-toc li::before{content:counter(toc) ".";color:var(--green);font-weight:600;margin-right:9px}
.post-toc a{font-size:var(--t-sm);color:var(--ink);text-decoration:none;font-weight:500}
.post-toc a:hover{color:var(--green);text-decoration:underline;text-underline-offset:3px}
.post-foot{
  margin-top:2.6em;padding-top:22px;border-top:1px solid var(--line);
  font-size:var(--t-sm);color:var(--faint);
}

/* ---------- material sample swatches (placeholders until real photos land) ---------- */
.brandblock{border-top:1px solid var(--line);padding-top:30px;margin-top:44px}
.brandblock:first-of-type{margin-top:0}
.brandblock .bh{display:flex;justify-content:space-between;align-items:baseline;gap:20px;flex-wrap:wrap}
.brandblock h3{font-family:var(--serif);font-weight:600;font-size:var(--h-sm);line-height:1.2}
.brandblock .tag{
  font-size:var(--t-micro);letter-spacing:.14em;text-transform:uppercase;color:var(--green);font-weight:600;
}
.brandblock > p{color:var(--muted);font-size:var(--t-sm);margin-top:10px;max-width:64ch}
.swatches{
  display:grid;grid-template-columns:repeat(auto-fill,minmax(112px,1fr));
  gap:14px;margin-top:22px;
}
.swatch{
  border:1px solid var(--line-soft);background:#fbfaf6;
  display:flex;flex-direction:column;overflow:hidden;
}
.swatch .chip{
  aspect-ratio:4/3;position:relative;
  background:
    repeating-linear-gradient(90deg,rgba(0,0,0,.05) 0 1px,transparent 1px 34px),
    linear-gradient(160deg,var(--c1),var(--c2));
}
.swatch .chip::after{
  content:"Sample";position:absolute;left:8px;bottom:8px;
  font-size:var(--t-nano);letter-spacing:.14em;text-transform:uppercase;font-weight:600;
  color:rgba(255,255,255,.92);background:rgba(var(--shade-rgb),.46);
  padding:3px 7px;border-radius:2px;
}
.swatch b{display:block;font-size:var(--t-cap);font-weight:600;color:var(--ink);padding:12px 13px 3px;line-height:1.3}
.swatch span{display:block;font-size:var(--t-micro);color:var(--faint);padding:0 13px 13px}
.swatch-note{
  font-size:var(--t-cap);color:var(--faint);margin-top:18px;
  padding:12px 16px;background:rgba(var(--acc-rgb),.05);border-left:2px solid var(--line);
}


/* ---------- wide feature card: type on a solid panel, never over the photo ---------- */
.feature{
  display:grid;grid-template-columns:minmax(0,7fr) minmax(0,5fr);
  background:#fbfaf6;border:1px solid var(--line-soft);overflow:hidden;
  transition:transform .3s cubic-bezier(.16,1,.3,1),box-shadow .3s ease;
}
a.feature:hover{transform:translateY(-3px);box-shadow:var(--elev-2)}
.feature .ph{overflow:hidden;min-height:100%;aspect-ratio:16/10}
.feature .ph img{width:100%;height:100%;object-fit:cover;transition:transform .8s cubic-bezier(.16,1,.3,1)}
a.feature:hover .ph img{transform:scale(1.04)}
.feature .tx{padding:var(--gut-md);align-self:center}
.feature .eyebrow{display:block;margin-bottom:14px}
.feature h3{
  font-family:var(--serif);font-weight:500;
  font-size:var(--h-md);line-height:1.16;color:var(--ink);
}
.feature p{color:var(--muted);font-size:var(--t-sm);margin-top:14px;max-width:46ch}
.feature .arrow-link{display:inline-block;margin-top:20px}
@media (max-width:860px){
  .feature{grid-template-columns:1fr}
  .feature .ph{aspect-ratio:16/9}
}

/* ---------- photo placeholders (stripped before launch via build.py flag) ---------- */
.phslot{
  position:relative;background:var(--paper2);
  border:1px dashed rgba(var(--acc-rgb),.4);
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  text-align:center;padding:26px 24px;gap:8px;min-height:220px;
}
.phslot::before{
  content:"Photo needed";
  font-size:var(--t-nano);letter-spacing:.16em;text-transform:uppercase;font-weight:600;
  color:var(--green);
}
.phslot p{color:var(--muted);font-size:var(--t-cap);line-height:1.55;max-width:38ch;margin:0}
.phslot.wide{aspect-ratio:16/9;min-height:0}
.phslot.tallish{aspect-ratio:4/5;min-height:0}
.phslot.square{aspect-ratio:1/1;min-height:0}
.phgrid{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin-top:2em}
@media (max-width:620px){.phgrid{grid-template-columns:1fr}}

/* a real photo standing in for one we still need */
.standin{position:relative}
.standin::after{
  content:"Stand-in";position:absolute;top:10px;left:10px;z-index:2;
  font-size:var(--t-nano);letter-spacing:.14em;text-transform:uppercase;font-weight:600;
  color:#fff;background:rgba(26,22,18,.6);padding:4px 8px;border-radius:2px;
}
.phcaption{
  font-size:var(--t-micro);line-height:1.5;color:var(--faint);
  padding:10px 22px 0;border-top:1px dashed rgba(var(--acc-rgb),.3);margin-top:2px;
}
.phcaption b{color:var(--green);font-weight:600;letter-spacing:.1em;text-transform:uppercase;font-size:var(--t-nano);display:block;margin-bottom:3px}


/* ---------- before / after slider ---------- */
.ba{margin:2.2em 0 0}
.ba-wrap{
  --pos:50%;
  position:relative;overflow:hidden;aspect-ratio:16/10;
  background:var(--paper2);border:1px solid var(--line-soft);
  touch-action:pan-y;user-select:none;
}
.ba-wrap img{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  pointer-events:none;
}
.ba-wrap .ba-before{clip-path:inset(0 calc(100% - var(--pos)) 0 0)}
.ba-line{
  position:absolute;top:0;bottom:0;left:var(--pos);width:2px;
  background:rgba(255,255,255,.9);box-shadow:0 0 0 1px rgba(26,22,18,.28);
  pointer-events:none;transform:translateX(-1px);
}
.ba-knob{
  position:absolute;top:50%;left:var(--pos);
  width:46px;height:46px;border-radius:50%;
  transform:translate(-50%,-50%);
  background:rgba(251,250,246,.96);box-shadow:var(--elev-2);
  display:flex;align-items:center;justify-content:center;gap:3px;
  pointer-events:none;color:var(--ink);font-size:var(--t-cap);line-height:1;
}
.ba-range{
  position:absolute;inset:0;width:100%;height:100%;margin:0;
  opacity:0;cursor:ew-resize;appearance:none;-webkit-appearance:none;background:transparent;
}
.ba-range::-webkit-slider-thumb{appearance:none;-webkit-appearance:none;width:52px;height:100%;cursor:ew-resize}
.ba-range::-moz-range-thumb{width:52px;height:100%;border:0;background:transparent;cursor:ew-resize}
.ba-range:focus-visible + .ba-line{background:var(--green);box-shadow:0 0 0 2px rgba(var(--onacc-rgb),.9)}
.ba-tag{
  position:absolute;bottom:14px;z-index:2;pointer-events:none;
  font-size:var(--t-nano);letter-spacing:.16em;text-transform:uppercase;font-weight:600;
  color:#fff;background:rgba(26,22,18,.58);padding:5px 11px;border-radius:2px;
}
.ba-tag.b{left:14px}
.ba-tag.a{right:14px}
.ba figcaption{font-size:var(--t-cap);color:var(--faint);margin-top:11px}
.ba figcaption b{color:var(--ink);font-weight:600}
@media (max-width:620px){.ba-wrap{aspect-ratio:4/3}}

/* ---------- wide reference layout (no sidebar) ----------
   Prose keeps a readable measure; tables, swatch grids and media break out
   into the extra width the missing sidebar frees up. */
.readwide .prose{
  max-width:none;
  display:grid;
  grid-template-columns:
    [wide-start] minmax(0,1fr)
    [text-start] min(70ch,100%) [text-end]
    minmax(0,1fr) [wide-end];
}
.readwide .prose > *{grid-column:text}
.readwide .prose > .tablewrap,
.readwide .prose > .linkgrid,
.readwide .prose > .phgrid,
.readwide .prose > .photoduo,
.readwide .prose > .ba,
.readwide .prose > .brandblock{grid-column:wide}
.readwide .prose > * + *{margin-top:1.1em}
.readwide .prose > h2{margin-top:2em}
.readwide .prose > .tablewrap,
.readwide .prose > .brandblock,
.readwide .prose > .phgrid,
.readwide .prose > .ba{margin-top:1.8em}
.readwide table.spec{min-width:0}
.readwide .brandblock .swatches{grid-template-columns:repeat(auto-fill,minmax(150px,1fr))}
@media (max-width:900px){
  .readwide .prose{display:block}
}

/* end-of-article block: what the sidebar used to hold, once the sidebar is gone */
.postend{
  display:grid;grid-template-columns:1fr 1fr;gap:20px;
  max-width:1156px;margin:var(--flow-md) auto 0;
}
@media (max-width:760px){.postend{grid-template-columns:1fr}}

/* placeholder sitting on the green showroom block */
.visit-media .phslot{
  aspect-ratio:3/2;min-height:0;
  background:rgba(var(--onacc-rgb),.07);
  border-color:rgba(var(--onacc-rgb),.4);
}
.visit-media .phslot::before{color:rgba(var(--onacc-rgb),.85)}
.visit-media .phslot p{color:rgba(var(--onacc-rgb),.72)}
.visit-media img{aspect-ratio:1/1}
@media (max-width:900px){.visit-media img{aspect-ratio:4/3}}

/* ---------- mega menu: panorama + links, panel ~half the page wide ---------- */
.menu > li.has-mega{position:static}
header.site .wrap.nav{position:relative}
@media (max-width:1100px){
}

/* ---------- footer: social + credit ---------- */
.foot-social{display:flex;gap:10px;margin-top:20px}
.foot-social a{
  width:38px;height:38px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;
  border:1px solid var(--line);color:var(--muted);
  transition:background .2s ease,border-color .2s ease,color .2s ease;
}
.foot-social a:hover{background:var(--green);border-color:var(--green);color:var(--green-ink)}
.foot-social svg{width:17px;height:17px;fill:currentColor;display:block}
.foot-legal .credit a{color:var(--muted);text-decoration:underline;text-underline-offset:3px}
.foot-legal .credit a:hover{color:var(--green)}

/* ---------- google map embed ---------- */
.mapwrap{
  position:relative;aspect-ratio:16/9;overflow:hidden;
  border:1px solid var(--line-soft);background:var(--paper2);
}
.mapwrap iframe{position:absolute;inset:0;width:100%;height:100%;border:0;display:block}
.visit-media .mapwrap{aspect-ratio:3/2;border-color:rgba(var(--onacc-rgb),.25)}
@media (max-width:620px){.mapwrap{aspect-ratio:4/3}}

/* clickable Google rating badge */
a.google-badge{display:inline-flex;color:var(--muted)}
a.google-badge:hover strong{color:var(--green)}
a.google-badge .gl{text-decoration:underline;text-underline-offset:3px}
a.google-badge:hover .gl{color:var(--green)}
