/* =========================================================================
   Stonevale — brand design layer over Kadence.
   Sections carry an sv- prefix so nothing collides with Kadence or core.
   ========================================================================= */

:root{
  --sv-ink:#171C21;
  --sv-charcoal:#323B44;
  --sv-red:#B02425;
  --sv-red-deep:#8C1B1C;
  --sv-limestone:#E5DFD6;
  --sv-paper:#FAF8F5;
  --sv-offwhite:#FAFAFA;
  --sv-nearblack:#0A0303;
  --sv-line:rgba(23,28,33,.14);
  --sv-line-light:rgba(255,255,255,.14);

  /* Two text tones on light backgrounds, and one reading measure. See
     "Typography" in CLAUDE.md. Six near-identical opacities (.66 to .82) had
     drifted in before these existed. */
  --sv-text:rgba(23,28,33,.82);    /* reading: paragraphs, lists, FAQ answers, ledes */
  --sv-text-2:rgba(23,28,33,.72);  /* supporting: labels, card text and meta, related rows, helper text */
  --sv-measure:40rem;              /* reading width below 1024px (640px); from 1024px, none: text may run to the full content width */

  --sv-pad:clamp(20px,5vw,72px);
  --sv-maxw:1240px;
}

/* ---------- base ---------- */
body{
  background:var(--sv-paper);
  color:var(--sv-ink);
  font-family:Barlow,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  font-size:17px;
  line-height:1.6;
  -webkit-font-smoothing:antialiased;
}
.sv-wrap{max-width:var(--sv-maxw);margin-inline:auto;padding-inline:var(--sv-pad);}

/* Images must never widen their container. Without this a 1600px photo sets
   the min-content width of its grid column and the whole page overflows
   horizontally on narrow viewports, pushing the header's menu toggle
   off-screen. */
img{max-width:100%;height:auto;}

/* Grid and flex children default to min-width:auto, which refuses to shrink
   below their content. Zero it wherever a photo or long string can land. */
.sv-hero__inner > *,
.sv-gal > *,
.sv-svc > *,
.sv-steps > li > *,
.sv-fin__inner > *,
.sv-contact-grid > *,
.sv-form > *,
.sv-fgrid > *{min-width:0;}
.sv-section{padding-block:clamp(56px,8vw,104px);}

/* Kadence wraps content in #inner-wrap; the homepage bands are full bleed. */
.home #inner-wrap,
.home #inner-wrap.wrap{max-width:none;width:auto;padding:0;margin:0;}

/* Barlow throughout — the guidelines specify a grotesque, not a serif.
   A grotesque needs more weight and tighter tracking than the serif it
   replaces to carry the same authority, and less size at the top of the scale. */
.sv-h1,.sv-head h1,.sv-head h2,.sv-fin h2,.sv-h2--tight,.sv-svc h2,.sv-svc h3,.sv-steps h3{
  font-family:Barlow,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  font-weight:700;line-height:1.08;letter-spacing:-.021em;margin:0;
}
.sv-eyebrow{
  font-family:"Barlow Condensed",Barlow,sans-serif;font-weight:700;
  text-transform:uppercase;letter-spacing:.18em;font-size:.82rem;
  color:var(--sv-red);margin:0;
}
.sv-muted{color:var(--sv-text-2);}
.sv-rule{width:78px;height:5px;background:var(--sv-red);margin:26px 0;}
.sv-sr-only{
  position:absolute;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0;
}
:focus-visible{outline:3px solid var(--sv-red);outline-offset:3px;}

/* Base link color — no default browser blue anywhere. This sits in the base
   layer on purpose: every component below (buttons, header CTA, footer, hero
   and dark panels) sets its own color and wins on cascade order. Appending
   this at the end of the file instead is what turned the header's phone CTA
   charcoal-on-red. */
a{color:var(--sv-charcoal);}
a:hover,a:focus-visible{color:var(--sv-red);}

/* ---------- buttons: 44px minimum tap target ---------- */
.sv-btns{display:flex;flex-wrap:wrap;gap:12px;margin-top:26px;}
.sv-btn{
  display:inline-flex;align-items:center;justify-content:center;
  min-height:44px;padding:15px 27px;
  text-decoration:none;font-weight:600;letter-spacing:.01em;
  border:1.5px solid transparent;transition:background .2s ease,color .2s ease;
}
.sv-btn--solid{background:var(--sv-charcoal);color:#fff;}
.sv-btn--solid:hover,.sv-btn--solid:focus-visible{background:var(--sv-ink);color:#fff;}
.sv-btn--ghost{border-color:var(--sv-charcoal);color:var(--sv-ink);}
.sv-btn--ghost:hover,.sv-btn--ghost:focus-visible{background:var(--sv-charcoal);color:#fff;}

/* Browsing tier — every button that moves the visitor somewhere to look rather
   than committing them to an action. One class, so the three cannot drift apart
   again: they previously carried --solid and --ghost and were then re-colored
   per section, which is how "Explore StonePave" ended up solid while "View the
   full gallery" stayed an outline despite being the same tier.

   Solid rather than outline because an outline over a photograph has no fill to
   carry its label: the hero's "See our work" measured 1.30-1.51:1 against the
   image behind it. Filled, the same label reads 11.38:1. */
.sv-btn--browse{background:var(--sv-charcoal);border-color:var(--sv-charcoal);color:#fff;}
.sv-btn--browse:hover,
.sv-btn--browse:focus-visible{background:var(--sv-ink);border-color:var(--sv-ink);color:#fff;}
.sv-btn--block{width:100%;}

/* Photo pairs simply stack now; the stepping motif is retired. */

.sv-shot{position:relative;margin:0;overflow:hidden;background:var(--sv-limestone);aspect-ratio:16/10;}
.sv-shot img{width:100%;height:100%;object-fit:cover;display:block;}

/* ---------- header (Kadence markup, Stonevale skin) ---------- */
/* Sticky offset. Logged in, WordPress pins a fixed admin bar at the top of the
   viewport; a header stuck to top:0 slides underneath it and the logo loses its
   top edge. The offset is driven by --sv-sticky-top, which header.js sets from
   the admin bar's real height when it is actually fixed. The media queries below
   are the no-JS fallback (32px desktop, 46px at WordPress's 782px breakpoint). */
#masthead{
  position:sticky;top:var(--sv-sticky-top,0px);z-index:50;
  background:rgba(250,248,245,.94);
  -webkit-backdrop-filter:blur(8px);
  backdrop-filter:blur(8px);
  border-bottom:1px solid var(--sv-line);
}
#masthead .site-container{max-width:var(--sv-maxw);padding-inline:var(--sv-pad);}
/* Horizontal lockup, extracted from page 12 of the brand guidelines.
   Guidelines minimum digital sizes: logomark 50px, logotype and full logo
   150px. The lockup is 3.148:1, so 190px wide clears the 150px floor with
   room to spare and still yields a compact ~60px header band.
   Never stretch, rotate, flip, shear, recolor or box the logo. */
#masthead .site-branding img,
#masthead .custom-logo{width:190px;min-width:150px;height:auto;max-width:none;}
#masthead .site-header-row{padding-block:14px;transition:padding-block .22s ease;}

/* Shrink on scroll. The full lockup must stay at or above the guidelines'
   150px minimum, so it goes 190px -> 158px and the padding tightens; the
   mark-only fallback is not needed. */
#masthead .site-branding img,
#masthead .custom-logo{transition:width .22s ease;}
#masthead.sv-header--shrunk .site-header-row{padding-block:8px;}
#masthead.sv-header--shrunk .site-branding img,
#masthead.sv-header--shrunk .custom-logo{width:158px;}

@media (prefers-reduced-motion:reduce){
  #masthead .site-header-row,
  #masthead .site-branding img,
  #masthead .custom-logo{transition:none;}
}

/* Kadence's toggle ships at 31px tall; the brief requires 44x44 minimum. */
#mobile-toggle,
#masthead .menu-toggle-open,
#masthead .menu-toggle-close{
  min-width:44px;min-height:44px;
  display:inline-flex;align-items:center;justify-content:center;
}

body.admin-bar{--sv-sticky-top:32px;}
@media screen and (max-width:782px){body.admin-bar{--sv-sticky-top:46px;}}

/* The logo already carries the wordmark; the text title would duplicate it. */
#masthead .site-title,
#masthead .site-description{
  position:absolute;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0;
}

#primary-menu{gap:26px;}
#primary-menu > li > a{
  text-decoration:none;font-weight:500;font-size:.97rem;
  padding-block:6px;border-bottom:2px solid transparent;color:var(--sv-ink);
  min-height:44px;display:inline-flex;align-items:center;
}
#primary-menu > li > a:hover,
#primary-menu > li > a:focus-visible{border-bottom-color:var(--sv-red);color:var(--sv-ink);}

/* The phone CTA is a menu item so it works in the mobile menu too. */
#primary-menu > li.sv-tel > a{
  background:var(--sv-red);color:#fff;font-weight:600;
  padding:11px 20px;border-bottom:0;
}
#primary-menu > li.sv-tel > a:hover,
#primary-menu > li.sv-tel > a:focus-visible{background:var(--sv-red-deep);color:#fff;}

/* ---------- hero ---------- */
.sv-hero{border-bottom:1px solid var(--sv-line);background:var(--sv-paper);}

/* Hero backdrop: the stripe field, with the copy on a dark panel over it. */
.sv-hero--field{color:#fff;border-bottom:0;}
.sv-hero--field .sv-h1,
.sv-hero--field .sv-lede,
.sv-hero--field .sv-lic{color:#fff;}
.sv-hero--field .sv-h1 em{color:#fff;opacity:.85;}
.sv-hero--field .sv-lede{color:#fff;}
.sv-hero--field .sv-lic{color:#fff;border-top-color:rgba(255,255,255,.38);}
.sv-hero--field .sv-lic strong{color:#fff;}
.sv-hero--field .sv-eyebrow{color:#fff;}
.sv-hero--field .sv-btn--solid{background:var(--sv-red);color:#fff;}
.sv-hero--field .sv-btn--solid:hover,
.sv-hero--field .sv-btn--solid:focus-visible{background:#fff;color:var(--sv-ink);}
.sv-hero__inner{
  display:grid;grid-template-columns:1fr 1.05fr;
  gap:clamp(28px,5vw,72px);align-items:center;
  padding-block:clamp(46px,7vw,92px);
}
.sv-hero--textonly .sv-hero__inner{grid-template-columns:minmax(0,760px);}
/* No photo slot renders, so the copy should not be trapped in a half-width
   grid column — the license line needs ~530px to stay on one line. */
.sv-hero--field .sv-hero__inner{grid-template-columns:minmax(0,1fr);}
.sv-hero--field .sv-hero__copy{max-width:46rem;}
/* Its own width, wider than the lede's measure, plus a deliberate break at the
   separator if it ever runs out of room. */
.sv-hero--field .sv-lic{max-width:none;}
.sv-h1{font-size:clamp(2.25rem,5.6vw,3.875rem);}
.sv-h1 em{font-style:normal;color:var(--sv-red);display:block;}
.sv-lede{font-size:1.12rem;max-width:46ch;margin:22px 0 0;color:var(--sv-text);}
.sv-lic{
  margin-top:30px;font-size:1.0625rem;color:var(--sv-text-2);
  border-top:1px solid var(--sv-line);padding-top:16px;
}
.sv-lic strong{color:var(--sv-ink);}
.sv-lic .sv-nowrap{white-space:nowrap;}

/* ---------- pillars ---------- */
.sv-pillars{background:var(--sv-charcoal);color:#fff;}
.sv-pillars ul{
  list-style:none;margin:0;padding:0;
  display:grid;grid-template-columns:repeat(4,1fr);
}
.sv-pillars li{padding:30px 26px;border-left:1px solid var(--sv-line-light);}
.sv-pillars li:first-child{border-left:0;}
.sv-pillars b{
  font-family:inherit;font-weight:700;font-size:1.0625rem;letter-spacing:-.012em;
  display:block;margin-bottom:5px;
}
.sv-pillars small{color:rgba(255,255,255,.72);font-size:.9375rem;line-height:1.55;display:block;}

/* ---------- section head ---------- */
.sv-head{max-width:var(--sv-measure);margin-bottom:clamp(30px,4vw,52px);}
.sv-head h1,
.sv-head h2{font-size:clamp(1.75rem,3.9vw,2.625rem);margin-top:10px;}
.sv-head p{color:var(--sv-text);margin:16px 0 0;}

/* ---------- services ---------- */
/* Eight services: 4 or 2 columns divide evenly, 3 would leave a dead cell. */
.sv-svc{
  display:grid;grid-template-columns:repeat(4,1fr);gap:1px;
  background:var(--sv-line);border:1px solid var(--sv-line);
}
/* Column flex so the link can be pinned to the card's bottom edge. Grid
   already stretches every card in a row to the tallest, so with the link on
   margin-top:auto all eight links land on one baseline however many lines the
   copy or the label runs to. */
.sv-svc article{
  background:var(--sv-paper);padding:32px 28px 30px;
  position:relative;transition:background .25s ease;
  display:flex;flex-direction:column;
}
.sv-svc article:hover{background:#fff;}
.sv-svc article::before{
  content:"";position:absolute;left:0;top:0;width:0;height:4px;
  background:var(--sv-red);transition:width .32s ease;
}
.sv-svc article:hover::before{width:100%;}
.sv-svc h2,.sv-svc h3{font-size:1.25rem;margin-bottom:10px;}
.sv-svc p{font-size:.99rem;color:var(--sv-text-2);margin:0 0 16px;}
/* Pushes the link to the bottom of the card regardless of copy length. */
.sv-svc a{margin-top:auto;align-self:flex-start;}
/* Inline, not inline-flex: with a two-line label the flex box pushed the arrow
   to the far right, detached from the end of the text. Inline keeps it in the
   text run, and the padding preserves the 44px tap target. */
.sv-svc a{
  font-family:"Barlow Condensed",sans-serif;text-transform:uppercase;
  letter-spacing:.13em;font-weight:700;font-size:.83rem;text-decoration:none;
  color:var(--sv-red);border-bottom:2px solid transparent;
  display:inline-block;padding-block:11px;
}
.sv-svc a:hover,.sv-svc a:focus-visible{border-bottom-color:var(--sv-red);}

/* ---------- StonePave product band ----------
   Contained, not full-bleed. The source is 1195x896 and is never upscaled, so
   the image column is capped at its native width and the layout gives it the
   narrower side. */
.sv-product{background:var(--sv-offwhite);}
.sv-product__inner{
  display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.02fr);
  gap:clamp(28px,4.5vw,60px);align-items:center;
}
.sv-product__media{max-width:1195px;}
.sv-product__media img{
  width:100%;height:auto;display:block;
  aspect-ratio:1195/896;object-fit:cover;
}
.sv-product__copy h2{
  font-size:clamp(1.75rem,3.9vw,2.625rem);margin-top:10px;line-height:1.08;
}
.sv-product__copy > p{color:var(--sv-text);margin:16px 0 0;}
.sv-product__points{
  list-style:none;padding:0;margin:22px 0 0;
  border-top:1px solid var(--sv-line);
}
.sv-product__points li{
  padding:11px 0 11px 26px;border-bottom:1px solid var(--sv-line);
  position:relative;color:var(--sv-text);font-size:.99rem;
}
.sv-product__points li::before{
  content:"";position:absolute;left:0;top:1.05em;
  width:10px;height:2px;background:var(--sv-red);
}
.sv-product__note{
  margin:18px 0 0;font-size:.9rem;color:var(--sv-text-2);
}

@media (max-width:940px){
  .sv-product__inner{grid-template-columns:1fr;}
  .sv-product__media{order:-1;max-width:none;}
}

/* ---------- process ---------- */
.sv-process{background:var(--sv-limestone);}

/* Two columns from 941px: timeline left, photograph right. The image is
   sticky so it stays in view while the five steps scroll past, which fills
   the ~40% of the section that was empty at desktop width. */
.sv-process__inner{display:grid;grid-template-columns:1fr;gap:0;}
.sv-process__media{margin:0;}
@media (min-width:941px){
  .sv-process__inner{
    grid-template-columns:minmax(0,1fr) minmax(0,1.3fr);
    gap:clamp(32px,4vw,64px);
    align-items:start;
  }
  /* A wide, short slot at the library's native 3:2. Cropping a landscape
     source into a tall column stripped the composition down to a fragment;
     36 of the 58 photographs are exactly 3:2, so the slot matches the
     library rather than the library being forced to match the slot. */
  .sv-process__media{
    position:sticky;
    top:calc(var(--sv-sticky-top,0px) + 96px);
  }
  .sv-process__media img{
    width:100%;height:auto;display:block;
    aspect-ratio:3/2;object-fit:cover;object-position:center;
  }
}
/* Below the two-column breakpoint the section is already full-width, so the
   image is not rendered — it would add height and bytes for no gain. */
@media (max-width:940px){
  .sv-process__media{display:none;}
}
@media (prefers-reduced-motion:reduce){
  .sv-process__media{position:static;}
}

/* Vertical timeline: a rail connecting the numerals, description directly
   beneath its title. The old three-column table left a dead gap between title
   and copy at desktop width and read as a table rather than a sequence. */
.sv-steps{list-style:none;display:block;margin:0;padding:0;}
.sv-steps li{
  position:relative;list-style:none;
  display:grid;grid-template-columns:44px 1fr;
  column-gap:clamp(16px,2.4vw,28px);
  padding:0 0 clamp(26px,3.4vw,42px);
}
.sv-steps li:last-child{padding-bottom:0;}
/* the rail, drawn between one node and the next */
/* Rail starts flush with the bottom of the 44px node — at 50px it left a 6px
   break beneath every node, which read as the sequence being cut short. It
   ends at the last node rather than running past it. */
.sv-steps li:not(:last-child)::before{
  content:"";position:absolute;left:21px;top:44px;bottom:0;
  width:2px;background:rgba(23,28,33,.20);
}
.sv-steps .sv-n{
  grid-column:1;grid-row:1;position:relative;z-index:1;
  width:44px;height:44px;border-radius:50%;
  display:grid;place-items:center;
  background:var(--sv-red);color:#fff;
  font-family:"Barlow Condensed",sans-serif;font-weight:700;
  font-size:1.05rem;letter-spacing:.04em;
}
.sv-steps h3{grid-column:2;grid-row:1;align-self:center;font-size:1.1875rem;}
.sv-steps p{grid-column:2;grid-row:2;margin:8px 0 0;color:var(--sv-text);max-width:62ch;}

/* ---------- gallery ---------- */
.sv-gal{display:grid;grid-template-columns:1fr 1fr;gap:16px;}
.sv-gal-foot{margin-top:34px;}

/* ---------- financing ---------- */
/* Financing panel: photographic backdrop over the stripe field, which stays
   underneath as the load-failure fallback. Scrim alpha is measured against the
   image's lightest pixels, not estimated — see the hero note. */
.sv-fin{color:#fff;position:relative;isolation:isolate;overflow:hidden;}
.sv-panel__media{position:absolute;inset:0;z-index:0;}
.sv-panel__pic{position:absolute;inset:0;display:block;}
.sv-panel__pic img{width:100%;height:100%;object-fit:cover;object-position:center;display:block;}
/* Same treatment as the hero: hold the scrim across the copy column, then
   release quickly. The copy occupies the left ~40% at desktop, so darkening
   the whole panel was washing out the room for no reason. */
.sv-panel__scrim{
  position:absolute;inset:0;pointer-events:none;
  background:
    /* A soft dark pool under the copy column's lower half, where the red CTA
       sits. Red at L=0.106 cannot reach 3:1 against any photographic surround
       — even an 80% black overlay only gets to 2.96 — so this buys separation
       rather than compliance, without a hard black box or lightening the red. */
    radial-gradient(85% 70% at 28% 80%, rgba(0,0,0,.58) 0%, rgba(0,0,0,.34) 50%, rgba(0,0,0,0) 100%),
    linear-gradient(
      90deg,
      rgba(23,28,33,.92) 0%,
      rgba(23,28,33,.90) 38%,
      rgba(23,28,33,.84) 48%,
      rgba(23,28,33,.46) 64%,
      rgba(23,28,33,.14) 80%,
      rgba(23,28,33,0) 100%
    );
}
.sv-fin__inner{position:relative;z-index:1;}
@media (max-width:940px){
  /* Single column below 941px, so the CTA sits near 60% down and 18-34% across
     rather than in the desktop position. The pool is re-anchored to match;
     without this the desktop radial misses the button entirely. */
  .sv-panel__scrim{
    background:
      radial-gradient(70% 34% at 26% 60%, rgba(0,0,0,.46) 0%, rgba(0,0,0,.24) 55%, rgba(0,0,0,0) 100%),
      linear-gradient(180deg, rgba(23,28,33,.06) 0%, rgba(23,28,33,.22) 100%),
      linear-gradient(90deg, rgba(23,28,33,.88) 0%, rgba(23,28,33,.84) 100%);
  }
}
/* Two columns from 941px. The right column is held open and stays empty until
   there is a confirmed figure for it, so dropping the fact card in later needs
   no layout change. The copy is narrowed so the empty half reads as deliberate
   rather than as something missing. */
.sv-fin__inner{
  display:grid;grid-template-columns:1fr;
  /* start, not center: centring left a gap under the heading and pushed the
     fact card low against the copy block it annotates. */
  gap:clamp(28px,5vw,64px);align-items:start;
}
@media (min-width:941px){
  .sv-fin__inner{grid-template-columns:minmax(0,1fr) minmax(0,0.72fr);}
}
.sv-fin__copy{max-width:36rem;}

/* Styling for the reserved card, ready for when it has content. */
/* The card is not clipped and never overflows — measured at 0px scroll overflow
   and 72px inside the wrap at 1440. What looked like a cut edge was the right
   border dissolving: at 28% white it held only 1.10:1 against the bright window
   behind it, while the left border read 2.27:1 against dark scrim. The card was
   therefore defined by its border on one side and by its fill on the other. A
   denser fill and a stronger border give it the same edge all the way round. */
.sv-fin__fact{
  background:rgba(10,3,3,.72);border:1px solid rgba(255,255,255,.46);
  padding:28px 30px;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);
}
.sv-fin__fact b{
  display:block;font-weight:700;font-size:1.3125rem;letter-spacing:-.015em;
  line-height:1.25;
}
.sv-fin__fact p{margin:10px 0 0;font-size:.94rem;color:rgba(255,255,255,.82);}
.sv-fin h2{font-size:clamp(1.75rem,3.9vw,2.625rem);color:#fff;}
.sv-fin p{color:rgba(255,255,255,.92);}
.sv-fin .sv-eyebrow{color:#fff;}
.sv-card{background:rgba(10,3,3,.55);border:1px solid rgba(255,255,255,.28);padding:32px;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);}
.sv-card b{font-weight:700;font-size:1.3125rem;letter-spacing:-.015em;display:block;margin-bottom:8px;}
.sv-card p{margin:0;}
.sv-fin .sv-btn--solid{background:var(--sv-red);color:#fff;}
.sv-fin .sv-btn--solid:hover,.sv-fin .sv-btn--solid:focus-visible{background:#fff;color:var(--sv-charcoal);}

/* ---------- contact ---------- */
.sv-contact-grid{display:grid;grid-template-columns:minmax(0,45fr) minmax(0,55fr);gap:clamp(30px,4vw,56px);}
.sv-h2--tight{font-size:clamp(1.75rem,3.9vw,2.625rem);margin-top:10px;}
.sv-contact-list{list-style:none;padding:0;margin:24px 0 0;}
.sv-contact-list li{padding:13px 0;border-top:1px solid var(--sv-line);}
.sv-contact-list a{
  text-decoration:none;font-weight:600;color:var(--sv-charcoal);
  display:inline-flex;align-items:center;min-height:44px;
}
.sv-contact-list a:hover,.sv-contact-list a:focus-visible{color:var(--sv-red);}

/* The form is a plain block. It used to be a two-column grid, which put
   .sv-form__fields into a single column and squeezed every input to half
   width — 131px inside a 572px column. The grid belongs on __fields only. */
.sv-form{display:block;}
.sv-form label{
  display:flex;align-items:baseline;gap:6px;flex-wrap:wrap;
  font-size:.85rem;font-weight:600;text-transform:uppercase;
  letter-spacing:.1em;margin-bottom:7px;color:var(--sv-text-2);
  min-height:1.2em;
}
.sv-form input,.sv-form select,.sv-form textarea{
  width:100%;padding:13px 14px;border:1px solid rgba(23,28,33,.28);
  background:#fff;font:inherit;color:#2D3748;
  font-size:16px; /* iOS zooms the page on focus below 16px. */
  min-height:44px;border-radius:0;
}
.sv-form input:disabled,.sv-form select:disabled,.sv-form textarea:disabled{
  background:#fff;color:rgba(23,28,33,.45);cursor:not-allowed;
}
/* The shared input rule above already gives the select its border, 16px font
   and 44px minimum height. This only strips the native control chrome so it
   matches the text inputs rather than rendering as a platform dropdown, and
   supplies its own chevron. padding-right leaves room for it. */
.sv-form select.sv-select{
  -webkit-appearance:none;-moz-appearance:none;appearance:none;
  padding-right:42px;cursor:pointer;
  background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='none' stroke='%23323B44' stroke-width='1.75' d='M1 1.5 6 6.5l5-5'/%3E%3C/svg%3E");
  background-repeat:no-repeat;
  background-position:right 15px center;
  background-size:12px 8px;
}
/* Safari keeps a focus ring of its own on an appearance:none select; the
   shared :focus-visible treatment is the one we want. */
.sv-form select.sv-select::-ms-expand{display:none;}

.sv-form .sv-full{grid-column:1/-1;}
.sv-form textarea{min-height:140px;resize:vertical;}
.sv-note{
  background:#FFF6D6;border-left:4px solid #C9A227;
  padding:14px 18px;font-size:.9rem;margin-top:26px;
}

/* ---------- footer ---------- */
.sv-footer{
  background:var(--sv-ink);color:rgba(255,255,255,.72);
  padding-block:56px 30px;font-size:.94rem;
}
.sv-flogo{width:168px;height:auto;margin-bottom:18px;}
.sv-fline{margin:0;max-width:34ch;}
.sv-fgrid{display:grid;grid-template-columns:1.4fr 1fr 1fr 1fr;gap:34px;}
.sv-fhead{
  font-family:"Barlow Condensed",sans-serif;text-transform:uppercase;
  letter-spacing:.15em;font-size:.82rem;color:#fff;margin:0 0 14px;font-weight:700;
}
.sv-footer ul{list-style:none;padding:0;margin:0;}
.sv-footer li{margin-bottom:9px;}
.sv-footer a{text-decoration:none;color:inherit;}
.sv-footer a:hover,.sv-footer a:focus-visible{color:#fff;}
.sv-legal{
  margin-top:44px;padding-top:22px;border-top:1px solid var(--sv-line-light);
  display:flex;flex-wrap:wrap;gap:14px;justify-content:space-between;
  font-size:.86rem;color:rgba(255,255,255,.5);
}

/* =========================================================================
   Responsive. Breakpoints follow content, and are verified at
   360 / 390 / 768 / 834 / 1024 / 1280 / 1440 / 1920.
   ========================================================================= */
@media (max-width:1200px){
  .sv-svc{grid-template-columns:repeat(2,1fr);}
}
@media (max-width:940px){
  .sv-hero__inner{grid-template-columns:1fr;}
  .sv-hero{background:var(--sv-paper);}
  .sv-fin__inner{grid-template-columns:1fr;}
  .sv-contact-grid{grid-template-columns:1fr;}
}
@media (max-width:860px){
  .sv-pillars ul{grid-template-columns:repeat(2,1fr);}
  .sv-pillars li:nth-child(3){border-left:0;}
  .sv-pillars li:nth-child(n+3){border-top:1px solid var(--sv-line-light);}
  .sv-fgrid{grid-template-columns:1fr 1fr;}
}
@media (max-width:760px){
  .sv-gal{grid-template-columns:1fr;}
  .sv-gal-foot{margin-top:34px;}
}
@media (max-width:620px){
  #masthead .site-branding img,
  #masthead .custom-logo{width:158px;min-width:150px;}
  .sv-svc{grid-template-columns:1fr;}
  .sv-form{grid-template-columns:1fr;}
}
@media (max-width:520px){
  .sv-pillars ul{grid-template-columns:1fr;}
  .sv-pillars li{border-left:0;border-top:1px solid var(--sv-line-light);}
  .sv-pillars li:first-child{border-top:0;}
  .sv-fgrid{grid-template-columns:1fr;}
}

/* ---------- motion ---------- */
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto;}
  *,*::before,*::after{animation-duration:.001ms!important;animation-iteration-count:1!important;transition-duration:.001ms!important;}
}

/* =========================================================================
   Utilities — defined last so a component's `background` shorthand cannot
   silently reset them.
   ========================================================================= */

/* ---------- gradient stripe field: the brand's signature device ----------
   Vertical bands of varying width, each stepping between primary red and
   near-black on its own phase, running the full height of a panel. Taken from
   the 2026 brand guidelines; it replaces the "offset course" invented before
   the guidelines existed. Pure CSS, no images.

   Restraint rule: this is a backdrop for dark panels only, never a texture
   laid over content. The lightest point is the primary red, so white text on
   it holds 6.8:1 — above WCAG AA for normal text. */
.sv-stripe-field,
.sv-hero.sv-stripe-field,
.sv-section.sv-stripe-field{
  background-color:var(--sv-nearblack);
  background-image:
    linear-gradient(180deg,var(--sv-red) 0%,var(--sv-nearblack) 100%),
    linear-gradient(180deg,var(--sv-nearblack) 0%,var(--sv-red) 100%),
    linear-gradient(180deg,#6B1416 0%,var(--sv-nearblack) 100%),
    linear-gradient(180deg,var(--sv-red) 0%,var(--sv-red) 100%),
    linear-gradient(180deg,var(--sv-nearblack) 0%,#6B1416 100%),
    linear-gradient(180deg,var(--sv-red) 0%,var(--sv-nearblack) 100%),
    linear-gradient(180deg,var(--sv-nearblack) 0%,var(--sv-nearblack) 100%),
    linear-gradient(180deg,#6B1416 0%,var(--sv-red) 100%),
    linear-gradient(180deg,var(--sv-red) 0%,var(--sv-nearblack) 100%),
    linear-gradient(180deg,var(--sv-nearblack) 0%,var(--sv-red) 100%),
    linear-gradient(180deg,var(--sv-nearblack) 0%,var(--sv-nearblack) 100%),
    linear-gradient(180deg,var(--sv-red) 0%,#6B1416 100%),
    linear-gradient(180deg,#6B1416 0%,var(--sv-nearblack) 100%),
    linear-gradient(180deg,var(--sv-nearblack) 0%,var(--sv-red) 100%),
    linear-gradient(180deg,var(--sv-red) 0%,var(--sv-nearblack) 100%),
    linear-gradient(180deg,var(--sv-nearblack) 0%,var(--sv-nearblack) 100%),
    linear-gradient(180deg,#6B1416 0%,var(--sv-red) 100%),
    linear-gradient(180deg,var(--sv-red) 0%,var(--sv-nearblack) 100%),
    linear-gradient(180deg,var(--sv-nearblack) 0%,#6B1416 100%),
    linear-gradient(180deg,var(--sv-red) 0%,var(--sv-nearblack) 100%);
  background-size:
    7.000% 100%, 4.000% 100%, 5.000% 100%, 4.000% 100%, 6.000% 100%, 4.000% 100%, 8.000% 100%, 4.000% 100%, 5.000% 100%, 4.000% 100%, 7.000% 100%, 4.000% 100%, 6.000% 100%, 4.000% 100%, 5.000% 100%, 4.000% 100%, 5.000% 100%, 4.000% 100%, 5.000% 100%, 5.000% 100%;
  background-position:
    0.000% 0, 7.292% 0, 11.579% 0, 16.667% 0, 21.277% 0, 27.083% 0, 32.609% 0, 39.583% 0, 44.211% 0, 48.958% 0, 54.839% 0, 60.417% 0, 65.957% 0, 70.833% 0, 75.789% 0, 80.208% 0, 85.263% 0, 89.583% 0, 94.737% 0, 100.000% 0;
  background-repeat:no-repeat;
}

/* =========================================================================
   Hero backdrop — rotating project photography over the stripe field.
   ========================================================================= */

.sv-hero--field{position:relative;isolation:isolate;overflow:hidden;}

/* The media layer carries .sv-stripe-field, so the brand stripes show through
   underneath and remain the backdrop if an image never loads. */
.sv-hero__media{position:absolute;inset:0;z-index:0;}

.sv-hero__slide{
  position:absolute;inset:0;display:block;
  opacity:0;z-index:0;transition:opacity 1.1s ease-in-out;
  will-change:opacity;
}
/* The outgoing slide holds full opacity *underneath* the incoming one until
   the fade completes. Cross-fading two translucent layers leaves a gap: at the
   midpoint each sits at .5, so coverage is only 1-(.5x.5)=75% and the stripe
   field beneath shows through as vertical red/black banding. Keeping the
   outgoing layer opaque below means coverage is always 100%; the two
   photographs still blend, which is what a crossfade is meant to look like. */
.sv-hero__slide.is-leaving{opacity:1;z-index:1;transition:none;}
.sv-hero__slide.is-active{opacity:1;z-index:2;}
.sv-hero__slide img,
.sv-hero__slide video{
  width:100%;height:100%;object-fit:cover;object-position:center;display:block;
}

/* Scrim. Every image in the set contains pure-white pixels (blown windows,
   white ceilings, sky) throughout the text band, so the worst case is white:
   white body text needs 0.69 charcoal over it to clear 4.5:1. The gradient
   therefore holds >=0.72 across the whole copy column before it releases, and
   the right of the frame stays clear. */
/* Scrim strength is a per-slide variable. The gradient below is the *shape*
   at full strength; --sv-scrim scales it. Each slide's value is measured
   against that image's own brightest pixels under the text, so no slide
   carries more darkening than it needs. */
/* Stacking order inside the hero media layer, and it is load-bearing:
   slide 0 · leaving slide 1 · active slide 2 · scrim 3 · copy 4.
   The scrim MUST outrank the active slide. It sat at z-index 1 while the
   crossfade fix gave the active slide z-index 2, which painted the photograph
   straight over the scrim and dropped the hero lede and license line to about
   1.1:1. Anything that changes a slide's z-index has to move this too. */
.sv-hero__scrim{
  position:absolute;inset:0;z-index:3;pointer-events:none;
  opacity:var(--sv-scrim,.74);
  background:linear-gradient(
    90deg,
    rgba(50,59,68,1) 0%,
    rgba(50,59,68,1) 48%,
    rgba(50,59,68,.97) 58%,
    rgba(50,59,68,.55) 70%,
    rgba(50,59,68,.14) 84%,
    rgba(50,59,68,0) 100%
  );
}
/* Measured requirement per slide (charcoal alpha for WCAG AA on that image).
   All four currently land at the same value because every one contains pure
   white under the text band; they are listed separately so a replacement
   photograph can carry its own value without touching the others. */
[data-sv-hero][data-active="0"] .sv-hero__scrim{--sv-scrim:.74}  /* interior-002 */
[data-sv-hero][data-active="1"] .sv-hero__scrim{--sv-scrim:.74}  /* addition-003 */
[data-sv-hero][data-active="2"] .sv-hero__scrim{--sv-scrim:.74}  /* decks-002   */
[data-sv-hero][data-active="3"] .sv-hero__scrim{--sv-scrim:.74}  /* basement-007 */

.sv-hero--field .sv-hero__inner{position:relative;z-index:4;}
.sv-hero--field .sv-hero__copy{max-width:41rem;}

/* Narrow viewports: the copy spans nearly the full width, so a left-to-right
   scrim alone cannot cover it. Hold the same 0.72+ floor across the frame and
   deepen slightly toward the license line at the bottom. */
@media (max-width:940px){
  .sv-hero__scrim{
    background:
      linear-gradient(180deg, rgba(23,28,33,.18) 0%, rgba(23,28,33,.46) 100%),
      linear-gradient(90deg, rgba(50,59,68,1) 0%, rgba(50,59,68,1) 60%, rgba(50,59,68,.96) 100%);
  }
  .sv-hero--field .sv-hero__copy{max-width:none;}
}

/* Reduced motion: the script never starts, so slide one simply stays put.
   Belt and braces in case the class is toggled by something else. */
@media (prefers-reduced-motion:reduce){
  .sv-hero__slide{transition:none;}
  .sv-hero__slide:not(:first-of-type){display:none;}
  .sv-hero__slide:first-of-type{opacity:1;}
}

/* =========================================================================
   Footer social icons, reviews, credentials
   ========================================================================= */

/* Inline SVG only — no icon font, no external request. */
.sv-social{
  list-style:none;margin:34px 0 0;padding:0;
  display:flex;gap:6px;flex-wrap:wrap;
}
.sv-social__link{
  display:inline-flex;align-items:center;justify-content:center;
  width:44px;height:44px;             /* 44px tap target around a 20px glyph */
  color:rgba(255,255,255,.62);
  transition:color .18s ease;
}
.sv-social__link:hover,
.sv-social__link:focus-visible{color:#fff;}
.sv-social__icon{display:block;width:20px;height:20px;}

/* ---------- reviews ---------- */
.sv-reviews{background:var(--sv-offwhite);}
.sv-reviews__meta{
  margin:14px 0 0;font-family:"Barlow Condensed",sans-serif;
  text-transform:uppercase;letter-spacing:.12em;font-weight:700;
  font-size:.86rem;color:var(--sv-text-2);
}
.sv-reviews__list{
  list-style:none;margin:0;padding:0;
  display:grid;grid-template-columns:repeat(3,1fr);gap:1px;
  background:var(--sv-line);border:1px solid var(--sv-line);
}
.sv-review{background:var(--sv-offwhite);padding:28px 26px;}
.sv-review__stars{margin:0;color:var(--sv-red);letter-spacing:.12em;font-size:1rem;}
.sv-review__text{margin:12px 0 0;color:var(--sv-text);font-size:.99rem;}
.sv-review__author{
  margin:14px 0 0;font-weight:600;font-size:.9rem;color:var(--sv-text-2);
}
@media (max-width:940px){ .sv-reviews__list{grid-template-columns:1fr;} }

/* ---------- credentials ---------- */
.sv-creds{padding-block:clamp(40px,5vw,64px);border-top:1px solid var(--sv-line);}
/* Inline strip: the title sits on the same line as its entries so the block
   reads as a deliberate credential bar rather than a short stack hard against
   the left of a 1240px measure. There is only ever one populated group at
   launch, so a max-content grid column left roughly two thirds of the band
   empty. Below 640px it falls back to a stacked list — an entry that wraps to
   two lines cannot sit inline without the icon detaching from its text. */
.sv-creds__grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(320px,max-content));gap:clamp(24px,4vw,52px);}
/* Both column gaps are 40px so the rhythm along the strip is even: measured at
   44px after the label against 40px between entries, which read as a wider
   gap after the heading than between the credentials themselves. */
.sv-creds__group{display:flex;align-items:center;gap:18px 40px;flex-wrap:wrap;}
.sv-creds__list{display:flex;flex-wrap:wrap;gap:10px 40px;}
@media (max-width:640px){
  .sv-creds__group{display:block;}
  .sv-creds__list{display:block;}
}
.sv-creds__title{
  font-family:"Barlow Condensed",sans-serif;text-transform:uppercase;
  letter-spacing:.15em;font-size:.82rem;font-weight:700;
  color:var(--sv-text-2);margin:0;flex:none;
}
@media (max-width:640px){
  .sv-creds__title{margin:0 0 14px;}
}
.sv-creds__list{list-style:none;margin:0;padding:0;}
.sv-cred{display:flex;gap:12px;align-items:center;padding:0;}
@media (max-width:640px){
  .sv-cred{align-items:flex-start;padding:9px 0;}
}
.sv-cred__icon{flex:none;color:var(--sv-red);margin-top:1px;}
.sv-cred__body{display:block;}
.sv-cred__name{display:block;font-weight:600;font-size:.99rem;}
.sv-cred__detail:empty{display:none;}
.sv-cred__detail{display:block;font-size:.9375rem;color:var(--sv-text-2);margin-top:2px;}
.sv-cred__verify{
  display:inline-block;margin-top:4px;font-size:.85rem;color:var(--sv-red);
  font-weight:600;
}


/* Stats line under the pillars — the one approved figure. */
.sv-pillars__stat{
  margin:0;padding:22px 26px 0;
  border-top:1px solid var(--sv-line-light);
  font-family:"Barlow Condensed",sans-serif;text-transform:uppercase;
  letter-spacing:.12em;font-weight:700;font-size:.95rem;color:#fff;
}
/* Print positioning line, directly above the services grid. */
.sv-head__line{
  margin:14px 0 0;font-weight:600;color:var(--sv-ink);
}

/* =========================================================================
   Header tagline, directly beneath the logo. The logo is the logotype without
   the tagline; the tagline is HTML text at a size we control, rather than
   ~6px baked into the image. (Variants A and B and the ?sv_tagline= switch
   were removed on 27 Sep 2026; the class names keep the -c suffix.)
   ========================================================================= */

.sv-tagline{
  font-family:"Barlow Condensed",sans-serif;font-weight:700;
  text-transform:uppercase;letter-spacing:.14em;
  color:var(--sv-text-2);white-space:nowrap;
}

.sv-tagline--c{
  display:none;
  margin-top:5px;font-size:.8125rem;letter-spacing:.12em;
}
.sv-tagline-c #masthead .brand{display:inline-block;}
.sv-tagline-c .sv-tagline--c{display:block;}
@media (max-width:400px){
  .sv-tagline-c .sv-tagline--c{font-size:.75rem;letter-spacing:.08em;}
}



/* ---------- estimate form ---------- */
.sv-hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden;}
/* font:inherit resets the weight to 400; the submit matches every other .sv-btn. */
.sv-form button.sv-btn{border:0;font:inherit;font-weight:600;cursor:pointer;}
.sv-form__notice{
  padding:14px 18px;margin:0 0 20px;font-size:.99rem;border-left:4px solid;
}
.sv-form__notice--ok{background:#EAF3EC;border-color:#2E7D46;color:#1B4A2A;}
.sv-form__notice--err{background:#FBEAEA;border-color:var(--sv-red);color:#7A1A1B;}

/* ---------- estimate form: project-type checkboxes + validation ---------- */
.sv-form__fields{display:grid;grid-template-columns:1fr 1fr;gap:16px;}
@media (max-width:620px){ .sv-form__fields{grid-template-columns:1fr;} }
.sv-checks{border:0;padding:0;margin:0;min-width:0;}
.sv-checks legend{
  padding:0;margin:0 0 10px;font-size:.85rem;font-weight:600;
  text-transform:uppercase;letter-spacing:.1em;color:var(--sv-text-2);
}
/* One column. Two narrow columns pushed "Driveways, Walkways & Porches" and
   "Bedrooms & Bathrooms" onto three lines each; a vertical list of ten scans
   faster than a squashed grid. */
.sv-checks__grid{display:grid;grid-template-columns:1fr;gap:0 24px;}
@media (min-width:768px){ .sv-checks__grid{grid-template-columns:1fr 1fr;} }

/* Beats `.sv-form label`, which is the uppercase field-label style. */
.sv-form label.sv-check{
  display:flex;align-items:center;gap:10px;
  font-size:1rem;font-weight:400;text-transform:none;letter-spacing:0;
  color:var(--sv-ink);margin:0;min-height:44px;padding:4px 0;cursor:pointer;
  line-height:1.35;
}
.sv-form label.sv-check input{width:20px;height:20px;flex:none;margin:0;accent-color:var(--sv-red);}
.sv-check input:focus-visible{outline:3px solid var(--sv-red);outline-offset:2px;}
.sv-req{color:var(--sv-red);}
.sv-form__err{
  display:block;margin-top:6px;font-size:.9375rem;color:#8C1B1C;font-weight:600;
}
.sv-form input[aria-invalid="true"],
.sv-form select[aria-invalid="true"],
.sv-form textarea[aria-invalid="true"]{border-color:var(--sv-red);border-width:2px;}


/* §6 CTA color hierarchy — red on exactly three elements sitewide: header
   phone, hero primary CTA, estimate-form submit. The form submit is the page's
   only conversion and was the quietest button on it. */
.sv-form button.sv-btn--solid{background:var(--sv-red);color:#fff;}
.sv-form button.sv-btn--solid:hover,
.sv-form button.sv-btn--solid:focus-visible{background:var(--sv-red-deep);color:#fff;}

/* 1.2 — with no gallery grid the section's own bottom padding reads as an
   empty band. Tighten it only while there are no photographs. */
.sv-no-photos #gallery{padding-bottom:clamp(32px,4vw,56px);}
.sv-opt{font-weight:400;text-transform:none;letter-spacing:.02em;font-size:.8125rem;color:var(--sv-text-2);}
.sv-skip-target{display:block;height:0;overflow:hidden;}
.sv-skip-target:focus{outline:none;}


/* Buttons are sorted by intent, not by count. "See financing options" is an
   action, so it is red — the scarcity argument was hero-specific and does not
   transfer to a band the visitor never sees alongside the hero. */
.sv-fin .sv-btn--ghost{background:var(--sv-red);border-color:var(--sv-red);color:#fff;}
.sv-fin .sv-btn--ghost:hover,
.sv-fin .sv-btn--ghost:focus-visible{background:var(--sv-red-deep);border-color:var(--sv-red-deep);color:#fff;}

/* Consent line under the submit button. */
.sv-consent{
  margin:12px 0 0;font-size:.875rem;line-height:1.5;color:var(--sv-text);
}
.sv-consent a{color:var(--sv-charcoal);text-decoration:underline;}
.sv-consent a:hover,.sv-consent a:focus-visible{color:var(--sv-red);}
.sv-fin__figure{
  display:block;font-weight:700;font-size:1.5rem;letter-spacing:-.015em;
  line-height:1.2;margin-bottom:8px;
}
.sv-fin__facttitle{
  display:block;font-family:"Barlow Condensed",sans-serif;text-transform:uppercase;
  letter-spacing:.13em;font-size:.8125rem;font-weight:700;
  color:rgba(255,255,255,.82);margin-bottom:10px;
}

/* =========================================================================
   Service pages — template-service.php
   ========================================================================= */

.sv-service__head{padding-block:clamp(48px,6vw,84px) clamp(28px,3vw,40px);}
.sv-service__lede{
  font-size:19px;line-height:1.6;text-wrap:pretty;
  max-width:var(--sv-measure);margin:18px 0 0;color:var(--sv-text);
}
.sv-service__head .sv-btns{margin-top:26px;}
/* The estimate button under a service-page lede commits the visitor to an
   action, so it takes brand red like the homepage hero's primary CTA (the base
   .sv-btn--solid is charcoal). Over a hero photograph it hovers to white, as the
   hero does; on a plain header, to the deeper red. */
.sv-service__head .sv-btn--solid{background:var(--sv-red);color:#fff;}
.sv-service__head .sv-btn--solid:hover,
.sv-service__head .sv-btn--solid:focus-visible{background:var(--sv-red-deep);color:#fff;}
.sv-service__head--photo .sv-btn--solid:hover,
.sv-service__head--photo .sv-btn--solid:focus-visible{background:#fff;color:var(--sv-ink);}
/* The estimate button under the lede jumps to #estimate. With JavaScript on,
   Kadence does the scroll and the offset comes from
   stonevale_anchor_scroll_offset(); this margin covers the jump without it. */
.sv-service__cta{scroll-margin-top:104px;}

/* One measure for reading. Long-form copy set to the full 1240px wrap would
   run past the ~75-character line where reading speed drops off. */
.sv-service__body{padding-block:clamp(8px,2vw,20px) clamp(40px,5vw,64px);}
.sv-service__block{max-width:var(--sv-measure);}
.sv-service__block + .sv-service__block{margin-top:clamp(30px,4vw,46px);}
.sv-service__block h2{font-size:clamp(1.375rem,2.4vw,1.75rem);margin:0 0 14px;}
.sv-service__block p{margin:0 0 14px;color:var(--sv-text);}
.sv-service__block p:last-child{margin-bottom:0;}

.sv-pricing{padding-block:clamp(40px,5vw,64px);}
.sv-pricing p{max-width:var(--sv-measure);margin:16px 0 0;color:var(--sv-text);}
.sv-pricing .sv-btns{margin-top:24px;}

.sv-service__cta{background:var(--sv-offwhite);border-top:1px solid var(--sv-line);}
.sv-service__cta .sv-h2--tight{margin-bottom:26px;}

/* =========================================================================
   About page — template-about.php
   ========================================================================= */

.sv-about__head{padding-block:clamp(48px,6vw,84px) clamp(24px,3vw,36px);}
/* With a photograph the head becomes a scrimmed band; without one it is plain
   paper and the page simply starts at the heading. */
.sv-about__head--photo{
  position:relative;isolation:isolate;overflow:hidden;
  padding-block:clamp(96px,12vw,180px) clamp(72px,9vw,132px);
}
.sv-about__media{position:absolute;inset:0;z-index:0;}
.sv-about__media picture,
.sv-about__media img{position:absolute;inset:0;width:100%;height:100%;}
.sv-about__media img{object-fit:cover;object-position:center;display:block;}
/* Scrim sits above the photograph and below the copy. Same stacking discipline
   as the homepage hero: anything that changes these values changes every
   contrast measurement on the band. */
.sv-about__scrim{
  position:absolute;inset:0;z-index:3;pointer-events:none;
  /* The plateau has to cover the whole heading measure, not most of it. The
     H1 wraps to two lines and the second ran past 58% at 1440, into the
     released zone over bright sky, at 1.95:1. Hold full strength to 62% and
     release later. */
  background:linear-gradient(
    90deg,
    rgba(50,59,68,.94) 0%,
    rgba(50,59,68,.94) 62%,
    rgba(50,59,68,.88) 72%,
    rgba(50,59,68,.54) 82%,
    rgba(50,59,68,.18) 92%,
    rgba(50,59,68,0) 100%
  );
}
.sv-about__head--photo .sv-about__headinner{position:relative;z-index:4;}
/* Keep the heading inside the scrim plateau rather than relying on the
   gradient to chase it. */
.sv-about__head--photo .sv-h1{max-width:22ch;}
.sv-about__head--photo .sv-eyebrow,
.sv-about__head--photo .sv-h1{color:#fff;}
@media (max-width:940px){
  .sv-about__scrim{
    background:
      linear-gradient(180deg, rgba(23,28,33,.16) 0%, rgba(23,28,33,.44) 100%),
      linear-gradient(90deg, rgba(50,59,68,.94) 0%, rgba(50,59,68,.90) 100%);
  }
}

.sv-about__body{padding-block:clamp(8px,2vw,20px) clamp(32px,4vw,52px);}
/* Body size, not display. Six sentences held at lede size made the page
   top-heavy before the reader had any reason to be invested. */
.sv-about__opening{
  font-size:1.0625rem;line-height:1.65;
  max-width:var(--sv-measure);margin:0;color:var(--sv-text);
}
/* The brand tagline set apart as a signature line. Reusable: body size, 600,
   brand red, never italic. Red on paper holds AA at this size and weight. */
.sv-tagline-line{font-size:17px;font-weight:600;font-style:normal;color:var(--sv-red);margin:14px 0 0;}
.sv-about__block{max-width:var(--sv-measure);}
.sv-about__block h2{font-size:clamp(1.375rem,2.4vw,1.75rem);margin:clamp(28px,4vw,44px) 0 14px;}
.sv-about__block p{margin:0 0 14px;color:var(--sv-text);}
.sv-about__block p:last-child{margin-bottom:0;}
.sv-about__block strong{color:var(--sv-ink);font-weight:700;}
/* :not(.sv-btn) is load-bearing. Without it this rule outranks .sv-btn--solid on
   color — both are class selectors but this one also matches the element — and
   painted the About CTA's label charcoal on a charcoal fill: invisible, not merely
   low contrast. A prose-link rule must never reach a button. */
.sv-about__block a:not(.sv-btn){color:var(--sv-charcoal);text-decoration:underline;text-underline-offset:2px;}
.sv-about__block a:not(.sv-btn):hover,.sv-about__block a:not(.sv-btn):focus-visible{color:var(--sv-red);}

/* Process. Two columns only when there is a photograph to put in the second. */
.sv-about__process{background:var(--sv-offwhite);border-block:1px solid var(--sv-line);}
.sv-about__processgrid{display:grid;grid-template-columns:1fr;gap:clamp(28px,4vw,52px);align-items:start;}
@media (min-width:941px){
  .sv-about__processgrid{grid-template-columns:minmax(0,1.3fr) minmax(0,1fr);}
}
.sv-about__processgrid--nomedia{grid-template-columns:1fr!important;}
.sv-about__processgrid > div{max-width:var(--sv-measure);}
.sv-about__processgrid h2{font-size:clamp(1.375rem,2.4vw,1.75rem);margin:0 0 14px;}
.sv-about__processgrid p{margin:0 0 14px;color:var(--sv-text);}
/* In-content subheading, one level below the H2 — the post H3 style. */
.sv-about__processgrid h3{font-size:19px;font-weight:700;line-height:1.3;letter-spacing:normal;margin:26px 0 8px;color:var(--sv-ink);}
/* Lead-in terms (About: Fixed price, Cost-plus, Change order): Barlow Medium in
   full ink, not bold and never underlined. */
.sv-leadin{font-weight:500;color:var(--sv-ink);text-decoration:none;}
.sv-about__processmedia{margin:0;}
.sv-about__processmedia img{width:100%;height:auto;display:block;}

.sv-about__pillars{background:var(--sv-charcoal);color:#fff;}
.sv-about__pillars .sv-h2--tight{color:#fff;}
.sv-about__pillargrid{
  display:grid;grid-template-columns:1fr;gap:1px;margin-top:28px;
  background:rgba(255,255,255,.16);border:1px solid rgba(255,255,255,.16);
}
@media (min-width:640px){.sv-about__pillargrid{grid-template-columns:repeat(2,1fr);}}
@media (min-width:1024px){.sv-about__pillargrid{grid-template-columns:repeat(4,1fr);}}
.sv-about__pillar{background:var(--sv-charcoal);padding:26px 24px;}
.sv-about__pillar h3{color:#fff;font-size:1.0625rem;margin:0 0 10px;font-weight:700;line-height:1.6;letter-spacing:-.012em;}
.sv-about__pillar p{color:rgba(255,255,255,.72);font-size:.9375rem;margin:0;line-height:1.55;}

/* Three-up band. Equal cells, one per category — range is the point. */
.sv-about__trio{padding-block:clamp(40px,5vw,64px);}
.sv-about__triogrid{display:grid;grid-template-columns:1fr;gap:clamp(12px,2vw,20px);}
@media (min-width:768px){.sv-about__triogrid{grid-template-columns:repeat(3,1fr);}}
.sv-about__triogrid figure{margin:0;}
.sv-about__triogrid img{width:100%;height:auto;display:block;aspect-ratio:4/3;object-fit:cover;}

.sv-about__close{background:var(--sv-offwhite);border-top:1px solid var(--sv-line);}
.sv-about__count{font-size:clamp(1.0625rem,1.5vw,1.1875rem);font-weight:600;color:var(--sv-ink);}
.sv-about__close .sv-btns{margin-top:26px;}

/* Related services — text links, not a pager. They were solid charcoal buttons,
   which read as previous/next navigation and competed with the page's own CTA. */
.sv-related{
  margin:26px 0 0;font-size:.9375rem;line-height:1.9;
  max-width:var(--sv-measure);color:var(--sv-text-2);
}
.sv-related__label{
  font-family:"Barlow Condensed",sans-serif;text-transform:uppercase;
  letter-spacing:.13em;font-size:.8125rem;font-weight:700;
  color:var(--sv-text-2);margin-right:12px;
}
.sv-related a{color:var(--sv-charcoal);text-decoration:underline;text-underline-offset:3px;}
.sv-related a:hover,.sv-related a:focus-visible{color:var(--sv-red);}
/* .36 measured 2.23:1 on paper — a separator is still visible text. */
.sv-related__sep{margin:0 8px;color:var(--sv-text-2);}

/* In-body cross references. Underlined so they read as links in running prose
   rather than relying on color alone. */
.sv-service__block a:not(.sv-btn){color:var(--sv-charcoal);text-decoration:underline;text-underline-offset:2px;}
.sv-service__block a:not(.sv-btn):hover,.sv-service__block a:not(.sv-btn):focus-visible{color:var(--sv-red);}

.sv-pricing__lead{margin-top:18px;}
.sv-pricing__drivers{list-style:none;margin:14px 0 0;padding:0;max-width:var(--sv-measure);}
.sv-pricing__drivers li{
  position:relative;padding:9px 0 9px 30px;border-top:1px solid var(--sv-line);
  font-size:.99rem;line-height:1.55;color:var(--sv-text);
}
.sv-pricing__drivers li:first-child{border-top:0;}
.sv-pricing__drivers li::before{
  content:"";position:absolute;left:0;top:18px;width:14px;height:2px;background:var(--sv-red);
}

/* FAQ. A description list, because that is what a question and answer pair is. */
.sv-faq{background:var(--sv-offwhite);border-top:1px solid var(--sv-line);}
.sv-faq__list{margin:26px 0 0;max-width:var(--sv-measure);}
.sv-faq__item{border-top:1px solid var(--sv-line);padding:20px 0;}
.sv-faq__item:first-child{border-top:0;padding-top:0;}
.sv-faq__list dt{font-weight:700;font-size:18px;line-height:1.5;letter-spacing:normal;color:var(--sv-ink);margin:0 0 8px;}
.sv-faq__list dd{margin:0;color:var(--sv-text);line-height:1.65;}

/* Service page hero. Same stacking discipline as the homepage and About heroes:
   photo 0 · scrim 3 · copy 4. The scrim must outrank the photograph, and any
   change here changes every contrast measurement on the band. */
.sv-service__head--photo{
  position:relative;isolation:isolate;overflow:hidden;
  padding-block:clamp(88px,11vw,164px) clamp(64px,8vw,116px);
}
.sv-service__media{position:absolute;inset:0;z-index:0;}
.sv-service__media picture,
.sv-service__media img{position:absolute;inset:0;width:100%;height:100%;}
.sv-service__media img{object-fit:cover;object-position:center;display:block;}
.sv-service__scrim{
  position:absolute;inset:0;z-index:3;pointer-events:none;
  background:linear-gradient(
    90deg,
    rgba(50,59,68,.94) 0%,
    rgba(50,59,68,.94) 62%,
    rgba(50,59,68,.88) 72%,
    rgba(50,59,68,.54) 82%,
    rgba(50,59,68,.18) 92%,
    rgba(50,59,68,0) 100%
  );
}
.sv-service__head--photo .sv-wrap{position:relative;z-index:4;}
.sv-service__head--photo .sv-eyebrow,
.sv-service__head--photo .sv-h1{color:#fff;}
.sv-service__head--photo .sv-service__lede{color:rgba(255,255,255,.92);}
.sv-service__head--photo .sv-h1{max-width:22ch;}
.sv-service__head--photo .sv-related{color:rgba(255,255,255,.78);}
.sv-service__head--photo .sv-related__label{color:rgba(255,255,255,.72);}
.sv-service__head--photo .sv-related a{color:#fff;}
.sv-service__head--photo .sv-related a:hover,
.sv-service__head--photo .sv-related a:focus-visible{color:#fff;text-decoration-thickness:2px;}
/* .5 white measured 3.86:1 over the hero. aria-hidden, so arguably exempt,
   but there is no reason to ship failing text when the fix is free. */
.sv-service__head--photo .sv-related__sep{color:rgba(255,255,255,.72);}
@media (max-width:940px){
  .sv-service__scrim{
    background:
      linear-gradient(180deg, rgba(23,28,33,.16) 0%, rgba(23,28,33,.44) 100%),
      linear-gradient(90deg, rgba(50,59,68,.94) 0%, rgba(50,59,68,.90) 100%);
  }
}

/* Mid-page band. Breaks a long column of prose at the point the copy turns to
   what the pictures show. Renders only with two or more images. */
.sv-service__band{
  display:grid;grid-template-columns:1fr;gap:clamp(12px,2vw,18px);
  margin:clamp(30px,4vw,46px) 0;max-width:none;
}
@media (min-width:768px){
  .sv-service__band{grid-template-columns:repeat(auto-fit,minmax(0,1fr));}
}
.sv-service__band figure{margin:0;}
.sv-service__band img{width:100%;height:auto;display:block;aspect-ratio:4/3;object-fit:cover;}

/* Related posts on a service page. Closes the loop — posts already link into
   service pages, and nothing linked back out. */
.sv-svcposts{background:var(--sv-offwhite);border-top:1px solid var(--sv-line);}
.sv-svcposts__list{list-style:none;margin:24px 0 0;padding:0;max-width:var(--sv-measure);}
.sv-svcposts__list li{padding:18px 0;border-top:1px solid var(--sv-line);}
.sv-svcposts__list li:first-child{border-top:0;padding-top:0;}
.sv-svcposts__list a{
  display:block;font-weight:700;font-size:1.0625rem;color:var(--sv-ink);
  text-decoration:underline;text-underline-offset:3px;
}
.sv-svcposts__list a:hover,.sv-svcposts__list a:focus-visible{color:var(--sv-red);}
.sv-svcposts__ex{display:block;margin-top:6px;color:var(--sv-text-2);font-size:.9375rem;line-height:1.6;}

/* Contact and Financing pages */
.sv-contactpage__head,.sv-finpage__head{padding-block:clamp(48px,6vw,84px) clamp(20px,3vw,32px);}
/* The shared lede style. .sv-svcindex__lede had no rule at all until 27 Sep 2026
   and inherited body text, which left the Services hub lede unbounded at 1,096px. */
/* Blog index, category archives, posts and the gallery joined on 27 Sep 2026;
   they had their own 17-19px clamp at 1.65. */
/* 19px below 1024px, 22px from 1024px. The homepage "What We Build" intro sits
   under the page's H1 and takes the lede style too (27 Sep 2026). */
.sv-contactpage__lede,.sv-finpage__lede,.sv-svcindex__lede,
.sv-bloghead__lede,.sv-post__lede,.sv-galpage__lede,.sv-head .sv-home__lede{
  font-size:19px;line-height:1.6;text-wrap:pretty;
  max-width:var(--sv-measure);margin:18px 0 0;color:var(--sv-text);
}
.sv-contactpage__grid{display:grid;grid-template-columns:1fr;gap:clamp(32px,5vw,64px);align-items:start;}
@media (min-width:941px){
  .sv-contactpage__grid{grid-template-columns:minmax(0,0.8fr) minmax(0,1.2fr);}
}
/* Sidebar headings. The credentials label (h2.sv-creds__title) sits in the same
   column and keeps its own 13.12px label style on every page. */
.sv-contactpage__aside h2:not(.sv-creds__title){font-size:19px;margin:clamp(24px,3vw,34px) 0 10px;}
.sv-contactpage__aside h2:not(.sv-creds__title):first-child{margin-top:0;}
.sv-contactpage__aside p{color:var(--sv-text);margin:0;}
.sv-contactpage__steps{margin:12px 0 0;padding-left:20px;color:var(--sv-text);}
.sv-contactpage__steps li{padding:5px 0;line-height:1.6;}
.sv-contactpage__form .sv-h2--tight{margin-bottom:22px;}

.sv-finpage__body{padding-block:clamp(8px,2vw,20px) clamp(40px,5vw,64px);}
.sv-finpage__block{max-width:var(--sv-measure);}
.sv-finpage__block + .sv-finpage__block{margin-top:clamp(28px,4vw,44px);}
.sv-finpage__block h2{font-size:clamp(1.375rem,2.4vw,1.75rem);margin:0 0 14px;}
.sv-finpage__block p{margin:0 0 14px;color:var(--sv-text);}
.sv-finpage__block p:last-child{margin-bottom:0;}
.sv-finpage__cta{background:var(--sv-offwhite);border-top:1px solid var(--sv-line);}
.sv-finpage__cta p{max-width:var(--sv-measure);margin:0 0 26px;color:var(--sv-text);}

/* Blog index and category archives */
.sv-bloghead{padding-block:clamp(48px,6vw,84px) clamp(20px,3vw,30px);}
/* Built from categories that actually have posts, so an empty topic never
   appears as a dead link to an empty archive. */
.sv-blogfilters{margin:24px 0 0;font-size:.9375rem;line-height:1.9;color:var(--sv-text-2);}
.sv-blogfilters__label{
  font-family:"Barlow Condensed",sans-serif;text-transform:uppercase;
  letter-spacing:.13em;font-size:.8125rem;font-weight:700;
  color:var(--sv-text-2);margin-right:12px;
}
.sv-blogfilters a{color:var(--sv-charcoal);text-decoration:underline;text-underline-offset:3px;text-transform:capitalize;}
.sv-blogfilters a:hover,.sv-blogfilters a:focus-visible{color:var(--sv-red);}
.sv-blogfilters a[aria-current]{color:var(--sv-red);text-decoration-thickness:2px;}
.sv-blogfilters__sep{margin:0 8px;color:var(--sv-text-2);}

.sv-bloglist{padding-block:clamp(28px,4vw,44px) clamp(40px,5vw,64px);}
.sv-bloglist__grid{display:grid;grid-template-columns:1fr;gap:clamp(28px,4vw,44px);}
@media (min-width:768px){.sv-bloglist__grid{grid-template-columns:repeat(2,minmax(0,1fr));}}
@media (min-width:1180px){.sv-bloglist__grid{grid-template-columns:repeat(3,minmax(0,1fr));}}
.sv-postcard{border-top:3px solid var(--sv-line);padding-top:18px;}
.sv-postcard__media{display:block;margin-bottom:16px;}
.sv-postcard__media img{width:100%;height:auto;display:block;aspect-ratio:16/9;object-fit:cover;}
.sv-postcard__meta{
  font-family:"Barlow Condensed",sans-serif;text-transform:uppercase;
  letter-spacing:.11em;font-size:.82rem;font-weight:700;
  /* The eyebrow's size. .6 measured 4.43:1 on paper at 12.5px — just under AA. */
  color:var(--sv-text-2);margin:0 0 8px;
}
.sv-postcard__title{font-size:1.1875rem;line-height:1.28;margin:0 0 10px;}
.sv-postcard__title a{color:var(--sv-ink);text-decoration:none;}
.sv-postcard__title a:hover,.sv-postcard__title a:focus-visible{color:var(--sv-red);text-decoration:underline;text-underline-offset:3px;}
.sv-postcard__ex{margin:0;color:var(--sv-text-2);font-size:.9375rem;line-height:1.6;}

.sv-blogcta{background:var(--sv-offwhite);border-top:1px solid var(--sv-line);}
.sv-blogcta p{max-width:var(--sv-measure);margin:0 0 24px;color:var(--sv-text);}

/* Single post. Replaces Kadence's default single template, which carried post
   meta and a related-posts block this theme never styled. */
.sv-post__head{padding-block:clamp(48px,6vw,84px) clamp(18px,2.5vw,28px);}
.sv-post__body{padding-block:clamp(12px,2vw,24px) clamp(40px,5vw,64px);}
/* One measure for reading. Long-form copy at the full wrap width runs past the
   line length where reading speed drops off. */
.sv-post__content{max-width:var(--sv-measure);}
.sv-post__content h2{font-size:clamp(1.375rem,2.4vw,1.75rem);margin:clamp(30px,4vw,46px) 0 14px;}
/* Post H3s are FAQ questions only; they match the service-page dt. */
.sv-post__content h3{font-size:18px;line-height:1.5;letter-spacing:normal;margin:26px 0 8px;color:var(--sv-ink);}
.sv-post__content h3 + p{line-height:1.65;}
.sv-post__content p{margin:0 0 14px;color:var(--sv-text);line-height:1.7;}
.sv-post__content ul{margin:0 0 16px;padding-left:20px;color:var(--sv-text);}
.sv-post__content li{padding:4px 0;line-height:1.6;}
.sv-post__content strong{color:var(--sv-ink);font-weight:700;}
.sv-post__content a{color:var(--sv-charcoal);text-decoration:underline;text-underline-offset:2px;}
.sv-post__content a:hover,.sv-post__content a:focus-visible{color:var(--sv-red);}
.sv-post__content figure{margin:clamp(24px,3vw,34px) 0;}
.sv-post__content figure img{width:100%;height:auto;display:block;}

.sv-post__related{background:var(--sv-offwhite);border-top:1px solid var(--sv-line);}
.sv-post__cta{background:var(--sv-charcoal);color:#fff;}
.sv-post__cta .sv-eyebrow,.sv-post__cta .sv-h2--tight{color:#fff;}
.sv-post__cta p{max-width:var(--sv-measure);margin:0 0 24px;color:rgba(255,255,255,.86);}
/* On the charcoal band the browse button needs its own treatment — charcoal on
   charcoal is exactly the failure the About CTA had. */
.sv-post__cta .sv-btn--browse{background:transparent;border-color:rgba(255,255,255,.7);color:#fff;}
.sv-post__cta .sv-btn--browse:hover,
.sv-post__cta .sv-btn--browse:focus-visible{background:#fff;border-color:#fff;color:var(--sv-ink);}
.sv-post__cta .sv-btn--solid{background:var(--sv-red);color:#fff;}
.sv-post__cta .sv-btn--solid:hover,.sv-post__cta .sv-btn--solid:focus-visible{background:var(--sv-red-deep);color:#fff;}

/* ---- Gallery ---------------------------------------------------------- */

.sv-galpage__head{padding-block:clamp(48px,6vw,84px) clamp(18px,2.5vw,28px);}
.sv-galpage__body{padding-block:clamp(16px,2vw,28px) clamp(40px,5vw,64px);}

.sv-galfilters{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin:0 0 22px;}
.sv-galfilters__label{
  font-family:"Barlow Condensed",sans-serif;text-transform:uppercase;
  letter-spacing:.11em;font-size:.8rem;font-weight:700;
  color:var(--sv-text-2);margin-right:4px;
}
.sv-galfilters__btn{
  font:inherit;font-size:.9375rem;line-height:1;
  /* 44px tap target: 13px padding + 18px line box + 2px border. */
  padding:13px 16px;border:1px solid var(--sv-line);border-radius:2px;
  background:#fff;color:var(--sv-charcoal);cursor:pointer;
  min-height:44px;
}
.sv-galfilters__btn:hover{border-color:var(--sv-charcoal);}
.sv-galfilters__btn.is-active{background:var(--sv-charcoal);border-color:var(--sv-charcoal);color:#fff;}
.sv-galfilters__btn:focus-visible{outline:2px solid var(--sv-red);outline-offset:2px;}

.sv-gal__grid{display:grid;gap:10px;grid-template-columns:1fr;}
@media (min-width:640px){.sv-gal__grid{grid-template-columns:repeat(2,1fr);}}
@media (min-width:1024px){.sv-gal__grid{grid-template-columns:repeat(3,1fr);}}
.sv-gal__cell[hidden]{display:none;}
.sv-gal__item{margin:0;cursor:zoom-in;overflow:hidden;background:var(--sv-limestone);}
.sv-gal__item img{display:block;width:100%;height:100%;object-fit:cover;aspect-ratio:4/3;}
.sv-gal__item:focus-visible{outline:2px solid var(--sv-red);outline-offset:2px;}
.sv-gal__none{margin:22px 0 0;color:var(--sv-text);}

.sv-lightbox{
  position:fixed;inset:0;z-index:9999;
  background:rgba(23,28,33,.94);
  display:flex;align-items:center;justify-content:center;padding:24px;
}
.sv-lightbox[hidden]{display:none;}
.sv-lightbox img{max-width:100%;max-height:100%;object-fit:contain;}
.sv-lightbox__close,.sv-lightbox__nav{
  position:absolute;background:transparent;border:0;color:#fff;cursor:pointer;
  /* White on the .94 charcoal scrim: 15.6:1. Nothing here sits over a photo. */
  min-width:44px;min-height:44px;line-height:1;
}
.sv-lightbox__close{top:10px;right:14px;font-size:2.25rem;}
.sv-lightbox__nav{top:50%;transform:translateY(-50%);font-size:3rem;padding:0 12px;}
.sv-lightbox__nav--prev{left:6px;}
.sv-lightbox__nav--next{right:6px;}
.sv-lightbox__close:focus-visible,.sv-lightbox__nav:focus-visible{outline:2px solid #fff;outline-offset:2px;}

.sv-galpage__cta{background:var(--sv-offwhite);border-top:1px solid var(--sv-line);}
.sv-galpage__cta p{max-width:var(--sv-measure);margin:0 0 24px;color:var(--sv-text);}

/* Seven buttons wrap to five lines at 390px — 252px of filter chrome before the
   first photograph. Trimming the horizontal padding only (the 13px vertical
   padding and the 44px min-height are untouched, so tap targets are unchanged)
   fits the shorter labels two to a line. */
@media (max-width:640px){
  .sv-galfilters{gap:6px;}
  /* min-width holds the 44px tap target for the short "All" label, which the
     tighter padding took under it. Height was never at risk. */
  .sv-galfilters__btn{padding-inline:11px;font-size:.9rem;min-width:44px;}
}

/* ---------------------------------------------------------------------------
   Breadcrumbs

   Rank Math builds the trail; the markup and every rule here are the theme's,
   so the crumbs read as part of the site rather than as plugin output. Barlow
   Condensed at the eyebrow's tracking ties them to the section labels without
   competing with the H1 immediately beneath.

   Colors are deliberately not the eyebrow's red: the trail is orientation, not
   emphasis, and red is reserved for actions. Links sit at .72 alpha on paper
   (5.5:1) and the current page at full ink, so the page you are on is the
   darkest item in the row.
   --------------------------------------------------------------------------- */
.sv-crumbs{background:var(--sv-paper);border-bottom:1px solid var(--sv-line);}
.sv-crumbs__list{
  display:flex;align-items:center;
  /* One line, always.

     This wrapped originally, and that was measured as a 0.107 layout shift on
     /stonepave/ against 0.005 with the breadcrumbs removed -- confirmed by
     disabling them and re-running, not inferred. The cause is not the row's
     line height but its line COUNT: the fallback face is wider than Barlow
     Condensed, so "Home > Services > AOne Materials(R) StonePave" wrapped to two
     lines and collapsed to one when the webfont swapped in, moving the whole
     article up. Lighthouse attributed the shift to article.sv-service, which is
     what moved, not to the row that moved it.

     Fixing the line height alone could not help, because the height changed by
     a whole line. Nowrap plus overflow makes the row exactly one line before and
     after the swap; the trail stays complete and scrolls on a narrow phone
     rather than being truncated. */
  flex-wrap:nowrap;white-space:nowrap;
  overflow-x:auto;overscroll-behavior-x:contain;
  scrollbar-width:none;-ms-overflow-style:none;
  list-style:none;margin:0;padding:14px 0;gap:0;
  font-family:"Barlow Condensed",Barlow,sans-serif;font-weight:600;
  text-transform:uppercase;letter-spacing:.12em;font-size:.8rem;
  /* Line height in px, not a ratio, so the row is exactly 48px tall before the
     webfont arrives and exactly 48px after. Barlow Condensed loads with
     font-display:swap and its metrics differ from the fallback, so a ratio made
     this row change height mid-load and pushed the whole article down --
     measured as a 0.10 layout shift on /stonepave/, attributed to
     article.sv-service rather than to the breadcrumbs that caused it. */
  line-height:20px;
}
.sv-crumbs__list::-webkit-scrollbar{display:none;}
.sv-crumbs__item{display:flex;align-items:center;margin:0;flex:0 0 auto;}
.sv-crumbs__item + .sv-crumbs__item::before{
  content:"\203A";                 /* single right angle quote, matches the nav */
  margin:0 .6em;opacity:.55;color:var(--sv-ink);
  speak:never;
}
.sv-crumbs__link{color:var(--sv-text-2);text-decoration:none;}
.sv-crumbs__link:hover,
.sv-crumbs__link:focus-visible{color:var(--sv-red);text-decoration:underline;}
.sv-crumbs__current{color:var(--sv-ink);}

/* The trail is orientation and can wrap to two lines on a narrow phone before
   it is worth truncating, so nothing is hidden -- a breadcrumb that ends in an
   ellipsis has stopped doing its one job. */
@media (max-width:600px){
  .sv-crumbs__list{font-size:.75rem;padding:11px 0;line-height:18px;}
}

/* Gallery intro prose. Named __intro, not __body: .sv-galpage__body is already
   the section wrapper below the filters and carries large block padding, which
   these paragraphs would have inherited one by one. */
.sv-galpage__intro{
  font-size:17px;line-height:1.6;max-width:var(--sv-measure);
  margin:14px 0 0;color:var(--sv-text);
}


/* =========================================================================
   Typography — 27 Sep 2026, from TYPE-AUDIT.md. The scale is recorded under
   "Typography" in CLAUDE.md; new pages and posts follow it.
   ========================================================================= */

/* Eyebrows are red on light backgrounds and white on dark ones. These five
   sections' paragraph rules outrank .sv-eyebrow on color and turned their
   eyebrows charcoal; restore the red. */
.sv-head .sv-eyebrow,.sv-product__copy > .sv-eyebrow,.sv-galpage__cta .sv-eyebrow,
.sv-blogcta .sv-eyebrow,.sv-finpage__cta .sv-eyebrow{color:var(--sv-red);}

/* Reading text that had no tone of its own and printed in full ink: the two
   legal pages (Kadence's default template), the empty-archive line and the
   Services hub CTA. */
.sv-page__content :is(p,li),
.sv-bloglist .sv-wrap > p,
.sv-svcindex__cta p:not(.sv-eyebrow){color:var(--sv-text);}
.sv-bloglist .sv-wrap > p a{color:var(--sv-charcoal);text-decoration:underline;text-underline-offset:2px;}
.sv-bloglist .sv-wrap > p a:hover,.sv-bloglist .sv-wrap > p a:focus-visible{color:var(--sv-red);}

/* In-content H2s keep their sizes. Kadence's global h2 rule set 1.5, which
   reads loose on a 28px bold heading that wraps. */
.sv-post__content h2,.sv-service__block h2,.sv-finpage__block h2,.sv-about__block h2,
.sv-about__processgrid h2,
.sv-faq h2:not(.sv-h2--tight),
.sv-page__content h2{line-height:1.25;}


/* One reading column sitewide, --sv-measure (40rem, ledes included). Every text block on a
   page shares one right edge; figures, photo bands and card grids keep the
   full container width. */
:is(.sv-post__content,.sv-service__block,.sv-finpage__block,
    .sv-page__content) :is(p,ul,ol,h2,h3,h4),
.sv-galpage__intro,.sv-faq__list,.sv-pricing p,.sv-about__opening,.sv-tagline-line,
.sv-blogcta p,.sv-finpage__cta p,.sv-galpage__cta p,
.sv-svcindex__cta p:not(.sv-eyebrow){max-width:var(--sv-measure);}

/* Privacy Policy and Accessibility — page.php. Same header position as Contact
   and Financing, content in the normal column at the reading measure. */
.sv-page__head{padding-block:clamp(48px,6vw,84px) clamp(20px,3vw,32px);}
.sv-page__body{padding-block:clamp(8px,2vw,20px) clamp(40px,5vw,64px);}
.sv-page__content{max-width:var(--sv-measure);}
.sv-page__content h2{font-size:clamp(1.375rem,2.4vw,1.75rem);margin:clamp(30px,4vw,46px) 0 14px;}
.sv-page__content > :first-child{margin-top:0;}
.sv-page__content p{margin:0 0 14px;}
.sv-page__content ul{margin:0 0 16px;padding-left:20px;}
.sv-page__content li{padding:4px 0;}
.sv-page__content strong{color:var(--sv-ink);}
.sv-page__content a{color:var(--sv-charcoal);text-decoration:underline;text-underline-offset:2px;}
.sv-page__content a:hover,.sv-page__content a:focus-visible{color:var(--sv-red);}

/* Services hub: the lede sits the standard section-head distance above the
   cards (.sv-head's margin), not a full section's padding on each side. */
.sv-svcindex__head{padding-bottom:0;}
.sv-svcindex__body{padding-top:clamp(30px,4vw,52px);}

/* Credentials inside the Contact column: the block is a full section with its
   own .sv-wrap padding, which indented it past the column's left edge. */
.sv-contactpage__aside .sv-creds > .sv-wrap{padding-inline:0;max-width:none;}

/* One text width across every page, from 1024px. Reading text may run to the
   full width of the area it sits in, so any line long enough to fill it ends
   level with the H1s, photo bands, card grids and forms; where text sits in its
   own column beside an image, card or form, it fills that column. A maximum,
   never a target: text stays left-aligned and short text ends where its words
   end. The larger size and line spacing carry the longer lines. Headings,
   figures, card grids, the pillar band, forms and the footer are unchanged, and
   below 1024px nothing changes. Decided by Jeljo, 27 Sep 2026. */
@media (min-width:1024px){
  :root{--sv-measure:none;}
  /* Reading text: paragraphs, list items and FAQ answers in the page content.
     :where() keeps this at zero specificity, so anything with a size of its
     own keeps it; the components below are not reading text and keep their
     inherited 17px/1.6. Setting this on body instead leaked into buttons,
     eyebrows, cards, forms, the footer and the nav. */
  :where(#inner-wrap :is(p,li,dd):not(.sv-eyebrow):not(:is(.sv-hero,.sv-svc,.sv-postcard,form,.sv-pillars,
      .sv-about__pillargrid,.sv-creds,.sv-fin__fact,.sv-gal,figure,.sv-crumbs,.sv-btns,.sv-reviews) *)){
    font-size:19px;line-height:1.7;
  }
  /* Reading text that set its own size or line height. */
  .sv-about__opening,.sv-galpage__intro,.sv-tagline-line,.sv-pricing__drivers li{font-size:19px;}
  .sv-about__opening,.sv-galpage__intro,.sv-faq__list dd,.sv-post__content h3 + p,
  .sv-post__content li,.sv-contactpage__steps li,.sv-pricing__drivers li{line-height:1.7;}
  /* Ledes: larger than the reading text so they still stand out. */
  .sv-contactpage__lede,.sv-finpage__lede,.sv-svcindex__lede,.sv-bloghead__lede,
  .sv-post__lede,.sv-galpage__lede,.sv-service__lede,.sv-head .sv-home__lede{font-size:22px;line-height:1.6;}
  /* Headings stay larger than the 19px reading text beneath them. In-content
     subheadings (an H3 that is not an FAQ question) 22px; FAQ questions (the
     service, Contact and Financing dt and the post H3s) 20px; the Contact
     sidebar headings and the homepage process step titles 22px. All stay
     below the in-content H2s (22-28px, 28px here). Eyebrows and the
     credentials label are labels, not headings, and stay small. */
  .sv-about__processgrid h3,.sv-contactpage__aside h2:not(.sv-creds__title),.sv-steps h3{font-size:22px;line-height:1.3;}
  .sv-faq__list dt,.sv-post__content h3{font-size:20px;line-height:1.4;}
  /* Columns beside an image or a card: the text fills its column. */
  .sv-steps p,.sv-fin__copy{max-width:none;}
  /* Text over a photograph keeps its width: the header scrim fades from .92 on
     the left to .14 at 80%, so a lede run to the full width lands on bright,
     unscrimmed photo (measured 2.3–3.3:1). Same reason as the homepage hero. */
  .sv-service__head--photo .sv-service__lede{max-width:40rem;}
}

