/*
Theme Name: Serenity Pools
Theme URI: https://serenitypoolsnc.com/
Author: Serenity Pools
Description: Custom theme for Serenity Pools — a Raleigh/Triangle-area vinyl liner replacement, safety cover, salt system and pool repair company. Rebuilt from the Cadmus Construction theme framework in the "Modern Coastal Trust" style, using the site's existing copy, service-area list and photos so search rankings are preserved. Activating this theme fully replaces the previous theme's appearance.
Version: 1.0.0
Requires at least: 5.9
Requires PHP: 7.2
License: GPL-2.0-or-later
Text Domain: serenity
*/


:root{
  /* Primary blue is the exact swatch supplied by the client: #022EEE.
     The rest of the family is derived from it (same hue, stepped value) so
     the palette reads as one colour rather than several unrelated blues. */
  /* One blue, stepped into a real ramp (each step ~2x the luminance of the one
     below it). Large surfaces sit on adjacent steps so the page descends
     smoothly instead of jumping between unrelated blues. blue-500 IS the
     client's #022EEE and stays the brand colour for buttons, links and
     accents, where its vividness is an asset; the big background panels use
     the calmer deeper steps so the vivid blue doesn't vibrate against them. */
  --blue-900:#020B33; --blue-800:#021152; --blue-700:#01187A;
  --blue-600:#0224B8; --blue-500:#022EEE; --blue-400:#2E55FF; --blue-300:#738DFF;
  /* Legacy aliases, kept so every existing rule keeps working. */
  --deep:#022EEE; --deep-deep:var(--blue-900); --deep-800:var(--blue-400); --deep-card:var(--blue-700);
  /* Hero gradient stops stay their OWN variables, separate from --deep above.
     --deep also serves as link/heading colour on white pages, so it can't be
     tuned purely for the banner; keeping these separate lets the hero be
     lightened or darkened without touching text contrast anywhere else. */
  --hero-hi:var(--blue-300); --hero-mid:var(--blue-500); --hero-lo:var(--blue-700);
  /* Accent = cyan. The previous gold sat almost opposite this blue on the
     colour wheel, which is why it read as a clash rather than a highlight;
     cyan is close enough in hue to belong to the same family, far enough
     apart in lightness to still pop as a call to action, and it reads as
     water. Three tokens because one value can't do all three jobs at an
     accessible contrast:
       --accent      button/badge FILLS (dark text sits on top)
       --accent-lt   small TEXT on the blue surfaces
       --accent-ink  small TEXT on white/paper surfaces               */
  --accent:#00D3E8; --accent-lt:#A6F7FF; --accent-ink:#006F7A;
  --accent-soft:rgba(0,211,232,.14); --accent-ink-on:#04222A;
  --paper:#F5F9F9; --paper-2:#EDF4F3; --white:#FFFFFF;
  --ink:#1D2544; --ink-soft:#3F445E; --stone:#666C82; --stone-lt:#969CB3;
  --line:rgba(2,46,238,.14); --line-2:rgba(2,46,238,.09);
  --line-dark:rgba(0,211,232,.24); --hair-dark:rgba(255,255,255,.10);
  --shadow:0 18px 50px -24px rgba(1,19,98,.45);
  --shadow-sm:0 8px 26px -18px rgba(1,19,98,.5);
  --r:14px; --r-lg:22px;
  --maxw:1200px; --pad:clamp(1.15rem,5vw,4rem);
  --sec:clamp(4.5rem,9vw,8rem);
  --f-display:'Space Grotesk',-apple-system,system-ui,sans-serif;
  --f-serif:'Space Grotesk',-apple-system,system-ui,sans-serif;
  --f-body:'Public Sans',-apple-system,system-ui,sans-serif;
}
*{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth;-webkit-text-size-adjust:100%}
body{font-family:var(--f-body);background:var(--paper);color:var(--ink);
  line-height:1.7;font-size:clamp(1rem,.5vw + .9rem,1.075rem);-webkit-font-smoothing:antialiased;overflow-x:hidden}
img{max-width:100%;display:block}
a{color:inherit;text-decoration:none}
h1,h2,h3,h4{font-family:var(--f-display);font-weight:700;line-height:1.05;letter-spacing:-.02em;color:var(--ink)}
.wrap{max-width:var(--maxw);margin:0 auto;padding-inline:var(--pad)}
.sec{padding-block:var(--sec)}
::selection{background:var(--accent);color:#fff}

/* ---------- before/after slider ---------- */
.wm{pointer-events:none;user-select:none}
/* DRAG-TO-COMPARE. The "after" photo lies underneath at full stage size; the
   "before" photo sits on top inside .ba-clip, whose width IS the divider
   position, so dragging wipes between the two.

   The one subtle part: .ba-clip's width changes constantly while dragging, so
   the photo inside it must not be sized relative to it or the image would
   squash as the divider moves. Sizing by height alone (height:100%;width:auto)
   makes the rendered width follow the STAGE's height instead — rock steady
   while dragging, and it uses nothing newer than CSS 2.1. main.js also pins an
   exact pixel width on load/resize so this stays true for any photo whose
   aspect ratio is not the 4:3 the supplied set happens to be. */
.ba-compare{max-width:760px;margin:0 auto}
.ba-stage-wrap{position:relative}
.ba-item{margin:0}
.ba-item[hidden]{display:none}
.ba-slider{position:relative;border-radius:var(--r-lg);overflow:hidden;
  box-shadow:0 40px 90px -40px rgba(0,0,0,.55);cursor:ew-resize;user-select:none;
  -webkit-user-select:none;border:1px solid var(--line-dark);background:var(--paper-2);
  touch-action:pan-y}
.ba-slider::before{content:"";display:block;padding-top:75%}   /* 4:3, matches the photos */
.ba-img{display:block;pointer-events:none;-webkit-user-drag:none}
.ba-under{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.ba-clip{position:absolute;top:0;left:0;bottom:0;width:var(--ba,50%);overflow:hidden}
.ba-clip .ba-img{position:absolute;top:0;left:0;height:100%;width:auto;max-width:none;object-fit:cover}
.ba-line{position:absolute;top:0;bottom:0;left:var(--ba,50%);width:0;pointer-events:none}
.ba-line::before{content:"";position:absolute;top:0;bottom:0;left:-1px;width:2px;background:#fff;box-shadow:0 0 0 1px rgba(0,0,0,.3)}
.ba-knob{position:absolute;top:50%;left:0;transform:translate(-50%,-50%);width:46px;height:46px;border-radius:50%;
  background:#fff;color:var(--deep);display:grid;place-items:center;box-shadow:0 8px 22px -6px rgba(0,0,0,.55)}
.ba-knob svg{width:22px;height:22px}
.ba-tag{position:absolute;top:1rem;font-family:var(--f-serif);text-transform:uppercase;letter-spacing:.14em;
  font-size:.72rem;color:#fff;background:rgba(2,11,51,.62);padding:.4rem .8rem;
  border-radius:999px;pointer-events:none;transition:opacity .25s ease}
.ba-tag-b{left:1rem}
.ba-tag-a{right:1rem}
/* Fade each label out when its side is nearly wiped away, so it never floats
   over the photo it is not labelling. */
.ba-slider[data-pos="min"] .ba-tag-b,.ba-slider[data-pos="max"] .ba-tag-a{opacity:0}
.ba-range{position:absolute;inset:0;width:100%;height:100%;margin:0;padding:0;opacity:0;cursor:ew-resize;
  -webkit-appearance:none;appearance:none;background:transparent;border:0}
.ba-range:focus-visible{opacity:1;outline:3px solid var(--accent);outline-offset:3px;background:transparent}
.ba-item figcaption{text-align:center;margin-top:1rem;color:var(--stone);font-size:.92rem}
.ba-arrow{position:absolute;top:calc(50% - 1.6rem);transform:translateY(-50%);width:46px;height:46px;border-radius:50%;
  background:var(--white);color:var(--deep);border:1px solid var(--line);display:grid;place-items:center;cursor:pointer;
  box-shadow:0 10px 24px -10px rgba(0,0,0,.45);transition:background .2s ease,color .2s ease;z-index:3}
.ba-arrow:hover{background:var(--accent);color:var(--accent-ink-on)}
.ba-arrow svg{width:20px;height:20px}
.ba-prev{left:-1.4rem}.ba-next{right:-1.4rem}
.ba-dots{display:flex;justify-content:center;flex-wrap:wrap;gap:.5rem;margin-top:1.1rem}
.ba-dot{width:9px;height:9px;border-radius:50%;background:var(--line);border:0;cursor:pointer;padding:0;
  transition:background .2s ease,transform .2s ease}
.ba-dot.active{background:var(--accent);transform:scale(1.3)}
.ba-hint{text-align:center;margin-top:.9rem;color:var(--stone);font-size:.85rem}
@media(max-width:900px){.ba-prev{left:.4rem}.ba-next{right:.4rem}}
/* Stacked: every pool on the page at once, one under the next. */
.ba-compare.stacked .ba-item + .ba-item{margin-top:clamp(2.2rem,4vw,3.2rem)}
.ba-compare.stacked .ba-item figcaption{margin-top:.85rem}
/* Grid: a row of comparisons side by side, for the homepage teaser. */
.ba-compare.grid-3{max-width:none}
/* Grid mode reuses "stacked" to mean "show them all, no paging", so the
   stacked vertical spacing has to be cancelled here — inside a grid it does
   not separate rows, it just pushes items 2 and 3 down inside their own
   cells and breaks the alignment of the row. The grid's own gap spaces them. */
.ba-compare.grid-3 .ba-item + .ba-item{margin-top:0}
.ba-compare.grid-3 .ba-stage-wrap{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(.9rem,1.8vw,1.4rem)}
.ba-compare.grid-3 .ba-item figcaption{font-size:.86rem;margin-top:.7rem}
.ba-compare.grid-3 .ba-knob{width:38px;height:38px}
.ba-compare.grid-3 .ba-knob svg{width:18px;height:18px}
.ba-compare.grid-3 .ba-tag{top:.6rem;font-size:.62rem;padding:.3rem .6rem;letter-spacing:.1em}
.ba-compare.grid-3 .ba-tag-b{left:.6rem}
.ba-compare.grid-3 .ba-tag-a{right:.6rem}
@media(max-width:860px){.ba-compare.grid-3 .ba-stage-wrap{grid-template-columns:1fr;gap:1.6rem}}
.ba-caption{text-align:center;margin-top:1.2rem;color:var(--stone);font-size:.92rem}

/* ---------- before/after slide-through (side-by-side pairs) ---------- */
.bna-slider{position:relative;max-width:960px;margin:0 auto}
.bna-track{display:flex;overflow-x:auto;scroll-snap-type:x mandatory;-webkit-overflow-scrolling:touch;
  scroll-behavior:smooth;border-radius:var(--r-lg);box-shadow:0 40px 90px -40px rgba(0,0,0,.55);
  border:1px solid var(--line-dark);cursor:grab;scrollbar-width:none}
.bna-track::-webkit-scrollbar{display:none}
.bna-track.dragging{cursor:grabbing;scroll-snap-type:none;scroll-behavior:auto}
.bna-slide{flex:0 0 100%;width:100%;scroll-snap-align:start;display:grid;grid-template-columns:1fr 1fr;gap:2px;background:var(--line-dark)}
.bna-slide figure{position:relative;margin:0;overflow:hidden;background:var(--paper-2)}
.bna-slide figure::before{content:"";display:block;padding-top:75%}   /* 4:3 */
.bna-slide img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}
.bna-slide figcaption{position:absolute;bottom:.9rem;left:.9rem;font-family:var(--f-serif);text-transform:uppercase;
  letter-spacing:.14em;font-size:.72rem;color:#fff;background:rgba(1,19,98,.6);backdrop-filter:blur(4px);
  padding:.4rem .8rem;border-radius:999px}
.bna-arrow{position:absolute;top:50%;transform:translateY(-50%);width:46px;height:46px;border-radius:50%;
  background:#fff;color:var(--deep-deep);border:0;display:grid;place-items:center;cursor:pointer;
  box-shadow:0 10px 24px -10px rgba(0,0,0,.4);z-index:2;transition:transform .25s,background .25s}
.bna-arrow:hover{background:var(--accent);color:var(--accent-ink-on)}
.bna-arrow svg{width:20px;height:20px}
.bna-prev{left:-1rem}.bna-next{right:-1rem}
.bna-dots{display:flex;justify-content:center;gap:.5rem;margin-top:1.3rem}
.bna-dot{width:9px;height:9px;border-radius:50%;background:var(--line);border:0;cursor:pointer;padding:0;
  transition:background .25s,transform .25s}
.bna-dot.active{background:var(--accent);transform:scale(1.3)}
@media(max-width:900px){.bna-prev{left:.4rem}.bna-next{right:.4rem}}
@media(max-width:640px){.bna-slide{grid-template-columns:1fr}.bna-slide figure::before{padding-top:62.5%}}   /* 16:10 */

/* ---------- Service-area map (interactive Google map + grouped chips) ---------- */
.sa-mapwrap{position:relative;margin-top:2.2rem;border-radius:var(--r-lg);overflow:hidden;
  border:1px solid var(--line);box-shadow:var(--shadow)}
#sa-map{width:100%;height:clamp(340px,52vw,540px);background:var(--deep-deep)}
/* Fallback state: the keyless Google embed fills the same box, so the layout
   is identical whether or not the API key is authorized for this domain. */
#sa-map.sa-map-fallback iframe{width:100%;height:100%;border:0;display:block}
/* Compact variant (Contact page sidebar): plain keyless embed, no JS map. */
.sa-mapwrap-compact{position:relative;margin-top:1.6rem}
.sa-mapwrap-compact::before{content:"";display:block;padding-top:75%}   /* 4:3 */
.sa-mapwrap-compact iframe{position:absolute;inset:0;width:100%;height:100%;border:0}
.sa-maplegend{display:flex;flex-wrap:wrap;gap:.6rem 1.5rem;margin-top:1rem;font-size:.86rem;color:var(--stone)}
.sa-maplegend span{display:inline-flex;align-items:center;gap:.5em}
.sa-dot{width:12px;height:12px;border-radius:50%;flex:none}
.sa-dot.core{background:rgba(0,211,232,.35);border:1px solid var(--accent)}
.sa-dot.pin{background:var(--accent-lt);border:1px solid rgba(1,19,98,.5)}
.sa-groups{display:grid;grid-template-columns:1fr;gap:1.5rem;margin-top:2.4rem}
.sa-group{background:var(--white);border:1px solid var(--line);border-radius:var(--r-lg);padding:1.6rem 1.7rem}
.sa-group h3{font-size:1.08rem;color:var(--deep);margin-bottom:1rem;display:flex;align-items:center;gap:.6em}
.sa-group h3 svg{width:18px;height:18px;color:var(--accent);flex:none}
.sa-chips{display:flex;flex-wrap:wrap;gap:.5rem}

/* Note beside the map: the radius is where we routinely work, not a fence. */
.sa-outside{margin-top:1rem;color:var(--ink-soft);font-size:.95rem;line-height:1.65;max-width:62ch}
.sa-outside strong{color:var(--ink)}
.sa-outside a{color:var(--deep);font-weight:700;text-decoration:underline;text-underline-offset:3px;
  text-decoration-color:var(--accent)}

/* ---------- eyebrow ---------- */
/* No decorative glyph before the label — the zigzag that used to sit here was
   a Cadmus motif and doesn't belong on this brand. */
.eyebrow{font-family:var(--f-serif);font-size:.8rem;letter-spacing:.22em;text-transform:uppercase;
  color:var(--accent-ink);display:inline-flex;align-items:center;margin-bottom:1.15rem;font-weight:700}
.eyebrow.on-dark{color:var(--accent-lt)}
.eyebrow.center{justify-content:center}

/* ---------- buttons ---------- */
.btn{display:inline-flex;align-items:center;gap:.6em;font-family:var(--f-body);font-weight:700;
  font-size:.98rem;letter-spacing:.01em;padding:.95em 1.6em;border-radius:100px;border:1.5px solid transparent;
  cursor:pointer;transition:transform .25s cubic-bezier(.2,.7,.2,1),background .25s,color .25s,box-shadow .25s;white-space:nowrap}
.btn svg{width:1.05em;height:1.05em}
.btn-primary{background:var(--accent);color:var(--accent-ink-on);box-shadow:0 12px 30px -12px rgba(0,211,232,.55)}
.btn-primary:hover{background:var(--accent-lt);transform:translateY(-2px)}
.btn-dark{background:var(--deep);color:var(--paper)}
.btn-dark:hover{background:var(--deep-800);transform:translateY(-2px)}
.btn-ghost{border-color:currentColor;color:var(--ink)}
.btn-ghost:hover{background:var(--ink);color:var(--paper);transform:translateY(-2px)}
.btn-ghost.on-dark{color:#ECEDF5}
.btn-ghost.on-dark:hover{background:var(--paper);color:var(--deep-deep);border-color:var(--paper)}
.btn-sm{padding:.7em 1.2em;font-size:.9rem}

/* ---------- "Text Us" option (see functions.php: serenity_render_text_btn) ---------- */
/* The Text Us option shows at EVERY width, beside every Call option. It was
   originally phone-only on the theory that SMS links are less useful on a
   desktop; the client wants it available everywhere, so these are simply the
   visible defaults now. (Renamed from .mobile-only-* accordingly — the old
   names described the opposite of what they do.) */
.text-opt-btn{display:inline-flex}
.text-opt-item{display:list-item}
.text-opt-flex{display:flex}

/* ---------- header ---------- */
header.site{position:fixed;inset:0 0 auto 0;z-index:60;transition:background .35s,box-shadow .35s,padding .35s;
  padding-block:.85rem}
header.site .bar{display:flex;align-items:center;justify-content:space-between;gap:1rem}
header.site.scrolled{background:rgba(1,19,98,.92);backdrop-filter:blur(12px);box-shadow:0 1px 0 var(--hair-dark);padding-block:.55rem}
.brand{display:flex;align-items:center;gap:.7rem;color:var(--paper);font-family:var(--f-display);font-weight:700;
  letter-spacing:-.01em;font-size:1.12rem;line-height:1;flex:none}
.brand img.logo{display:block;height:60px;width:auto;flex:none}
.brand > span{white-space:nowrap}
.brand small{display:block;font-family:var(--f-serif);font-weight:500;font-size:.56rem;letter-spacing:.2em;
  color:var(--accent-lt);margin-top:.28em;text-transform:uppercase}
/* The real logo (an oval ~300x134 graphic, not a small square glyph) is noticeably
   wider than the placeholder icon this was designed around. On phones it — plus the
   wordmark and the header's Free Estimate button — no longer all fit on one line, so
   the wordmark steps aside first, then the logo shrinks further. See style.css's
   1180px breakpoint for the corresponding rest of the mobile header layout. */
@media(max-width:640px){
  header.site .brand img.logo{height:42px}
  header.site .brand small{display:none}
}
nav.main{display:flex;align-items:center;gap:1.5rem}
nav.main a.nl{color:#E5E8F4;font-size:.92rem;font-weight:500;position:relative;padding-block:.3em}
nav.main a.nl::after{content:"";position:absolute;left:0;bottom:0;width:0;height:1.5px;background:var(--accent-lt);transition:width .3s}
nav.main a.nl:hover{color:#fff}nav.main a.nl:hover::after{width:100%}
/* ---------- "Services" dropdown (folds 6 service pages into one nav item so
   the desktop nav — logo + links + phone + Free Estimate button — actually
   fits on one line instead of wrapping) ---------- */
.nav-drop{position:relative}
.nav-drop-trigger{display:inline-flex;align-items:center;gap:.35em;background:none;border:0;cursor:pointer;
  color:#E5E8F4;font-family:var(--f-body);font-size:.92rem;font-weight:500;padding-block:.3em}
.nav-drop-trigger .chev{width:.85em;height:.85em;transition:transform .2s}
.nav-drop:hover .nav-drop-trigger,.nav-drop:focus-within .nav-drop-trigger,
.nav-drop.open .nav-drop-trigger{color:#fff}
.nav-drop:hover .nav-drop-trigger .chev,.nav-drop:focus-within .nav-drop-trigger .chev,
.nav-drop.open .nav-drop-trigger .chev{transform:rotate(180deg)}
/* The panel sits flush against the trigger (top:100%) and creates its visual
   gap with padding-top on ITSELF, not margin. With margin the gap was dead
   space outside .nav-drop — moving the mouse from "Services" down toward the
   menu crossed it, :hover ended, and the menu vanished before you could reach
   it. The transparent padding band is part of the panel, so the hover chain
   never breaks. */
.nav-drop-panel{position:absolute;top:100%;left:50%;transform:translateX(-50%);
  padding-top:.85rem;min-width:230px;
  opacity:0;visibility:hidden;pointer-events:none;transition:opacity .18s}
.nav-drop-panel-inner{background:var(--white);border-radius:var(--r);box-shadow:var(--shadow);
  padding:.5rem;display:grid;gap:.1rem}
.nav-drop-panel a{display:block;color:var(--ink-soft);font-size:.92rem;font-weight:500;padding:.6em .8em;border-radius:calc(var(--r) - 6px)}
.nav-drop-panel a:hover,.nav-drop-panel a:focus-visible{background:var(--paper-2);color:var(--deep)}
/* .open is set by JS on click/tap — touch devices have no hover at all, so
   without it the menu was unreachable on a touchscreen laptop or tablet. */
.nav-drop:hover .nav-drop-panel,.nav-drop:focus-within .nav-drop-panel,
.nav-drop.open .nav-drop-panel{opacity:1;visibility:visible;pointer-events:auto}
.header-cta{display:flex;align-items:center;gap:1rem}
.phone-link{display:inline-flex;align-items:center;gap:.5em;color:var(--paper);font-weight:700;font-size:.95rem;white-space:nowrap}
.phone-link svg{width:1em;height:1em;color:var(--accent-lt)}
/* "Call" label drops out first when the header gets tight — the number alone
   still reads as a phone link next to the handset icon. */
.phone-link .pl-label{margin-right:.1em}
@media(max-width:1320px){.phone-link .pl-label{display:none}}
/* The header's own Text Us control. Visible next to Call at every width. On
   narrow phones it drops its label and becomes an icon-only tap target so it
   does not crowd out the logo and Free Estimate button — see the 660px
   breakpoint below. */
.text-link{display:inline-flex;align-items:center;justify-content:center;gap:.45em;color:var(--paper);
  font-weight:700;font-size:.95rem;white-space:nowrap;border:1.5px solid rgba(255,255,255,.35);border-radius:100px;
  padding:.5em .9em}
.text-link:hover{border-color:#fff}
.text-link svg{width:1em;height:1em;color:var(--accent-lt);flex:none}
.menu-btn{display:none;background:none;border:0;cursor:pointer;padding:.4rem;color:var(--paper)}
.menu-btn svg{width:28px;height:28px}

/* ---------- hero ---------- */
.hero{position:relative;background:radial-gradient(120% 90% at 82% -10%,var(--hero-hi) 0%,var(--hero-mid) 45%,var(--hero-lo) 100%);
  color:var(--paper);padding-top:clamp(8rem,15vw,11rem);padding-bottom:clamp(4rem,8vw,6.5rem);overflow:hidden}
/* Pool-water caustics. Drawn as an SVG turbulence filter rather than a photo:
   the postcard's own water texture is only ~72x130px of usable, text-free area
   at its scan resolution, so lifting and tiling it would look blurry and
   visibly repeated. This is resolution-independent (crisp on any screen), a
   few hundred bytes, and tuned to the same cyan the postcard uses. The ridge
   trick: type="turbulence" is |noise|, so values near zero form thin ribbon
   lines — a negative alpha gain lights up exactly those, which is what pool
   caustics actually look like. */
.hero .grain{position:absolute;inset:-8%;opacity:.34;pointer-events:none;
  mix-blend-mode:screen;background-size:cover;
  background-image:url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22800%22%20height%3D%22800%22%3E%3Cfilter%20id%3D%22c%22%20x%3D%220%22%20y%3D%220%22%20width%3D%22100%25%22%20height%3D%22100%25%22%3E%3CfeTurbulence%20type%3D%22turbulence%22%20baseFrequency%3D%220.013%200.02%22%20numOctaves%3D%222%22%20seed%3D%225%22%20result%3D%22t%22%2F%3E%3CfeColorMatrix%20in%3D%22t%22%20type%3D%22matrix%22%20values%3D%220%200%200%200%201%20%200%200%200%200%201%20%200%200%200%200%201%20%20-7%200%200%200%201%22%2F%3E%3CfeGaussianBlur%20stdDeviation%3D%220.3%22%2F%3E%3C%2Ffilter%3E%3Crect%20width%3D%22100%25%22%20height%3D%22100%25%22%20filter%3D%22url%28%23c%29%22%2F%3E%3C%2Fsvg%3E")}
/* Text-safe scrim. A plain left-to-right wash wasn't enough: bright caustic
   ridges crossing behind a letter dropped measured contrast to 2.5:1 on the
   lead paragraph and 1.4:1 on the gold eyebrow — fine in a screenshot, bad to
   actually read. This is feathered and anchored over the text block instead,
   so the copy sits on genuinely dark water while the right side stays bright.
   Now that the gold eyebrow label is gone from the hero, the only text
   here is the white headline and the paragraph, which tolerate a far lighter
   shadow than the eyebrow did — this is the lightest setting that still
   passes: h1 4.8:1 (needs 3.0), paragraph 5.0:1 (needs 4.5)
   (WCAG AA needs 3.0 large / 4.5 small). */
.hero::after{content:"";position:absolute;inset:0;pointer-events:none;z-index:1;
  background:radial-gradient(130% 150% at 18% 52%,rgba(1,16,80,.42) 0%,rgba(1,16,80,.26) 42%,rgba(1,16,80,.06) 70%,transparent 92%)}
.hero-inner{position:relative;z-index:2;max-width:760px}
.hero h1{font-size:clamp(2.4rem,6.4vw,4.6rem);color:#fff;letter-spacing:-.02em;line-height:1.04;
  text-wrap:balance}
.hero .lead{font-size:clamp(1.05rem,1.5vw,1.24rem);color:#E1E5F3;max-width:52ch;margin:1.5rem 0 2.1rem;font-weight:400}
.hero-cta{display:flex;flex-wrap:wrap;gap:.9rem;align-items:center}
/* Call and Text Us are kept together as one unit. All three buttons cannot
   fit on one line at any desktop width, so without this the third wrapped
   alone and looked like an accident; grouped, the row breaks deliberately
   into primary action / contact options. */
.hero-contact{display:flex;flex-wrap:wrap;gap:.9rem;align-items:center}
.trust{display:flex;flex-wrap:wrap;gap:.9rem 1.6rem;align-items:center;margin-top:2.2rem;
  padding-top:1.8rem;border-top:1px solid var(--hair-dark)}
.trust .ti{display:flex;align-items:center;gap:.5rem;color:#D2D5E7;font-size:.82rem;font-weight:600;letter-spacing:.01em;white-space:nowrap}
.trust .ti svg{width:1.3em;height:1.3em;color:var(--accent-lt);flex:none}
.trust .ti b{color:#fff;font-family:var(--f-display);font-weight:700}

/* ---------- page hero (inner pages) ---------- */
.page-hero{position:relative;overflow:hidden;
  background:radial-gradient(120% 90% at 80% -10%,var(--hero-hi),var(--hero-mid) 48%,var(--hero-lo));
  color:var(--paper);padding-top:clamp(7.5rem,13vw,10rem);padding-bottom:clamp(2.6rem,5vw,3.6rem)}
/* Same caustics as the homepage hero, lighter, so interior pages match. */
.page-hero::before{content:"";position:absolute;inset:-8%;pointer-events:none;opacity:.30;
  mix-blend-mode:screen;background-size:cover;
  background-image:url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22800%22%20height%3D%22800%22%3E%3Cfilter%20id%3D%22c%22%20x%3D%220%22%20y%3D%220%22%20width%3D%22100%25%22%20height%3D%22100%25%22%3E%3CfeTurbulence%20type%3D%22turbulence%22%20baseFrequency%3D%220.013%200.02%22%20numOctaves%3D%222%22%20seed%3D%225%22%20result%3D%22t%22%2F%3E%3CfeColorMatrix%20in%3D%22t%22%20type%3D%22matrix%22%20values%3D%220%200%200%200%201%20%200%200%200%200%201%20%200%200%200%200%201%20%20-7%200%200%200%201%22%2F%3E%3CfeGaussianBlur%20stdDeviation%3D%220.3%22%2F%3E%3C%2Ffilter%3E%3Crect%20width%3D%22100%25%22%20height%3D%22100%25%22%20filter%3D%22url%28%23c%29%22%2F%3E%3C%2Fsvg%3E")}
.page-hero::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(100deg,rgba(1,19,98,.55),rgba(1,19,98,.15) 60%,transparent)}
.page-hero .wrap{position:relative;z-index:2}
.page-hero .crumb{font-size:.82rem;color:#BDC2D7;margin-bottom:1.2rem;display:flex;gap:.5em;align-items:center}
.page-hero .crumb a:hover{color:var(--accent-lt)}
.page-hero h1{color:#fff;font-size:clamp(1.9rem,4.6vw,3rem);max-width:26ch;line-height:1.06}
.page-hero p.sub{margin-top:1rem;color:#DBDEF0;max-width:60ch;font-size:1.05rem}

/* ---------- stats ---------- */

/* ---------- section heads ---------- */
.head{max-width:64ch}
.head.center{margin-inline:auto;text-align:center}
.head h2{font-size:clamp(1.9rem,4.2vw,3rem)}
.head p.sub{margin-top:1.1rem;color:var(--stone);font-size:1.06rem;max-width:56ch}
.head.center p.sub{margin-inline:auto}

/* ---------- services ---------- */
#services{background:var(--paper)}

/* ---------- why / trust ---------- */
#why{background:var(--blue-600);color:var(--paper);position:relative;overflow:hidden}
#why .split{display:grid;grid-template-columns:1.05fr 1fr;gap:clamp(2rem,5vw,4.5rem);align-items:center;position:relative}
#why h2{color:#fff}
#why .head p.sub{color:#DBDEF0}
#why .lead2{color:#E1E5F3;margin:1.4rem 0 0;font-size:1.05rem}
#why .head{max-width:none}
#why .head .lead2{margin-inline:auto;max-width:64ch}
/* The four steps run left-to-right as a single row. They're a sequence, so a
   counter numbers them — reading order carries the meaning now that they're
   side by side rather than stacked. Each card stacks internally (icon over
   text) because four narrow columns can't fit an icon beside a paragraph. */
/* Four across needs real width; step down to 2x2 then a single column rather
   than letting the cards get too narrow to read. */
@media(max-width:900px){.feat-list{grid-template-columns:repeat(2,1fr)}}
@media(max-width:560px){.feat-list{grid-template-columns:1fr}}

/* ---------- process ---------- */
#process{background:var(--paper-2)}
.steps{display:grid;grid-template-columns:repeat(4,1fr);gap:1.2rem;margin-top:3rem;counter-reset:s}
.step{position:relative;padding:1.6rem 1.3rem 1.4rem;border:1px solid var(--line);border-radius:var(--r);background:var(--white);
  transition:transform .3s,box-shadow .3s}
.step:hover{transform:translateY(-4px);box-shadow:var(--shadow-sm)}
.step .num{font-family:var(--f-display);font-weight:700;font-size:1.9rem;color:var(--accent);letter-spacing:-.02em;line-height:1;
  display:flex;align-items:baseline;gap:.15em}
.step .num::after{content:"";width:30px;height:1.5px;background:var(--line);align-self:center;margin-left:.4rem}
.step h4{font-size:1.06rem;margin:.85rem 0 .45rem}
.step p{color:var(--stone);font-size:.92rem}
@media(max-width:900px){.steps{grid-template-columns:repeat(2,1fr)}}

/* ---------- service area ---------- */
#areas{background:var(--paper)}
#areas .split{display:grid;grid-template-columns:1fr 1fr;gap:clamp(2rem,5vw,4rem);align-items:center}
.areas-chips{display:flex;flex-wrap:wrap;gap:.55rem;margin-top:1.6rem}
.chip{display:inline-flex;align-items:center;padding:.5em 1em;border-radius:999px;background:var(--white);
  border:1px solid var(--line);font-size:.87rem;font-weight:600;color:var(--ink-soft)}
/* Must come after .chip — equal specificity, so source order decides. */
.chip-accent{background:var(--accent-soft);border-color:var(--accent);color:var(--deep);font-weight:700}
.map-graphic{aspect-ratio:1/1;border-radius:var(--r-lg);background:var(--paper-2);border:1px solid var(--line);
  display:grid;place-items:center;color:var(--stone)}

/* ---------- gallery ---------- */
.gallery-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(190px,1fr));gap:1rem;margin-top:2.5rem}
.gallery-grid a{display:block;position:relative;border-radius:var(--r);overflow:hidden;border:1px solid var(--line);
  background:var(--paper-2);transition:transform .3s,box-shadow .3s}
.gallery-grid a:hover{transform:translateY(-3px);box-shadow:var(--shadow-sm)}
.gallery-grid a::before{content:"";display:block;padding-top:100%}
.gallery-grid img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}

/* ---------- vinyl liner pattern catalog (Vinyl Pool Liners page) ---------- */
.vlp-filterbar{display:flex;flex-direction:column;gap:1.1rem;margin-bottom:2.2rem;padding-bottom:1.6rem;border-bottom:1px solid var(--line)}
.vlp-shade-tabs{display:flex;flex-wrap:wrap;gap:.5rem}
.vlp-tab{font-family:var(--f-body);font-weight:700;font-size:.88rem;padding:.6em 1.2em;border-radius:999px;
  border:1.5px solid var(--line);background:var(--white);color:var(--ink-soft);cursor:pointer;transition:background .2s,color .2s,border-color .2s}
.vlp-tab:hover{border-color:var(--accent)}
.vlp-tab.active{background:var(--deep);border-color:var(--deep);color:#fff}
.vlp-chips{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem}
.vlp-chips-label{font-size:.82rem;font-weight:700;color:var(--stone);letter-spacing:.03em;margin-right:.2rem}
.vlp-chip{font-family:var(--f-body);font-size:.84rem;font-weight:600;padding:.5em 1em;border-radius:999px;
  border:1.5px solid var(--line);background:var(--white);color:var(--ink-soft);cursor:pointer;transition:background .2s,color .2s,border-color .2s}
.vlp-chip:hover{border-color:var(--accent)}
.vlp-chip.active{background:var(--accent-soft);border-color:var(--accent);color:var(--deep);font-weight:700}
.vlp-chip.vlp-clear{background:transparent;border-color:transparent;color:var(--stone);text-decoration:underline;text-underline-offset:3px}
.vlp-count{font-size:.85rem;color:var(--stone);font-weight:600}
.vlp-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:1.3rem}
.vlp-card{border:1px solid var(--line);border-radius:var(--r-lg);overflow:hidden;background:var(--white);
  transition:transform .3s,box-shadow .3s}
.vlp-card:hover{transform:translateY(-4px);box-shadow:var(--shadow-sm)}
.vlp-card.is-hidden{display:none}
/* FIXED-RATIO BOXES — padding technique, not aspect-ratio.
   Safari has been unreliable with `aspect-ratio` in the two shapes used here:
   a box whose only children are absolutely positioned (it can collapse to
   zero height), and an in-flow child with height:100% inside it (circular —
   the child's height depends on a parent height that aspect-ratio has not
   resolved). Either way the container is still laid out and the page looks
   fine, but the image inside is invisible — which is exactly the reported
   symptom, and why it only showed on iOS. The padding-top technique predates
   aspect-ratio, behaves identically in every browser, and cannot collapse. */
.vlp-card-media{position:relative;overflow:hidden;background:var(--paper-2)}
.vlp-card-media::before{content:"";display:block;padding-top:100%}
.vlp-card-img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;transition:opacity .35s ease}
.vlp-card-img--hover{opacity:0}
.vlp-card:hover .vlp-card-img--hover,.vlp-card:focus-within .vlp-card-img--hover{opacity:1}
.vlp-card-body{padding:1rem 1.1rem 1.2rem}
.vlp-card-body h3{font-size:1.02rem;margin-bottom:.3rem}
.vlp-card-meta{font-size:.8rem;color:var(--stone)}
.vlp-attrib{margin-top:2.4rem;font-size:.85rem;color:var(--stone-lt);text-align:center}
.vlp-attrib a{color:var(--stone);text-decoration:underline;text-underline-offset:3px}
@media(max-width:640px){
  .vlp-grid{grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:.9rem}
}

/* ---------- CTA band ---------- */
.cta-band{background:linear-gradient(120deg,var(--blue-700),var(--blue-800));color:var(--paper);border-radius:var(--r-lg);
  padding:clamp(1.8rem,4vw,2.6rem) clamp(1.8rem,4vw,3rem);display:flex;align-items:center;justify-content:space-between;
  gap:1.5rem;flex-wrap:wrap}
.cta-band h3{color:#fff;font-size:clamp(1.3rem,2.6vw,1.7rem)}
.cta-band p{color:#DBDEF0;margin-top:.4rem;font-size:.98rem}
.cta-band .btns{display:flex;gap:.8rem;flex-wrap:wrap}

/* ---------- liner promo band ---------- */
.promo-band{background:radial-gradient(130% 160% at 88% -10%,var(--blue-400) 0%,var(--blue-600) 46%,var(--blue-800) 100%);
  border-radius:var(--r-lg);padding:clamp(2.2rem,5vw,3.4rem);color:var(--paper);
  display:grid;gap:clamp(1.6rem,4vw,2.6rem);align-items:center;position:relative;overflow:hidden}
.promo-band::before{content:"";position:absolute;inset:0;opacity:.5;pointer-events:none;
  background:radial-gradient(closest-side,rgba(255,255,255,.08),transparent);mix-blend-mode:overlay}
.promo-band .pb-text{position:relative}
.promo-band .eyebrow{color:var(--accent-lt)}
.promo-band h2{color:#fff;font-size:clamp(1.5rem,3.4vw,2.1rem);line-height:1.15}
.promo-band p{color:#DBDEF0;margin-top:.7rem;font-size:1.02rem;max-width:46ch}
.promo-band .btns{display:flex;gap:.8rem;flex-wrap:wrap;margin-top:1.4rem}
@media(max-width:800px){.promo-band{grid-template-columns:1fr;text-align:center}
  .promo-band .btns{justify-content:center}.promo-band p{margin-inline:auto}}
/* Narrow phones: buttons are nowrap by default, which is right for short
   labels but pushed the long ones ("Call Today: 919-749-1787", "View Full
   Gallery & Comparison Slider") past the viewport edge. Below this width let
   any button wrap instead of overflowing. */
@media(max-width:430px){
  .promo-band{padding:1.6rem 1.1rem}
  .btn{white-space:normal;text-align:center}
}

/* ---------- contact ---------- */
#contact-cta{background:var(--blue-800)}
.contact-info{display:grid;gap:1.1rem;margin-top:2rem}
.contact-info a,.contact-info div{display:flex;gap:1rem;align-items:flex-start;color:#E5E8F4}
.contact-info .ci{width:44px;height:44px;flex:none;border-radius:12px;background:rgba(0,211,232,.15);color:var(--accent-lt);
  display:grid;place-items:center}
.contact-info .ci svg{width:21px;height:21px}
.contact-info b{color:#fff;display:block;font-family:var(--f-body);font-weight:700;font-size:1rem}
.contact-info span{font-size:.92rem;color:#C5C9DA}
.contact-info a:hover b{color:var(--accent-lt)}

/* generic styling for whatever form plugin renders inside page content
   (Contact Form 7 / Gravity Forms / WPForms all emit <form><label><input>) */
.content-card{background:var(--white);border-radius:var(--r-lg);padding:clamp(1.6rem,3vw,2.4rem);box-shadow:var(--shadow);color:var(--ink)}
.content-card form,.article-wrap form{display:block}
.content-card p,.article-wrap form p{margin-bottom:1rem}
.content-card label,.article-wrap form label{display:block;font-size:.85rem;font-weight:700;letter-spacing:.02em;margin-bottom:.35rem;color:var(--ink-soft)}
.content-card input[type=text],.content-card input[type=email],.content-card input[type=tel],.content-card select,.content-card textarea,
.article-wrap form input[type=text],.article-wrap form input[type=email],.article-wrap form input[type=tel],.article-wrap form select,.article-wrap form textarea{
  width:100%;font-family:var(--f-body);font-size:.98rem;padding:.85em 1em;
  border:1.5px solid var(--line);border-radius:11px;background:#fff;color:var(--ink);transition:border-color .25s,box-shadow .25s}
.content-card textarea,.article-wrap form textarea{resize:vertical;min-height:110px}
.content-card input:focus,.content-card select:focus,.content-card textarea:focus,
.article-wrap form input:focus,.article-wrap form select:focus,.article-wrap form textarea:focus{outline:0;border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft)}
.content-card input[type=submit],.content-card button[type=submit],
.article-wrap form input[type=submit],.article-wrap form button[type=submit]{
  display:inline-flex;align-items:center;gap:.6em;font-family:var(--f-body);font-weight:700;font-size:.98rem;
  padding:.95em 1.8em;border-radius:100px;border:1.5px solid transparent;cursor:pointer;
  background:var(--accent);color:var(--accent-ink-on);transition:transform .25s,background .25s;width:100%;justify-content:center}
.content-card input[type=submit]:hover,.content-card button[type=submit]:hover,
.article-wrap form input[type=submit]:hover,.article-wrap form button[type=submit]:hover{background:var(--accent-lt);transform:translateY(-2px)}

/* ---------- footer ---------- */
footer.site{background:var(--blue-900);color:#C5C9DA;padding-top:clamp(3.2rem,6vw,4.6rem)}
footer.site .top{display:grid;grid-template-columns:1.5fr 1fr 1fr 1.2fr;gap:2.4rem 2rem;padding-bottom:2.6rem;border-bottom:1px solid var(--hair-dark)}
footer .fbrand .brand{margin-bottom:1.1rem}
footer .fbrand p{font-size:.92rem;max-width:34ch;color:#B2B9D7}
footer .fbrand p.areas{font-size:.82rem;color:#9AA0B9;margin-top:.7rem;line-height:1.55;max-width:34ch}
footer h5{color:#fff;font-family:var(--f-display);font-weight:700;font-size:.86rem;letter-spacing:.05em;text-transform:uppercase;margin-bottom:1.05rem}
footer ul{list-style:none;display:grid;gap:.6rem}
footer ul a{font-size:.92rem;color:#B4BAD1;transition:color .25s;display:flex;align-items:flex-start;gap:.55em;white-space:normal;overflow-wrap:break-word;line-height:1.5}
footer ul a svg{width:16px;height:16px;flex:none;margin-top:.18em}
footer ul a>span{flex:1;min-width:0}
footer ul a .nowrap{white-space:nowrap}
footer ul a:hover{color:var(--accent-lt)}
footer .bottom{display:flex;justify-content:space-between;align-items:center;gap:1rem;flex-wrap:wrap;
  padding-block:1.5rem;font-size:.82rem;color:#8C91AB}
footer .bottom a{color:#B2B9D7}footer .bottom a:hover{color:var(--accent-lt)}

/* ---------- reveal ---------- */
.rv{opacity:0;transform:translateY(24px);transition:opacity .7s cubic-bezier(.2,.7,.2,1),transform .7s cubic-bezier(.2,.7,.2,1)}
.rv.in{opacity:1;transform:none}
html:not(.js) .rv{opacity:1;transform:none}
.rv.d1{transition-delay:.08s}.rv.d2{transition-delay:.16s}.rv.d3{transition-delay:.24s}.rv.d4{transition-delay:.32s}

/* ---------- mobile nav ---------- */
.mobile-nav{position:fixed;inset:0;z-index:70;background:var(--deep-deep);transform:translateX(100%);
  transition:transform .4s cubic-bezier(.4,0,.2,1);display:flex;flex-direction:column;padding:1.4rem var(--pad)}
.mobile-nav.open{transform:none}
.mobile-nav .mtop{display:flex;justify-content:space-between;align-items:center;margin-bottom:2.2rem}
.mobile-nav a.ml{color:#ECEDF5;font-family:var(--f-display);font-weight:700;font-size:1.55rem;padding-block:.5rem;
  border-bottom:1px solid var(--hair-dark)}
.mobile-nav a.ml:hover{color:var(--accent-lt)}
.mobile-nav .mcta{margin-top:auto;display:grid;gap:.8rem;padding-block:2rem}
.close-btn{background:none;border:0;color:var(--paper);cursor:pointer;padding:.4rem}
.close-btn svg{width:30px;height:30px}

/* ---------- generic page / article wrapper ---------- */
.article-wrap{max-width:760px;margin:0 auto;padding-inline:var(--pad)}
.article-wrap.wide{max-width:var(--maxw)}
article.post-body{padding-block:clamp(3rem,6vw,4.5rem)}
article.post-body h1{font-size:clamp(1.9rem,4.4vw,2.8rem);margin-bottom:1.3rem}
article.post-body h2{font-size:clamp(1.4rem,3vw,1.9rem);margin:2.4rem 0 1rem}
article.post-body h3{font-size:1.2rem;margin:1.8rem 0 .6rem}
article.post-body p{margin-bottom:1.1rem;color:var(--ink-soft)}
article.post-body ul,article.post-body ol{margin:0 0 1.2rem 1.1rem;display:grid;gap:.5rem}
article.post-body li{color:var(--ink-soft);padding-left:.3rem}
article.post-body li::marker{color:var(--accent)}
article.post-body a.ilink,article.post-body a{color:var(--deep);font-weight:700;text-decoration:underline;text-underline-offset:3px;text-decoration-color:var(--accent)}
article.post-body strong{color:var(--ink)}
article.post-body img{border-radius:var(--r);margin:1.5rem 0}
article.post-body figure{margin:1.5rem 0}
/* The prose rules above are written for body copy, and they were strong enough
   to repaint a CTA band that happened to sit inside an article: the paragraph
   turned dark grey on dark blue and the buttons picked up prose link styling,
   underline and all. A self-contained component dropped into prose must keep
   its own appearance, so these put it back explicitly. */
article.post-body .cta-band h3{color:#fff}
article.post-body .cta-band p{color:#DBDEF0}
article.post-body .cta-band a{color:inherit;font-weight:inherit;text-decoration:none}
article.post-body .cta-band a.btn-primary{color:var(--accent-ink-on)}
article.post-body .cta-band img,article.post-body .cta-band figure{margin:0;border-radius:0}

/* The "Browse All Latham Liner Patterns" button sits in a bare <p> outside
   .post-body, so the prose paragraph spacing never reached it and the reset's
   margin:0 left it flush against the promo band directly below. */
.liner-actions{margin:0 0 clamp(2rem,4.5vw,3.2rem)}

.article-cta{background:var(--paper-2);border:1px solid var(--line);border-radius:var(--r-lg);padding:2rem;margin-top:2.5rem;text-align:center}
.article-cta h3{font-size:1.3rem;margin-bottom:.5rem}
.article-cta p{color:var(--stone);margin-bottom:1.3rem}

/* Related-services block. Its job is internal linking, so the anchors are set
   at a readable size rather than shrunk into fine print — an internal link is
   worth roughly what a reader is likely to click. */
.related-svc{background:var(--paper-2);border-top:1px solid var(--line);padding-block:clamp(2.6rem,5vw,3.6rem)}
.related-svc h2{font-size:clamp(1.2rem,2.4vw,1.5rem);margin-bottom:1.3rem}
.related-list{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(2,1fr);gap:.9rem}
.related-list li{background:var(--white);border:1px solid var(--line-2);border-radius:var(--r);padding:1rem 1.2rem;
  transition:border-color .2s ease,transform .2s ease}
.related-list li:hover{border-color:var(--accent);transform:translateY(-2px)}
.related-list a{display:block;font-family:var(--f-display);font-weight:700;font-size:1.02rem;color:var(--deep)}
.related-list span{display:block;margin-top:.25rem;color:var(--stone);font-size:.9rem;line-height:1.5}
.related-area{margin-top:1.3rem;color:var(--ink-soft);font-size:.95rem;max-width:70ch}
.related-area a{color:var(--deep);font-weight:700;text-decoration:underline;text-underline-offset:3px;
  text-decoration-color:var(--accent)}
.vlp-h2{font-size:clamp(1.4rem,3vw,1.9rem);margin-bottom:1.4rem}
@media(max-width:760px){.related-list{grid-template-columns:1fr}}

/* ---------- responsive ---------- */
@media(max-width:1180px){
  nav.main,.header-cta .phone-link{display:none}
  .menu-btn{display:block}
  .header-cta{gap:.7rem}
  .stats .grid{grid-template-columns:repeat(2,1fr)}
  #areas .split{grid-template-columns:1fr}
  .grid2{grid-template-columns:1fr}
  footer.site .top{grid-template-columns:1fr 1fr}
  .cta-band{flex-direction:column;align-items:flex-start}
}
@media(max-width:560px){
  footer.site .top{grid-template-columns:1fr}
}
/* Compact header state: below this, the desktop nav is already hidden
   (see the 1180px breakpoint), so what's left fighting for space is the
   logo, the Text-Us button, and the Free Estimate button. All three
   compact down together at the same breakpoint so there's no in-between
   width where only some of them have shrunk — that in-between state was
   exactly what caused the header to overlap itself. */
.header-cta .btn-primary .short-label{display:none}
@media(max-width:660px){
  header.site .brand > span{display:none}
  .header-cta{gap:.55rem}
  .text-link{padding:.55em;border-radius:50%}
  .text-link .tl-label{display:none}
  .header-cta .btn-primary .full-label{display:none}
  .header-cta .btn-primary .short-label{display:inline}
}
@media(max-width:400px){
  header.site .brand img.logo{height:34px}
  .header-cta .btn-primary{padding:.7em .95em}
}
@media(prefers-reduced-motion:reduce){
  *{animation:none!important;transition:none!important;scroll-behavior:auto}
  .rv{opacity:1;transform:none}
}

/* ===========================================================================
   HOMEPAGE — asymmetric editorial layout
   Replaces the stacked centered-card-grid pattern the framework shipped with.
   =========================================================================== */

/* ---------- hero: copy left, real before/after proof right ---------- */
.hero-grid{position:relative;z-index:2;display:grid;grid-template-columns:1.15fr .85fr;
  gap:clamp(2rem,5vw,4.5rem);align-items:center}
.hero-copy{max-width:44rem}
.hero-copy h1{text-wrap:balance}

.hero-proof{position:relative;min-height:clamp(300px,34vw,430px);
  display:grid;place-items:center}
.proof-card{position:relative;margin:0;border-radius:var(--r-lg);overflow:hidden;
  border:1px solid rgba(255,255,255,.22);background:var(--blue-800);
  box-shadow:0 40px 90px -34px rgba(0,0,0,.65)}
.proof-card img{position:absolute;inset:0;display:block;width:100%;height:100%;object-fit:cover}
/* Two real jobs stacked, the back one peeking out — reads as a portfolio,
   not a stock hero image. */
.proof-card.back{position:absolute;width:76%;top:2%;left:0;transform:rotate(-5deg);
  opacity:.9}
.proof-card.back::before{content:"";display:block;padding-top:37.5%}   /* 8:3 */
.proof-card.front{width:92%;justify-self:end;transform:rotate(1.5deg)}
.proof-card.front::before{content:"";display:block;padding-top:42.5%}   /* 8:3.4 */
.proof-card.front figcaption{position:absolute;left:0;right:0;bottom:0;
  display:flex;align-items:center;justify-content:center;gap:.7em;
  padding:.6rem 1rem;background:rgba(2,11,51,.88);backdrop-filter:blur(3px);
  color:#fff;font-family:var(--f-serif);text-transform:uppercase;letter-spacing:.16em;font-size:.68rem}
.proof-card.front figcaption svg{width:1.15em;height:1.15em;color:var(--accent-lt)}

/* ---------- proof rail: numbers on a card straddling the hero edge ---------- */
.rail-sec{padding:0;position:relative;z-index:3}
.proof-rail{display:grid;grid-template-columns:repeat(4,1fr);
  background:var(--white);border:1px solid var(--line);border-radius:var(--r-lg);
  box-shadow:var(--shadow);margin-top:clamp(-4.5rem,-5vw,-2.5rem);overflow:hidden}
.pr-item{padding:clamp(1.4rem,2.6vw,2rem) 1.2rem;text-align:center;border-right:1px solid var(--line-2)}
.pr-item:last-child{border-right:0}
.pr-item .n{font-family:var(--f-display);font-weight:700;color:var(--deep);
  font-size:clamp(1.9rem,3.6vw,2.7rem);line-height:1;letter-spacing:-.02em}
/* Lighter tint of the same blue as the numeral — a foreign hue here read
   as a clash against the vivid blue digits. */
.pr-item .n .u{color:var(--blue-400)}
.pr-item .l{margin-top:.5rem;font-size:.82rem;color:var(--stone);letter-spacing:.01em}

/* ---------- services: typographic index ---------- */
.svc-sec{padding-top:clamp(3.5rem,7vw,6rem)}
.svc-sec .head{max-width:70ch}
.svc-sec .head .sub{color:var(--ink-soft);margin-top:1rem;font-size:1rem;line-height:1.7;max-width:66ch}
.svc-aside-cta{display:flex;flex-wrap:wrap;gap:.7rem;margin-top:2rem}

/* The two specialties. Given real size, a photo each and room to explain
   themselves — the hierarchy is what does the focusing here, not the deletion
   of the other services, which are all still on the page and still linked. */
.spec-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:clamp(1.2rem,2.5vw,2rem);margin-top:clamp(2.2rem,4vw,3.2rem)}
.spec-card{display:flex;flex-direction:column;background:var(--white);border:1px solid var(--line);
  border-radius:var(--r-lg);overflow:hidden;transition:transform .25s ease,box-shadow .25s ease,border-color .25s ease}
.spec-card:hover{transform:translateY(-5px);box-shadow:var(--shadow);border-color:var(--line-dark)}
.spec-media{position:relative;display:block;overflow:hidden;background:var(--paper-2)}
.spec-media::before{content:"";display:block;padding-top:60%}   /* 5:3 */
.spec-media img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block;
  transition:transform .5s cubic-bezier(.2,.7,.2,1)}
.spec-card:hover .spec-media img{transform:scale(1.04)}
.spec-body{display:flex;flex-direction:column;flex:1;padding:clamp(1.4rem,2.4vw,1.9rem)}
.spec-eyebrow{font-family:var(--f-serif);font-size:.72rem;letter-spacing:.2em;text-transform:uppercase;
  color:var(--accent-ink);margin-bottom:.5rem}
.spec-name{font-family:var(--f-display);font-weight:700;letter-spacing:-.02em;
  font-size:clamp(1.45rem,2.6vw,1.9rem);color:var(--ink);line-height:1.1}
.spec-desc{margin-top:.7rem;color:var(--ink-soft);font-size:.98rem;line-height:1.65;flex:1}
.spec-go{display:inline-flex;align-items:center;gap:.5em;margin-top:1.2rem;font-family:var(--f-display);
  font-weight:700;font-size:.95rem;color:var(--deep)}
.spec-go svg{width:18px;height:18px;transition:transform .25s ease}
.spec-card:hover .spec-go svg{transform:translateX(4px)}

/* Everything else we do: present, linked, deliberately quieter. */
.svc-more{margin-top:clamp(2rem,3.5vw,2.8rem);border-top:1px solid var(--line);padding-top:1.6rem}
.svc-more h3{font-family:var(--f-serif);font-size:.78rem;letter-spacing:.2em;text-transform:uppercase;
  color:var(--stone);font-weight:600}
.svc-more ul{list-style:none;margin:1rem 0 0;padding:0;display:grid;grid-template-columns:repeat(3,1fr);gap:.9rem}
.svc-more a{display:block;padding:.9rem 1.1rem;border:1px solid var(--line-2);border-radius:var(--r);
  background:var(--white);transition:border-color .2s ease,transform .2s ease}
.svc-more a:hover{border-color:var(--accent);transform:translateY(-2px)}
.svc-more strong{display:block;font-family:var(--f-display);font-size:1rem;color:var(--deep)}
.svc-more span{display:block;margin-top:.2rem;color:var(--stone);font-size:.88rem;line-height:1.5}
@media(max-width:860px){.spec-grid{grid-template-columns:1fr}
  .svc-more ul{grid-template-columns:1fr}}

/* ---------- process: a real timeline ---------- */
.why-head{display:grid;grid-template-columns:1fr 1fr;gap:clamp(1.4rem,4vw,3.5rem);
  align-items:end;margin-bottom:clamp(2.6rem,5vw,4rem)}
.why-head h2{color:#fff;font-size:clamp(1.9rem,3.8vw,2.9rem);text-wrap:balance}
.timeline{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(4,1fr);
  gap:clamp(1.2rem,2.6vw,2rem);position:relative}
/* the rail the nodes sit on */
.timeline::before{content:"";position:absolute;left:0;right:0;top:calc(2.1rem + 23px);height:2px;
  background:linear-gradient(90deg,transparent,rgba(255,255,255,.28) 8%,rgba(255,255,255,.28) 92%,transparent)}
.tl-step{position:relative;padding-top:0}
.tl-day{display:block;font-family:var(--f-serif);text-transform:uppercase;letter-spacing:.16em;
  font-size:.68rem;color:var(--accent-lt);height:2.1rem}
.tl-dot{position:relative;z-index:2;width:46px;height:46px;border-radius:50%;
  display:grid;place-items:center;background:var(--blue-800);border:2px solid rgba(255,255,255,.3);
  color:var(--accent-lt);margin-bottom:1.1rem}
.tl-dot svg{width:20px;height:20px}
.tl-step h4{color:#fff;font-size:1.05rem;margin-bottom:.35rem}
.tl-step p{color:#CFD4E6;font-size:.92rem;line-height:1.6}

/* ---------- recent work: offset mosaic ---------- */
.work-sec{background:var(--paper-2)}
.work-head{display:flex;flex-wrap:wrap;gap:1.4rem;align-items:end;justify-content:space-between;
  margin-bottom:clamp(2rem,4vw,3rem)}
.work-head h2{font-size:clamp(1.7rem,3.4vw,2.4rem);max-width:20ch}
.work-mosaic{display:grid;grid-template-columns:repeat(6,1fr);gap:clamp(.7rem,1.4vw,1.1rem)}
.wm-tile{display:block;border-radius:var(--r);overflow:hidden;background:var(--white);
  border:1px solid var(--line);box-shadow:var(--shadow-sm);transition:transform .3s,box-shadow .3s}
.wm-tile img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}
.wm-tile:hover{transform:translateY(-4px);box-shadow:var(--shadow)}
/* Every gallery photo is a wide 800x300 BEFORE/AFTER composite, so each tile
   must stay near that ratio — cropping to a squarer tile would slice off half
   the comparison, which is the entire point of the photo. Rhythm therefore
   comes from varying tile WIDTH across two rows (2 large, then 3 smaller),
   never from changing the aspect ratio. */
.wm-tile{position:relative}
.wm-tile::before{content:"";display:block;padding-top:37.5%}   /* 8:3 */
.wm-tile:nth-child(1),.wm-tile:nth-child(2){grid-column:span 3}
.wm-tile:nth-child(3),.wm-tile:nth-child(4),.wm-tile:nth-child(5){grid-column:span 2}

/* ---------- responsive ---------- */
@media(max-width:1024px){
  .hero-grid{grid-template-columns:1fr;gap:2.5rem}
  .hero-proof{min-height:0;margin-top:.5rem}
  .proof-card.front{width:100%;justify-self:stretch}
  .proof-card.back{width:70%}
  .why-head{grid-template-columns:1fr;align-items:start}
}
@media(max-width:860px){
  .timeline{grid-template-columns:repeat(2,1fr);gap:2rem 1.5rem}
  .timeline::before{display:none}
  .work-mosaic{grid-template-columns:repeat(2,1fr)}
  .wm-tile:nth-child(1),.wm-tile:nth-child(2){grid-column:span 1}
  .wm-tile:nth-child(n+3){grid-column:span 1}
  .wm-tile:nth-child(5){grid-column:span 2}
}
@media(max-width:640px){
  .proof-rail{grid-template-columns:repeat(2,1fr);margin-top:-2rem}
  .pr-item{border-bottom:1px solid var(--line-2)}
  .pr-item:nth-child(2n){border-right:0}
  .pr-item:nth-child(n+3){border-bottom:0}
  .timeline{grid-template-columns:1fr}
  .work-mosaic{grid-template-columns:1fr}
  .wm-tile{grid-column:span 1 !important}
  }
