/* Roof Ops — light, photo-forward. The brief is explicit that the site cannot be
   uniformly dark: sections alternate so the eye gets a break and the photography
   does not suffocate. Dark is reserved for full-bleed photo bands and the footer. */

:root{
  --ground:#FBFBFA;     /* paper */
  --ground-2:#F1F1EE;   /* alternating band */
  --raise:#FFFFFF;      /* cards */
  --raise-2:#E8E8E4;
  --ink:#15161A;
  --ink-2:#55585F;
  --ink-3:#65686F;
  --rule:#E3E3DF;
  --rule-2:#D2D2CD;
  --rust:#C8161E;       /* logo red, deepened to carry on white */
  --rust-lift:#E01C24;  /* the logo value itself, for dark grounds */
  --rust-dim:#FBE8E8;
  --steel:#6E7178;

  /* dark grounds that survive the flip: photo overlays and the footer */
  --dark:#111113;
  --dark-2:#191A1E;
  --dark-rule:#2C2E33;
  --on-photo:#FFFFFF;
  --on-photo-2:#D8DADD;

  --railh:clamp(210px,28vw,310px);

  --f-display:'Archivo','Helvetica Neue',Arial,sans-serif;
  --f-body:'Source Serif 4',Georgia,'Times New Roman',serif;
  --f-mono:'IBM Plex Mono',ui-monospace,'SF Mono',Menlo,monospace;

  --gut:clamp(20px,4.5vw,64px);
  --hdr-h:78px;        /* bar height; the mobile nav and scroll offsets follow it */
  --max:1340px;
  --bar:0px;
}

@media(min-width:1560px){:root{--max:1460px}}
@media(min-width:1800px){:root{--max:1580px;--gut:clamp(20px,4.5vw,76px)}}
@media(min-width:2200px){:root{--max:1700px}}

*{box-sizing:border-box}
html{scroll-behavior:smooth}
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{animation-duration:.01ms!important;transition-duration:.01ms!important}
}
body{
  margin:0;background:var(--ground);color:var(--ink);
  font-family:var(--f-body);font-size:17px;line-height:1.62;
  -webkit-font-smoothing:antialiased;overflow-x:hidden;
  padding-bottom:var(--bar);
}
img,video{max-width:100%;display:block}
a{color:inherit}
p{margin:0 0 1.05em}
:focus-visible{outline:2px solid var(--rust-lift);outline-offset:3px}
.wrap{max-width:var(--max);margin:0 auto;padding:0 var(--gut)}
.narrow{max-width:66ch}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}

/* ---------- type ---------- */
h1,h2,h3,h4{font-family:var(--f-display);margin:0;text-wrap:balance;letter-spacing:-.024em;line-height:1.05}
h1{font-size:clamp(38px,6.2vw,74px);font-weight:800}
h2{font-size:clamp(28px,4vw,46px);font-weight:700}
h3{font-size:clamp(19px,2.1vw,25px);font-weight:700;letter-spacing:-.018em;line-height:1.16}
h4{font-size:17px;font-weight:700;letter-spacing:-.01em;line-height:1.25}
.lede{font-size:clamp(18px,2vw,21px);line-height:1.55;color:var(--ink-2)}
.eyebrow{
  font-family:var(--f-mono);font-size:11px;font-weight:500;letter-spacing:.16em;
  text-transform:uppercase;color:var(--rust);display:block;
}
/* on photography red disappears into the image — labels go light instead */
.hero .eyebrow,.cta .eyebrow{color:var(--on-photo-2);text-shadow:0 1px 10px rgba(0,0,0,.5)}
.eyebrow.dim{color:var(--ink-3)}
.mono{font-family:var(--f-mono);font-variant-numeric:tabular-nums}

/* ---------- header ---------- */
.hdr{
  position:sticky;top:0;z-index:60;background:rgba(251,251,250,.90);
  backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);
  border-bottom:1px solid var(--rule);
}
.hdr .wrap{display:flex;align-items:center;gap:26px;height:var(--hdr-h)}
.brand{text-decoration:none;display:flex;align-items:center;min-height:44px;flex:none}
.brand img{height:48px;width:auto;display:block}
.ftr .brand img{height:58px}
@media(max-width:420px){:root{--hdr-h:68px}.brand img{height:40px}}
.nav{display:flex;gap:clamp(17px,1.7vw,28px);margin-left:auto;align-items:center}
.nav a{font-family:var(--f-display);font-size:15px;font-weight:500;text-decoration:none;
  color:var(--ink-2);white-space:nowrap;transition:color .15s;letter-spacing:-.005em}
.nav a:hover,.nav a[aria-current="page"]{color:var(--ink)}
/* Contact is the one nav item asking to be clicked, so it carries the brand red
   rather than sitting at the same weight as the rest. */
.nav a.nav-cta{color:var(--rust);font-weight:600}
.nav a.nav-cta:hover,.nav a.nav-cta[aria-current="page"]{color:var(--rust-lift)}
.hdr-tel{
  font-family:var(--f-mono);font-size:13.5px;font-weight:600;text-decoration:none;
  color:var(--rust);border:1px solid var(--rust);padding:8px 14px;border-radius:2px;
  white-space:nowrap;transition:border-color .15s,background .15s,color .15s;
}
.hdr-tel:hover{background:var(--rust);color:#fff;border-color:var(--rust)}
.burger{display:none;margin-left:auto;background:none;border:1px solid var(--rule-2);
  color:var(--ink);width:46px;height:44px;border-radius:2px;cursor:pointer;
  font-size:17px;line-height:1;align-items:center;justify-content:center}
@media(max-width:1080px){
  .nav{position:fixed;inset:var(--hdr-h) 0 auto;flex-direction:column;align-items:stretch;gap:0;
    background:var(--raise);border-bottom:1px solid var(--rule);padding:6px 0;margin:0;
    box-shadow:0 14px 26px rgba(17,17,19,.10);
    max-height:calc(100vh - var(--hdr-h));overflow-y:auto}
  .nav[hidden]{display:none}
  .nav a{padding:13px var(--gut);font-size:16px;border-bottom:1px solid var(--rule)}
  .nav a:last-child{border-bottom:0}
  .burger{display:flex}
  .hdr-tel{display:none}
}

/* mobile sticky call bar */
.callbar{display:none}
@media(max-width:1080px){
  :root{--bar:56px}
  .callbar{
    display:grid;grid-template-columns:1fr 1fr;position:fixed;inset:auto 0 0;z-index:70;
    border-top:1px solid var(--rule-2);background:var(--raise);
    box-shadow:0 -6px 20px rgba(17,17,19,.08);
  }
  .callbar a{
    font-family:var(--f-display);font-weight:600;font-size:14.5px;text-decoration:none;
    padding:17px 8px;text-align:center;letter-spacing:.01em;
  }
  .callbar a+a{background:var(--rust);color:#fff}
}

/* ---------- hero ---------- */
.hero{position:relative;min-height:min(78vh,700px);display:flex;align-items:flex-end;
  overflow:hidden;border-bottom:1px solid var(--rule)}
@media(min-width:1100px) and (min-height:760px){
  .hero{min-height:min(88vh,900px)}
}
.hero-media{position:absolute;inset:0;z-index:0}
/* the <picture> has no intrinsic height, so pin it to the band or it resolves
   to the photo's full height and overflows the section */
.hero-media>.shot,.cta-media>.shot{position:absolute;inset:0;width:100%;height:100%}
.hero-media img,.hero-media video{width:100%;height:100%;object-fit:cover}
/* Two scrims, because the hero footage is bright: the vertical one seats the
   header and the proof bar, and the horizontal one sits under the left-aligned
   copy so the picture stays open on the right. Tuned against the brightest
   frame of the hero clip -- grass and sky in full sun -- not against a still. */
.hero-media::after{
  content:"";position:absolute;inset:0;
  background:
    linear-gradient(90deg,rgba(17,17,19,.72) 0%,rgba(17,17,19,.52) 38%,rgba(17,17,19,.08) 72%,rgba(17,17,19,0) 100%),
    linear-gradient(180deg,rgba(17,17,19,.66) 0%,rgba(17,17,19,.30) 34%,rgba(17,17,19,.92) 100%);
}
/* The home page video reads better with more of the footage showing; the copy
   keeps its own text-shadow, so the scrim only needs to hold contrast. */
.hero-media:has(video)::after{
  background:
    linear-gradient(90deg,rgba(17,17,19,.55) 0%,rgba(17,17,19,.36) 38%,rgba(17,17,19,.04) 72%,rgba(17,17,19,0) 100%),
    linear-gradient(180deg,rgba(17,17,19,.48) 0%,rgba(17,17,19,.16) 34%,rgba(17,17,19,.78) 100%);
}
.hero .wrap{position:relative;z-index:1;width:100%;
  padding-top:clamp(80px,14vw,150px);padding-bottom:clamp(34px,5vw,58px)}
.hero h1{max-width:15ch;margin:18px 0 20px;color:var(--on-photo);
  text-shadow:0 2px 30px rgba(0,0,0,.45)}
.hero .lede{max-width:52ch;color:var(--on-photo-2);margin-bottom:26px}

.btns{display:flex;flex-wrap:wrap;gap:11px}
.btn{
  font-family:var(--f-display);font-size:15px;font-weight:600;text-decoration:none;
  padding:13px 22px;border-radius:2px;background:var(--rust);color:#fff;
  border:1px solid var(--rust);transition:background .16s,border-color .16s;
  display:inline-flex;align-items:center;gap:8px;cursor:pointer;
}
.btn:hover{background:var(--rust-lift);border-color:var(--rust-lift)}
/* ghost sits on photography by default, and on paper inside a light section */
.btn.ghost{background:rgba(17,17,19,.34);border-color:rgba(255,255,255,.72);color:var(--on-photo);
  backdrop-filter:blur(3px);-webkit-backdrop-filter:blur(3px)}
.btn.ghost:hover{background:rgba(255,255,255,.18);border-color:#fff}
section:not(.cta):not(.hero) .btn.ghost{background:transparent;border-color:var(--rule-2);color:var(--ink)}
section:not(.cta):not(.hero) .btn.ghost:hover{background:var(--ground-2);border-color:var(--ink-3)}

/* ---------- proof bar ---------- */
.proof{border-bottom:1px solid var(--rule);background:var(--ground-2)}
.proof .wrap{display:flex;flex-wrap:wrap;gap:0}
/* must stay child-scoped: a bare `.proof div` also matches .wrap and turns the
   whole bar into a column */
.proof .wrap>div,.proof .wrap>a{flex:1 1 200px;padding:18px 26px 18px 0;
  border-right:1px solid var(--rule);
  display:flex;flex-direction:column;gap:3px;min-width:0}
.proof .wrap>:last-child{border-right:0}
/* the rating is a link to the Google listing; it should read as part of the bar
   until you reach for it */
.proof-link{text-decoration:none;color:inherit}
.proof-link:hover b,.proof-link:focus-visible b{color:var(--rust)}
.proof-link:hover>span,.proof-link:focus-visible>span{color:var(--rust)}
.proof-link:focus-visible{outline:2px solid var(--rust);outline-offset:-4px}
.proof b{font-family:var(--f-display);font-size:21px;font-weight:700;letter-spacing:-.02em;
  font-variant-numeric:tabular-nums;display:flex;align-items:baseline}
.proof .wrap>div>span,.proof .wrap>a>span{font-family:var(--f-mono);font-size:11px;
  letter-spacing:.1em;text-transform:uppercase;color:var(--ink-3);transition:color .15s}
.stars{color:var(--rust);letter-spacing:.08em;font-size:15px;margin-right:3px}

/* ---------- sections ---------- */
section{padding:clamp(56px,8vw,110px) 0}
section.tight{padding:clamp(40px,5vw,68px) 0}
section.alt{background:var(--ground-2);border-block:1px solid var(--rule)}
.shead{margin-bottom:clamp(28px,4vw,48px);max-width:60ch}
.shead .eyebrow{margin-bottom:14px}
.shead h2{margin-bottom:16px}
.shead p{color:var(--ink-2);margin:0;font-size:18px}

/* On wide screens a 60ch heading block left a ~900px void beside every section.
   Where there is an intro paragraph, set it against the heading instead — still
   left-aligned, but the row now occupies the width it was given. Collapses back
   to a single stack below 1080px. */
@media(min-width:1080px){
  .shead:has(p){display:grid;max-width:none;align-items:end;
    grid-template-columns:minmax(0,1.15fr) minmax(0,1fr);
    column-gap:clamp(32px,4vw,72px)}
  .shead:has(p) .eyebrow{grid-column:1;grid-row:1}
  /* h1 as well as h2: page headers use h1, and without an explicit position it
     auto-flowed into column 2, pushing the title and intro right and leaving the
     eyebrow stranded on its own. */
  .shead:has(p) h1,
  .shead:has(p) h2{grid-column:1;grid-row:2;margin-bottom:0}
  .shead:has(p) p{grid-column:2;grid-row:2;max-width:48ch}
}

/* ---------- generic grids ---------- */
.g3{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:clamp(16px,2vw,26px)}
.g2{display:grid;grid-template-columns:repeat(auto-fit,minmax(340px,1fr));gap:clamp(18px,2.4vw,34px)}

/* ---------- figure / photo cards ---------- */
.shot{position:relative;overflow:hidden;background:var(--raise-2);border-radius:2px;display:block}
.shot img{width:100%;height:100%;object-fit:cover;display:block;
  transition:transform .5s cubic-bezier(.2,.7,.3,1)}
a.shot:hover img,.card:hover .shot img{transform:scale(1.035)}
.cap{font-family:var(--f-mono);font-size:12px;line-height:1.5;color:var(--ink-3);
  margin-top:10px;display:block}

/* card = photo + text block */
.card{display:flex;flex-direction:column;gap:0;text-decoration:none;background:var(--raise);
  border:1px solid var(--rule);border-radius:2px;overflow:hidden;
  transition:border-color .18s,box-shadow .18s}
.card:hover{border-color:var(--rule-2);box-shadow:0 10px 26px rgba(17,17,19,.07)}
.card .body{padding:20px 22px 24px;display:flex;flex-direction:column;gap:9px;flex:1}
.card .body h3{margin:0}
.card .body p{margin:0;color:var(--ink-2);font-size:15.5px;line-height:1.5}
.card .meta{font-family:var(--f-mono);font-size:11px;letter-spacing:.1em;text-transform:uppercase;
  color:var(--ink-3);margin-top:auto;padding-top:10px}
.card .meta b{color:var(--ink-2);font-weight:600}

/* ---------- finish swatch cards ---------- */
.finish{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:clamp(18px,3vw,44px);
  align-items:center;padding:clamp(28px,4vw,52px) 0;border-bottom:1px solid var(--rule)}
.finish:last-child{border-bottom:0}
.finish:nth-child(even) .finish-text{order:-1}
.finish-text .eyebrow{margin-bottom:12px}
.finish-text h3{font-size:clamp(24px,3vw,34px);margin-bottom:12px}
.finish-text p{color:var(--ink-2);margin-bottom:1em}
.finish-shots{display:flex;justify-content:flex-start}
.finish-shots .lead{display:inline-block;height:clamp(300px,38vw,470px);width:auto;max-width:100%}
@media(max-width:760px){.finish-shots .lead{height:auto;width:100%}}
@media(max-width:760px){
  .finish{grid-template-columns:1fr;gap:20px}
  .finish:nth-child(even) .finish-text{order:0}
}

/* ---------- detail strip (vertical craft shots) ---------- */
.rail{display:flex;gap:14px;overflow-x:auto;scroll-snap-type:x mandatory;
  padding-bottom:16px;margin:0 calc(var(--gut)*-1);padding-inline:var(--gut);
  scrollbar-width:thin;scrollbar-color:var(--rule-2) transparent}
.rail::-webkit-scrollbar{height:7px}
.rail::-webkit-scrollbar-thumb{background:var(--rule-2);border-radius:4px}
.rail>*{flex:0 0 auto;scroll-snap-align:start;max-width:86vw}
.rail .shot{height:var(--railh)}
.rail figcaption,.rail .cap{max-width:min(340px,86vw)}

/* ---------- video ---------- */
.vframe{position:relative;background:#000;border-radius:2px;overflow:hidden}
.vframe video{width:100%;height:auto;display:block}
.vframe.vert video{aspect-ratio:9/16;object-fit:cover}
.vframe.land video{aspect-ratio:16/9;object-fit:cover}

/* ---------- spec table ---------- */
.spec{width:100%;border-collapse:collapse;font-size:15.5px}
.spec caption{text-align:left;font-family:var(--f-mono);font-size:11px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--ink-3);padding-bottom:12px}
.spec th,.spec td{text-align:left;padding:13px 18px 13px 0;border-bottom:1px solid var(--rule);
  vertical-align:top}
.spec th{font-family:var(--f-display);font-weight:600;font-size:14.5px;width:34%;color:var(--ink)}
.spec td{color:var(--ink-2)}
.spec td .mono{color:var(--ink);font-size:14px}
.tscroll{overflow-x:auto}

/* ---------- quote ---------- */
.quote{border-left:2px solid var(--rust);padding:2px 0 2px clamp(18px,3vw,30px)}
.quote p{font-size:clamp(18px,2.2vw,23px);line-height:1.5;color:var(--ink);margin-bottom:16px}
.quote footer{font-family:var(--f-mono);font-size:12px;line-height:1.6;color:var(--ink-3);
  letter-spacing:.03em}
.quote footer b{color:var(--ink);font-weight:600;display:block;font-size:13px}
.quote.sm p{font-size:16.5px;line-height:1.55;color:var(--ink-2)}

.reviews{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));
  gap:clamp(20px,3vw,38px)}

/* ---------- steps ---------- */
.steps{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:1px;
  background:var(--rule);border:1px solid var(--rule)}
.steps>div{background:var(--raise);padding:24px 22px 26px;display:flex;flex-direction:column;gap:9px}
section.alt .steps>div{background:var(--raise)}
.steps .n{font-family:var(--f-mono);font-size:12px;font-weight:600;color:var(--rust);
  letter-spacing:.1em}
.steps h4{margin:0}
.steps p{margin:0;font-size:15px;line-height:1.5;color:var(--ink-2)}

/* ---------- form ---------- */
.form{display:grid;gap:14px}
.form label{display:flex;flex-direction:column;gap:6px;font-family:var(--f-mono);
  font-size:11px;letter-spacing:.11em;text-transform:uppercase;color:var(--ink-3)}
.form input,.form textarea,.form select{
  font-family:var(--f-body);font-size:16.5px;color:var(--ink);background:var(--raise);
  border:1px solid var(--rule-2);border-radius:2px;padding:12px 14px;width:100%;
  min-height:48px;transition:border-color .15s;
}
.form textarea{min-height:104px;resize:vertical;line-height:1.5}
.form input:focus,.form textarea:focus,.form select:focus{border-color:var(--rust);outline:none}
.form .row{display:grid;grid-template-columns:1fr 1fr;gap:14px}
@media(max-width:560px){.form .row{grid-template-columns:1fr}}
.form .btn{justify-content:center;margin-top:4px}
.formnote{font-family:var(--f-mono);font-size:11.5px;line-height:1.6;color:var(--ink-3);margin:0}

/* ---------- area list ---------- */
.areas{display:flex;flex-wrap:wrap;gap:9px}
.areas span{font-family:var(--f-mono);font-size:13px;padding:8px 15px;border:1px solid var(--rule-2);
  border-radius:2px;color:var(--ink-2)}

/* ---------- CTA band ---------- */
.cta{position:relative;overflow:hidden;border-block:1px solid var(--rule)}
.cta-media{position:absolute;inset:0;z-index:0}
.cta-media img{width:100%;height:100%;object-fit:cover}
.cta-media::after{content:"";position:absolute;inset:0;background:rgba(17,17,19,.82)}
.cta .wrap{position:relative;z-index:1}
.cta h2,.cta .lede{color:var(--on-photo)}
.cta .lede{color:var(--on-photo-2)}

/* ---------- footer ---------- */
.ftr{background:var(--ground-2);border-top:1px solid var(--rule);
  padding:clamp(40px,5vw,66px) 0 34px;font-size:15px;color:var(--ink-2)}
.ftr p{color:var(--ink-2)}
.ftr-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));
  gap:32px;margin-bottom:36px}
.ftr h4{margin-bottom:14px;font-size:13px;font-family:var(--f-mono);font-weight:600;
  letter-spacing:.12em;text-transform:uppercase;color:var(--ink-3)}
.ftr ul{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:2px}
.ftr li{display:flex}
.ftr a{color:var(--ink-2);text-decoration:none;transition:color .15s;
  padding:11px 0;line-height:1.3;min-height:44px;display:flex;align-items:center}
.ftr li[style]{padding:11px 0;line-height:1.35}
.ftr a:hover{color:var(--ink)}
.ftr .legal{border-top:1px solid var(--rule);padding-top:22px;font-family:var(--f-mono);
  font-size:11.5px;color:var(--ink-3);line-height:1.7;display:flex;flex-wrap:wrap;
  gap:6px 22px;justify-content:space-between}

/* ---------- filter chips ---------- */
.chips{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:clamp(22px,3vw,34px)}
.chip{font-family:var(--f-mono);font-size:12px;letter-spacing:.06em;padding:8px 16px;
  border:1px solid var(--rule-2);background:transparent;color:var(--ink-2);border-radius:2px;
  cursor:pointer;transition:all .15s;text-transform:uppercase;
  min-height:44px;display:inline-flex;align-items:center}
.chip:hover{border-color:var(--ink-3);color:var(--ink)}
.chip[aria-pressed="true"]{background:var(--rust);border-color:var(--rust);color:#fff}
.masonry{columns:3 290px;column-gap:clamp(14px,1.8vw,22px)}
.masonry>figure{break-inside:avoid;margin:0 0 clamp(14px,1.8vw,22px)}
.masonry figcaption{font-family:var(--f-mono);font-size:11.5px;line-height:1.5;
  color:var(--ink-3);margin-top:9px}

/* crosshair rule — the logo motif as a section divider */
.xrule{display:flex;align-items:center;gap:14px;margin:0 0 clamp(26px,4vw,44px);color:var(--rust)}
.xrule::before,.xrule::after{content:"";height:1px;background:var(--rule-2);flex:1}
.xrule svg{width:17px;height:17px;flex:none}
.xrule::before{flex:0 0 clamp(20px,5vw,64px)}

/* stacked pair: two photos, each at its own ratio */
.pair{display:grid;gap:14px}
.pair.two{grid-template-columns:1fr 1fr}
@media(max-width:620px){.pair.two{grid-template-columns:1fr}}

/* plain three-across explainer, replaces the .steps kludge */
.notes{display:grid;grid-template-columns:repeat(auto-fit,minmax(250px,1fr));
  gap:clamp(20px,3vw,38px)}
.notes>div{border-top:2px solid var(--rust);padding-top:16px}
.notes .n{font-family:var(--f-mono);font-size:11px;font-weight:600;letter-spacing:.12em;
  text-transform:uppercase;color:var(--rust);display:block;margin-bottom:10px}
.notes h4{margin-bottom:9px}
.notes p{margin:0;font-size:15.5px;line-height:1.55;color:var(--ink-2)}

/* ---------- quick service cards: the first fork in the road ---------- */
.qcards{display:grid;grid-template-columns:repeat(auto-fit,minmax(275px,1fr));
  gap:clamp(16px,2.4vw,30px)}
.qcard{background:var(--raise);border:1px solid var(--rule);
  border-radius:2px;padding:clamp(26px,3vw,36px);display:flex;flex-direction:column;gap:9px;
  text-decoration:none;transition:box-shadow .18s,transform .18s,border-color .18s}
.qcard:hover{box-shadow:0 12px 30px rgba(17,17,19,.09);transform:translateY(-2px);
  border-color:var(--rule-2)}
.qcard .lbl{font-family:var(--f-mono);font-size:10.5px;font-weight:600;letter-spacing:.15em;
  text-transform:uppercase;color:var(--ink-3)}
.qcard h3{font-size:clamp(20px,2.2vw,24px)}
.qcard p{margin:0;color:var(--ink-2);font-size:15.5px;line-height:1.55;flex:1}
.qcard .go{font-family:var(--f-display);font-weight:600;font-size:15px;color:var(--rust);
  display:flex;align-items:center;gap:7px;margin-top:6px}
.qcard:hover .go{color:var(--rust)}

/* ---------- problem cards ---------- */
.probs{display:flex;flex-wrap:wrap;gap:1px;background:var(--rule);border:1px solid var(--rule)}
.prob{flex:1 1 265px;background:var(--raise);padding:clamp(22px,2.6vw,30px);
  display:flex;flex-direction:column;gap:10px}
.prob .n{font-family:var(--f-mono);font-size:10.5px;font-weight:600;letter-spacing:.14em;
  text-transform:uppercase;color:var(--rust)}
.prob h3{font-size:19px;line-height:1.25}
.prob p{margin:0;color:var(--ink-2);font-size:15px;line-height:1.55}

/* ---------- full service grid ---------- */
.svcs{display:flex;flex-wrap:wrap;gap:clamp(14px,1.6vw,22px);background:transparent;border:0}
.svc{flex:1 1 282px;background:var(--raise);border:1px solid var(--rule);border-radius:2px;
  display:flex;flex-direction:column;text-decoration:none;overflow:hidden;
  transition:border-color .18s,box-shadow .18s}
.svc:hover{border-color:var(--rule-2);box-shadow:0 12px 30px rgba(17,17,19,.08)}
.svc .shot{aspect-ratio:3/2}
.svc img{transition:transform .5s cubic-bezier(.2,.7,.3,1)}
.svc:hover img{transform:scale(1.04)}
.svc-body{padding:20px 22px 24px;display:flex;flex-direction:column;gap:8px;flex:1}
.svc .tagline{font-family:var(--f-mono);font-size:10px;font-weight:600;letter-spacing:.13em;
  text-transform:uppercase;color:var(--ink-3)}
.svc h3{font-size:18px}
.svc p{margin:0;color:var(--ink-2);font-size:14.5px;line-height:1.5;flex:1}
.svc .go{font-family:var(--f-mono);font-size:11px;letter-spacing:.09em;text-transform:uppercase;
  color:var(--ink-3);margin-top:auto;padding-top:8px}
.svc:hover .go{color:var(--rust)}

/* ---------- promises ---------- */
.promises{display:grid;grid-template-columns:repeat(auto-fit,minmax(290px,1fr));
  gap:clamp(22px,3vw,40px)}
.promise{display:grid;grid-template-columns:38px 1fr;gap:0 16px}
.promise .n{font-family:var(--f-mono);font-size:12px;font-weight:600;color:var(--rust);
  padding-top:3px;font-variant-numeric:tabular-nums}
.promise h3{font-size:17.5px;margin-bottom:7px;line-height:1.3}
.promise p{margin:0;color:var(--ink-2);font-size:15px;line-height:1.55}

/* ---------- spec row ---------- */
.specrow{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:1px;
  background:var(--rule);border:1px solid var(--rule);margin-top:26px}
.specrow>div{background:var(--raise);padding:18px 20px}
.specrow b{display:block;font-family:var(--f-display);font-size:clamp(19px,2.2vw,24px);
  font-weight:700;letter-spacing:-.02em;line-height:1.1;margin-bottom:5px}
.specrow span{font-family:var(--f-mono);font-size:10.5px;letter-spacing:.1em;text-transform:uppercase;
  color:var(--ink-3);line-height:1.4;display:block}

/* ---------- scroll reveal ---------- */
/* the hidden state is gated on html.reveal, which JS sets. Without JS, or if the
   observer never fires, every section renders visible rather than blank. */
.rv{transition:opacity .6s ease,transform .6s cubic-bezier(.2,.7,.3,1)}
html.reveal .rv{opacity:0;transform:translateY(16px)}
html.reveal .rv.in{opacity:1;transform:none}
@media (prefers-reduced-motion:reduce){
  html.reveal .rv{opacity:1;transform:none;transition:none}
}

/* a link that is itself a call to action needs a real touch target, even inline */
.touch{display:inline-flex;align-items:center;min-height:44px}

/* honeypot. `.sr` loses to `.form input` on specificity, which rendered it as a
   full-size visible field — and a filled honeypot is treated as a bot, so a real
   person typing in it would have had their enquiry silently dropped. */
.hp{display:none}

/* ---------- form submit states ---------- */
.formstatus{font-family:var(--f-mono);font-size:12.5px;line-height:1.55;margin:2px 0 0;
  padding:11px 14px;border-radius:2px;border:1px solid var(--rule-2);background:var(--ground-2);
  color:var(--ink-2)}
.formstatus.ok{border-color:#2F6B4F;background:#E8F2EC;color:#1E4A36}
.formstatus.bad{border-color:var(--rust);background:var(--rust-dim);color:var(--rust)}
.form.sending button[type=submit]{opacity:.6;pointer-events:none}

/* ---------- map ---------- */
.mapwrap{position:relative;height:var(--maph,360px);border:1px solid var(--rule);
  border-radius:2px;overflow:hidden;background:var(--surface-2)}
.mapwrap iframe{width:100%;height:100%;border:0;display:block;filter:saturate(.82)}
.areas a{font-family:var(--f-mono);font-size:13px;padding:9px 15px;border:1px solid var(--rule-2);
  border-radius:2px;color:var(--ink-2);text-decoration:none;transition:all .15s;
  display:inline-flex;align-items:center;min-height:44px}
.areas a:hover{border-color:var(--rust);color:var(--rust)}

/* ---------- visualizer ---------- */
.vgrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(320px,1fr));
  gap:clamp(22px,3vw,40px);margin-bottom:clamp(26px,3vw,40px)}
.vstep{display:flex;flex-direction:column;gap:12px}
.vnum{font-family:var(--f-mono);font-size:11px;font-weight:600;letter-spacing:.14em;
  text-transform:uppercase;color:var(--rust)}
.vstep h2{font-size:clamp(20px,2.2vw,25px)}

.vdrop{position:relative;display:flex;align-items:center;justify-content:center;
  aspect-ratio:4/3;min-height:300px;border:2px dashed var(--rule-2);border-radius:2px;
  background:var(--raise);cursor:pointer;overflow:hidden;
  transition:border-color .15s,background .15s}
.vdrop:hover,.vdrop:focus-visible,.vdrop.over{border-color:var(--rust);background:var(--ground-2)}
.vdrop-in{display:flex;flex-direction:column;gap:5px;align-items:center;text-align:center;
  padding:20px;pointer-events:none}
.vdrop-in strong{font-family:var(--f-display);font-size:17px;color:var(--ink)}
.vdrop-in span{font-family:var(--f-mono);font-size:11.5px;color:var(--ink-3)}
.vdrop img{width:100%;height:100%;object-fit:cover;position:absolute;inset:0}

.vfins{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:10px}
.vfin{display:flex;flex-direction:column;gap:6px;padding:0 0 11px;text-align:left;
  background:var(--raise);border:1px solid var(--rule);border-radius:2px;cursor:pointer;
  overflow:hidden;transition:border-color .15s,box-shadow .15s}
.vfin:hover{border-color:var(--rule-2)}
.vfin[aria-pressed="true"]{border-color:var(--rust);box-shadow:0 0 0 1px var(--rust)}
.vfin .shot{border-radius:0}
.vfin-name{font-family:var(--f-display);font-weight:700;font-size:14.5px;color:var(--ink);
  padding:9px 12px 0}
.vfin-desc{font-family:var(--f-mono);font-size:10.5px;line-height:1.45;color:var(--ink-3);
  padding:0 12px}

.vgo{display:flex;flex-direction:column;gap:12px;align-items:flex-start;
  padding-top:clamp(6px,1vw,12px)}
.vgo .btn[disabled]{opacity:.45;pointer-events:none}
#vturnstile:empty{display:none}

.vout{scroll-margin-top:calc(var(--hdr-h) + 20px);margin-top:clamp(30px,4vw,52px);border-top:1px solid var(--rule);
  padding-top:clamp(26px,3vw,40px)}
.vout-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(320px,1fr));
  gap:clamp(18px,2.4vw,32px);align-items:start}
.vresult{margin:0;display:flex;flex-direction:column;gap:9px}
.vresult img{width:100%;height:auto;display:block;border:1px solid var(--rule);border-radius:2px}
.vlabel{font-family:var(--f-mono);font-size:10.5px;font-weight:600;letter-spacing:.13em;
  text-transform:uppercase;color:var(--rust)}
.vreal{display:flex;flex-direction:column;gap:9px}
.vreal[hidden]{display:none}
.vcta{margin-top:clamp(22px,3vw,34px);padding:clamp(20px,2.6vw,28px);
  background:var(--ground-2);border:1px solid var(--rule);border-radius:2px}
.vcta p{margin:0 0 16px;color:var(--ink-2);max-width:68ch}
.vcta strong{color:var(--ink)}
.vprivacy{font-family:var(--f-mono);font-size:11.5px;line-height:1.6;color:var(--ink-3);
  margin-top:clamp(24px,3vw,36px);max-width:70ch}

/* any element toggled with the hidden attribute needs this: an author `display`
   declaration outranks the UA stylesheet's [hidden]{display:none} */
[hidden]{display:none!important}

/* ---------- visualizer output: AI and real work must never be confused ---------- */
.vout-grid{align-items:stretch}
.vblock{display:flex;flex-direction:column;gap:14px;padding:clamp(18px,2.2vw,26px);
  border-radius:2px;border:1px solid var(--rule);background:var(--raise)}
.vblock-ai{border-style:dashed;background:var(--ground-2)}
.vblock-real{border-color:var(--rule-2)}
.vhead{display:flex;flex-direction:column;gap:8px}
.vhead h2{font-size:clamp(18px,2vw,22px);line-height:1.2}
.vhead p{margin:0;font-size:14.5px;line-height:1.5;color:var(--ink-2)}
.vtag{font-family:var(--f-mono);font-size:10px;font-weight:600;letter-spacing:.14em;
  text-transform:uppercase;padding:4px 9px;border-radius:2px;align-self:flex-start}
.vtag-ai{background:var(--rust-dim);color:var(--rust);border:1px solid var(--rust)}
.vtag-real{background:#E8F2EC;color:#1E4A36;border:1px solid #2F6B4F}
.vblock .vresult{margin:0}
/* The provider returns a square image while our own photography is 4:3, so a
   fixed box letterboxed the render ~25% narrower than the photo beside it.
   --vaspect is set from the render's own dimensions once it loads: the AI frame
   then fits it exactly (no bars, no crop) and the real photo, which is ours to
   crop safely, covers the same box. Both end up identical on screen. */
.vblock .vresult img{border-radius:2px;aspect-ratio:var(--vaspect,4/3);width:100%;height:auto;
  object-fit:cover;background:var(--surface-2)}
.vblock-real .shot{aspect-ratio:var(--vaspect,4/3)!important}
.vblock-real .shot img{width:100%;height:100%;object-fit:cover}

/* ---------- CMG material swatches in the finish picker ---------- */
.vswatch{display:block;width:100%;aspect-ratio:3/2;overflow:hidden;background:var(--raise-2)}
.vswatch img{width:100%;height:100%;object-fit:cover;display:block}
.vswatch-flat{aspect-ratio:3/2}
.vfin .vswatch{border-bottom:1px solid var(--rule)}

/* ---------- CMG color catalogue ---------- */
.ccards{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));
  gap:clamp(12px,1.6vw,20px)}
.ccard{display:flex;flex-direction:column;background:var(--raise);border:1px solid var(--rule);
  border-radius:2px;overflow:hidden}
.ccard-flat,.ccard-img{display:block;width:100%;aspect-ratio:4/3}
.ccard-img img{width:100%;height:100%;object-fit:cover;display:block}
.ccard-name{font-family:var(--f-display);font-weight:600;font-size:14px;color:var(--ink);
  padding:10px 12px 4px;line-height:1.25}
.ccard-done{font-family:var(--f-mono);font-size:9.5px;font-weight:600;letter-spacing:.1em;
  text-transform:uppercase;color:#1E4A36;background:#E8F2EC;border:1px solid #2F6B4F;
  border-radius:2px;padding:3px 7px;margin:0 12px 4px;align-self:flex-start}
.ccard-try{font-family:var(--f-mono);font-size:10.5px;letter-spacing:.05em;color:var(--rust);
  text-decoration:none;padding:0 12px 11px;margin-top:auto}
.ccard-try:hover{text-decoration:underline}
.ccard:not(:has(.ccard-try)) .ccard-name{padding-bottom:12px}

/* "+ more finishes" tile in the visualizer picker */
.vfin-more{text-decoration:none;justify-content:flex-start}
.vmore-plus{display:flex;align-items:center;justify-content:center;width:100%;aspect-ratio:3/2;
  background:var(--ground-2);border-bottom:1px solid var(--rule);
  font-family:var(--f-display);font-size:34px;font-weight:300;color:var(--rust);line-height:1}
.vfin-more:hover .vmore-plus{background:var(--rust-dim)}

/* ---------- visualizer: rendering state ---------- */
/* A full-screen takeover rather than a panel in the flow: the wait is ~20s and
   the visitor's own house, held large, is the most reassuring thing to show
   them. Above the sticky header (60) and the mobile call bar (70). */
.vload{position:fixed;inset:0;z-index:200;overflow:hidden;background:var(--dark)}
.vload-frame{margin:0;position:absolute;inset:0;overflow:hidden}
.vload-frame img{width:100%;height:100%;object-fit:cover;display:block;
  filter:saturate(.5) brightness(.38)}
/* a scrim under the text, so contrast never depends on the photo */
.vload-frame::after{content:"";position:absolute;inset:0;
  background:radial-gradient(ellipse at center,rgba(20,20,22,.52),rgba(20,20,22,.80))}
.vload-veil{position:absolute;inset:0;display:flex;flex-direction:column;
  align-items:center;justify-content:center;gap:16px;padding:24px;text-align:center}
.vload-spin{width:40px;height:40px;border-radius:50%;flex:none;
  border:2px solid rgba(255,255,255,.26);border-top-color:#fff;
  animation:vspin .9s linear infinite}
.vload-msg{font-family:var(--f-display);font-weight:600;font-size:clamp(19px,3.2vw,27px);
  color:#fff;line-height:1.25;min-height:1.25em;margin:0;max-width:18ch}
.vroof{width:min(320px,78%);height:auto;display:block;margin:2px auto 0}
/* Each stroke is drawn on as its stage arrives. pathLength=1 normalises every
   path, so one dash rule covers strokes of wildly different lengths. */
/* fill/stroke live on the <svg> element itself, not here. If this stylesheet
   is ever stale or blocked, the roof still renders as a plain white line
   drawing; relying on CSS for fill meant an unstyled SVG fell back to its
   default black fill, which turned the windows and door into black blocks. */
.vroof [data-draw]{stroke:rgba(255,255,255,.34);
  stroke-dasharray:1;stroke-dashoffset:1;
  transition:stroke-dashoffset 1s ease,stroke .7s ease}
.vroof g.on [data-draw]{stroke-dashoffset:0;stroke:rgba(255,255,255,.92)}
/* the stage being drawn right now leads in the brand red, then settles to white */
.vroof g.now [data-draw]{stroke:var(--rust-lift)}
.vroof g [data-draw]:nth-child(1){transition-delay:0.00s}
.vroof g [data-draw]:nth-child(2){transition-delay:0.09s}
.vroof g [data-draw]:nth-child(3){transition-delay:0.18s}
.vroof g [data-draw]:nth-child(4){transition-delay:0.27s}
.vroof g [data-draw]:nth-child(5){transition-delay:0.36s}
.vroof g [data-draw]:nth-child(6){transition-delay:0.45s}
.vroof g [data-draw]:nth-child(7){transition-delay:0.54s}
.vroof g [data-draw]:nth-child(8){transition-delay:0.63s}
.vroof g [data-draw]:nth-child(9){transition-delay:0.72s}
.vroof g [data-draw]:nth-child(10){transition-delay:0.81s}
/* Finishing the roof once the render lands. The per-stroke stagger runs to
   .81s, which outlasts the overlay, so it collapses here and every remaining
   stroke completes inside the hold. */
.vload-done .vroof [data-draw]{transition-duration:.3s}
.vload-done .vroof g [data-draw]{transition-delay:0s}
.vload-note{font-family:var(--f-mono);font-size:clamp(13px,1.5vw,15px);letter-spacing:.03em;
  color:rgba(255,255,255,.88);line-height:1.6;margin:0;max-width:36ch}
/* a takeover with no way out is a trap; this aborts the request */
.vload-cancel{margin-top:6px;min-height:44px;padding:11px 22px;cursor:pointer;
  font-family:var(--f-mono);font-size:11px;letter-spacing:.1em;text-transform:uppercase;
  color:#fff;background:transparent;border:1px solid rgba(255,255,255,.42);border-radius:2px}
.vload-cancel:hover{background:rgba(255,255,255,.1);border-color:#fff}
.vload-cancel:focus-visible{outline:2px solid #fff;outline-offset:2px}
/* hold the page still behind the overlay */
html.vload-open,html.vload-open body{overflow:hidden}
@keyframes vspin{to{transform:rotate(360deg)}}
@media (prefers-reduced-motion:reduce){
  .vload-spin{animation:none;border-top-color:rgba(255,255,255,.26)}
  /* no drawing-on; each stage simply appears */
  .vroof [data-draw]{transition:none}
  .vroof g [data-draw]{transition-delay:0s}
}

/* ---------- address suggestions ---------- */
/* One field. City, state and ZIP ride along in hidden inputs when a suggestion
   is chosen, so AccuLynx still receives the parts without the form growing. */
.addrwrap{position:relative}
.addrsug{position:absolute;top:100%;left:0;right:0;z-index:30;margin:4px 0 0;
  padding:4px;list-style:none;max-height:272px;overflow-y:auto;
  background:var(--raise);border:1px solid var(--rule-2);border-radius:2px;
  box-shadow:0 12px 28px rgba(16,18,22,.14)}
.addrsug li{font-family:var(--f-body);font-size:15.5px;color:var(--ink);line-height:1.35;
  padding:11px 12px;min-height:44px;display:flex;align-items:center;cursor:pointer;
  border-radius:2px}
.addrsug li[aria-selected="true"],.addrsug li:hover{background:var(--rust-dim);color:var(--rust)}
.addrsug li b{font-weight:600}
