patx/voldservices

add service pages and location pages

Commit f037fe3 · patx · 2026-09-08T22:47:41-04:00

Changeset
f037fe378aed3a58c1fc1d625678c08791a54ef5
Parents
9e198090e1a77e33c434c7c98d5b5e368f6707a2

View source at this commit

Comments

No comments yet.

Log in to comment

Diff

diff --git a/docs/assets/home-hero.js b/docs/assets/home-hero.js
new file mode 100644
index 0000000..b242aa9
--- /dev/null
+++ b/docs/assets/home-hero.js
@@ -0,0 +1,232 @@
+(function () {
+'use strict';
+var reduceMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
+if (!document.getElementById('hero-sticky')) return;
+      /* ── cinematic hero scroll ────────────────────────────────
+         The section supplies the scroll distance; its sticky child remains
+         pinned while these values interpolate from the user's real scroll.
+         No scroll is captured or eased, so trackpads and touch keep their
+         native feel. */
+      var heroCinematic = document.getElementById('top');
+      var heroSticky = document.getElementById('hero-sticky');
+      var heroCue = heroSticky.querySelector('.hero-cue');
+      var heroEyebrow = heroSticky.querySelector('.hero-eyebrow');
+      var heroLead = heroSticky.querySelector('.hero-lead');
+      var heroActions = document.getElementById('hero-actions');
+      var heroMedia = heroSticky.querySelector('.hero-media');
+      var heroVideo = document.getElementById('hero-video');
+      var heroVideoReady = false;
+      var heroVideoPrimed = false;
+      var heroVideoPrimePending = false;
+      var heroTouchStarted = false;
+      var heroUsesTouch = ('ontouchstart' in window) || navigator.maxTouchPoints > 0;
+      var heroVideoVisible = false;
+      var heroVideoRevealPending = false;
+      var heroVideoProgress = 0;
+      var heroVideoObjectUrl = '';
+
+      function clamp01(value) {
+        return Math.max(0, Math.min(1, value));
+      }
+
+      function smoothstep(value) {
+        value = clamp01(value);
+        return value * value * (3 - (2 * value));
+      }
+
+      function paintReveal(element, progress, travel) {
+        element.style.opacity = progress.toFixed(4);
+        element.style.transform = 'translate3d(0,' + ((1 - progress) * travel).toFixed(2) + 'px,0)';
+      }
+
+      /* The optimized file has a seek point every three frames. Keep the
+         video paused and seek its playhead to the user's actual scroll
+         position; there is no autonomous playback or scroll hijacking. */
+      function syncHeroVideo(progress, force) {
+        heroVideoProgress = progress;
+        if (reduceMotion || !heroVideoReady || !Number.isFinite(heroVideo.duration)) return;
+
+        var usableDuration = Math.max(heroVideo.duration - (1 / 24), 0);
+        // Safari can clear the poster before it has decoded a seek at exactly
+        // zero. Start a fraction into the first frame and keep a real image
+        // beneath the video until a decoded frame has actually been painted.
+        var targetTime = Math.max(1 / 48, usableDuration * heroVideoProgress);
+        if (!force && (heroVideo.seeking || Math.abs(heroVideo.currentTime - targetTime) < (1 / 48))) return;
+        heroVideo.currentTime = targetTime;
+      }
+
+      function revealHeroVideo() {
+        if (reduceMotion || heroVideoVisible || heroVideoRevealPending || heroVideo.readyState < 2) return;
+        heroVideoRevealPending = true;
+
+        var reveal = function () {
+          heroVideoRevealPending = false;
+          if (reduceMotion || heroVideoVisible || heroVideo.readyState < 2) return;
+          heroVideoVisible = true;
+          heroMedia.classList.add('is-video-ready');
+        };
+
+        if (typeof heroVideo.requestVideoFrameCallback === 'function') {
+          heroVideo.requestVideoFrameCallback(reveal);
+          // A paused iOS video can finish seeking before a queued frame
+          // callback is delivered. By this point seeked + HAVE_CURRENT_DATA
+          // make a delayed reveal safe, while the poster covers the handoff.
+          window.setTimeout(reveal, 160);
+        } else {
+          window.requestAnimationFrame(function () {
+            window.requestAnimationFrame(reveal);
+          });
+        }
+      }
+
+      function finishHeroVideoPrime() {
+        heroVideo.pause();
+        heroVideoPrimePending = false;
+        heroVideoPrimed = true;
+        heroVideoReady = true;
+        window.removeEventListener('touchstart', primeHeroVideoFromTouch);
+        syncHeroVideo(heroVideoProgress, true);
+      }
+
+      function usePausedSeekFallback() {
+        heroVideo.pause();
+        heroVideoPrimePending = false;
+        heroVideoReady = true;
+        syncHeroVideo(heroVideoProgress, true);
+      }
+
+      // iOS may load metadata for a muted video without activating its decoder.
+      // On touch devices, a brief hidden play/pause on the first scroll touch
+      // primes frame presentation without autoplay or visible player chrome.
+      function primeHeroVideo() {
+        if (reduceMotion || heroVideoPrimed || heroVideoPrimePending || heroVideo.readyState < 1) return;
+
+        heroVideoPrimePending = true;
+        heroVideo.muted = true;
+        heroVideo.defaultMuted = true;
+
+        var playAttempt = heroVideo.play();
+        if (playAttempt && typeof playAttempt.then === 'function') {
+          playAttempt.then(finishHeroVideoPrime).catch(usePausedSeekFallback);
+        } else {
+          finishHeroVideoPrime();
+        }
+      }
+
+      function primeHeroVideoFromTouch() {
+        heroTouchStarted = true;
+        primeHeroVideo();
+      }
+
+      function prepareHeroVideo() {
+        if (!heroUsesTouch || heroTouchStarted) primeHeroVideo();
+      }
+
+      function attachHeroVideoSource(source) {
+        heroVideo.src = source;
+        heroVideo.load();
+      }
+
+      /* The origin currently serves MP4 files without byte-range responses.
+         Mobile's smaller encode can finish downloading before that becomes
+         noticeable, but desktop seeks otherwise snap back to frame zero.
+         Buffer the desktop file into a blob so its full timeline is locally
+         seekable, keeping the poster visible until the first frame is ready. */
+      function loadHeroVideo() {
+        var mobileSource = window.innerWidth <= 720;
+        var source = mobileSource
+          ? heroVideo.getAttribute('data-mobile-src')
+          : heroVideo.getAttribute('data-desktop-src');
+
+        if (mobileSource || typeof window.fetch !== 'function' || typeof window.URL.createObjectURL !== 'function') {
+          attachHeroVideoSource(source);
+          return;
+        }
+
+        window.fetch(source, { cache: 'force-cache' })
+          .then(function (response) {
+            if (!response.ok) throw new Error('Hero video request failed');
+            return response.blob();
+          })
+          .then(function (blob) {
+            heroVideoObjectUrl = window.URL.createObjectURL(blob);
+            attachHeroVideoSource(heroVideoObjectUrl);
+          })
+          .catch(function () {
+            attachHeroVideoSource(source);
+          });
+      }
+
+      if (reduceMotion) {
+        heroVideo.pause();
+      } else {
+        heroVideo.addEventListener('loadedmetadata', prepareHeroVideo);
+        if (heroUsesTouch) {
+          window.addEventListener('touchstart', primeHeroVideoFromTouch, { passive: true });
+        }
+
+        // Cached media can reach metadata before this bottom-of-page script runs.
+        if (heroVideo.readyState >= 1) prepareHeroVideo();
+
+        loadHeroVideo();
+      }
+
+      window.addEventListener('beforeunload', function () {
+        if (heroVideoObjectUrl) window.URL.revokeObjectURL(heroVideoObjectUrl);
+      });
+
+      // If the user scrolls again while a seek is being decoded, catch the
+      // playhead up to the most recent position as soon as that frame lands.
+      heroVideo.addEventListener('seeked', function () {
+        revealHeroVideo();
+        syncHeroVideo(heroVideoProgress, false);
+      });
+
+      heroVideo.addEventListener('error', function () {
+        heroVideoReady = false;
+        heroVideoPrimed = false;
+        heroVideoPrimePending = false;
+        heroVideoVisible = false;
+        heroVideoRevealPending = false;
+        heroMedia.classList.remove('is-video-ready');
+      });
+
+      function paintHeroScroll() {
+        if (reduceMotion) {
+          heroActions.inert = false;
+          heroActions.setAttribute('aria-hidden', 'false');
+          return;
+        }
+
+        var runway = Math.max(heroCinematic.offsetHeight - window.innerHeight, 1);
+        var progress = clamp01(-heroCinematic.getBoundingClientRect().top / runway);
+        syncHeroVideo(progress, false);
+        var eyebrowIn = smoothstep((progress - 0.1) / 0.15);
+        var leadIn = smoothstep((progress - 0.28) / 0.18);
+        var actionsIn = smoothstep((progress - 0.42) / 0.18);
+        var cueOut = smoothstep(progress / 0.12);
+        var scrimIn = smoothstep((progress - 0.08) / 0.42);
+
+        heroSticky.style.setProperty('--hero-media-scale', (1.03 + (0.08 * smoothstep(progress))).toFixed(4));
+        heroSticky.style.setProperty('--hero-scrim-opacity', (0.3 + (0.7 * scrimIn)).toFixed(4));
+        heroSticky.style.setProperty('--hero-cue-opacity', (1 - cueOut).toFixed(4));
+
+        paintReveal(heroEyebrow, eyebrowIn, 20);
+        paintReveal(heroLead, leadIn, 30);
+        paintReveal(heroActions, actionsIn, 24);
+
+        var cueActive = cueOut < 0.92;
+        var actionsActive = actionsIn > 0.8;
+
+        heroCue.style.pointerEvents = cueActive ? '' : 'none';
+        heroCue.inert = !cueActive;
+        heroCue.setAttribute('aria-hidden', String(!cueActive));
+        heroActions.style.pointerEvents = actionsActive ? '' : 'none';
+        heroActions.inert = !actionsActive;
+        heroActions.setAttribute('aria-hidden', String(!actionsActive));
+      }
+
+
+window.voldPaintHero = paintHeroScroll;
+})();
+
diff --git a/docs/assets/pages.css b/docs/assets/pages.css
new file mode 100644
index 0000000..90490cf
--- /dev/null
+++ b/docs/assets/pages.css
@@ -0,0 +1,55 @@
+.inner-page .nav { background: var(--ink); border-bottom-color: var(--line); }
+.page-hero { padding: 180px 0 72px; background: linear-gradient(180deg, var(--ink-2), var(--ink)); }
+.breadcrumbs { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 40px; color: var(--muted); font-family: var(--mono); font-size: .72rem; }
+.breadcrumbs a { text-decoration: none; }
+.breadcrumbs a:hover { color: var(--lift); }
+.page-hero-grid { display: grid; grid-template-columns: 1.2fr 1fr; gap: 56px; align-items: center; }
+.page-hero-copy { min-width: 0; }
+.page-hero h1 { font-size: clamp(3.5rem, 5.8vw, 6rem); }
+.page-hero h1 .accent { display: block; }
+.page-hero .lead { margin-top: 24px; }
+.page-actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 28px; }
+.page-hero-note { margin: 24px 0 0; color: var(--muted); font-family: var(--mono); font-size: .72rem; }
+.page-hero-photo { margin: 0; border: 1px solid var(--line); background: var(--ink-2); }
+.page-hero-photo img { display: block; width: 100%; height: 480px; object-fit: cover; }
+.page-hero-photo figcaption, .page-comparison figcaption { padding: 15px 18px; font-family: var(--mono); font-size: .72rem; line-height: 1.7; color: var(--muted); }
+.page-detail-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 56px; align-items: start; }
+.page-detail-grid .lead { margin: 0; }
+.page-detail-grid .area .lead { font-size: .98rem; margin-top: 16px; }
+.page-detail-grid .area h3 { font-size: 2rem; }
+.page-surface-list { display: grid !important; gap: 12px !important; margin-top: 20px !important; }
+.page-surface-list li::after { content: none; }
+.page-three-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 20px; }
+.page-two-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px; }
+.page-link { display: inline-block; color: var(--lift); font-family: var(--mono); font-size: .78rem; text-underline-offset: 5px; margin-top: 24px; }
+.page-link:hover { color: var(--bone); }
+.inner-page .service .page-link { margin-top: auto; padding-top: 24px; }
+.page-comparison { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; }
+.page-comparison figure { margin: 0; border: 1px solid var(--line); }
+.page-comparison img { width: 100%; height: 460px; object-fit: cover; display: block; }
+.page-caption { color: var(--muted); font-size: .86rem; margin: 20px 0 0; }
+.page-cities { list-style: none; padding: 0; margin: 30px 0 0; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); column-gap: 32px; }
+.page-cities li { padding: 14px 0; border-bottom: 1px solid var(--line); color: var(--bone); }
+.page-faq { max-width: 920px; }
+.page-faq details { border-top: 1px solid var(--line); }
+.page-faq details:last-child { border-bottom: 1px solid var(--line); }
+.page-faq summary { padding: 24px 6px; cursor: pointer; font-weight: 600; color: var(--bone); }
+.page-faq summary::marker { color: var(--lift); }
+.page-faq details p { max-width: 76ch; margin: 0; padding: 0 6px 24px; color: var(--muted); line-height: 1.8; }
+@media (max-width: 1000px) {
+  .page-hero-grid, .page-detail-grid { gap: 32px; }
+  .page-three-grid { grid-template-columns: 1fr; }
+  .page-hero-photo img { height: 430px; }
+}
+@media (max-width: 700px) {
+  .page-hero { padding: 150px 0 48px; }
+  .breadcrumbs { margin-bottom: 28px; font-size: .65rem; }
+  .page-hero-grid, .page-detail-grid, .page-two-grid { grid-template-columns: 1fr; }
+  .page-hero h1 { font-size: clamp(3rem, 12vw, 4.6rem); }
+  .page-hero-photo img { height: 340px; }
+  .page-actions .btn { flex: 1 1 auto; }
+  .page-comparison { gap: 12px; }
+  .page-comparison img { height: 260px; }
+  .page-comparison figcaption { padding: 12px; font-size: .65rem; }
+  .page-cities { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 20px; }
+}
diff --git a/docs/assets/site.css b/docs/assets/site.css
new file mode 100644
index 0000000..1692691
--- /dev/null
+++ b/docs/assets/site.css
@@ -0,0 +1,1361 @@
+
+    /* True charcoal and concrete neutrals, with the logo blue reserved
+       for actions and small highlights rather than page backgrounds. */
+    :root {
+      --ink:        #080808;
+      --ink-2:      #10100f;
+      --ink-3:      #181816;
+      --brand:      #078ed1;
+      --brand-deep: #056ca1;
+      --lift:       #58bdec;
+      --spray:      #c9efff;
+      --bone:       #f2f0e9;
+      --muted:      #aaa89f;
+      --muted-dim:  #77766f;
+
+      --line:       rgba(242, 240, 233, 0.17);
+      --line-soft:  rgba(242, 240, 233, 0.08);
+      --panel:      rgba(255, 255, 255, 0.035);
+
+      --display: "Teko", Impact, sans-serif;
+      --body:    "Manrope", system-ui, sans-serif;
+      --mono:    "Roboto Mono", ui-monospace, monospace;
+
+      --gutter: clamp(20px, 4vw, 44px);
+      --wrap:   1240px;
+      --nav-h:  76px;
+    }
+
+    /* ── base ───────────────────────────────────────────────────── */
+    *, *::before, *::after { box-sizing: border-box; }
+
+    html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }
+
+    body {
+      margin: 0;
+      background: var(--ink);
+      color: var(--bone);
+      font-family: var(--body);
+      font-size: 16px;
+      line-height: 1.65;
+      overflow-x: hidden;
+      -webkit-font-smoothing: antialiased;
+    }
+
+    img, video { max-width: 100%; display: block; }
+    a { color: inherit; }
+
+    :focus-visible {
+      outline: 2px solid var(--lift);
+      outline-offset: 3px;
+      border-radius: 2px;
+    }
+
+    .skip-link {
+      position: absolute;
+      left: 12px;
+      top: -60px;
+      z-index: 200;
+      background: var(--brand);
+      color: #fff;
+      padding: 12px 18px;
+      font-family: var(--mono);
+      font-size: .8rem;
+      text-decoration: none;
+      transition: top .18s ease;
+    }
+    .skip-link:focus { top: 12px; }
+
+    .wrap {
+      width: min(var(--wrap), 100% - (var(--gutter) * 2));
+      margin-inline: auto;
+    }
+
+    /* Section rhythm. The hairline at the top of each band is the
+       "wand pass" — the same gesture as the before/after handle. */
+    .band {
+      position: relative;
+      padding: clamp(76px, 9.5vw, 132px) 0;
+      /* Anchor jumps clear the fixed nav instead of landing behind it. The
+         logo can push the bar past --nav-h on wide screens, so leave slack. */
+      scroll-margin-top: calc(var(--nav-h) + 24px);
+    }
+    .band::before {
+      content: "";
+      position: absolute;
+      inset: 0 0 auto 0;
+      height: 1px;
+      background: var(--line);
+    }
+    .band--tinted { background: linear-gradient(180deg, var(--ink-2), var(--ink)); }
+    .band--flush::before { display: none; }
+
+    /* ── type ───────────────────────────────────────────────────── */
+    .eyebrow {
+      font-family: var(--mono);
+      font-size: .74rem;
+      letter-spacing: .2em;
+      text-transform: uppercase;
+      color: var(--lift);
+      margin: 0 0 18px;
+      display: flex;
+      align-items: center;
+      gap: 12px;
+    }
+    .eyebrow::before {
+      content: "";
+      width: 26px;
+      height: 1px;
+      background: var(--brand);
+      flex: 0 0 auto;
+    }
+
+    h1, h2, h3, h4 {
+      font-family: var(--display);
+      font-weight: 600;
+      letter-spacing: -.015em;
+      line-height: .88;
+      text-transform: uppercase;
+      margin: 0;
+      text-wrap: balance;
+    }
+
+    h1 { font-size: clamp(4.2rem, 9.3vw, 8.4rem); }
+    .h2 { font-size: clamp(3.1rem, 6vw, 5.4rem); }
+    .h3 { font-size: clamp(1.85rem, 2.8vw, 2.35rem); letter-spacing: -.01em; }
+
+    .accent { color: var(--lift); }
+
+    .lead {
+      max-width: 60ch;
+      margin: 22px 0 0;
+      color: var(--muted);
+      font-size: clamp(1rem, 1.25vw, 1.14rem);
+      line-height: 1.72;
+    }
+    .lead strong { color: var(--bone); font-weight: 600; }
+
+    .section-head { max-width: 780px; }
+    .section-head .lead { margin-top: 20px; }
+
+    /* ── buttons ────────────────────────────────────────────────── */
+    .btn {
+      display: inline-flex;
+      align-items: center;
+      justify-content: center;
+      gap: 10px;
+      min-height: 52px;
+      padding: 0 26px;
+      border: 1px solid transparent;
+      border-radius: 0;
+      font-family: var(--display);
+      font-weight: 700;
+      font-size: .88rem;
+      letter-spacing: .06em;
+      text-transform: uppercase;
+      text-decoration: none;
+      cursor: pointer;
+      white-space: nowrap;
+      transition: background .18s ease, border-color .18s ease, color .18s ease, transform .18s ease;
+    }
+    .btn:hover { transform: translateY(-1px); }
+    .btn:active { transform: translateY(0); }
+
+    .btn--primary { background: var(--brand); color: #fff; }
+    .btn--primary:hover { background: var(--lift); color: var(--ink); }
+
+    .btn--ghost {
+      border-color: rgba(242, 240, 233, .32);
+      color: var(--bone);
+      background: rgba(8, 8, 8, .4);
+    }
+    .btn--ghost:hover { border-color: var(--lift); background: rgba(7, 142, 209, .12); }
+
+    .btn--block { width: 100%; }
+
+    .btn-row {
+      display: flex;
+      flex-wrap: wrap;
+      gap: 14px;
+      margin-top: 34px;
+    }
+
+    /* ── nav ────────────────────────────────────────────────────── */
+    .nav {
+      position: fixed;
+      inset: 0 0 auto 0;
+      z-index: 90;
+      background: transparent;
+      border-bottom: 1px solid transparent;
+      transition: background .28s ease, border-color .28s ease;
+    }
+    .nav.is-stuck {
+      background: var(--ink);
+      border-bottom-color: var(--line);
+    }
+    /* Opaque, not near-opaque: the open menu sits over page content and any
+       alpha at all lets the hero read through it. */
+    .nav.is-open { background: var(--ink); }
+
+    .nav-inner {
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      gap: 20px;
+      min-height: var(--nav-live-height, clamp(112px, 12vh, 138px));
+    }
+
+    .brand { display: inline-flex; align-items: center; flex: 0 0 auto; }
+    .brand img { width: var(--nav-live-logo, clamp(230px, 24vw, 310px)); height: auto; }
+
+    .nav-links {
+      position: absolute;
+      top: 100%;
+      right: var(--gutter);
+      display: none;
+      width: min(360px, calc(100vw - 40px));
+      flex-direction: column;
+      align-items: stretch;
+      gap: 0;
+      padding: 9px 20px 20px;
+      font-family: var(--mono);
+      font-size: .86rem;
+      letter-spacing: .06em;
+      background: var(--ink);
+      border: 1px solid var(--line);
+      border-top: 0;
+      box-shadow: 0 22px 48px rgba(0, 0, 0, .38);
+    }
+    .nav.is-open .nav-links { display: flex; }
+    .nav-links a {
+      position: relative;
+      color: var(--muted);
+      text-decoration: none;
+      padding: 15px 4px;
+      border-bottom: 1px solid var(--line-soft);
+      transition: color .18s ease;
+    }
+    .nav-links a:last-child { border-bottom: 0; }
+    .nav-links a::after {
+      content: "";
+      position: absolute;
+      left: 0;
+      bottom: 0;
+      width: 100%;
+      height: 1px;
+      background: var(--lift);
+      transform: scaleX(0);
+      transform-origin: left;
+      transition: transform .22s ease;
+    }
+    .nav-links a:hover, .nav-links a.is-current { color: var(--bone); }
+    .nav-links a::after { display: none; }
+
+    .nav-actions {
+      display: flex;
+      align-items: center;
+      justify-content: flex-end;
+      gap: 10px;
+      flex: 0 0 auto;
+    }
+    .nav-call {
+      display: inline-flex;
+      align-items: center;
+      gap: 9px;
+      background: var(--brand);
+      color: #fff;
+      font-family: var(--display);
+      font-weight: 700;
+      font-size: var(--nav-live-call-font, 1rem);
+      letter-spacing: .02em;
+      text-decoration: none;
+      padding: var(--nav-live-call-y, 14px) var(--nav-live-call-x, 22px);
+      border-radius: 0;
+      flex: 0 0 auto;
+      white-space: nowrap;
+      transition: background .18s ease;
+    }
+    .nav-call:hover { background: var(--lift); color: var(--ink); }
+    .nav-call svg {
+      width: var(--nav-live-icon, 18px);
+      height: var(--nav-live-icon, 18px);
+      flex: 0 0 auto;
+    }
+
+    .nav-toggle {
+      display: inline-flex;
+      width: 46px;
+      height: 46px;
+      padding: 0;
+      border: 1px solid var(--line);
+      background: rgba(255, 255, 255, .04);
+      color: var(--bone);
+      cursor: pointer;
+      border-radius: 3px;
+      align-items: center;
+      justify-content: center;
+      flex-direction: column;
+      gap: 5px;
+    }
+    .nav-toggle span {
+      display: block;
+      width: 19px;
+      height: 1.5px;
+      background: currentColor;
+      transition: transform .22s ease, opacity .22s ease;
+    }
+    .nav-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(6.5px) rotate(45deg); }
+    .nav-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
+    .nav-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-6.5px) rotate(-45deg); }
+
+    .nav-progress {
+      position: absolute;
+      left: 0;
+      bottom: -1px;
+      height: 2px;
+      width: 100%;
+      transform: scaleX(0);
+      transform-origin: left;
+      background: linear-gradient(90deg, var(--brand), var(--spray));
+      opacity: 0;
+      transition: opacity .3s ease;
+    }
+    .nav.is-stuck .nav-progress { opacity: 1; }
+
+    /* ── hero ─────────────────────────────────────────────────────
+       The footage and service headline are present from the first frame.
+       Scrolling advances the footage and stages in the supporting message.
+       ───────────────────────────────────────────────────────────── */
+    .hero {
+      position: relative;
+      isolation: isolate;
+      height: 300vh;
+      height: 300svh;
+      scroll-margin-top: var(--nav-h);
+    }
+
+    .hero-sticky {
+      --hero-media-scale: 1.03;
+      --hero-scrim-opacity: .3;
+      --hero-cue-opacity: 1;
+      position: sticky;
+      top: 0;
+      display: grid;
+      align-items: center;
+      width: 100%;
+      height: 100vh;
+      height: 100svh;
+      min-height: 100vh;
+      min-height: 100svh;
+      padding-top: calc(var(--nav-h) + clamp(40px, 7vh, 88px));
+      padding-bottom: clamp(64px, 10vh, 120px);
+      overflow: hidden;
+      background: var(--ink);
+    }
+
+    .hero-media {
+      position: absolute;
+      inset: 0;
+      z-index: 0;
+      overflow: hidden;
+      background: var(--ink);
+    }
+    .hero-media video,
+    .hero-media img.hero-fallback {
+      position: absolute;
+      inset: 0;
+      display: block;
+      width: 100%;
+      height: 100%;
+      object-fit: cover;
+      object-position: center 52%;
+      filter: saturate(1.04) contrast(1.03) brightness(.94);
+      transform: scale(var(--hero-media-scale));
+      transform-origin: center 52%;
+      will-change: transform;
+    }
+    .hero-media img.hero-fallback { z-index: 0; }
+    .hero-media video {
+      z-index: 1;
+      opacity: 0;
+      pointer-events: none;
+      transition: opacity .18s ease-out;
+    }
+    .hero-media.is-video-ready video { opacity: 1; }
+    .hero-media video::-webkit-media-controls,
+    .hero-media video::-webkit-media-controls-panel,
+    .hero-media video::-webkit-media-controls-play-button,
+    .hero-media video::-webkit-media-controls-start-playback-button {
+      display: none !important;
+      -webkit-appearance: none;
+      opacity: 0;
+      pointer-events: none;
+    }
+    .hero-media::after {
+      content: "";
+      position: absolute;
+      inset: 0;
+      z-index: 2;
+      pointer-events: none;
+      background:
+        linear-gradient(90deg, rgba(8, 8, 8, .94) 0%, rgba(8, 8, 8, .62) 43%, rgba(8, 8, 8, .06) 74%),
+        linear-gradient(180deg, rgba(8, 8, 8, .55), transparent 28%, rgba(8, 8, 8, .38) 76%, rgba(8, 8, 8, .82));
+      opacity: var(--hero-scrim-opacity);
+    }
+
+    .hero-grain {
+      position: absolute;
+      inset: 0;
+      z-index: 2;
+      pointer-events: none;
+      opacity: .2;
+      mix-blend-mode: overlay;
+      background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='.5'/%3E%3C/svg%3E");
+    }
+
+    .hero-inner {
+      position: relative;
+      z-index: 3;
+      width: min(66%, 820px);
+    }
+    .hero h1 {
+      max-width: none;
+      font-size: clamp(4.2rem, 7.45vw, 7.1rem);
+    }
+    .hero-title-line {
+      display: block;
+      overflow: hidden;
+      white-space: nowrap;
+    }
+    .hero-title-inner {
+      display: block;
+      opacity: 1;
+      transform: translate3d(0, 0, 0);
+      will-change: transform, opacity;
+    }
+    .hero .lead { max-width: 48ch; margin-top: 26px; }
+
+    .hero-inner .eyebrow,
+    .hero h1,
+    .hero .lead { text-shadow: 0 2px 26px rgba(0, 0, 0, .7); }
+
+    .hero-eyebrow,
+    .hero-lead,
+    .hero-primary-actions {
+      opacity: 1;
+      transform: translate3d(0, 0, 0);
+      will-change: transform, opacity;
+    }
+
+    .hero-cue {
+      position: absolute;
+      z-index: 3;
+      left: 50%;
+      bottom: 26px;
+      transform: translateX(-50%);
+      display: flex;
+      align-items: center;
+      gap: 10px;
+      font-family: var(--mono);
+      font-size: .68rem;
+      letter-spacing: .18em;
+      text-transform: uppercase;
+      color: var(--muted-dim);
+      text-decoration: none;
+      opacity: var(--hero-cue-opacity);
+      transition: color .2s ease;
+    }
+    .hero-cue:hover { color: var(--spray); }
+    .hero-cue::after {
+      content: "";
+      width: 8px;
+      height: 8px;
+      border-right: 1px solid currentColor;
+      border-bottom: 1px solid currentColor;
+      transform: rotate(45deg) translate(-2px, -2px);
+    }
+
+    /* ── credential strip ───────────────────────────────────────── */
+    .strip {
+      border-block: 1px solid var(--line-soft);
+      background: #0d0d0c;
+    }
+    .strip-viewport { overflow: hidden; }
+    .strip-inner {
+      display: flex;
+      align-items: center;
+      padding: 17px 0;
+      font-family: var(--mono);
+      font-size: .74rem;
+      letter-spacing: .09em;
+      text-transform: uppercase;
+      color: var(--muted-dim);
+    }
+    .strip-group {
+      display: flex;
+      flex-wrap: wrap;
+      align-items: center;
+      justify-content: space-between;
+      gap: 14px 30px;
+      width: 100%;
+    }
+    .strip-group--clone { display: none; }
+    .strip-inner span { display: inline-flex; align-items: center; gap: 9px; }
+    .strip-inner span::before {
+      content: "";
+      width: 5px;
+      height: 5px;
+      border-radius: 50%;
+      background: var(--brand);
+      flex: 0 0 auto;
+    }
+    .strip-inner a { color: var(--bone); text-decoration: none; }
+    .strip-inner a:hover { color: var(--lift); }
+    @keyframes credential-ticker {
+      to { transform: translate3d(-50%, 0, 0); }
+    }
+
+    /* ── services ───────────────────────────────────────────────── */
+    .service-grid {
+      display: grid;
+      grid-template-columns: repeat(2, minmax(0, 1fr));
+      gap: 18px;
+      margin-top: 52px;
+    }
+    .service {
+      position: relative;
+      display: flex;
+      flex-direction: column;
+      padding: 32px 30px 30px;
+      border: 1px solid var(--line);
+      border-radius: 0;
+      background: var(--panel);
+      overflow: hidden;
+      transition: border-color .24s ease, transform .24s ease;
+    }
+    .service:hover { border-color: rgba(88, 189, 236, .44); transform: translateY(-3px); }
+    .service::before {
+      content: "";
+      position: absolute;
+      inset: 0 0 auto 0;
+      height: 2px;
+      background: var(--tint, var(--brand));
+      opacity: .85;
+    }
+    .service--wash  { --tint: var(--brand); }
+    .service--seal  { --tint: var(--brand); }
+    .service--repair { --tint: var(--brand); }
+    .service--roof  { --tint: var(--brand); }
+
+    .service-icon {
+      width: 42px;
+      height: 42px;
+      margin-bottom: 22px;
+      color: var(--lift);
+    }
+    .service--seal .service-icon,
+    .service--repair .service-icon,
+    .service--roof .service-icon { color: var(--lift); }
+    .service-icon svg { width: 100%; height: 100%; }
+
+    .service h3 { margin-bottom: 12px; }
+    .service p {
+      margin: 0;
+      color: var(--muted);
+      font-size: .96rem;
+      line-height: 1.7;
+    }
+    .service-list {
+      margin: 22px 0 0;
+      padding: 20px 0 0;
+      border-top: 1px solid var(--line-soft);
+      list-style: none;
+      display: grid;
+      gap: 9px;
+      font-family: var(--mono);
+      font-size: .78rem;
+      color: var(--muted-dim);
+    }
+    .service-list li { display: flex; gap: 10px; align-items: flex-start; }
+    .service-list li::before { content: "—"; color: var(--brand); flex: 0 0 auto; }
+
+    /* ─────────────────────────────────────────────────────────────
+       Signature: the wand line. A drag reveals the cleaned surface
+       behind a lit seam — the same edge you see on a real job.
+       A range input drives it so keyboard and screen readers work.
+       ───────────────────────────────────────────────────────────── */
+    .results-head { max-width: 780px; }
+    .results-head .lead { max-width: 56ch; }
+    .wand-comparisons {
+      display: grid;
+      grid-template-columns: repeat(2, minmax(0, 1fr));
+      gap: 20px;
+      margin-top: 50px;
+    }
+    .wand-project {
+      margin: 0;
+      border: 1px solid var(--line);
+      background: var(--panel);
+      overflow: hidden;
+    }
+
+    .wand {
+      --pos: 50%;
+      position: relative;
+      /* Matches the source photos (746×829) so nothing important is cropped.
+         width must be definite, or the max-height resolves through the ratio
+         and shrinks the box horizontally instead of cropping it. */
+      width: 100%;
+      aspect-ratio: 746 / 829;
+      max-height: min(76vh, 700px);
+      border: 1px solid var(--line);
+      border-radius: 4px;
+      overflow: hidden;
+      background: var(--ink-2);
+      touch-action: pan-y;
+    }
+    .wand-layer { position: absolute; inset: 0; }
+    .wand-layer img { width: 100%; height: 100%; object-fit: cover; }
+    /* Before stays on the left; the cleaned surface occupies the right. */
+    .wand-layer--after { clip-path: inset(0 0 0 var(--pos)); }
+
+    .wand-seam {
+      position: absolute;
+      top: 0;
+      bottom: 0;
+      left: var(--pos);
+      width: 2px;
+      margin-left: -1px;
+      background: linear-gradient(180deg, rgba(184, 236, 255, .35), var(--spray) 42%, rgba(184, 236, 255, .35));
+      box-shadow: 0 0 18px 3px rgba(184, 236, 255, .5);
+      pointer-events: none;
+    }
+    /* Fan of spray thrown just ahead of the seam. */
+    .wand-seam::before {
+      content: "";
+      position: absolute;
+      top: 0;
+      bottom: 0;
+      left: 1px;
+      width: 66px;
+      background: linear-gradient(90deg, rgba(184, 236, 255, .3), transparent 78%);
+      pointer-events: none;
+    }
+
+    .wand-handle {
+      position: absolute;
+      top: 50%;
+      left: var(--pos);
+      transform: translate(-50%, -50%);
+      width: 52px;
+      height: 52px;
+      border-radius: 50%;
+      background: var(--spray);
+      color: var(--ink);
+      display: grid;
+      place-items: center;
+      box-shadow: 0 6px 26px rgba(0, 0, 0, .48), 0 0 0 1px rgba(255, 255, 255, .5) inset;
+      pointer-events: none;
+    }
+    .wand-handle svg { width: 24px; height: 24px; }
+
+    .wand-range {
+      position: absolute;
+      inset: 0;
+      width: 100%;
+      height: 100%;
+      margin: 0;
+      opacity: 0;
+      cursor: ew-resize;
+      -webkit-appearance: none;
+      appearance: none;
+      background: transparent;
+    }
+    .wand-range::-webkit-slider-thumb {
+      -webkit-appearance: none;
+      width: 58px;
+      height: 100%;
+      cursor: ew-resize;
+    }
+    .wand-range::-moz-range-thumb {
+      width: 58px;
+      height: 100%;
+      border: 0;
+      border-radius: 0;
+      cursor: ew-resize;
+    }
+    .wand-range:focus-visible ~ .wand-handle {
+      outline: 2px solid var(--lift);
+      outline-offset: 4px;
+    }
+
+    .wand-tag {
+      position: absolute;
+      top: 14px;
+      z-index: 2;
+      font-family: var(--mono);
+      font-size: .7rem;
+      letter-spacing: .16em;
+      text-transform: uppercase;
+      padding: 6px 12px;
+      border-radius: 999px;
+      background: rgba(8, 8, 8, .82);
+      backdrop-filter: blur(6px);
+      pointer-events: none;
+    }
+    .wand-tag--before { left: 14px; color: var(--muted); border: 1px solid var(--line); }
+    .wand-tag--after  { right: 14px; color: var(--spray); border: 1px solid rgba(184, 236, 255, .34); }
+    .wand-project .wand {
+      max-height: none;
+      border: 0;
+      border-radius: 0;
+    }
+
+    /* ── work gallery ───────────────────────────────────────────── */
+    .work-heading {
+      display: flex;
+      align-items: flex-end;
+      justify-content: space-between;
+      gap: 32px;
+    }
+    .work-instagram {
+      display: inline-flex;
+      align-items: center;
+      gap: 9px;
+      flex: 0 0 auto;
+      margin-bottom: 7px;
+      padding-bottom: 5px;
+      border-bottom: 1px solid rgba(88, 189, 236, .42);
+      color: var(--lift);
+      font-family: var(--mono);
+      font-size: .75rem;
+      letter-spacing: .08em;
+      text-decoration: none;
+      text-transform: uppercase;
+    }
+    .work-instagram svg { width: 15px; height: 15px; }
+    .work-instagram:hover { color: var(--bone); border-bottom-color: var(--bone); }
+    .work-grid {
+      display: grid;
+      grid-template-columns: repeat(3, minmax(0, 1fr));
+      gap: 14px;
+      margin-top: 50px;
+    }
+    .work-tile {
+      position: relative;
+      aspect-ratio: 746 / 829;
+      padding: 0;
+      border: 1px solid var(--line-soft);
+      border-radius: 4px;
+      overflow: hidden;
+      background: var(--ink-2);
+      cursor: zoom-in;
+      color: inherit;
+      text-align: left;
+      display: block;
+    }
+    .work-tile img {
+      width: 100%;
+      height: 100%;
+      object-fit: cover;
+      transition: transform .5s ease;
+    }
+    .work-tile:hover img { transform: scale(1.05); }
+    .work-tile::after {
+      content: "";
+      position: absolute;
+      inset: 0;
+      background: linear-gradient(180deg, transparent 42%, rgba(8, 8, 8, .9));
+    }
+    .work-cap {
+      position: absolute;
+      left: 18px;
+      bottom: 15px;
+      z-index: 2;
+    }
+    .work-cap b {
+      display: block;
+      font-family: var(--display);
+      font-weight: 700;
+      font-size: 1rem;
+      letter-spacing: -.01em;
+    }
+    .work-cap span {
+      display: block;
+      font-family: var(--mono);
+      font-size: .7rem;
+      letter-spacing: .08em;
+      color: var(--lift);
+      text-transform: uppercase;
+      margin-top: 2px;
+    }
+
+    /* ── service areas ──────────────────────────────────────────── */
+    .areas-grid {
+      display: grid;
+      grid-template-columns: 1.35fr 1fr 1fr;
+      gap: 20px;
+      margin-top: 50px;
+      align-items: start;
+    }
+    .area {
+      padding: 30px 28px;
+      border: 1px solid var(--line);
+      border-radius: 4px;
+      background: linear-gradient(180deg, var(--panel), transparent);
+    }
+    .area--primary { border-color: rgba(7, 142, 209, .42); }
+    .area h3 { font-size: 1.24rem; margin-bottom: 6px; }
+    .area-note {
+      font-family: var(--mono);
+      font-size: .72rem;
+      letter-spacing: .08em;
+      text-transform: uppercase;
+      color: var(--lift);
+      margin: 0 0 18px;
+    }
+    .area ul {
+      margin: 0;
+      padding: 0;
+      list-style: none;
+      display: flex;
+      flex-wrap: wrap;
+      gap: 6px 8px;
+      font-size: .87rem;
+      color: var(--muted);
+    }
+    .area li::after { content: " ·"; color: var(--muted-dim); }
+    .area li:last-child::after { content: ""; }
+
+    /* ── reviews ────────────────────────────────────────────────── */
+    .reviews {
+      display: grid;
+      grid-template-columns: repeat(3, minmax(0, 1fr));
+      gap: 18px;
+      margin-top: 50px;
+    }
+    .review {
+      margin: 0;
+      padding: 30px 28px;
+      border: 1px solid var(--line);
+      border-radius: 4px;
+      background: var(--panel);
+      display: flex;
+      flex-direction: column;
+    }
+    .review blockquote {
+      margin: 0 0 22px;
+      font-size: 1rem;
+      line-height: 1.72;
+      color: var(--bone);
+    }
+    .review figcaption {
+      margin-top: auto;
+      padding-top: 18px;
+      border-top: 1px solid var(--line-soft);
+      font-family: var(--mono);
+      font-size: .76rem;
+      color: var(--muted-dim);
+      letter-spacing: .04em;
+    }
+    .stars { color: var(--lift); letter-spacing: .18em; margin-bottom: 14px; font-size: .84rem; }
+
+    .placeholder-note {
+      margin-top: 22px;
+      font-family: var(--mono);
+      font-size: .74rem;
+      color: var(--muted-dim);
+      border-left: 2px solid var(--brand);
+      padding-left: 14px;
+    }
+
+    /* ── quote ──────────────────────────────────────────────────── */
+    .quote-grid {
+      display: grid;
+      grid-template-columns: .82fr 1.18fr;
+      gap: 26px;
+      margin-top: 50px;
+      align-items: start;
+    }
+    .quote-side, .quote-form, .form-success {
+      border: 1px solid var(--line);
+      border-radius: 4px;
+      padding: 32px 30px;
+      background: var(--panel);
+    }
+    .quote-side { background: linear-gradient(180deg, rgba(7, 142, 209, .11), var(--panel) 46%); }
+
+    .quote-row { padding: 20px 0; border-top: 1px solid var(--line-soft); }
+    .quote-row:first-of-type { border-top: 0; padding-top: 0; }
+    .quote-label {
+      font-family: var(--mono);
+      font-size: .72rem;
+      letter-spacing: .14em;
+      text-transform: uppercase;
+      color: var(--lift);
+      margin-bottom: 7px;
+    }
+    .quote-value { color: var(--bone); text-decoration: none; font-size: .97rem; }
+    a.quote-value:hover { color: var(--lift); }
+    .quote-phone {
+      font-family: var(--display);
+      font-weight: 800;
+      font-size: clamp(1.6rem, 3vw, 2rem);
+      letter-spacing: -.02em;
+      text-decoration: none;
+      display: inline-block;
+    }
+    .quote-phone:hover { color: var(--lift); }
+
+    .social-links {
+      display: flex;
+      flex-wrap: wrap;
+      gap: 10px;
+    }
+    .social-link {
+      display: inline-flex;
+      align-items: center;
+      justify-content: center;
+      width: 44px;
+      height: 44px;
+      border: 1px solid var(--line);
+      border-radius: 3px;
+      color: var(--muted);
+      background: rgba(8, 8, 8, .28);
+      text-decoration: none;
+      transition: color .18s ease, border-color .18s ease, background .18s ease, transform .18s ease;
+    }
+    .social-link svg { width: 19px; height: 19px; }
+    .social-link:hover {
+      color: #fff;
+      border-color: var(--brand);
+      background: var(--brand);
+      transform: translateY(-2px);
+    }
+
+    .quote-form-wrap { min-width: 0; }
+    .quote-form { display: grid; gap: 18px; }
+    .quote-form[hidden], .form-success[hidden], .form-error[hidden] { display: none; }
+    .field-row {
+      display: grid;
+      grid-template-columns: repeat(2, minmax(0, 1fr));
+      gap: 18px;
+    }
+    .field label {
+      display: block;
+      margin-bottom: 7px;
+      font-family: var(--mono);
+      font-size: .72rem;
+      letter-spacing: .1em;
+      text-transform: uppercase;
+      color: var(--muted-dim);
+    }
+    .field input, .field select, .field textarea {
+      width: 100%;
+      padding: 13px 14px;
+      border: 1px solid var(--line);
+      border-radius: 3px;
+      background: rgba(8, 8, 8, .64);
+      color: var(--bone);
+      font: inherit;
+      font-size: .95rem;
+      transition: border-color .18s ease, background .18s ease;
+    }
+    .field input::placeholder, .field textarea::placeholder { color: var(--muted-dim); }
+    .field input:focus, .field select:focus, .field textarea:focus {
+      outline: none;
+      border-color: var(--lift);
+      background: rgba(7, 142, 209, .08);
+    }
+    .field select option { background: var(--ink-2); color: var(--bone); }
+    .field textarea { min-height: 122px; resize: vertical; }
+
+    .field input.photo-input {
+      position: absolute;
+      width: 1px;
+      height: 1px;
+      padding: 0;
+      margin: -1px;
+      overflow: hidden;
+      clip: rect(0, 0, 0, 0);
+      white-space: nowrap;
+      border: 0;
+    }
+    .field .photo-picker {
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      gap: 14px;
+      min-height: 54px;
+      margin: 0;
+      padding: 8px 10px 8px 8px;
+      border: 1px solid var(--line);
+      border-radius: 3px;
+      background: rgba(8, 8, 8, .64);
+      color: var(--muted);
+      font-family: inherit;
+      font-size: .78rem;
+      letter-spacing: 0;
+      text-transform: none;
+      cursor: pointer;
+      transition: border-color .18s ease, background .18s ease;
+    }
+    .photo-picker__action {
+      display: inline-grid;
+      place-items: center;
+      min-height: 38px;
+      padding: 0 15px;
+      border: 1px solid var(--line);
+      border-radius: 2px;
+      background: rgba(7, 142, 209, .14);
+      color: var(--bone);
+      font-family: var(--mono);
+      font-size: .72rem;
+      letter-spacing: .08em;
+      text-transform: uppercase;
+      transition: border-color .18s ease, background .18s ease, color .18s ease;
+    }
+    .photo-picker__note { text-align: right; }
+    .field .photo-picker:hover,
+    .field .photo-input:focus-visible + .photo-picker {
+      border-color: var(--lift);
+      background: rgba(7, 142, 209, .08);
+    }
+    .field .photo-picker:hover .photo-picker__action,
+    .field .photo-input:focus-visible + .photo-picker .photo-picker__action {
+      border-color: var(--lift);
+      background: var(--brand);
+      color: #fff;
+    }
+    .field .photo-input:focus-visible + .photo-picker {
+      outline: 2px solid var(--lift);
+      outline-offset: 2px;
+    }
+    .field-help, .photo-status {
+      margin: 7px 0 0;
+      font-family: var(--mono);
+      font-size: .7rem;
+      line-height: 1.55;
+      color: var(--muted-dim);
+    }
+    .photo-status:not(:empty) { color: var(--muted); }
+    .photo-list {
+      display: grid;
+      gap: 6px;
+      margin: 9px 0 0;
+      padding: 0;
+      list-style: none;
+    }
+    .photo-list[hidden] { display: none; }
+    .photo-item {
+      display: grid;
+      grid-template-columns: minmax(0, 1fr) auto;
+      align-items: center;
+      gap: 12px;
+      padding: 9px 10px 9px 12px;
+      border-left: 2px solid var(--brand);
+      border-radius: 2px;
+      background: rgba(255, 255, 255, .035);
+    }
+    .photo-file { min-width: 0; }
+    .photo-name {
+      display: block;
+      overflow: hidden;
+      color: var(--bone);
+      font-size: .82rem;
+      text-overflow: ellipsis;
+      white-space: nowrap;
+    }
+    .photo-size {
+      display: block;
+      margin-top: 2px;
+      color: var(--muted-dim);
+      font-family: var(--mono);
+      font-size: .65rem;
+      letter-spacing: .06em;
+      text-transform: uppercase;
+    }
+    .photo-remove {
+      padding: 6px 8px;
+      border: 1px solid transparent;
+      border-radius: 2px;
+      background: transparent;
+      color: var(--muted);
+      font-family: var(--mono);
+      font-size: .66rem;
+      letter-spacing: .07em;
+      text-transform: uppercase;
+      cursor: pointer;
+    }
+    .photo-remove:hover, .photo-remove:focus-visible {
+      border-color: rgba(255, 132, 111, .55);
+      color: #ffd8d1;
+      outline: none;
+    }
+
+    .form-note {
+      font-family: var(--mono);
+      font-size: .72rem;
+      color: var(--muted-dim);
+      margin: 0;
+    }
+    .form-error {
+      padding: 12px 14px;
+      border: 1px solid rgba(255, 132, 111, .55);
+      border-radius: 3px;
+      background: rgba(141, 42, 26, .18);
+      color: #ffd8d1;
+      font-size: .84rem;
+      line-height: 1.55;
+    }
+    .quote-form[aria-busy="true"] .btn { cursor: wait; }
+    .quote-form .btn:disabled {
+      opacity: .68;
+      transform: none;
+    }
+    .form-success {
+      min-height: 410px;
+      align-items: flex-start;
+      justify-content: center;
+      background:
+        linear-gradient(135deg, rgba(7, 142, 209, .18), transparent 58%),
+        var(--panel);
+    }
+    .form-success:not([hidden]) { display: flex; }
+    .success-mark {
+      display: grid;
+      place-items: center;
+      width: 54px;
+      height: 54px;
+      margin-bottom: 26px;
+      border: 1px solid rgba(88, 189, 236, .6);
+      border-radius: 50%;
+      color: var(--lift);
+      background: rgba(7, 142, 209, .14);
+    }
+    .success-mark svg { width: 25px; height: 25px; }
+    .form-success .eyebrow { margin-bottom: 17px; }
+    .form-success h3 { font-size: clamp(2.3rem, 5vw, 4rem); }
+    .form-success p {
+      max-width: 46ch;
+      margin: 20px 0 0;
+      color: var(--muted);
+    }
+    .form-success .quote-value {
+      display: inline-block;
+      margin-top: 22px;
+      color: var(--lift);
+      font-family: var(--mono);
+      font-size: .76rem;
+    }
+
+    /* ── footer ─────────────────────────────────────────────────── */
+    .footer {
+      border-top: 1px solid var(--line);
+      padding: 52px 0 40px;
+      background: var(--ink-2);
+    }
+    .footer-inner {
+      display: grid;
+      grid-template-columns: 1.4fr 1fr 1fr;
+      gap: 34px;
+    }
+    .footer img { width: 168px; margin-bottom: 18px; }
+    .footer p { margin: 0; color: var(--muted-dim); font-size: .9rem; max-width: 42ch; }
+    .footer .social-links { margin-top: 22px; }
+    .footer .social-link { width: 38px; height: 38px; }
+    .footer .social-link svg { width: 17px; height: 17px; }
+    .footer h4 {
+      font-size: .8rem;
+      font-family: var(--mono);
+      font-weight: 500;
+      letter-spacing: .14em;
+      text-transform: uppercase;
+      color: var(--lift);
+      margin-bottom: 14px;
+    }
+    .footer ul { margin: 0; padding: 0; list-style: none; display: grid; gap: 9px; }
+    .footer ul a { color: var(--muted); text-decoration: none; font-size: .9rem; }
+    .footer ul a:hover { color: var(--bone); }
+    .footer-base {
+      margin-top: 42px;
+      padding-top: 22px;
+      border-top: 1px solid var(--line-soft);
+      display: flex;
+      flex-wrap: wrap;
+      gap: 12px 26px;
+      justify-content: space-between;
+      font-family: var(--mono);
+      font-size: .74rem;
+      color: var(--muted-dim);
+    }
+
+    /* ── mobile sticky CTA ──────────────────────────────────────── */
+    .sticky-cta { display: none; }
+
+    /* ── reveal ─────────────────────────────────────────────────── */
+    .reveal {
+      opacity: 0;
+      transform: translateY(22px);
+      transition: opacity .6s ease, transform .7s cubic-bezier(.2,.7,.3,1);
+    }
+    .reveal.is-in { opacity: 1; transform: none; }
+
+    .service-title-link { color: inherit; text-decoration: none; }
+    .service-title-link:hover { color: var(--lift); }
+
+    /* ── lightbox ───────────────────────────────────────────────── */
+    .lightbox {
+      position: fixed;
+      inset: 0;
+      z-index: 200;
+      display: grid;
+      place-items: center;
+      padding: 26px;
+      background: rgba(8, 8, 8, .94);
+      backdrop-filter: blur(12px);
+      opacity: 0;
+      visibility: hidden;
+      transition: opacity .22s ease, visibility .22s ease;
+    }
+    .lightbox.is-open { opacity: 1; visibility: visible; }
+    .lightbox img { max-width: 100%; max-height: 88vh; border-radius: 4px; }
+    .lightbox-close {
+      position: absolute;
+      top: 18px;
+      right: 18px;
+      width: 46px;
+      height: 46px;
+      border: 1px solid var(--line);
+      border-radius: 3px;
+      background: rgba(20, 20, 20, .8);
+      color: var(--bone);
+      font-size: 1.7rem;
+      line-height: 1;
+      cursor: pointer;
+    }
+    body.is-locked { overflow: hidden; }
+
+    /* ── responsive ─────────────────────────────────────────────── */
+    @media (max-width: 1060px) {
+      .service-grid, .reviews { grid-template-columns: repeat(2, minmax(0, 1fr)); }
+      .areas-grid { grid-template-columns: 1fr 1fr; }
+      .areas-grid > :first-child { grid-column: span 2; }
+      .quote-grid { grid-template-columns: 1fr; }
+      .footer-inner { grid-template-columns: 1fr 1fr; }
+    }
+
+    @media (max-width: 900px) {
+      .hero-inner { width: min(62%, 610px); }
+
+      .work-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
+      .wand-comparisons { grid-template-columns: 1fr; max-width: 680px; }
+
+      /* Bottom bar takes over from the nav's call button on phones. */
+      .sticky-cta {
+        position: fixed;
+        left: 0;
+        right: 0;
+        bottom: 0;
+        z-index: 95;
+        display: flex;
+        align-items: stretch;
+        gap: 10px;
+        padding: 11px var(--gutter) calc(11px + env(safe-area-inset-bottom));
+        background: rgba(8, 8, 8, .97);
+        backdrop-filter: blur(16px);
+        border-top: 1px solid var(--line);
+        box-shadow: 0 -14px 40px rgba(0, 0, 0, .46);
+        transform: translateY(110%);
+        transition: transform .32s cubic-bezier(.4,0,.2,1);
+      }
+      .sticky-cta.is-up { transform: none; }
+      .sticky-cta .btn { flex: 1 1 0; min-height: 50px; padding: 0 14px; font-size: .84rem; }
+      .sticky-cta .btn--primary { flex: 1.35 1 0; }
+      body { padding-bottom: 78px; }
+    }
+
+    @media (max-width: 720px) {
+      .nav-actions .nav-call { display: none; }
+      .nav-links { left: 0; right: 0; width: auto; border-inline: 0; }
+      .service-grid, .reviews, .work-grid,
+      .areas-grid, .field-row, .footer-inner {
+        grid-template-columns: 1fr;
+      }
+      .areas-grid > :first-child { grid-column: auto; }
+      .work-heading { align-items: flex-start; flex-direction: column; gap: 17px; }
+      .work-instagram { margin-bottom: 0; }
+      .work-grid { margin-top: 34px; }
+      .strip-inner {
+        width: max-content;
+        max-width: none;
+        margin-inline: 0;
+        flex-wrap: nowrap;
+        align-items: center;
+        justify-content: flex-start;
+        gap: 0;
+        padding-block: 15px;
+        animation: credential-ticker 24s linear infinite;
+        will-change: transform;
+      }
+      .strip-group {
+        width: max-content;
+        flex: 0 0 auto;
+        flex-wrap: nowrap;
+        justify-content: flex-start;
+        gap: 32px;
+        padding: 0 32px 0 var(--gutter);
+      }
+      .strip-group--clone { display: flex; }
+      .strip-inner span { width: auto; white-space: nowrap; }
+      .strip-viewport:hover .strip-inner { animation-play-state: paused; }
+      .btn-row .btn { width: 100%; }
+      .hero { height: 300vh; height: 300svh; }
+      .hero-sticky {
+        align-items: start;
+        padding-top: calc(var(--nav-h) + 54px);
+        padding-bottom: 24px;
+      }
+      .hero-inner { width: 100%; }
+      .hero h1 { font-size: clamp(2.7rem, 12.25vw, 3.45rem); }
+      .hero .lead { margin-top: 19px; font-size: .94rem; line-height: 1.62; }
+      .hero .eyebrow { margin-bottom: 14px; font-size: .65rem; }
+      .hero .hero-primary-actions { margin-top: 22px; }
+      .hero .hero-primary-actions .btn { width: auto; min-height: 48px; padding-inline: 18px; }
+      .hero .hero-primary-actions .btn--ghost { display: none; }
+      .hero-media video,
+      .hero-media img.hero-fallback {
+        object-position: center 50%;
+        filter: saturate(1.02) contrast(1.03) brightness(.9);
+      }
+      .hero-cue { left: 20px; bottom: 26px; transform: none; }
+    }
+
+    @media (prefers-reduced-motion: reduce) {
+      html { scroll-behavior: auto; }
+      .hero { height: auto; }
+      .hero-sticky {
+        position: relative;
+        --hero-cue-opacity: 1;
+        --hero-media-scale: 1;
+        --hero-scrim-opacity: .9;
+        min-height: 100vh;
+        min-height: 100svh;
+      }
+      .hero-media video,
+      .hero-media img.hero-fallback { transform: none; will-change: auto; }
+      .hero-title-inner,
+      .hero-eyebrow,
+      .hero-lead,
+      .hero-primary-actions { opacity: 1 !important; transform: none !important; will-change: auto; }
+      .reveal { opacity: 1; transform: none; transition: none; }
+      .nav, .sticky-cta, .work-tile img, .btn, .service { transition: none; }
+      .work-tile:hover img, .btn:hover, .service:hover { transform: none; }
+    }
+
+    @media (max-width: 720px) and (prefers-reduced-motion: reduce) {
+      .strip-viewport { overflow-x: auto; scrollbar-width: none; }
+      .strip-viewport::-webkit-scrollbar { display: none; }
+      .strip-inner { animation: none; will-change: auto; }
+      .strip-group--clone { display: none; }
+    }
diff --git a/docs/assets/site.js b/docs/assets/site.js
new file mode 100644
index 0000000..7bc9dec
--- /dev/null
+++ b/docs/assets/site.js
@@ -0,0 +1,464 @@
+    (function () {
+      'use strict';
+
+      var reduceMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
+
+      var heroCinematic = document.getElementById('top');
+      function clamp01(value) { return Math.max(0, Math.min(1, value)); }
+      function smoothstep(value) { value = clamp01(value); return value * value * (3 - 2 * value); }
+      /* ── scroll-aware nav ─────────────────────────────────────
+         Keeps the nav visible while the oversized opening state compacts. */
+      var nav = document.getElementById('nav');
+      var navProgress = document.getElementById('nav-progress');
+      var navToggle = document.querySelector('.nav-toggle');
+      var navLinksWrap = document.getElementById('nav-links');
+      var navAnchors = navLinksWrap.querySelectorAll('a[href^="#"]');
+      var stickyCta = document.getElementById('sticky-cta');
+      var ticking = false;
+
+      function mix(from, to, progress) {
+        return from + ((to - from) * progress);
+      }
+
+      /* The opening masthead collapses over the first 220px of real scroll.
+         Values finish at the original compact nav measurements. */
+      function paintNavScale(y) {
+        var mobileNav = window.innerWidth <= 900;
+        var progress = reduceMotion ? (y > 12 ? 1 : 0) : smoothstep(clamp01(y / 220));
+        var compactLogo = Math.min(188, Math.max(146, window.innerWidth * 0.17));
+        var introLogo = mobileNav
+          ? Math.min(240, Math.max(190, window.innerWidth * 0.45))
+          : Math.min(310, Math.max(230, window.innerWidth * 0.24));
+        var introHeight = mobileNav
+          ? 104
+          : Math.min(138, Math.max(112, window.innerHeight * 0.12));
+
+        nav.style.setProperty('--nav-live-height', mix(introHeight, 76, progress).toFixed(2) + 'px');
+        nav.style.setProperty('--nav-live-logo', mix(introLogo, compactLogo, progress).toFixed(2) + 'px');
+        nav.style.setProperty('--nav-live-call-font', mix(16, 13.76, progress).toFixed(2) + 'px');
+        nav.style.setProperty('--nav-live-call-y', mix(14, 11, progress).toFixed(2) + 'px');
+        nav.style.setProperty('--nav-live-call-x', mix(22, 18, progress).toFixed(2) + 'px');
+        nav.style.setProperty('--nav-live-icon', mix(18, 15, progress).toFixed(2) + 'px');
+      }
+
+      function onScroll() {
+        var y = window.scrollY;
+        var max = document.documentElement.scrollHeight - window.innerHeight;
+
+        if (window.voldPaintHero) window.voldPaintHero();
+        paintNavScale(y);
+
+        nav.classList.toggle('is-stuck', y > 12);
+        navProgress.style.transform = 'scaleX(' + (max > 0 ? Math.min(y / max, 1) : 0) + ')';
+
+        stickyCta.classList.toggle('is-up', heroCinematic && y > heroCinematic.offsetTop + heroCinematic.offsetHeight);
+        ticking = false;
+      }
+
+      window.addEventListener('scroll', function () {
+        if (ticking) return;
+        ticking = true;
+        window.requestAnimationFrame(onScroll);
+      }, { passive: true });
+      window.addEventListener('resize', function () {
+        if (ticking) return;
+        ticking = true;
+        window.requestAnimationFrame(onScroll);
+      });
+      onScroll();
+
+      /* ── mobile menu ──────────────────────────────────────── */
+      navToggle.addEventListener('click', function () {
+        var open = navToggle.getAttribute('aria-expanded') === 'true';
+        navToggle.setAttribute('aria-expanded', String(!open));
+        navToggle.setAttribute('aria-label', open ? 'Open menu' : 'Close menu');
+        nav.classList.toggle('is-open', !open);
+      });
+
+      function closeMenu() {
+        navToggle.setAttribute('aria-expanded', 'false');
+        navToggle.setAttribute('aria-label', 'Open menu');
+        nav.classList.remove('is-open');
+      }
+      navLinksWrap.addEventListener('click', function (e) {
+        if (e.target.closest('a')) closeMenu();
+      });
+      document.addEventListener('keydown', function (e) {
+        if (e.key === 'Escape' && nav.classList.contains('is-open')) {
+          closeMenu();
+          navToggle.focus();
+        }
+      });
+      document.addEventListener('click', function (e) {
+        if (!nav.classList.contains('is-open') || nav.contains(e.target)) return;
+        closeMenu();
+      });
+
+      /* ── active section in the nav ────────────────────────── */
+      var sections = [];
+      navAnchors.forEach(function (a) {
+        var el = document.querySelector(a.getAttribute('href'));
+        if (el) sections.push({ el: el, link: a });
+      });
+
+      if (sections.length && 'IntersectionObserver' in window) {
+        var spy = new IntersectionObserver(function (entries) {
+          entries.forEach(function (entry) {
+            if (!entry.isIntersecting) return;
+            navAnchors.forEach(function (a) { a.classList.remove('is-current'); });
+            var match = sections.find(function (s) { return s.el === entry.target; });
+            if (match) match.link.classList.add('is-current');
+          });
+        }, { rootMargin: '-45% 0px -50% 0px' });
+        sections.forEach(function (s) { spy.observe(s.el); });
+      }
+
+      /* ── reveal on scroll ─────────────────────────────────── */
+      var reveals = document.querySelectorAll('.reveal');
+      if (reduceMotion || !('IntersectionObserver' in window)) {
+        reveals.forEach(function (el) { el.classList.add('is-in'); });
+      } else {
+        var revealObserver = new IntersectionObserver(function (entries) {
+          entries.forEach(function (entry) {
+            if (!entry.isIntersecting) return;
+            entry.target.classList.add('is-in');
+            revealObserver.unobserve(entry.target);
+          });
+        }, { threshold: 0.12, rootMargin: '0px 0px -6% 0px' });
+        reveals.forEach(function (el) { revealObserver.observe(el); });
+      }
+
+      /* ── the wand line ────────────────────────────────────── */
+      document.querySelectorAll('.wand').forEach(function (wand) {
+        var wandRange = wand.querySelector('.wand-range');
+
+        function paintWand() {
+          wand.style.setProperty('--pos', wandRange.value + '%');
+          var beforePercent = Math.round(Number(wandRange.value));
+          wandRange.setAttribute('aria-valuetext', beforePercent + '% before, ' + (100 - beforePercent) + '% after');
+        }
+
+        wandRange.addEventListener('input', paintWand);
+        paintWand();
+      });
+
+      /* ── gallery lightbox ─────────────────────────────────── */
+      var lightbox = document.getElementById('lightbox');
+      if (lightbox && document.getElementById('work-grid')) {
+      var lightboxImg = document.getElementById('lightbox-img');
+      var lightboxClose = lightbox.querySelector('.lightbox-close');
+      var lastFocused = null;
+      var workGrid = document.getElementById('work-grid');
+
+      workGrid.addEventListener('click', function (event) {
+        var tile = event.target.closest('.work-tile');
+        if (!tile || !workGrid.contains(tile)) return;
+        var img = tile.querySelector('img');
+        if (!img) return;
+        lastFocused = tile;
+        lightboxImg.src = img.dataset.full || img.currentSrc || img.src;
+        lightboxImg.alt = img.alt;
+        lightbox.classList.add('is-open');
+        document.body.classList.add('is-locked');
+        lightboxClose.focus();
+      });
+
+      function renderManagedPhotos(manifest) {
+        if (!manifest || manifest.version !== 1 || !Array.isArray(manifest.images)) return;
+
+        if (Array.isArray(manifest.comparisons)) {
+          manifest.comparisons.forEach(function (comparison) {
+            var project = Array.prototype.find.call(
+              document.querySelectorAll('[data-comparison-id]'),
+              function (item) { return item.dataset.comparisonId === comparison.id; }
+            );
+            if (!project) return;
+            ['before', 'after'].forEach(function (side) {
+              var media = comparison[side];
+              var image = project.querySelector('[data-comparison-side="' + side + '"]');
+              if (!image || !media || !media.src || !media.alt) return;
+              image.src = new URL(media.src, window.location.origin + '/').href;
+              image.alt = media.alt;
+            });
+          });
+        }
+
+        var fragment = document.createDocumentFragment();
+        manifest.images.forEach(function (item) {
+          if (!item || !item.src || !item.caption || !item.alt) return;
+          var tile = document.createElement('button');
+          tile.className = 'work-tile';
+          tile.type = 'button';
+
+          var image = document.createElement('img');
+          image.src = new URL(item.thumb || item.src, window.location.origin + '/').href;
+          image.alt = item.alt;
+          image.loading = 'lazy';
+          image.decoding = 'async';
+          image.dataset.full = new URL(item.src, window.location.origin + '/').href;
+
+          var cap = document.createElement('span');
+          cap.className = 'work-cap';
+          var title = document.createElement('b');
+          title.textContent = item.caption;
+          cap.appendChild(title);
+          tile.appendChild(image);
+          tile.appendChild(cap);
+          fragment.appendChild(tile);
+        });
+        workGrid.replaceChildren(fragment);
+      }
+
+      fetch(workGrid.dataset.galleryManifest, { credentials: 'same-origin' })
+        .then(function (response) {
+          if (!response.ok) throw new Error('Gallery request failed');
+          return response.json();
+        })
+        .then(renderManagedPhotos)
+        .catch(function () {
+          // Keep the server-rendered photos in place as the resilient fallback.
+        });
+
+      function closeLightbox() {
+        lightbox.classList.remove('is-open');
+        document.body.classList.remove('is-locked');
+        lightboxImg.removeAttribute('src');
+        lightboxImg.alt = '';
+        if (lastFocused) lastFocused.focus();
+      }
+      lightboxClose.addEventListener('click', closeLightbox);
+      lightbox.addEventListener('click', function (e) {
+        if (e.target === lightbox) closeLightbox();
+      });
+      document.addEventListener('keydown', function (e) {
+        if (e.key === 'Escape' && lightbox.classList.contains('is-open')) closeLightbox();
+      });
+
+      }
+
+      /* ── quote form ─────────────────────────────────────────── */
+      var form = document.getElementById('quote-form');
+      if (form) {
+      var success = document.getElementById('form-success');
+      var successName = document.getElementById('success-name');
+      var formError = document.getElementById('form-error');
+      var submitButton = document.getElementById('quote-submit');
+      var photoInput = document.getElementById('q-photos');
+      var photoList = document.getElementById('q-photo-list');
+      var photoStatus = document.getElementById('q-photos-status');
+      var maxPhotos = 5;
+      var maxPhotoBytes = 25 * 1024 * 1024;
+      var maxTotalPhotoBytes = 90 * 1024 * 1024;
+      var selectedPhotos = [];
+
+      function clearFormError() {
+        formError.hidden = true;
+        formError.textContent = '';
+      }
+
+      function showFormError(message) {
+        formError.textContent = message;
+        formError.hidden = false;
+      }
+
+      function formatPhotoStatus(files) {
+        if (!files.length) return '';
+        return files.length + ' of ' + maxPhotos + (files.length === 1 ? ' photo is' : ' photos are') + ' ready to send.';
+      }
+
+      function photoValidationMessage(files) {
+        var totalBytes = files.reduce(function (total, file) { return total + file.size; }, 0);
+        var oversizedPhoto = files.find(function (file) { return file.size > maxPhotoBytes; });
+        var nonPhoto = files.find(function (file) {
+          return file.type && file.type.indexOf('image/') !== 0;
+        });
+
+        if (files.length > maxPhotos) {
+          return 'Choose no more than 5 photos. Remove one before adding another.';
+        }
+        if (oversizedPhoto) {
+          return oversizedPhoto.name + ' is larger than 25 MB and was not added.';
+        }
+        if (totalBytes > maxTotalPhotoBytes) {
+          return 'Keep the combined photo size under 90 MB. Those photos were not added.';
+        }
+        if (nonPhoto) return 'Choose image files only.';
+        return '';
+      }
+
+      function formatPhotoSize(bytes) {
+        if (bytes < 1024 * 1024) return Math.max(1, Math.round(bytes / 1024)) + ' KB';
+        return (bytes / (1024 * 1024)).toFixed(1).replace('.0', '') + ' MB';
+      }
+
+      function photoKey(file) {
+        return [file.name, file.size, file.lastModified, file.type].join('|');
+      }
+
+      function renderPhotos(message) {
+        photoList.textContent = '';
+        selectedPhotos.forEach(function (file, index) {
+          var item = document.createElement('li');
+          var fileDetails = document.createElement('span');
+          var fileName = document.createElement('span');
+          var fileSize = document.createElement('span');
+          var removeButton = document.createElement('button');
+
+          item.className = 'photo-item';
+          fileDetails.className = 'photo-file';
+          fileName.className = 'photo-name';
+          fileName.textContent = file.name;
+          fileSize.className = 'photo-size';
+          fileSize.textContent = 'Photo ' + (index + 1) + ' · ' + formatPhotoSize(file.size);
+          removeButton.className = 'photo-remove';
+          removeButton.type = 'button';
+          removeButton.dataset.photoIndex = index;
+          removeButton.setAttribute('aria-label', 'Remove ' + file.name);
+          removeButton.textContent = 'Remove';
+
+          fileDetails.appendChild(fileName);
+          fileDetails.appendChild(fileSize);
+          item.appendChild(fileDetails);
+          item.appendChild(removeButton);
+          photoList.appendChild(item);
+        });
+
+        photoList.hidden = selectedPhotos.length === 0;
+        photoStatus.textContent = message || formatPhotoStatus(selectedPhotos);
+      }
+
+      function validatePhotos() {
+        var message = photoValidationMessage(selectedPhotos);
+        photoInput.setCustomValidity(message);
+        if (message) {
+          photoStatus.textContent = message;
+          return false;
+        }
+
+        photoStatus.textContent = formatPhotoStatus(selectedPhotos);
+        return true;
+      }
+
+      function formspreeErrorMessage(data, status) {
+        var errors = data && Array.isArray(data.errors) ? data.errors : [];
+        var codes = errors.map(function (error) { return error.code; });
+
+        if (status === 429) {
+          return 'Too many requests were sent at once. Wait a minute, then try again.';
+        }
+        if (codes.indexOf('NO_FILE_UPLOADS') !== -1) {
+          return 'Photo uploads are not enabled for this form yet. Remove the photos and try again, or call or text (954) 401-3301.';
+        }
+        if (codes.indexOf('TOO_MANY_FILES') !== -1) {
+          return 'Too many photos were attached. Choose up to 5 and try again.';
+        }
+        if (codes.indexOf('FILES_TOO_BIG') !== -1) {
+          return 'One or more photos are too large. Choose smaller files and try again.';
+        }
+
+        var messages = errors.map(function (error) { return error.message; }).filter(Boolean);
+        if (messages.length) return messages.join(' ');
+        return 'Your request could not be sent. Check your connection and try again, or call or text (954) 401-3301.';
+      }
+
+      photoInput.addEventListener('change', function () {
+        clearFormError();
+        var incomingPhotos = Array.prototype.slice.call(photoInput.files || []);
+        var selectedKeys = selectedPhotos.map(photoKey);
+        var duplicateCount = 0;
+
+        photoInput.value = '';
+        incomingPhotos = incomingPhotos.filter(function (file) {
+          var key = photoKey(file);
+          if (selectedKeys.indexOf(key) !== -1) {
+            duplicateCount += 1;
+            return false;
+          }
+          selectedKeys.push(key);
+          return true;
+        });
+
+        var candidatePhotos = selectedPhotos.concat(incomingPhotos);
+        var message = photoValidationMessage(candidatePhotos);
+        photoInput.setCustomValidity('');
+
+        if (message) {
+          renderPhotos(message);
+          return;
+        }
+
+        selectedPhotos = candidatePhotos;
+        renderPhotos(duplicateCount
+          ? (duplicateCount === 1 ? 'That photo is already selected. ' : 'Those photos are already selected. ') + formatPhotoStatus(selectedPhotos)
+          : '');
+      });
+
+      photoList.addEventListener('click', function (e) {
+        var removeButton = e.target.closest('.photo-remove');
+        if (!removeButton) return;
+
+        var index = Number(removeButton.dataset.photoIndex);
+        if (!Number.isInteger(index) || !selectedPhotos[index]) return;
+
+        selectedPhotos.splice(index, 1);
+        photoInput.setCustomValidity('');
+        clearFormError();
+        renderPhotos();
+      });
+
+      form.addEventListener('submit', async function (e) {
+        e.preventDefault();
+        clearFormError();
+
+        if (!validatePhotos() || !form.checkValidity()) {
+          form.reportValidity();
+          return;
+        }
+
+        var submittedName = form.querySelector('#q-name').value.trim();
+        var originalButtonText = submitButton.textContent;
+        form.setAttribute('aria-busy', 'true');
+        submitButton.disabled = true;
+        submitButton.textContent = 'Sending request…';
+
+        try {
+          var formData = new FormData(form);
+          formData.delete(photoInput.name);
+          selectedPhotos.forEach(function (file) {
+            formData.append(photoInput.name, file, file.name);
+          });
+
+          var response = await fetch(form.action, {
+            method: form.method,
+            body: formData,
+            headers: { 'Accept': 'application/json' }
+          });
+          var data = await response.json().catch(function () { return null; });
+
+          if (!response.ok) {
+            throw { formspree: true, data: data, status: response.status };
+          }
+
+          successName.textContent = submittedName || 'we’ve got it';
+          form.reset();
+          selectedPhotos = [];
+          renderPhotos();
+          form.hidden = true;
+          success.hidden = false;
+          success.focus();
+        } catch (error) {
+          var message = error && error.formspree
+            ? formspreeErrorMessage(error.data, error.status)
+            : 'Your request could not be sent. Check your connection and try again, or call or text (954) 401-3301.';
+          showFormError(message);
+        } finally {
+          form.removeAttribute('aria-busy');
+          submitButton.disabled = false;
+          submitButton.textContent = originalButtonText;
+        }
+      });
+
+      }
+      document.getElementById('year').textContent = new Date().getFullYear();
+    })();
+
diff --git a/docs/index.html b/docs/index.html
index cd7c605..7f8ba31 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -41,1365 +41,7 @@
   <link href="https://fonts.googleapis.com/css2?family=Manrope:wght@400;500;600&family=Roboto+Mono:wght@400;500&family=Teko:wght@500;600&display=swap" rel="stylesheet" />
   <link rel="preload" as="image" href="https://voldservices.com/img/hero-poster-v2.jpg" />
 
-  <style>
-    /* True charcoal and concrete neutrals, with the logo blue reserved
-       for actions and small highlights rather than page backgrounds. */
-    :root {
-      --ink:        #080808;
-      --ink-2:      #10100f;
-      --ink-3:      #181816;
-      --brand:      #078ed1;
-      --brand-deep: #056ca1;
-      --lift:       #58bdec;
-      --spray:      #c9efff;
-      --bone:       #f2f0e9;
-      --muted:      #aaa89f;
-      --muted-dim:  #77766f;
-
-      --line:       rgba(242, 240, 233, 0.17);
-      --line-soft:  rgba(242, 240, 233, 0.08);
-      --panel:      rgba(255, 255, 255, 0.035);
-
-      --display: "Teko", Impact, sans-serif;
-      --body:    "Manrope", system-ui, sans-serif;
-      --mono:    "Roboto Mono", ui-monospace, monospace;
-
-      --gutter: clamp(20px, 4vw, 44px);
-      --wrap:   1240px;
-      --nav-h:  76px;
-    }
-
-    /* ── base ───────────────────────────────────────────────────── */
-    *, *::before, *::after { box-sizing: border-box; }
-
-    html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }
-
-    body {
-      margin: 0;
-      background: var(--ink);
-      color: var(--bone);
-      font-family: var(--body);
-      font-size: 16px;
-      line-height: 1.65;
-      overflow-x: hidden;
-      -webkit-font-smoothing: antialiased;
-    }
-
-    img, video { max-width: 100%; display: block; }
-    a { color: inherit; }
-
-    :focus-visible {
-      outline: 2px solid var(--lift);
-      outline-offset: 3px;
-      border-radius: 2px;
-    }
-
-    .skip-link {
-      position: absolute;
-      left: 12px;
-      top: -60px;
-      z-index: 200;
-      background: var(--brand);
-      color: #fff;
-      padding: 12px 18px;
-      font-family: var(--mono);
-      font-size: .8rem;
-      text-decoration: none;
-      transition: top .18s ease;
-    }
-    .skip-link:focus { top: 12px; }
-
-    .wrap {
-      width: min(var(--wrap), 100% - (var(--gutter) * 2));
-      margin-inline: auto;
-    }
-
-    /* Section rhythm. The hairline at the top of each band is the
-       "wand pass" — the same gesture as the before/after handle. */
-    .band {
-      position: relative;
-      padding: clamp(76px, 9.5vw, 132px) 0;
-      /* Anchor jumps clear the fixed nav instead of landing behind it. The
-         logo can push the bar past --nav-h on wide screens, so leave slack. */
-      scroll-margin-top: calc(var(--nav-h) + 24px);
-    }
-    .band::before {
-      content: "";
-      position: absolute;
-      inset: 0 0 auto 0;
-      height: 1px;
-      background: var(--line);
-    }
-    .band--tinted { background: linear-gradient(180deg, var(--ink-2), var(--ink)); }
-    .band--flush::before { display: none; }
-
-    /* ── type ───────────────────────────────────────────────────── */
-    .eyebrow {
-      font-family: var(--mono);
-      font-size: .74rem;
-      letter-spacing: .2em;
-      text-transform: uppercase;
-      color: var(--lift);
-      margin: 0 0 18px;
-      display: flex;
-      align-items: center;
-      gap: 12px;
-    }
-    .eyebrow::before {
-      content: "";
-      width: 26px;
-      height: 1px;
-      background: var(--brand);
-      flex: 0 0 auto;
-    }
-
-    h1, h2, h3, h4 {
-      font-family: var(--display);
-      font-weight: 600;
-      letter-spacing: -.015em;
-      line-height: .88;
-      text-transform: uppercase;
-      margin: 0;
-      text-wrap: balance;
-    }
-
-    h1 { font-size: clamp(4.2rem, 9.3vw, 8.4rem); }
-    .h2 { font-size: clamp(3.1rem, 6vw, 5.4rem); }
-    .h3 { font-size: clamp(1.85rem, 2.8vw, 2.35rem); letter-spacing: -.01em; }
-
-    .accent { color: var(--lift); }
-
-    .lead {
-      max-width: 60ch;
-      margin: 22px 0 0;
-      color: var(--muted);
-      font-size: clamp(1rem, 1.25vw, 1.14rem);
-      line-height: 1.72;
-    }
-    .lead strong { color: var(--bone); font-weight: 600; }
-
-    .section-head { max-width: 780px; }
-    .section-head .lead { margin-top: 20px; }
-
-    /* ── buttons ────────────────────────────────────────────────── */
-    .btn {
-      display: inline-flex;
-      align-items: center;
-      justify-content: center;
-      gap: 10px;
-      min-height: 52px;
-      padding: 0 26px;
-      border: 1px solid transparent;
-      border-radius: 0;
-      font-family: var(--display);
-      font-weight: 700;
-      font-size: .88rem;
-      letter-spacing: .06em;
-      text-transform: uppercase;
-      text-decoration: none;
-      cursor: pointer;
-      white-space: nowrap;
-      transition: background .18s ease, border-color .18s ease, color .18s ease, transform .18s ease;
-    }
-    .btn:hover { transform: translateY(-1px); }
-    .btn:active { transform: translateY(0); }
-
-    .btn--primary { background: var(--brand); color: #fff; }
-    .btn--primary:hover { background: var(--lift); color: var(--ink); }
-
-    .btn--ghost {
-      border-color: rgba(242, 240, 233, .32);
-      color: var(--bone);
-      background: rgba(8, 8, 8, .4);
-    }
-    .btn--ghost:hover { border-color: var(--lift); background: rgba(7, 142, 209, .12); }
-
-    .btn--block { width: 100%; }
-
-    .btn-row {
-      display: flex;
-      flex-wrap: wrap;
-      gap: 14px;
-      margin-top: 34px;
-    }
-
-    /* ── nav ────────────────────────────────────────────────────── */
-    .nav {
-      position: fixed;
-      inset: 0 0 auto 0;
-      z-index: 90;
-      background: transparent;
-      border-bottom: 1px solid transparent;
-      transition: background .28s ease, border-color .28s ease;
-    }
-    .nav.is-stuck {
-      background: var(--ink);
-      border-bottom-color: var(--line);
-    }
-    /* Opaque, not near-opaque: the open menu sits over page content and any
-       alpha at all lets the hero read through it. */
-    .nav.is-open { background: var(--ink); }
-
-    .nav-inner {
-      display: flex;
-      align-items: center;
-      justify-content: space-between;
-      gap: 20px;
-      min-height: var(--nav-live-height, clamp(112px, 12vh, 138px));
-    }
-
-    .brand { display: inline-flex; align-items: center; flex: 0 0 auto; }
-    .brand img { width: var(--nav-live-logo, clamp(230px, 24vw, 310px)); height: auto; }
-
-    .nav-links {
-      position: absolute;
-      top: 100%;
-      right: var(--gutter);
-      display: none;
-      width: min(360px, calc(100vw - 40px));
-      flex-direction: column;
-      align-items: stretch;
-      gap: 0;
-      padding: 9px 20px 20px;
-      font-family: var(--mono);
-      font-size: .86rem;
-      letter-spacing: .06em;
-      background: var(--ink);
-      border: 1px solid var(--line);
-      border-top: 0;
-      box-shadow: 0 22px 48px rgba(0, 0, 0, .38);
-    }
-    .nav.is-open .nav-links { display: flex; }
-    .nav-links a {
-      position: relative;
-      color: var(--muted);
-      text-decoration: none;
-      padding: 15px 4px;
-      border-bottom: 1px solid var(--line-soft);
-      transition: color .18s ease;
-    }
-    .nav-links a:last-child { border-bottom: 0; }
-    .nav-links a::after {
-      content: "";
-      position: absolute;
-      left: 0;
-      bottom: 0;
-      width: 100%;
-      height: 1px;
-      background: var(--lift);
-      transform: scaleX(0);
-      transform-origin: left;
-      transition: transform .22s ease;
-    }
-    .nav-links a:hover, .nav-links a.is-current { color: var(--bone); }
-    .nav-links a::after { display: none; }
-
-    .nav-actions {
-      display: flex;
-      align-items: center;
-      justify-content: flex-end;
-      gap: 10px;
-      flex: 0 0 auto;
-    }
-    .nav-call {
-      display: inline-flex;
-      align-items: center;
-      gap: 9px;
-      background: var(--brand);
-      color: #fff;
-      font-family: var(--display);
-      font-weight: 700;
-      font-size: var(--nav-live-call-font, 1rem);
-      letter-spacing: .02em;
-      text-decoration: none;
-      padding: var(--nav-live-call-y, 14px) var(--nav-live-call-x, 22px);
-      border-radius: 0;
-      flex: 0 0 auto;
-      white-space: nowrap;
-      transition: background .18s ease;
-    }
-    .nav-call:hover { background: var(--lift); color: var(--ink); }
-    .nav-call svg {
-      width: var(--nav-live-icon, 18px);
-      height: var(--nav-live-icon, 18px);
-      flex: 0 0 auto;
-    }
-
-    .nav-toggle {
-      display: inline-flex;
-      width: 46px;
-      height: 46px;
-      padding: 0;
-      border: 1px solid var(--line);
-      background: rgba(255, 255, 255, .04);
-      color: var(--bone);
-      cursor: pointer;
-      border-radius: 3px;
-      align-items: center;
-      justify-content: center;
-      flex-direction: column;
-      gap: 5px;
-    }
-    .nav-toggle span {
-      display: block;
-      width: 19px;
-      height: 1.5px;
-      background: currentColor;
-      transition: transform .22s ease, opacity .22s ease;
-    }
-    .nav-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(6.5px) rotate(45deg); }
-    .nav-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
-    .nav-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-6.5px) rotate(-45deg); }
-
-    .nav-progress {
-      position: absolute;
-      left: 0;
-      bottom: -1px;
-      height: 2px;
-      width: 100%;
-      transform: scaleX(0);
-      transform-origin: left;
-      background: linear-gradient(90deg, var(--brand), var(--spray));
-      opacity: 0;
-      transition: opacity .3s ease;
-    }
-    .nav.is-stuck .nav-progress { opacity: 1; }
-
-    /* ── hero ─────────────────────────────────────────────────────
-       The footage and service headline are present from the first frame.
-       Scrolling advances the footage and stages in the supporting message.
-       ───────────────────────────────────────────────────────────── */
-    .hero {
-      position: relative;
-      isolation: isolate;
-      height: 300vh;
-      height: 300svh;
-      scroll-margin-top: var(--nav-h);
-    }
-
-    .hero-sticky {
-      --hero-media-scale: 1.03;
-      --hero-scrim-opacity: .3;
-      --hero-cue-opacity: 1;
-      position: sticky;
-      top: 0;
-      display: grid;
-      align-items: center;
-      width: 100%;
-      height: 100vh;
-      height: 100svh;
-      min-height: 100vh;
-      min-height: 100svh;
-      padding-top: calc(var(--nav-h) + clamp(40px, 7vh, 88px));
-      padding-bottom: clamp(64px, 10vh, 120px);
-      overflow: hidden;
-      background: var(--ink);
-    }
-
-    .hero-media {
-      position: absolute;
-      inset: 0;
-      z-index: 0;
-      overflow: hidden;
-      background: var(--ink);
-    }
-    .hero-media video,
-    .hero-media img.hero-fallback {
-      position: absolute;
-      inset: 0;
-      display: block;
-      width: 100%;
-      height: 100%;
-      object-fit: cover;
-      object-position: center 52%;
-      filter: saturate(1.04) contrast(1.03) brightness(.94);
-      transform: scale(var(--hero-media-scale));
-      transform-origin: center 52%;
-      will-change: transform;
-    }
-    .hero-media img.hero-fallback { z-index: 0; }
-    .hero-media video {
-      z-index: 1;
-      opacity: 0;
-      pointer-events: none;
-      transition: opacity .18s ease-out;
-    }
-    .hero-media.is-video-ready video { opacity: 1; }
-    .hero-media video::-webkit-media-controls,
-    .hero-media video::-webkit-media-controls-panel,
-    .hero-media video::-webkit-media-controls-play-button,
-    .hero-media video::-webkit-media-controls-start-playback-button {
-      display: none !important;
-      -webkit-appearance: none;
-      opacity: 0;
-      pointer-events: none;
-    }
-    .hero-media::after {
-      content: "";
-      position: absolute;
-      inset: 0;
-      z-index: 2;
-      pointer-events: none;
-      background:
-        linear-gradient(90deg, rgba(8, 8, 8, .94) 0%, rgba(8, 8, 8, .62) 43%, rgba(8, 8, 8, .06) 74%),
-        linear-gradient(180deg, rgba(8, 8, 8, .55), transparent 28%, rgba(8, 8, 8, .38) 76%, rgba(8, 8, 8, .82));
-      opacity: var(--hero-scrim-opacity);
-    }
-
-    .hero-grain {
-      position: absolute;
-      inset: 0;
-      z-index: 2;
-      pointer-events: none;
-      opacity: .2;
-      mix-blend-mode: overlay;
-      background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='.5'/%3E%3C/svg%3E");
-    }
-
-    .hero-inner {
-      position: relative;
-      z-index: 3;
-      width: min(66%, 820px);
-    }
-    .hero h1 {
-      max-width: none;
-      font-size: clamp(4.2rem, 7.45vw, 7.1rem);
-    }
-    .hero-title-line {
-      display: block;
-      overflow: hidden;
-      white-space: nowrap;
-    }
-    .hero-title-inner {
-      display: block;
-      opacity: 1;
-      transform: translate3d(0, 0, 0);
-      will-change: transform, opacity;
-    }
-    .hero .lead { max-width: 48ch; margin-top: 26px; }
-
-    .hero-inner .eyebrow,
-    .hero h1,
-    .hero .lead { text-shadow: 0 2px 26px rgba(0, 0, 0, .7); }
-
-    .hero-eyebrow,
-    .hero-lead,
-    .hero-primary-actions {
-      opacity: 1;
-      transform: translate3d(0, 0, 0);
-      will-change: transform, opacity;
-    }
-
-    .hero-cue {
-      position: absolute;
-      z-index: 3;
-      left: 50%;
-      bottom: 26px;
-      transform: translateX(-50%);
-      display: flex;
-      align-items: center;
-      gap: 10px;
-      font-family: var(--mono);
-      font-size: .68rem;
-      letter-spacing: .18em;
-      text-transform: uppercase;
-      color: var(--muted-dim);
-      text-decoration: none;
-      opacity: var(--hero-cue-opacity);
-      transition: color .2s ease;
-    }
-    .hero-cue:hover { color: var(--spray); }
-    .hero-cue::after {
-      content: "";
-      width: 8px;
-      height: 8px;
-      border-right: 1px solid currentColor;
-      border-bottom: 1px solid currentColor;
-      transform: rotate(45deg) translate(-2px, -2px);
-    }
-
-    /* ── credential strip ───────────────────────────────────────── */
-    .strip {
-      border-block: 1px solid var(--line-soft);
-      background: #0d0d0c;
-    }
-    .strip-viewport { overflow: hidden; }
-    .strip-inner {
-      display: flex;
-      align-items: center;
-      padding: 17px 0;
-      font-family: var(--mono);
-      font-size: .74rem;
-      letter-spacing: .09em;
-      text-transform: uppercase;
-      color: var(--muted-dim);
-    }
-    .strip-group {
-      display: flex;
-      flex-wrap: wrap;
-      align-items: center;
-      justify-content: space-between;
-      gap: 14px 30px;
-      width: 100%;
-    }
-    .strip-group--clone { display: none; }
-    .strip-inner span { display: inline-flex; align-items: center; gap: 9px; }
-    .strip-inner span::before {
-      content: "";
-      width: 5px;
-      height: 5px;
-      border-radius: 50%;
-      background: var(--brand);
-      flex: 0 0 auto;
-    }
-    .strip-inner a { color: var(--bone); text-decoration: none; }
-    .strip-inner a:hover { color: var(--lift); }
-    @keyframes credential-ticker {
-      to { transform: translate3d(-50%, 0, 0); }
-    }
-
-    /* ── services ───────────────────────────────────────────────── */
-    .service-grid {
-      display: grid;
-      grid-template-columns: repeat(2, minmax(0, 1fr));
-      gap: 18px;
-      margin-top: 52px;
-    }
-    .service {
-      position: relative;
-      display: flex;
-      flex-direction: column;
-      padding: 32px 30px 30px;
-      border: 1px solid var(--line);
-      border-radius: 0;
-      background: var(--panel);
-      overflow: hidden;
-      transition: border-color .24s ease, transform .24s ease;
-    }
-    .service:hover { border-color: rgba(88, 189, 236, .44); transform: translateY(-3px); }
-    .service::before {
-      content: "";
-      position: absolute;
-      inset: 0 0 auto 0;
-      height: 2px;
-      background: var(--tint, var(--brand));
-      opacity: .85;
-    }
-    .service--wash  { --tint: var(--brand); }
-    .service--seal  { --tint: var(--brand); }
-    .service--repair { --tint: var(--brand); }
-    .service--roof  { --tint: var(--brand); }
-
-    .service-icon {
-      width: 42px;
-      height: 42px;
-      margin-bottom: 22px;
-      color: var(--lift);
-    }
-    .service--seal .service-icon,
-    .service--repair .service-icon,
-    .service--roof .service-icon { color: var(--lift); }
-    .service-icon svg { width: 100%; height: 100%; }
-
-    .service h3 { margin-bottom: 12px; }
-    .service p {
-      margin: 0;
-      color: var(--muted);
-      font-size: .96rem;
-      line-height: 1.7;
-    }
-    .service-list {
-      margin: 22px 0 0;
-      padding: 20px 0 0;
-      border-top: 1px solid var(--line-soft);
-      list-style: none;
-      display: grid;
-      gap: 9px;
-      font-family: var(--mono);
-      font-size: .78rem;
-      color: var(--muted-dim);
-    }
-    .service-list li { display: flex; gap: 10px; align-items: flex-start; }
-    .service-list li::before { content: "—"; color: var(--brand); flex: 0 0 auto; }
-
-    /* ─────────────────────────────────────────────────────────────
-       Signature: the wand line. A drag reveals the cleaned surface
-       behind a lit seam — the same edge you see on a real job.
-       A range input drives it so keyboard and screen readers work.
-       ───────────────────────────────────────────────────────────── */
-    .results-head { max-width: 780px; }
-    .results-head .lead { max-width: 56ch; }
-    .wand-comparisons {
-      display: grid;
-      grid-template-columns: repeat(2, minmax(0, 1fr));
-      gap: 20px;
-      margin-top: 50px;
-    }
-    .wand-project {
-      margin: 0;
-      border: 1px solid var(--line);
-      background: var(--panel);
-      overflow: hidden;
-    }
-
-    .wand {
-      --pos: 50%;
-      position: relative;
-      /* Matches the source photos (746×829) so nothing important is cropped.
-         width must be definite, or the max-height resolves through the ratio
-         and shrinks the box horizontally instead of cropping it. */
-      width: 100%;
-      aspect-ratio: 746 / 829;
-      max-height: min(76vh, 700px);
-      border: 1px solid var(--line);
-      border-radius: 4px;
-      overflow: hidden;
-      background: var(--ink-2);
-      touch-action: pan-y;
-    }
-    .wand-layer { position: absolute; inset: 0; }
-    .wand-layer img { width: 100%; height: 100%; object-fit: cover; }
-    /* Before stays on the left; the cleaned surface occupies the right. */
-    .wand-layer--after { clip-path: inset(0 0 0 var(--pos)); }
-
-    .wand-seam {
-      position: absolute;
-      top: 0;
-      bottom: 0;
-      left: var(--pos);
-      width: 2px;
-      margin-left: -1px;
-      background: linear-gradient(180deg, rgba(184, 236, 255, .35), var(--spray) 42%, rgba(184, 236, 255, .35));
-      box-shadow: 0 0 18px 3px rgba(184, 236, 255, .5);
-      pointer-events: none;
-    }
-    /* Fan of spray thrown just ahead of the seam. */
-    .wand-seam::before {
-      content: "";
-      position: absolute;
-      top: 0;
-      bottom: 0;
-      left: 1px;
-      width: 66px;
-      background: linear-gradient(90deg, rgba(184, 236, 255, .3), transparent 78%);
-      pointer-events: none;
-    }
-
-    .wand-handle {
-      position: absolute;
-      top: 50%;
-      left: var(--pos);
-      transform: translate(-50%, -50%);
-      width: 52px;
-      height: 52px;
-      border-radius: 50%;
-      background: var(--spray);
-      color: var(--ink);
-      display: grid;
-      place-items: center;
-      box-shadow: 0 6px 26px rgba(0, 0, 0, .48), 0 0 0 1px rgba(255, 255, 255, .5) inset;
-      pointer-events: none;
-    }
-    .wand-handle svg { width: 24px; height: 24px; }
-
-    .wand-range {
-      position: absolute;
-      inset: 0;
-      width: 100%;
-      height: 100%;
-      margin: 0;
-      opacity: 0;
-      cursor: ew-resize;
-      -webkit-appearance: none;
-      appearance: none;
-      background: transparent;
-    }
-    .wand-range::-webkit-slider-thumb {
-      -webkit-appearance: none;
-      width: 58px;
-      height: 100%;
-      cursor: ew-resize;
-    }
-    .wand-range::-moz-range-thumb {
-      width: 58px;
-      height: 100%;
-      border: 0;
-      border-radius: 0;
-      cursor: ew-resize;
-    }
-    .wand-range:focus-visible ~ .wand-handle {
-      outline: 2px solid var(--lift);
-      outline-offset: 4px;
-    }
-
-    .wand-tag {
-      position: absolute;
-      top: 14px;
-      z-index: 2;
-      font-family: var(--mono);
-      font-size: .7rem;
-      letter-spacing: .16em;
-      text-transform: uppercase;
-      padding: 6px 12px;
-      border-radius: 999px;
-      background: rgba(8, 8, 8, .82);
-      backdrop-filter: blur(6px);
-      pointer-events: none;
-    }
-    .wand-tag--before { left: 14px; color: var(--muted); border: 1px solid var(--line); }
-    .wand-tag--after  { right: 14px; color: var(--spray); border: 1px solid rgba(184, 236, 255, .34); }
-    .wand-project .wand {
-      max-height: none;
-      border: 0;
-      border-radius: 0;
-    }
-
-    /* ── work gallery ───────────────────────────────────────────── */
-    .work-heading {
-      display: flex;
-      align-items: flex-end;
-      justify-content: space-between;
-      gap: 32px;
-    }
-    .work-instagram {
-      display: inline-flex;
-      align-items: center;
-      gap: 9px;
-      flex: 0 0 auto;
-      margin-bottom: 7px;
-      padding-bottom: 5px;
-      border-bottom: 1px solid rgba(88, 189, 236, .42);
-      color: var(--lift);
-      font-family: var(--mono);
-      font-size: .75rem;
-      letter-spacing: .08em;
-      text-decoration: none;
-      text-transform: uppercase;
-    }
-    .work-instagram svg { width: 15px; height: 15px; }
-    .work-instagram:hover { color: var(--bone); border-bottom-color: var(--bone); }
-    .work-grid {
-      display: grid;
-      grid-template-columns: repeat(3, minmax(0, 1fr));
-      gap: 14px;
-      margin-top: 50px;
-    }
-    .work-tile {
-      position: relative;
-      aspect-ratio: 746 / 829;
-      padding: 0;
-      border: 1px solid var(--line-soft);
-      border-radius: 4px;
-      overflow: hidden;
-      background: var(--ink-2);
-      cursor: zoom-in;
-      color: inherit;
-      text-align: left;
-      display: block;
-    }
-    .work-tile img {
-      width: 100%;
-      height: 100%;
-      object-fit: cover;
-      transition: transform .5s ease;
-    }
-    .work-tile:hover img { transform: scale(1.05); }
-    .work-tile::after {
-      content: "";
-      position: absolute;
-      inset: 0;
-      background: linear-gradient(180deg, transparent 42%, rgba(8, 8, 8, .9));
-    }
-    .work-cap {
-      position: absolute;
-      left: 18px;
-      bottom: 15px;
-      z-index: 2;
-    }
-    .work-cap b {
-      display: block;
-      font-family: var(--display);
-      font-weight: 700;
-      font-size: 1rem;
-      letter-spacing: -.01em;
-    }
-    .work-cap span {
-      display: block;
-      font-family: var(--mono);
-      font-size: .7rem;
-      letter-spacing: .08em;
-      color: var(--lift);
-      text-transform: uppercase;
-      margin-top: 2px;
-    }
-
-    /* ── service areas ──────────────────────────────────────────── */
-    .areas-grid {
-      display: grid;
-      grid-template-columns: 1.35fr 1fr 1fr;
-      gap: 20px;
-      margin-top: 50px;
-      align-items: start;
-    }
-    .area {
-      padding: 30px 28px;
-      border: 1px solid var(--line);
-      border-radius: 4px;
-      background: linear-gradient(180deg, var(--panel), transparent);
-    }
-    .area--primary { border-color: rgba(7, 142, 209, .42); }
-    .area h3 { font-size: 1.24rem; margin-bottom: 6px; }
-    .area-note {
-      font-family: var(--mono);
-      font-size: .72rem;
-      letter-spacing: .08em;
-      text-transform: uppercase;
-      color: var(--lift);
-      margin: 0 0 18px;
-    }
-    .area ul {
-      margin: 0;
-      padding: 0;
-      list-style: none;
-      display: flex;
-      flex-wrap: wrap;
-      gap: 6px 8px;
-      font-size: .87rem;
-      color: var(--muted);
-    }
-    .area li::after { content: " ·"; color: var(--muted-dim); }
-    .area li:last-child::after { content: ""; }
-
-    /* ── reviews ────────────────────────────────────────────────── */
-    .reviews {
-      display: grid;
-      grid-template-columns: repeat(3, minmax(0, 1fr));
-      gap: 18px;
-      margin-top: 50px;
-    }
-    .review {
-      margin: 0;
-      padding: 30px 28px;
-      border: 1px solid var(--line);
-      border-radius: 4px;
-      background: var(--panel);
-      display: flex;
-      flex-direction: column;
-    }
-    .review blockquote {
-      margin: 0 0 22px;
-      font-size: 1rem;
-      line-height: 1.72;
-      color: var(--bone);
-    }
-    .review figcaption {
-      margin-top: auto;
-      padding-top: 18px;
-      border-top: 1px solid var(--line-soft);
-      font-family: var(--mono);
-      font-size: .76rem;
-      color: var(--muted-dim);
-      letter-spacing: .04em;
-    }
-    .stars { color: var(--lift); letter-spacing: .18em; margin-bottom: 14px; font-size: .84rem; }
-
-    .placeholder-note {
-      margin-top: 22px;
-      font-family: var(--mono);
-      font-size: .74rem;
-      color: var(--muted-dim);
-      border-left: 2px solid var(--brand);
-      padding-left: 14px;
-    }
-
-    /* ── quote ──────────────────────────────────────────────────── */
-    .quote-grid {
-      display: grid;
-      grid-template-columns: .82fr 1.18fr;
-      gap: 26px;
-      margin-top: 50px;
-      align-items: start;
-    }
-    .quote-side, .quote-form, .form-success {
-      border: 1px solid var(--line);
-      border-radius: 4px;
-      padding: 32px 30px;
-      background: var(--panel);
-    }
-    .quote-side { background: linear-gradient(180deg, rgba(7, 142, 209, .11), var(--panel) 46%); }
-
-    .quote-row { padding: 20px 0; border-top: 1px solid var(--line-soft); }
-    .quote-row:first-of-type { border-top: 0; padding-top: 0; }
-    .quote-label {
-      font-family: var(--mono);
-      font-size: .72rem;
-      letter-spacing: .14em;
-      text-transform: uppercase;
-      color: var(--lift);
-      margin-bottom: 7px;
-    }
-    .quote-value { color: var(--bone); text-decoration: none; font-size: .97rem; }
-    a.quote-value:hover { color: var(--lift); }
-    .quote-phone {
-      font-family: var(--display);
-      font-weight: 800;
-      font-size: clamp(1.6rem, 3vw, 2rem);
-      letter-spacing: -.02em;
-      text-decoration: none;
-      display: inline-block;
-    }
-    .quote-phone:hover { color: var(--lift); }
-
-    .social-links {
-      display: flex;
-      flex-wrap: wrap;
-      gap: 10px;
-    }
-    .social-link {
-      display: inline-flex;
-      align-items: center;
-      justify-content: center;
-      width: 44px;
-      height: 44px;
-      border: 1px solid var(--line);
-      border-radius: 3px;
-      color: var(--muted);
-      background: rgba(8, 8, 8, .28);
-      text-decoration: none;
-      transition: color .18s ease, border-color .18s ease, background .18s ease, transform .18s ease;
-    }
-    .social-link svg { width: 19px; height: 19px; }
-    .social-link:hover {
-      color: #fff;
-      border-color: var(--brand);
-      background: var(--brand);
-      transform: translateY(-2px);
-    }
-
-    .quote-form-wrap { min-width: 0; }
-    .quote-form { display: grid; gap: 18px; }
-    .quote-form[hidden], .form-success[hidden], .form-error[hidden] { display: none; }
-    .field-row {
-      display: grid;
-      grid-template-columns: repeat(2, minmax(0, 1fr));
-      gap: 18px;
-    }
-    .field label {
-      display: block;
-      margin-bottom: 7px;
-      font-family: var(--mono);
-      font-size: .72rem;
-      letter-spacing: .1em;
-      text-transform: uppercase;
-      color: var(--muted-dim);
-    }
-    .field input, .field select, .field textarea {
-      width: 100%;
-      padding: 13px 14px;
-      border: 1px solid var(--line);
-      border-radius: 3px;
-      background: rgba(8, 8, 8, .64);
-      color: var(--bone);
-      font: inherit;
-      font-size: .95rem;
-      transition: border-color .18s ease, background .18s ease;
-    }
-    .field input::placeholder, .field textarea::placeholder { color: var(--muted-dim); }
-    .field input:focus, .field select:focus, .field textarea:focus {
-      outline: none;
-      border-color: var(--lift);
-      background: rgba(7, 142, 209, .08);
-    }
-    .field select option { background: var(--ink-2); color: var(--bone); }
-    .field textarea { min-height: 122px; resize: vertical; }
-
-    .field input.photo-input {
-      position: absolute;
-      width: 1px;
-      height: 1px;
-      padding: 0;
-      margin: -1px;
-      overflow: hidden;
-      clip: rect(0, 0, 0, 0);
-      white-space: nowrap;
-      border: 0;
-    }
-    .field .photo-picker {
-      display: flex;
-      align-items: center;
-      justify-content: space-between;
-      gap: 14px;
-      min-height: 54px;
-      margin: 0;
-      padding: 8px 10px 8px 8px;
-      border: 1px solid var(--line);
-      border-radius: 3px;
-      background: rgba(8, 8, 8, .64);
-      color: var(--muted);
-      font-family: inherit;
-      font-size: .78rem;
-      letter-spacing: 0;
-      text-transform: none;
-      cursor: pointer;
-      transition: border-color .18s ease, background .18s ease;
-    }
-    .photo-picker__action {
-      display: inline-grid;
-      place-items: center;
-      min-height: 38px;
-      padding: 0 15px;
-      border: 1px solid var(--line);
-      border-radius: 2px;
-      background: rgba(7, 142, 209, .14);
-      color: var(--bone);
-      font-family: var(--mono);
-      font-size: .72rem;
-      letter-spacing: .08em;
-      text-transform: uppercase;
-      transition: border-color .18s ease, background .18s ease, color .18s ease;
-    }
-    .photo-picker__note { text-align: right; }
-    .field .photo-picker:hover,
-    .field .photo-input:focus-visible + .photo-picker {
-      border-color: var(--lift);
-      background: rgba(7, 142, 209, .08);
-    }
-    .field .photo-picker:hover .photo-picker__action,
-    .field .photo-input:focus-visible + .photo-picker .photo-picker__action {
-      border-color: var(--lift);
-      background: var(--brand);
-      color: #fff;
-    }
-    .field .photo-input:focus-visible + .photo-picker {
-      outline: 2px solid var(--lift);
-      outline-offset: 2px;
-    }
-    .field-help, .photo-status {
-      margin: 7px 0 0;
-      font-family: var(--mono);
-      font-size: .7rem;
-      line-height: 1.55;
-      color: var(--muted-dim);
-    }
-    .photo-status:not(:empty) { color: var(--muted); }
-    .photo-list {
-      display: grid;
-      gap: 6px;
-      margin: 9px 0 0;
-      padding: 0;
-      list-style: none;
-    }
-    .photo-list[hidden] { display: none; }
-    .photo-item {
-      display: grid;
-      grid-template-columns: minmax(0, 1fr) auto;
-      align-items: center;
-      gap: 12px;
-      padding: 9px 10px 9px 12px;
-      border-left: 2px solid var(--brand);
-      border-radius: 2px;
-      background: rgba(255, 255, 255, .035);
-    }
-    .photo-file { min-width: 0; }
-    .photo-name {
-      display: block;
-      overflow: hidden;
-      color: var(--bone);
-      font-size: .82rem;
-      text-overflow: ellipsis;
-      white-space: nowrap;
-    }
-    .photo-size {
-      display: block;
-      margin-top: 2px;
-      color: var(--muted-dim);
-      font-family: var(--mono);
-      font-size: .65rem;
-      letter-spacing: .06em;
-      text-transform: uppercase;
-    }
-    .photo-remove {
-      padding: 6px 8px;
-      border: 1px solid transparent;
-      border-radius: 2px;
-      background: transparent;
-      color: var(--muted);
-      font-family: var(--mono);
-      font-size: .66rem;
-      letter-spacing: .07em;
-      text-transform: uppercase;
-      cursor: pointer;
-    }
-    .photo-remove:hover, .photo-remove:focus-visible {
-      border-color: rgba(255, 132, 111, .55);
-      color: #ffd8d1;
-      outline: none;
-    }
-
-    .form-note {
-      font-family: var(--mono);
-      font-size: .72rem;
-      color: var(--muted-dim);
-      margin: 0;
-    }
-    .form-error {
-      padding: 12px 14px;
-      border: 1px solid rgba(255, 132, 111, .55);
-      border-radius: 3px;
-      background: rgba(141, 42, 26, .18);
-      color: #ffd8d1;
-      font-size: .84rem;
-      line-height: 1.55;
-    }
-    .quote-form[aria-busy="true"] .btn { cursor: wait; }
-    .quote-form .btn:disabled {
-      opacity: .68;
-      transform: none;
-    }
-    .form-success {
-      min-height: 410px;
-      align-items: flex-start;
-      justify-content: center;
-      background:
-        linear-gradient(135deg, rgba(7, 142, 209, .18), transparent 58%),
-        var(--panel);
-    }
-    .form-success:not([hidden]) { display: flex; }
-    .success-mark {
-      display: grid;
-      place-items: center;
-      width: 54px;
-      height: 54px;
-      margin-bottom: 26px;
-      border: 1px solid rgba(88, 189, 236, .6);
-      border-radius: 50%;
-      color: var(--lift);
-      background: rgba(7, 142, 209, .14);
-    }
-    .success-mark svg { width: 25px; height: 25px; }
-    .form-success .eyebrow { margin-bottom: 17px; }
-    .form-success h3 { font-size: clamp(2.3rem, 5vw, 4rem); }
-    .form-success p {
-      max-width: 46ch;
-      margin: 20px 0 0;
-      color: var(--muted);
-    }
-    .form-success .quote-value {
-      display: inline-block;
-      margin-top: 22px;
-      color: var(--lift);
-      font-family: var(--mono);
-      font-size: .76rem;
-    }
-
-    /* ── footer ─────────────────────────────────────────────────── */
-    .footer {
-      border-top: 1px solid var(--line);
-      padding: 52px 0 40px;
-      background: var(--ink-2);
-    }
-    .footer-inner {
-      display: grid;
-      grid-template-columns: 1.4fr 1fr 1fr;
-      gap: 34px;
-    }
-    .footer img { width: 168px; margin-bottom: 18px; }
-    .footer p { margin: 0; color: var(--muted-dim); font-size: .9rem; max-width: 42ch; }
-    .footer .social-links { margin-top: 22px; }
-    .footer .social-link { width: 38px; height: 38px; }
-    .footer .social-link svg { width: 17px; height: 17px; }
-    .footer h4 {
-      font-size: .8rem;
-      font-family: var(--mono);
-      font-weight: 500;
-      letter-spacing: .14em;
-      text-transform: uppercase;
-      color: var(--lift);
-      margin-bottom: 14px;
-    }
-    .footer ul { margin: 0; padding: 0; list-style: none; display: grid; gap: 9px; }
-    .footer ul a { color: var(--muted); text-decoration: none; font-size: .9rem; }
-    .footer ul a:hover { color: var(--bone); }
-    .footer-base {
-      margin-top: 42px;
-      padding-top: 22px;
-      border-top: 1px solid var(--line-soft);
-      display: flex;
-      flex-wrap: wrap;
-      gap: 12px 26px;
-      justify-content: space-between;
-      font-family: var(--mono);
-      font-size: .74rem;
-      color: var(--muted-dim);
-    }
-
-    /* ── mobile sticky CTA ──────────────────────────────────────── */
-    .sticky-cta { display: none; }
-
-    /* ── reveal ─────────────────────────────────────────────────── */
-    .reveal {
-      opacity: 0;
-      transform: translateY(22px);
-      transition: opacity .6s ease, transform .7s cubic-bezier(.2,.7,.3,1);
-    }
-    .reveal.is-in { opacity: 1; transform: none; }
-
-    /* ── lightbox ───────────────────────────────────────────────── */
-    .lightbox {
-      position: fixed;
-      inset: 0;
-      z-index: 200;
-      display: grid;
-      place-items: center;
-      padding: 26px;
-      background: rgba(8, 8, 8, .94);
-      backdrop-filter: blur(12px);
-      opacity: 0;
-      visibility: hidden;
-      transition: opacity .22s ease, visibility .22s ease;
-    }
-    .lightbox.is-open { opacity: 1; visibility: visible; }
-    .lightbox img { max-width: 100%; max-height: 88vh; border-radius: 4px; }
-    .lightbox-close {
-      position: absolute;
-      top: 18px;
-      right: 18px;
-      width: 46px;
-      height: 46px;
-      border: 1px solid var(--line);
-      border-radius: 3px;
-      background: rgba(20, 20, 20, .8);
-      color: var(--bone);
-      font-size: 1.7rem;
-      line-height: 1;
-      cursor: pointer;
-    }
-    body.is-locked { overflow: hidden; }
-
-    /* ── responsive ─────────────────────────────────────────────── */
-    @media (max-width: 1060px) {
-      .service-grid, .reviews { grid-template-columns: repeat(2, minmax(0, 1fr)); }
-      .areas-grid { grid-template-columns: 1fr 1fr; }
-      .areas-grid > :first-child { grid-column: span 2; }
-      .quote-grid { grid-template-columns: 1fr; }
-      .footer-inner { grid-template-columns: 1fr 1fr; }
-    }
-
-    @media (max-width: 900px) {
-      .hero-inner { width: min(62%, 610px); }
-
-      .work-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
-      .wand-comparisons { grid-template-columns: 1fr; max-width: 680px; }
-
-      /* Bottom bar takes over from the nav's call button on phones. */
-      .sticky-cta {
-        position: fixed;
-        left: 0;
-        right: 0;
-        bottom: 0;
-        z-index: 95;
-        display: flex;
-        align-items: stretch;
-        gap: 10px;
-        padding: 11px var(--gutter) calc(11px + env(safe-area-inset-bottom));
-        background: rgba(8, 8, 8, .97);
-        backdrop-filter: blur(16px);
-        border-top: 1px solid var(--line);
-        box-shadow: 0 -14px 40px rgba(0, 0, 0, .46);
-        transform: translateY(110%);
-        transition: transform .32s cubic-bezier(.4,0,.2,1);
-      }
-      .sticky-cta.is-up { transform: none; }
-      .sticky-cta .btn { flex: 1 1 0; min-height: 50px; padding: 0 14px; font-size: .84rem; }
-      .sticky-cta .btn--primary { flex: 1.35 1 0; }
-      body { padding-bottom: 78px; }
-    }
-
-    @media (max-width: 720px) {
-      .nav-actions .nav-call { display: none; }
-      .nav-links { left: 0; right: 0; width: auto; border-inline: 0; }
-      .service-grid, .reviews, .work-grid,
-      .areas-grid, .field-row, .footer-inner {
-        grid-template-columns: 1fr;
-      }
-      .areas-grid > :first-child { grid-column: auto; }
-      .work-heading { align-items: flex-start; flex-direction: column; gap: 17px; }
-      .work-instagram { margin-bottom: 0; }
-      .work-grid { margin-top: 34px; }
-      .strip-inner {
-        width: max-content;
-        max-width: none;
-        margin-inline: 0;
-        flex-wrap: nowrap;
-        align-items: center;
-        justify-content: flex-start;
-        gap: 0;
-        padding-block: 15px;
-        animation: credential-ticker 24s linear infinite;
-        will-change: transform;
-      }
-      .strip-group {
-        width: max-content;
-        flex: 0 0 auto;
-        flex-wrap: nowrap;
-        justify-content: flex-start;
-        gap: 32px;
-        padding: 0 32px 0 var(--gutter);
-      }
-      .strip-group--clone { display: flex; }
-      .strip-inner span { width: auto; white-space: nowrap; }
-      .strip-viewport:hover .strip-inner { animation-play-state: paused; }
-      .btn-row .btn { width: 100%; }
-      .hero { height: 300vh; height: 300svh; }
-      .hero-sticky {
-        align-items: start;
-        padding-top: calc(var(--nav-h) + 54px);
-        padding-bottom: 24px;
-      }
-      .hero-inner { width: 100%; }
-      .hero h1 { font-size: clamp(2.7rem, 12.25vw, 3.45rem); }
-      .hero .lead { margin-top: 19px; font-size: .94rem; line-height: 1.62; }
-      .hero .eyebrow { margin-bottom: 14px; font-size: .65rem; }
-      .hero .hero-primary-actions { margin-top: 22px; }
-      .hero .hero-primary-actions .btn { width: auto; min-height: 48px; padding-inline: 18px; }
-      .hero .hero-primary-actions .btn--ghost { display: none; }
-      .hero-media video,
-      .hero-media img.hero-fallback {
-        object-position: center 50%;
-        filter: saturate(1.02) contrast(1.03) brightness(.9);
-      }
-      .hero-cue { left: 20px; bottom: 26px; transform: none; }
-    }
-
-    @media (prefers-reduced-motion: reduce) {
-      html { scroll-behavior: auto; }
-      .hero { height: auto; }
-      .hero-sticky {
-        position: relative;
-        --hero-cue-opacity: 1;
-        --hero-media-scale: 1;
-        --hero-scrim-opacity: .9;
-        min-height: 100vh;
-        min-height: 100svh;
-      }
-      .hero-media video,
-      .hero-media img.hero-fallback { transform: none; will-change: auto; }
-      .hero-title-inner,
-      .hero-eyebrow,
-      .hero-lead,
-      .hero-primary-actions { opacity: 1 !important; transform: none !important; will-change: auto; }
-      .reveal { opacity: 1; transform: none; transition: none; }
-      .nav, .sticky-cta, .work-tile img, .btn, .service { transition: none; }
-      .work-tile:hover img, .btn:hover, .service:hover { transform: none; }
-    }
-
-    @media (max-width: 720px) and (prefers-reduced-motion: reduce) {
-      .strip-viewport { overflow-x: auto; scrollbar-width: none; }
-      .strip-viewport::-webkit-scrollbar { display: none; }
-      .strip-inner { animation: none; will-change: auto; }
-      .strip-group--clone { display: none; }
-    }
-  </style>
+  <link rel="stylesheet" href="/assets/site.css" />
 </head>
 <body>
   <a class="skip-link" href="#main">Skip to content</a>
@@ -1407,7 +49,7 @@
   <header class="nav" id="nav">
     <div class="wrap nav-inner">
       <a class="brand" href="#top" aria-label="Vold Services home">
-        <img src="https://voldservices.com/logo.png" alt="Vold Services" width="188" height="97" />
+        <img src="/logo.png" alt="Vold Services" width="188" height="97" />
       </a>
 
       <div class="nav-actions">
@@ -1437,7 +79,7 @@
     <section class="hero" id="top">
       <div class="hero-sticky" id="hero-sticky">
         <div class="hero-media">
-          <img class="hero-fallback" src="https://voldservices.com/img/hero-scrub-poster.jpg" alt="" aria-hidden="true" />
+          <img class="hero-fallback" src="/img/hero-scrub-poster.jpg" alt="" aria-hidden="true" />
           <video
             id="hero-video"
             data-desktop-src="/hero-scrub.mp4"
@@ -1511,7 +153,7 @@
                 <path d="M8 26h-3M8 32h-5M8 20h-4"/>
               </svg>
             </div>
-            <h3 class="h3">Pressure washing</h3>
+            <h3 class="h3"><a class="service-title-link" href="/services/pressure-washing/">Pressure washing</a></h3>
             <p>
               We use surface cleaners on concrete and lower pressure on painted or porous areas.
               That clears algae, dirt, and tire marks without treating every surface like a driveway.
@@ -1532,7 +174,7 @@
                 <path d="M6 40h36M6 44h36"/>
               </svg>
             </div>
-            <h3 class="h3">Paver sealing</h3>
+            <h3 class="h3"><a class="service-title-link" href="/services/paver-sealing/">Paver sealing</a></h3>
             <p>
               Good sealing starts with clean, dry pavers and full joints. We wash the surface,
               replace missing joint sand, and apply the finish you choose once the pavers are ready.
@@ -1555,7 +197,7 @@
                 <path d="M27 34h16M35 24v18M30 29l5-5 5 5"/>
               </svg>
             </div>
-            <h3 class="h3">Paver repair</h3>
+            <h3 class="h3"><a class="service-title-link" href="/services/paver-repair/">Paver repair</a></h3>
             <p>
               Loose, sunken, or separated pavers need more than fresh sand. We lift the affected
               area, correct the base, replace damaged pieces when a match is available, and reset it.
@@ -1576,7 +218,7 @@
                 <path d="M16 40V28h8v12"/><path d="M30 28h6v6h-6z"/>
               </svg>
             </div>
-            <h3 class="h3">Roof cleaning</h3>
+            <h3 class="h3"><a class="service-title-link" href="/services/roof-cleaning/">Roof cleaning</a></h3>
             <p>
               Black roof streaks are algae. We clean tile, shingle, and metal roofs with a
               low-pressure soft wash, so a pressure-washer wand never touches the roof surface.
@@ -1604,12 +246,12 @@
           <article class="wand-project reveal" data-comparison-id="result-1">
             <div class="wand">
               <div class="wand-layer">
-                <img data-comparison-side="before" src="https://voldservices.com/img/before-driveway.jpg"
+                <img data-comparison-side="before" src="/img/before-driveway.jpg"
                      alt="Travertine paver driveway dulled by dirt and organic growth before cleaning"
                      loading="lazy" decoding="async" width="746" height="829" />
               </div>
               <div class="wand-layer wand-layer--after">
-                <img data-comparison-side="after" src="https://voldservices.com/img/after-driveway.jpg"
+                <img data-comparison-side="after" src="/img/after-driveway.jpg"
                      alt="The same driveway after pressure washing, re-sanding, and sealing"
                      loading="lazy" decoding="async" width="746" height="829" />
               </div>
@@ -1632,12 +274,12 @@
           <article class="wand-project reveal" data-comparison-id="result-2">
             <div class="wand">
               <div class="wand-layer">
-                <img data-comparison-side="before" src="https://voldservices.com/img/before-pool-deck.jpg"
+                <img data-comparison-side="before" src="/img/before-pool-deck.jpg"
                      alt="Gold travertine pool deck greyed by weathering and organic staining before cleaning"
                      loading="lazy" decoding="async" width="746" height="829" />
               </div>
               <div class="wand-layer wand-layer--after">
-                <img data-comparison-side="after" src="https://voldservices.com/img/after-pool-deck.jpg"
+                <img data-comparison-side="after" src="/img/after-pool-deck.jpg"
                      alt="The same pool deck after cleaning and sealing, with the stone color brought back"
                      loading="lazy" decoding="async" width="746" height="829" />
               </div>
@@ -1677,29 +319,29 @@
           </a>
         </div>
 
-        <div class="work-grid reveal" id="work-grid" data-gallery-manifest="gallery/gallery.json">
+        <div class="work-grid reveal" id="work-grid" data-gallery-manifest="/gallery/gallery.json">
           <button class="work-tile" type="button">
-            <img src="https://voldservices.com/img/after-driveway.jpg" alt="Travertine paver driveway cleaned and sealed at a two-storey South Florida home" loading="lazy" decoding="async" width="746" height="829" />
+            <img src="/img/after-driveway.jpg" alt="Travertine paver driveway cleaned and sealed at a two-storey South Florida home" loading="lazy" decoding="async" width="746" height="829" />
             <span class="work-cap"><b>Driveway wash &amp; seal</b><span>Paver sealing</span></span>
           </button>
           <button class="work-tile" type="button">
-            <img src="https://voldservices.com/img/after-pool-deck.jpg" alt="Gold travertine pool deck sealed to a wet look beside a screened pool" loading="lazy" decoding="async" width="746" height="829" />
+            <img src="/img/after-pool-deck.jpg" alt="Gold travertine pool deck sealed to a wet look beside a screened pool" loading="lazy" decoding="async" width="746" height="829" />
             <span class="work-cap"><b>Pool deck seal</b><span>Paver sealing</span></span>
           </button>
           <button class="work-tile" type="button">
-            <img src="https://voldservices.com/img/after-lanai.jpg" alt="Screened lanai with travertine pavers cleaned back to a warm tone" loading="lazy" decoding="async" width="746" height="829" />
+            <img src="/img/after-lanai.jpg" alt="Screened lanai with travertine pavers cleaned back to a warm tone" loading="lazy" decoding="async" width="746" height="829" />
             <span class="work-cap"><b>Screened lanai</b><span>Pressure washing</span></span>
           </button>
           <button class="work-tile" type="button">
-            <img src="https://voldservices.com/img/after-patio.jpg" alt="Front paver patio and walkway cleaned, weeded, and re-sanded" loading="lazy" decoding="async" width="746" height="829" />
+            <img src="/img/after-patio.jpg" alt="Front paver patio and walkway cleaned, weeded, and re-sanded" loading="lazy" decoding="async" width="746" height="829" />
             <span class="work-cap"><b>Patio &amp; walkway</b><span>Pressure washing</span></span>
           </button>
           <button class="work-tile" type="button">
-            <img src="https://voldservices.com/img/work-driveway-travertine.jpg" alt="Finished travertine paver driveway taped off after sealing" loading="lazy" decoding="async" width="746" height="829" />
+            <img src="/img/work-driveway-travertine.jpg" alt="Finished travertine paver driveway taped off after sealing" loading="lazy" decoding="async" width="746" height="829" />
             <span class="work-cap"><b>Travertine driveway</b><span>Sealed &amp; taped off</span></span>
           </button>
           <button class="work-tile" type="button">
-            <img src="https://voldservices.com/img/work-driveway-install.jpg" alt="Paver driveway restoration in progress, with new pavers being laid over the old concrete" loading="lazy" decoding="async" width="746" height="829" />
+            <img src="/img/work-driveway-install.jpg" alt="Paver driveway restoration in progress, with new pavers being laid over the old concrete" loading="lazy" decoding="async" width="746" height="829" />
             <span class="work-cap"><b>Driveway restoration</b><span>In progress</span></span>
           </button>
         </div>
@@ -1718,7 +360,7 @@
 
         <div class="areas-grid reveal">
           <div class="area area--primary">
-            <h3>Broward County</h3>
+            <h3><a class="service-title-link" href="/service-areas/broward-county/">Broward County</a></h3>
             <ul>
               <li>Fort Lauderdale</li><li>Pembroke Pines</li><li>Hollywood</li><li>Miramar</li>
               <li>Coral Springs</li><li>Plantation</li><li>Weston</li><li>Pompano Beach</li><li>Deerfield Beach</li><li>Coconut Creek</li>
@@ -1728,7 +370,7 @@
           </div>
 
           <div class="area">
-            <h3>Miami-Dade County</h3>
+            <h3><a class="service-title-link" href="/service-areas/miami-dade-county/">Miami-Dade County</a></h3>
             <ul>
               <li>Miami</li><li>Aventura</li><li>Miami Beach</li><li>Doral</li>
               <li>Hialeah</li><li>Kendall</li><li>Coral Gables</li><li>Miami Lakes</li>
@@ -1737,7 +379,7 @@
           </div>
 
           <div class="area">
-            <h3>Palm Beach County</h3>
+            <h3><a class="service-title-link" href="/service-areas/palm-beach-county/">Palm Beach County</a></h3>
             <ul>
               <li>Boca Raton</li><li>Delray Beach</li><li>Boynton Beach</li><li>West Palm Beach</li>
               <li>Wellington</li><li>Jupiter</li><li>Royal Palm Beach</li><li>Lake Worth</li>
@@ -1841,6 +483,7 @@
                   action="https://formspree.io/f/xaewpyaq"
                   method="POST"
                   enctype="multipart/form-data">
+              <input type="hidden" name="source_page" value="/" />
               <div class="field-row">
                 <div class="field">
                   <label for="q-name">Name</label>
@@ -1928,7 +571,7 @@
     <div class="wrap">
       <div class="footer-inner">
         <div>
-          <img src="https://voldservices.com/logo.png" alt="Vold Services" width="168" height="87" />
+          <img src="/logo.png" alt="Vold Services" width="168" height="87" />
           <p>
             Exterior cleaning for homes, HOAs, and commercial properties across Broward,
             Miami-Dade, and Palm Beach counties.
@@ -1956,12 +599,12 @@
         <div>
           <h4>Services</h4>
           <ul>
-            <li><a href="#services">Pressure washing</a></li>
-            <li><a href="#services">Paver sealing</a></li>
-            <li><a href="#services">Paver repair</a></li>
-            <li><a href="#services">Roof cleaning</a></li>
-            <li><a href="#services">House &amp; building wash</a></li>
-            <li><a href="#services">Commercial cleaning</a></li>
+            <li><a href="/services/pressure-washing/">Pressure washing</a></li>
+            <li><a href="/services/paver-sealing/">Paver sealing</a></li>
+            <li><a href="/services/paver-repair/">Paver repair</a></li>
+            <li><a href="/services/roof-cleaning/">Roof cleaning</a></li>
+            <li><a href="/services/pressure-washing/">House &amp; building wash</a></li>
+            <li><a href="/services/pressure-washing/">Commercial cleaning</a></li>
           </ul>
         </div>
         <div>
@@ -1969,7 +612,9 @@
           <ul>
             <li><a href="#results">Before &amp; after</a></li>
             <li><a href="#work">Recent work</a></li>
-            <li><a href="#areas">Service areas</a></li>
+            <li><a href="/service-areas/broward-county/">Broward County</a></li>
+            <li><a href="/service-areas/miami-dade-county/">Miami-Dade County</a></li>
+            <li><a href="/service-areas/palm-beach-county/">Palm Beach County</a></li>
             <li><a href="#quote">Contact</a></li>
             <li><a href="tel:+19544013301">(954) 401-3301</a></li>
           </ul>
@@ -2110,686 +755,7 @@
   }
   </script>
 
-  <script>
-    (function () {
-      'use strict';
-
-      var reduceMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
-
-      /* ── cinematic hero scroll ────────────────────────────────
-         The section supplies the scroll distance; its sticky child remains
-         pinned while these values interpolate from the user's real scroll.
-         No scroll is captured or eased, so trackpads and touch keep their
-         native feel. */
-      var heroCinematic = document.getElementById('top');
-      var heroSticky = document.getElementById('hero-sticky');
-      var heroCue = heroSticky.querySelector('.hero-cue');
-      var heroEyebrow = heroSticky.querySelector('.hero-eyebrow');
-      var heroLead = heroSticky.querySelector('.hero-lead');
-      var heroActions = document.getElementById('hero-actions');
-      var heroMedia = heroSticky.querySelector('.hero-media');
-      var heroVideo = document.getElementById('hero-video');
-      var heroVideoReady = false;
-      var heroVideoPrimed = false;
-      var heroVideoPrimePending = false;
-      var heroTouchStarted = false;
-      var heroUsesTouch = ('ontouchstart' in window) || navigator.maxTouchPoints > 0;
-      var heroVideoVisible = false;
-      var heroVideoRevealPending = false;
-      var heroVideoProgress = 0;
-      var heroVideoObjectUrl = '';
-
-      function clamp01(value) {
-        return Math.max(0, Math.min(1, value));
-      }
-
-      function smoothstep(value) {
-        value = clamp01(value);
-        return value * value * (3 - (2 * value));
-      }
-
-      function paintReveal(element, progress, travel) {
-        element.style.opacity = progress.toFixed(4);
-        element.style.transform = 'translate3d(0,' + ((1 - progress) * travel).toFixed(2) + 'px,0)';
-      }
-
-      /* The optimized file has a seek point every three frames. Keep the
-         video paused and seek its playhead to the user's actual scroll
-         position; there is no autonomous playback or scroll hijacking. */
-      function syncHeroVideo(progress, force) {
-        heroVideoProgress = progress;
-        if (reduceMotion || !heroVideoReady || !Number.isFinite(heroVideo.duration)) return;
-
-        var usableDuration = Math.max(heroVideo.duration - (1 / 24), 0);
-        // Safari can clear the poster before it has decoded a seek at exactly
-        // zero. Start a fraction into the first frame and keep a real image
-        // beneath the video until a decoded frame has actually been painted.
-        var targetTime = Math.max(1 / 48, usableDuration * heroVideoProgress);
-        if (!force && (heroVideo.seeking || Math.abs(heroVideo.currentTime - targetTime) < (1 / 48))) return;
-        heroVideo.currentTime = targetTime;
-      }
-
-      function revealHeroVideo() {
-        if (reduceMotion || heroVideoVisible || heroVideoRevealPending || heroVideo.readyState < 2) return;
-        heroVideoRevealPending = true;
-
-        var reveal = function () {
-          heroVideoRevealPending = false;
-          if (reduceMotion || heroVideoVisible || heroVideo.readyState < 2) return;
-          heroVideoVisible = true;
-          heroMedia.classList.add('is-video-ready');
-        };
-
-        if (typeof heroVideo.requestVideoFrameCallback === 'function') {
-          heroVideo.requestVideoFrameCallback(reveal);
-          // A paused iOS video can finish seeking before a queued frame
-          // callback is delivered. By this point seeked + HAVE_CURRENT_DATA
-          // make a delayed reveal safe, while the poster covers the handoff.
-          window.setTimeout(reveal, 160);
-        } else {
-          window.requestAnimationFrame(function () {
-            window.requestAnimationFrame(reveal);
-          });
-        }
-      }
-
-      function finishHeroVideoPrime() {
-        heroVideo.pause();
-        heroVideoPrimePending = false;
-        heroVideoPrimed = true;
-        heroVideoReady = true;
-        window.removeEventListener('touchstart', primeHeroVideoFromTouch);
-        syncHeroVideo(heroVideoProgress, true);
-      }
-
-      function usePausedSeekFallback() {
-        heroVideo.pause();
-        heroVideoPrimePending = false;
-        heroVideoReady = true;
-        syncHeroVideo(heroVideoProgress, true);
-      }
-
-      // iOS may load metadata for a muted video without activating its decoder.
-      // On touch devices, a brief hidden play/pause on the first scroll touch
-      // primes frame presentation without autoplay or visible player chrome.
-      function primeHeroVideo() {
-        if (reduceMotion || heroVideoPrimed || heroVideoPrimePending || heroVideo.readyState < 1) return;
-
-        heroVideoPrimePending = true;
-        heroVideo.muted = true;
-        heroVideo.defaultMuted = true;
-
-        var playAttempt = heroVideo.play();
-        if (playAttempt && typeof playAttempt.then === 'function') {
-          playAttempt.then(finishHeroVideoPrime).catch(usePausedSeekFallback);
-        } else {
-          finishHeroVideoPrime();
-        }
-      }
-
-      function primeHeroVideoFromTouch() {
-        heroTouchStarted = true;
-        primeHeroVideo();
-      }
-
-      function prepareHeroVideo() {
-        if (!heroUsesTouch || heroTouchStarted) primeHeroVideo();
-      }
-
-      function attachHeroVideoSource(source) {
-        heroVideo.src = source;
-        heroVideo.load();
-      }
-
-      /* The origin currently serves MP4 files without byte-range responses.
-         Mobile's smaller encode can finish downloading before that becomes
-         noticeable, but desktop seeks otherwise snap back to frame zero.
-         Buffer the desktop file into a blob so its full timeline is locally
-         seekable, keeping the poster visible until the first frame is ready. */
-      function loadHeroVideo() {
-        var mobileSource = window.innerWidth <= 720;
-        var source = mobileSource
-          ? heroVideo.getAttribute('data-mobile-src')
-          : heroVideo.getAttribute('data-desktop-src');
-
-        if (mobileSource || typeof window.fetch !== 'function' || typeof window.URL.createObjectURL !== 'function') {
-          attachHeroVideoSource(source);
-          return;
-        }
-
-        window.fetch(source, { cache: 'force-cache' })
-          .then(function (response) {
-            if (!response.ok) throw new Error('Hero video request failed');
-            return response.blob();
-          })
-          .then(function (blob) {
-            heroVideoObjectUrl = window.URL.createObjectURL(blob);
-            attachHeroVideoSource(heroVideoObjectUrl);
-          })
-          .catch(function () {
-            attachHeroVideoSource(source);
-          });
-      }
-
-      if (reduceMotion) {
-        heroVideo.pause();
-      } else {
-        heroVideo.addEventListener('loadedmetadata', prepareHeroVideo);
-        if (heroUsesTouch) {
-          window.addEventListener('touchstart', primeHeroVideoFromTouch, { passive: true });
-        }
-
-        // Cached media can reach metadata before this bottom-of-page script runs.
-        if (heroVideo.readyState >= 1) prepareHeroVideo();
-
-        loadHeroVideo();
-      }
-
-      window.addEventListener('beforeunload', function () {
-        if (heroVideoObjectUrl) window.URL.revokeObjectURL(heroVideoObjectUrl);
-      });
-
-      // If the user scrolls again while a seek is being decoded, catch the
-      // playhead up to the most recent position as soon as that frame lands.
-      heroVideo.addEventListener('seeked', function () {
-        revealHeroVideo();
-        syncHeroVideo(heroVideoProgress, false);
-      });
-
-      heroVideo.addEventListener('error', function () {
-        heroVideoReady = false;
-        heroVideoPrimed = false;
-        heroVideoPrimePending = false;
-        heroVideoVisible = false;
-        heroVideoRevealPending = false;
-        heroMedia.classList.remove('is-video-ready');
-      });
-
-      function paintHeroScroll() {
-        if (reduceMotion) {
-          heroActions.inert = false;
-          heroActions.setAttribute('aria-hidden', 'false');
-          return;
-        }
-
-        var runway = Math.max(heroCinematic.offsetHeight - window.innerHeight, 1);
-        var progress = clamp01(-heroCinematic.getBoundingClientRect().top / runway);
-        syncHeroVideo(progress, false);
-        var eyebrowIn = smoothstep((progress - 0.1) / 0.15);
-        var leadIn = smoothstep((progress - 0.28) / 0.18);
-        var actionsIn = smoothstep((progress - 0.42) / 0.18);
-        var cueOut = smoothstep(progress / 0.12);
-        var scrimIn = smoothstep((progress - 0.08) / 0.42);
-
-        heroSticky.style.setProperty('--hero-media-scale', (1.03 + (0.08 * smoothstep(progress))).toFixed(4));
-        heroSticky.style.setProperty('--hero-scrim-opacity', (0.3 + (0.7 * scrimIn)).toFixed(4));
-        heroSticky.style.setProperty('--hero-cue-opacity', (1 - cueOut).toFixed(4));
-
-        paintReveal(heroEyebrow, eyebrowIn, 20);
-        paintReveal(heroLead, leadIn, 30);
-        paintReveal(heroActions, actionsIn, 24);
-
-        var cueActive = cueOut < 0.92;
-        var actionsActive = actionsIn > 0.8;
-
-        heroCue.style.pointerEvents = cueActive ? '' : 'none';
-        heroCue.inert = !cueActive;
-        heroCue.setAttribute('aria-hidden', String(!cueActive));
-        heroActions.style.pointerEvents = actionsActive ? '' : 'none';
-        heroActions.inert = !actionsActive;
-        heroActions.setAttribute('aria-hidden', String(!actionsActive));
-      }
-
-      /* ── scroll-aware nav ─────────────────────────────────────
-         Keeps the nav visible while the oversized opening state compacts. */
-      var nav = document.getElementById('nav');
-      var navProgress = document.getElementById('nav-progress');
-      var navToggle = document.querySelector('.nav-toggle');
-      var navLinksWrap = document.getElementById('nav-links');
-      var navAnchors = navLinksWrap.querySelectorAll('a[href^="#"]');
-      var stickyCta = document.getElementById('sticky-cta');
-      var ticking = false;
-
-      function mix(from, to, progress) {
-        return from + ((to - from) * progress);
-      }
-
-      /* The opening masthead collapses over the first 220px of real scroll.
-         Values finish at the original compact nav measurements. */
-      function paintNavScale(y) {
-        var mobileNav = window.innerWidth <= 900;
-        var progress = reduceMotion ? (y > 12 ? 1 : 0) : smoothstep(clamp01(y / 220));
-        var compactLogo = Math.min(188, Math.max(146, window.innerWidth * 0.17));
-        var introLogo = mobileNav
-          ? Math.min(240, Math.max(190, window.innerWidth * 0.45))
-          : Math.min(310, Math.max(230, window.innerWidth * 0.24));
-        var introHeight = mobileNav
-          ? 104
-          : Math.min(138, Math.max(112, window.innerHeight * 0.12));
-
-        nav.style.setProperty('--nav-live-height', mix(introHeight, 76, progress).toFixed(2) + 'px');
-        nav.style.setProperty('--nav-live-logo', mix(introLogo, compactLogo, progress).toFixed(2) + 'px');
-        nav.style.setProperty('--nav-live-call-font', mix(16, 13.76, progress).toFixed(2) + 'px');
-        nav.style.setProperty('--nav-live-call-y', mix(14, 11, progress).toFixed(2) + 'px');
-        nav.style.setProperty('--nav-live-call-x', mix(22, 18, progress).toFixed(2) + 'px');
-        nav.style.setProperty('--nav-live-icon', mix(18, 15, progress).toFixed(2) + 'px');
-      }
-
-      function onScroll() {
-        var y = window.scrollY;
-        var max = document.documentElement.scrollHeight - window.innerHeight;
-
-        paintHeroScroll();
-        paintNavScale(y);
-
-        nav.classList.toggle('is-stuck', y > 12);
-        navProgress.style.transform = 'scaleX(' + (max > 0 ? Math.min(y / max, 1) : 0) + ')';
-
-        stickyCta.classList.toggle('is-up', y > heroCinematic.offsetTop + heroCinematic.offsetHeight);
-        ticking = false;
-      }
-
-      window.addEventListener('scroll', function () {
-        if (ticking) return;
-        ticking = true;
-        window.requestAnimationFrame(onScroll);
-      }, { passive: true });
-      window.addEventListener('resize', function () {
-        if (ticking) return;
-        ticking = true;
-        window.requestAnimationFrame(onScroll);
-      });
-      onScroll();
-
-      /* ── mobile menu ──────────────────────────────────────── */
-      navToggle.addEventListener('click', function () {
-        var open = navToggle.getAttribute('aria-expanded') === 'true';
-        navToggle.setAttribute('aria-expanded', String(!open));
-        navToggle.setAttribute('aria-label', open ? 'Open menu' : 'Close menu');
-        nav.classList.toggle('is-open', !open);
-      });
-
-      function closeMenu() {
-        navToggle.setAttribute('aria-expanded', 'false');
-        navToggle.setAttribute('aria-label', 'Open menu');
-        nav.classList.remove('is-open');
-      }
-      navLinksWrap.addEventListener('click', function (e) {
-        if (e.target.closest('a')) closeMenu();
-      });
-      document.addEventListener('keydown', function (e) {
-        if (e.key === 'Escape' && nav.classList.contains('is-open')) {
-          closeMenu();
-          navToggle.focus();
-        }
-      });
-      document.addEventListener('click', function (e) {
-        if (!nav.classList.contains('is-open') || nav.contains(e.target)) return;
-        closeMenu();
-      });
-
-      /* ── active section in the nav ────────────────────────── */
-      var sections = [];
-      navAnchors.forEach(function (a) {
-        var el = document.querySelector(a.getAttribute('href'));
-        if (el) sections.push({ el: el, link: a });
-      });
-
-      if (sections.length && 'IntersectionObserver' in window) {
-        var spy = new IntersectionObserver(function (entries) {
-          entries.forEach(function (entry) {
-            if (!entry.isIntersecting) return;
-            navAnchors.forEach(function (a) { a.classList.remove('is-current'); });
-            var match = sections.find(function (s) { return s.el === entry.target; });
-            if (match) match.link.classList.add('is-current');
-          });
-        }, { rootMargin: '-45% 0px -50% 0px' });
-        sections.forEach(function (s) { spy.observe(s.el); });
-      }
-
-      /* ── reveal on scroll ─────────────────────────────────── */
-      var reveals = document.querySelectorAll('.reveal');
-      if (reduceMotion || !('IntersectionObserver' in window)) {
-        reveals.forEach(function (el) { el.classList.add('is-in'); });
-      } else {
-        var revealObserver = new IntersectionObserver(function (entries) {
-          entries.forEach(function (entry) {
-            if (!entry.isIntersecting) return;
-            entry.target.classList.add('is-in');
-            revealObserver.unobserve(entry.target);
-          });
-        }, { threshold: 0.12, rootMargin: '0px 0px -6% 0px' });
-        reveals.forEach(function (el) { revealObserver.observe(el); });
-      }
-
-      /* ── the wand line ────────────────────────────────────── */
-      document.querySelectorAll('.wand').forEach(function (wand) {
-        var wandRange = wand.querySelector('.wand-range');
-
-        function paintWand() {
-          wand.style.setProperty('--pos', wandRange.value + '%');
-          var beforePercent = Math.round(Number(wandRange.value));
-          wandRange.setAttribute('aria-valuetext', beforePercent + '% before, ' + (100 - beforePercent) + '% after');
-        }
-
-        wandRange.addEventListener('input', paintWand);
-        paintWand();
-      });
-
-      /* ── gallery lightbox ─────────────────────────────────── */
-      var lightbox = document.getElementById('lightbox');
-      var lightboxImg = document.getElementById('lightbox-img');
-      var lightboxClose = lightbox.querySelector('.lightbox-close');
-      var lastFocused = null;
-      var workGrid = document.getElementById('work-grid');
-
-      workGrid.addEventListener('click', function (event) {
-        var tile = event.target.closest('.work-tile');
-        if (!tile || !workGrid.contains(tile)) return;
-        var img = tile.querySelector('img');
-        if (!img) return;
-        lastFocused = tile;
-        lightboxImg.src = img.dataset.full || img.currentSrc || img.src;
-        lightboxImg.alt = img.alt;
-        lightbox.classList.add('is-open');
-        document.body.classList.add('is-locked');
-        lightboxClose.focus();
-      });
-
-      function renderManagedPhotos(manifest) {
-        if (!manifest || manifest.version !== 1 || !Array.isArray(manifest.images)) return;
-
-        if (Array.isArray(manifest.comparisons)) {
-          manifest.comparisons.forEach(function (comparison) {
-            var project = Array.prototype.find.call(
-              document.querySelectorAll('[data-comparison-id]'),
-              function (item) { return item.dataset.comparisonId === comparison.id; }
-            );
-            if (!project) return;
-            ['before', 'after'].forEach(function (side) {
-              var media = comparison[side];
-              var image = project.querySelector('[data-comparison-side="' + side + '"]');
-              if (!image || !media || !media.src || !media.alt) return;
-              image.src = media.src;
-              image.alt = media.alt;
-            });
-          });
-        }
-
-        var fragment = document.createDocumentFragment();
-        manifest.images.forEach(function (item) {
-          if (!item || !item.src || !item.caption || !item.alt) return;
-          var tile = document.createElement('button');
-          tile.className = 'work-tile';
-          tile.type = 'button';
-
-          var image = document.createElement('img');
-          image.src = item.thumb || item.src;
-          image.alt = item.alt;
-          image.loading = 'lazy';
-          image.decoding = 'async';
-          image.dataset.full = item.src;
-
-          var cap = document.createElement('span');
-          cap.className = 'work-cap';
-          var title = document.createElement('b');
-          title.textContent = item.caption;
-          cap.appendChild(title);
-          tile.appendChild(image);
-          tile.appendChild(cap);
-          fragment.appendChild(tile);
-        });
-        workGrid.replaceChildren(fragment);
-      }
-
-      fetch(workGrid.dataset.galleryManifest, { credentials: 'same-origin' })
-        .then(function (response) {
-          if (!response.ok) throw new Error('Gallery request failed');
-          return response.json();
-        })
-        .then(renderManagedPhotos)
-        .catch(function () {
-          // Keep the server-rendered photos in place as the resilient fallback.
-        });
-
-      function closeLightbox() {
-        lightbox.classList.remove('is-open');
-        document.body.classList.remove('is-locked');
-        lightboxImg.removeAttribute('src');
-        lightboxImg.alt = '';
-        if (lastFocused) lastFocused.focus();
-      }
-      lightboxClose.addEventListener('click', closeLightbox);
-      lightbox.addEventListener('click', function (e) {
-        if (e.target === lightbox) closeLightbox();
-      });
-      document.addEventListener('keydown', function (e) {
-        if (e.key === 'Escape' && lightbox.classList.contains('is-open')) closeLightbox();
-      });
-
-      /* ── quote form ─────────────────────────────────────────── */
-      var form = document.getElementById('quote-form');
-      var success = document.getElementById('form-success');
-      var successName = document.getElementById('success-name');
-      var formError = document.getElementById('form-error');
-      var submitButton = document.getElementById('quote-submit');
-      var photoInput = document.getElementById('q-photos');
-      var photoList = document.getElementById('q-photo-list');
-      var photoStatus = document.getElementById('q-photos-status');
-      var maxPhotos = 5;
-      var maxPhotoBytes = 25 * 1024 * 1024;
-      var maxTotalPhotoBytes = 90 * 1024 * 1024;
-      var selectedPhotos = [];
-
-      function clearFormError() {
-        formError.hidden = true;
-        formError.textContent = '';
-      }
-
-      function showFormError(message) {
-        formError.textContent = message;
-        formError.hidden = false;
-      }
-
-      function formatPhotoStatus(files) {
-        if (!files.length) return '';
-        return files.length + ' of ' + maxPhotos + (files.length === 1 ? ' photo is' : ' photos are') + ' ready to send.';
-      }
-
-      function photoValidationMessage(files) {
-        var totalBytes = files.reduce(function (total, file) { return total + file.size; }, 0);
-        var oversizedPhoto = files.find(function (file) { return file.size > maxPhotoBytes; });
-        var nonPhoto = files.find(function (file) {
-          return file.type && file.type.indexOf('image/') !== 0;
-        });
-
-        if (files.length > maxPhotos) {
-          return 'Choose no more than 5 photos. Remove one before adding another.';
-        }
-        if (oversizedPhoto) {
-          return oversizedPhoto.name + ' is larger than 25 MB and was not added.';
-        }
-        if (totalBytes > maxTotalPhotoBytes) {
-          return 'Keep the combined photo size under 90 MB. Those photos were not added.';
-        }
-        if (nonPhoto) return 'Choose image files only.';
-        return '';
-      }
-
-      function formatPhotoSize(bytes) {
-        if (bytes < 1024 * 1024) return Math.max(1, Math.round(bytes / 1024)) + ' KB';
-        return (bytes / (1024 * 1024)).toFixed(1).replace('.0', '') + ' MB';
-      }
-
-      function photoKey(file) {
-        return [file.name, file.size, file.lastModified, file.type].join('|');
-      }
-
-      function renderPhotos(message) {
-        photoList.textContent = '';
-        selectedPhotos.forEach(function (file, index) {
-          var item = document.createElement('li');
-          var fileDetails = document.createElement('span');
-          var fileName = document.createElement('span');
-          var fileSize = document.createElement('span');
-          var removeButton = document.createElement('button');
-
-          item.className = 'photo-item';
-          fileDetails.className = 'photo-file';
-          fileName.className = 'photo-name';
-          fileName.textContent = file.name;
-          fileSize.className = 'photo-size';
-          fileSize.textContent = 'Photo ' + (index + 1) + ' · ' + formatPhotoSize(file.size);
-          removeButton.className = 'photo-remove';
-          removeButton.type = 'button';
-          removeButton.dataset.photoIndex = index;
-          removeButton.setAttribute('aria-label', 'Remove ' + file.name);
-          removeButton.textContent = 'Remove';
-
-          fileDetails.appendChild(fileName);
-          fileDetails.appendChild(fileSize);
-          item.appendChild(fileDetails);
-          item.appendChild(removeButton);
-          photoList.appendChild(item);
-        });
-
-        photoList.hidden = selectedPhotos.length === 0;
-        photoStatus.textContent = message || formatPhotoStatus(selectedPhotos);
-      }
-
-      function validatePhotos() {
-        var message = photoValidationMessage(selectedPhotos);
-        photoInput.setCustomValidity(message);
-        if (message) {
-          photoStatus.textContent = message;
-          return false;
-        }
-
-        photoStatus.textContent = formatPhotoStatus(selectedPhotos);
-        return true;
-      }
-
-      function formspreeErrorMessage(data, status) {
-        var errors = data && Array.isArray(data.errors) ? data.errors : [];
-        var codes = errors.map(function (error) { return error.code; });
-
-        if (status === 429) {
-          return 'Too many requests were sent at once. Wait a minute, then try again.';
-        }
-        if (codes.indexOf('NO_FILE_UPLOADS') !== -1) {
-          return 'Photo uploads are not enabled for this form yet. Remove the photos and try again, or call or text (954) 401-3301.';
-        }
-        if (codes.indexOf('TOO_MANY_FILES') !== -1) {
-          return 'Too many photos were attached. Choose up to 5 and try again.';
-        }
-        if (codes.indexOf('FILES_TOO_BIG') !== -1) {
-          return 'One or more photos are too large. Choose smaller files and try again.';
-        }
-
-        var messages = errors.map(function (error) { return error.message; }).filter(Boolean);
-        if (messages.length) return messages.join(' ');
-        return 'Your request could not be sent. Check your connection and try again, or call or text (954) 401-3301.';
-      }
-
-      photoInput.addEventListener('change', function () {
-        clearFormError();
-        var incomingPhotos = Array.prototype.slice.call(photoInput.files || []);
-        var selectedKeys = selectedPhotos.map(photoKey);
-        var duplicateCount = 0;
-
-        photoInput.value = '';
-        incomingPhotos = incomingPhotos.filter(function (file) {
-          var key = photoKey(file);
-          if (selectedKeys.indexOf(key) !== -1) {
-            duplicateCount += 1;
-            return false;
-          }
-          selectedKeys.push(key);
-          return true;
-        });
-
-        var candidatePhotos = selectedPhotos.concat(incomingPhotos);
-        var message = photoValidationMessage(candidatePhotos);
-        photoInput.setCustomValidity('');
-
-        if (message) {
-          renderPhotos(message);
-          return;
-        }
-
-        selectedPhotos = candidatePhotos;
-        renderPhotos(duplicateCount
-          ? (duplicateCount === 1 ? 'That photo is already selected. ' : 'Those photos are already selected. ') + formatPhotoStatus(selectedPhotos)
-          : '');
-      });
-
-      photoList.addEventListener('click', function (e) {
-        var removeButton = e.target.closest('.photo-remove');
-        if (!removeButton) return;
-
-        var index = Number(removeButton.dataset.photoIndex);
-        if (!Number.isInteger(index) || !selectedPhotos[index]) return;
-
-        selectedPhotos.splice(index, 1);
-        photoInput.setCustomValidity('');
-        clearFormError();
-        renderPhotos();
-      });
-
-      form.addEventListener('submit', async function (e) {
-        e.preventDefault();
-        clearFormError();
-
-        if (!validatePhotos() || !form.checkValidity()) {
-          form.reportValidity();
-          return;
-        }
-
-        var submittedName = form.querySelector('#q-name').value.trim();
-        var originalButtonText = submitButton.textContent;
-        form.setAttribute('aria-busy', 'true');
-        submitButton.disabled = true;
-        submitButton.textContent = 'Sending request…';
-
-        try {
-          var formData = new FormData(form);
-          formData.delete(photoInput.name);
-          selectedPhotos.forEach(function (file) {
-            formData.append(photoInput.name, file, file.name);
-          });
-
-          var response = await fetch(form.action, {
-            method: form.method,
-            body: formData,
-            headers: { 'Accept': 'application/json' }
-          });
-          var data = await response.json().catch(function () { return null; });
-
-          if (!response.ok) {
-            throw { formspree: true, data: data, status: response.status };
-          }
-
-          successName.textContent = submittedName || 'we’ve got it';
-          form.reset();
-          selectedPhotos = [];
-          renderPhotos();
-          form.hidden = true;
-          success.hidden = false;
-          success.focus();
-        } catch (error) {
-          var message = error && error.formspree
-            ? formspreeErrorMessage(error.data, error.status)
-            : 'Your request could not be sent. Check your connection and try again, or call or text (954) 401-3301.';
-          showFormError(message);
-        } finally {
-          form.removeAttribute('aria-busy');
-          submitButton.disabled = false;
-          submitButton.textContent = originalButtonText;
-        }
-      });
-
-      document.getElementById('year').textContent = new Date().getFullYear();
-    })();
-  </script>
+  <script src="/assets/home-hero.js"></script>
+  <script src="/assets/site.js"></script>
 </body>
 </html>
diff --git a/docs/robots.txt b/docs/robots.txt
new file mode 100644
index 0000000..1a3a8e3
--- /dev/null
+++ b/docs/robots.txt
@@ -0,0 +1,4 @@
+User-agent: *
+Allow: /
+
+Sitemap: https://voldservices.com/sitemap.xml
diff --git a/docs/service-areas/broward-county/index.html b/docs/service-areas/broward-county/index.html
new file mode 100644
index 0000000..9e14e06
--- /dev/null
+++ b/docs/service-areas/broward-county/index.html
@@ -0,0 +1,455 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8" />
+<meta name="viewport" content="width=device-width, initial-scale=1.0" />
+<title>Pressure Washing &amp; Paver Sealing in Broward County | Vold Services</title>
+<meta name="description" content="Pressure washing, paver sealing and repair, and roof cleaning in Broward County. Serving Fort Lauderdale, Hollywood, Pembroke Pines, and surrounding cities." />
+<meta name="robots" content="index, follow, max-image-preview:large" />
+<link rel="canonical" href="https://voldservices.com/service-areas/broward-county/" />
+<meta property="og:type" content="website" />
+<meta property="og:site_name" content="Vold Services" />
+<meta property="og:title" content="Pressure Washing &amp; Paver Sealing in Broward County | Vold Services" />
+<meta property="og:description" content="Pressure washing, paver sealing and repair, and roof cleaning in Broward County. Serving Fort Lauderdale, Hollywood, Pembroke Pines, and surrounding cities." />
+<meta property="og:url" content="https://voldservices.com/service-areas/broward-county/" />
+<meta property="og:image" content="https://voldservices.com/og-card-v2.jpg" />
+<meta property="og:image:alt" content="Vold Services exterior cleaning in South Florida" />
+<meta name="twitter:card" content="summary_large_image" />
+<meta name="twitter:title" content="Pressure Washing &amp; Paver Sealing in Broward County | Vold Services" />
+<meta name="twitter:description" content="Pressure washing, paver sealing and repair, and roof cleaning in Broward County. Serving Fort Lauderdale, Hollywood, Pembroke Pines, and surrounding cities." />
+<meta name="twitter:image" content="https://voldservices.com/og-card-v2.jpg" />
+<link rel="icon" href="/favicon.png" type="image/png" />
+<link rel="apple-touch-icon" href="/favicon.png" />
+  <link rel="preconnect" href="https://fonts.googleapis.com" />
+  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
+  <link href="https://fonts.googleapis.com/css2?family=Manrope:wght@400;500;600&family=Roboto+Mono:wght@400;500&family=Teko:wght@500;600&display=swap" rel="stylesheet" />
+<link rel="stylesheet" href="/assets/site.css" />
+<link rel="stylesheet" href="/assets/pages.css" />
+<noscript><style>.reveal { opacity: 1; transform: none; }</style></noscript>
+<script type="application/ld+json">{
+  "@context": "https://schema.org",
+  "@graph": [
+    {
+      "@type": "WebPage",
+      "@id": "https://voldservices.com/service-areas/broward-county/#webpage",
+      "url": "https://voldservices.com/service-areas/broward-county/",
+      "name": "Pressure Washing & Paver Sealing in Broward County | Vold Services",
+      "description": "Pressure washing, paver sealing and repair, and roof cleaning in Broward County. Serving Fort Lauderdale, Hollywood, Pembroke Pines, and surrounding cities.",
+      "isPartOf": {
+        "@id": "https://voldservices.com/#website"
+      },
+      "about": {
+        "@id": "https://voldservices.com/service-areas/broward-county/#service"
+      },
+      "breadcrumb": {
+        "@id": "https://voldservices.com/service-areas/broward-county/#breadcrumb"
+      }
+    },
+    {
+      "@type": "BreadcrumbList",
+      "@id": "https://voldservices.com/service-areas/broward-county/#breadcrumb",
+      "itemListElement": [
+        {
+          "@type": "ListItem",
+          "position": 1,
+          "name": "Home",
+          "item": "https://voldservices.com/"
+        },
+        {
+          "@type": "ListItem",
+          "position": 2,
+          "name": "Service areas",
+          "item": "https://voldservices.com/#areas"
+        },
+        {
+          "@type": "ListItem",
+          "position": 3,
+          "name": "Broward County",
+          "item": "https://voldservices.com/service-areas/broward-county/"
+        }
+      ]
+    },
+    {
+      "@type": "Service",
+      "@id": "https://voldservices.com/service-areas/broward-county/#service",
+      "name": "Exterior cleaning in Broward County",
+      "serviceType": [
+        "Pressure washing",
+        "Paver sealing",
+        "Paver repair",
+        "Roof cleaning"
+      ],
+      "url": "https://voldservices.com/service-areas/broward-county/",
+      "description": "Pressure washing, paver sealing and repair, and roof cleaning in Broward County. Serving Fort Lauderdale, Hollywood, Pembroke Pines, and surrounding cities.",
+      "provider": {
+        "@id": "https://voldservices.com/#business"
+      },
+      "areaServed": [
+        {
+          "@type": "AdministrativeArea",
+          "name": "Broward County, Florida"
+        }
+      ]
+    },
+    {
+      "@type": [
+        "LocalBusiness",
+        "HomeAndConstructionBusiness"
+      ],
+      "@id": "https://voldservices.com/#business",
+      "name": "Vold Services",
+      "url": "https://voldservices.com/",
+      "telephone": "+1-954-401-3301",
+      "logo": "https://voldservices.com/logo.png",
+      "image": "https://voldservices.com/og-card-v2.jpg",
+      "sameAs": [
+        "https://www.instagram.com/voldservices/",
+        "https://www.facebook.com/p/VOLD-Services-61553817020348/",
+        "https://share.google/Gy96TtpQu6SzJoTp2"
+      ],
+      "areaServed": [
+        {
+          "@type": "AdministrativeArea",
+          "name": "Broward County, Florida"
+        },
+        {
+          "@type": "AdministrativeArea",
+          "name": "Miami-Dade County, Florida"
+        },
+        {
+          "@type": "AdministrativeArea",
+          "name": "Palm Beach County, Florida"
+        },
+        {
+          "@type": "City",
+          "name": "Fort Lauderdale"
+        },
+        {
+          "@type": "City",
+          "name": "Pembroke Pines"
+        },
+        {
+          "@type": "City",
+          "name": "Hollywood"
+        },
+        {
+          "@type": "City",
+          "name": "Miramar"
+        },
+        {
+          "@type": "City",
+          "name": "Coral Springs"
+        },
+        {
+          "@type": "City",
+          "name": "Davie"
+        },
+        {
+          "@type": "City",
+          "name": "Plantation"
+        },
+        {
+          "@type": "City",
+          "name": "Sunrise"
+        },
+        {
+          "@type": "City",
+          "name": "Weston"
+        },
+        {
+          "@type": "City",
+          "name": "Pompano Beach"
+        },
+        {
+          "@type": "City",
+          "name": "Deerfield Beach"
+        },
+        {
+          "@type": "City",
+          "name": "Parkland"
+        },
+        {
+          "@type": "City",
+          "name": "Boca Raton"
+        },
+        {
+          "@type": "City",
+          "name": "Miami"
+        }
+      ],
+      "openingHoursSpecification": [
+        {
+          "@type": "OpeningHoursSpecification",
+          "dayOfWeek": [
+            "Monday",
+            "Tuesday",
+            "Wednesday",
+            "Thursday",
+            "Friday",
+            "Saturday"
+          ],
+          "opens": "07:00",
+          "closes": "18:00"
+        }
+      ]
+    },
+    {
+      "@type": "WebSite",
+      "@id": "https://voldservices.com/#website",
+      "url": "https://voldservices.com/",
+      "name": "Vold Services",
+      "publisher": {
+        "@id": "https://voldservices.com/#business"
+      }
+    }
+  ]
+}</script>
+</head>
+<body class="inner-page">
+<a class="skip-link" href="#main">Skip to content</a>
+  <header class="nav" id="nav">
+    <div class="wrap nav-inner">
+      <a class="brand" href="/" aria-label="Vold Services home">
+        <img src="/logo.png" alt="Vold Services" width="188" height="97" />
+      </a>
+
+      <div class="nav-actions">
+        <a class="nav-call" href="tel:+19544013301">
+          <svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M6.6 10.8c1.4 2.7 3.6 4.9 6.3 6.3l2.1-2.1c.3-.3.8-.4 1.1-.2 1.1.4 2.3.6 3.5.6.5 0 .9.4.9.9V20c0 .5-.4.9-.9.9C10.7 20.9 3.1 13.3 3.1 4c0-.5.4-.9.9-.9h3.7c.5 0 .9.4.9.9 0 1.2.2 2.4.6 3.5.1.4.1.8-.2 1.1L6.6 10.8z"/></svg>
+          (954) 401-3301
+        </a>
+        <button class="nav-toggle" type="button" aria-label="Open menu" aria-controls="nav-links" aria-expanded="false">
+          <span></span><span></span><span></span>
+        </button>
+      </div>
+
+      <nav class="nav-links" id="nav-links" aria-label="Primary">
+        <a href="/#services">Services</a>
+        <a href="/#results">Results</a>
+        <a href="/#work">Recent Work</a>
+        <a href="/#areas">Service Areas</a>
+        <a href="/#reviews">Reviews</a>
+        <a href="#quote">Contact</a>
+      </nav>
+    </div>
+    <div class="nav-progress" id="nav-progress" aria-hidden="true"></div>
+  </header>
+<main id="main"><section class="page-hero" id="top"><div class="wrap">
+<nav class="breadcrumbs" aria-label="Breadcrumb"><a href="/">Home</a><span aria-hidden="true">/</span><a href="/#areas">Service areas</a><span aria-hidden="true">/</span><span aria-current="page">Broward County</span></nav>
+<div class="page-hero-grid"><div class="page-hero-copy"><p class="eyebrow">Residential · Commercial · HOA</p><h1>Exterior cleaning<span class="accent">Broward County.</span></h1><p class="lead">From a Fort Lauderdale driveway to a Pembroke Pines patio, plan the exterior work your property needs in one place. Vold Services offers pressure washing, paver sealing and repair, and roof cleaning throughout Broward County.</p><div class="page-actions"><a class="btn btn--primary" href="#quote">Request an estimate</a><a class="btn btn--ghost" href="tel:+19544013301">Call (954) 401-3301</a></div><p class="page-hero-note">Pressure washing · Paver care · Roof cleaning</p></div><figure class="page-hero-photo"><img src="/img/after-driveway.jpg" alt="Completed travertine driveway cleaning and sealing project" width="746" height="829" fetchpriority="high" /><figcaption>From our South Florida project gallery.</figcaption></figure></div></div></section><section class="band"><div class="wrap"><div class="section-head"><p class="eyebrow">Your property. Your project.</p><h2 class="h2">From the driveway to the roof</h2></div><div class="page-detail-grid"><p class="lead">A Broward property may need more than one type of exterior care. Start with the surfaces that need attention: a dirty driveway, worn paver finish, loose border, or streaked roof. We can discuss cleaning, repairs, and sealing together so the estimate reflects the work you actually want.</p><div class="area"><h3 class="h3">Planning work at an occupied property</h3><p class="lead">For a home, storefront, or HOA property, include parking arrangements, gate access, and any areas that need to stay accessible. If you are responding to an HOA notice, describe the requested work and timeframe. We will confirm the scope and arrange a walkthrough when needed.</p></div></div></div></section><section class="band band--tinted" id="services"><div class="wrap"><div class="section-head"><p class="eyebrow">Services in Broward County</p><h2 class="h2">Choose the work you need</h2></div><div class="service-grid"><article class="service"><h3 class="h3"><a class="service-title-link" href="/services/pressure-washing/">Pressure washing</a></h3><p>From a darkened driveway to a tired pool deck, the right wash makes a visible difference. We clean concrete, pavers, and exterior surfaces with pressure and treatment selected for the material.</p><a class="page-link" href="/services/pressure-washing/">Explore pressure washing <span aria-hidden="true">↗</span></a></article>
+<article class="service"><h3 class="h3"><a class="service-title-link" href="/services/paver-sealing/">Paver sealing</a></h3><p>Give your driveway, walkway, or pool deck a finish that suits the property. We clean the pavers, replace missing joint sand, and seal once the surface is ready.</p><a class="page-link" href="/services/paver-sealing/">Explore paver sealing <span aria-hidden="true">↗</span></a></article>
+<article class="service"><h3 class="h3"><a class="service-title-link" href="/services/paver-repair/">Paver repair</a></h3><p>Loose borders, sunken sections, and uneven joints need attention beneath the surface. We lift the affected pavers, correct the base, and reset the area.</p><a class="page-link" href="/services/paver-repair/">Explore paver repair <span aria-hidden="true">↗</span></a></article>
+<article class="service"><h3 class="h3"><a class="service-title-link" href="/services/roof-cleaning/">Roof cleaning</a></h3><p>Give a roof marked by dark streaks and organic buildup a fresh start. We use a low-pressure soft wash for tile, shingle, and metal roofs, with care for the landscaping below.</p><a class="page-link" href="/services/roof-cleaning/">Explore roof cleaning <span aria-hidden="true">↗</span></a></article></div></div></section><section class="band" id="areas"><div class="wrap"><div class="section-head"><p class="eyebrow">Local coverage</p><h2 class="h2">Broward County communities</h2></div><p class="lead">We serve Broward County, including the communities below. Send your property address with your request so we can confirm the job details and scheduling.</p><ul class="page-cities"><li>Fort Lauderdale</li><li>Pembroke Pines</li><li>Hollywood</li><li>Miramar</li><li>Coral Springs</li><li>Plantation</li><li>Weston</li><li>Pompano Beach</li><li>Deerfield Beach</li><li>Coconut Creek</li><li>Parkland</li><li>Margate</li><li>Lauderhill</li><li>Oakland Park</li><li>Wilton Manors</li><li>Dania Beach</li><li>Hallandale Beach</li><li>Lighthouse Point</li><li>Lauderdale-by-the-Sea</li></ul><a class="page-link" href="#quote">Tell us about your property <span aria-hidden="true">↗</span></a></div></section><section class="band band--tinted"><div class="wrap"><div class="section-head"><p class="eyebrow">Before you book</p><h2 class="h2">Planning your service</h2></div><div class="page-faq"><details><summary>Do you serve both coastal and inland Broward cities?</summary><p>Yes. Our listed coverage includes Fort Lauderdale, Hollywood, and Pompano Beach as well as Pembroke Pines, Weston, Coral Springs, and other Broward communities shown here.</p></details><details><summary>Can I request several services for the same property?</summary><p>Yes. Choose the main service and describe the other areas in your message. For example, include a paver repair with a cleaning and sealing request.</p></details><details><summary>Can you help with exterior cleaning requested by an HOA?</summary><p>We serve HOA and multi-family properties and can provide roof cleaning photos for HOA notices. Include the notice details and requested timeframe so we can discuss the work.</p></details></div></div></section><section class="band band--tinted" id="quote">
+      <div class="wrap">
+        <div class="section-head reveal">
+          <h2 class="h2">Request an estimate</h2>
+          <p class="lead">
+            Send the address, the surface, and any details you know. We'll call or text to confirm
+            the job and arrange a walkthrough if one is needed.
+          </p>
+        </div>
+
+        <div class="quote-grid reveal">
+          <div class="quote-side">
+            <div class="quote-row">
+              <div class="quote-label">Call or text</div>
+              <a class="quote-phone" href="tel:+19544013301">(954) 401-3301</a>
+            </div>
+            <div class="quote-row">
+              <div class="quote-label">Find us online</div>
+              <div class="social-links" aria-label="Vold Services social links">
+                <a class="social-link" href="https://www.instagram.com/voldservices/" target="_blank" rel="noopener noreferrer" aria-label="Vold Services on Instagram" title="Instagram">
+                  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" aria-hidden="true">
+                    <rect x="3" y="3" width="18" height="18" rx="5" />
+                    <circle cx="12" cy="12" r="4" />
+                    <circle cx="17.4" cy="6.6" r="1" fill="currentColor" stroke="none" />
+                  </svg>
+                </a>
+                <a class="social-link" href="https://www.facebook.com/p/VOLD-Services-61553817020348/" target="_blank" rel="noopener noreferrer" aria-label="Vold Services on Facebook" title="Facebook">
+                  <svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
+                    <path d="M14.2 8H17V4h-3.2C10.6 4 9 5.9 9 9v2H6v4h3v7h4v-7h3.2l.8-4h-4V9.4c0-1 .3-1.4 1.2-1.4Z" />
+                  </svg>
+                </a>
+                <a class="social-link" href="https://share.google/Gy96TtpQu6SzJoTp2" target="_blank" rel="noopener noreferrer" aria-label="Vold Services on Google" title="Google">
+                  <svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
+                    <path d="M12.48 10.92v3.28h4.58c-.18 1.1-1.37 3.23-4.58 3.23-2.75 0-5-2.28-5-5.07s2.25-5.07 5-5.07c1.57 0 2.62.67 3.22 1.25l2.2-2.13C16.48 5.1 14.66 4.3 12.48 4.3 8.02 4.3 4.4 7.9 4.4 12.36s3.62 8.06 8.08 8.06c4.66 0 7.75-3.27 7.75-7.89 0-.53-.06-.93-.13-1.61h-7.62Z" />
+                  </svg>
+                </a>
+              </div>
+            </div>
+            <div class="quote-row">
+              <div class="quote-label">Services</div>
+              <div class="quote-value">Pressure washing · Paver sealing · Paver repair · Roof cleaning</div>
+            </div>
+            <div class="quote-row">
+              <div class="quote-label">Service area</div>
+              <div class="quote-value">Broward, Miami-Dade, and Palm Beach counties</div>
+            </div>
+            <div class="quote-row">
+              <div class="quote-label">Property types</div>
+              <div class="quote-value">Residential, commercial, HOA and multi-family</div>
+            </div>
+            <div class="quote-row">
+              <div class="quote-label">Hours</div>
+              <div class="quote-value">Monday–Saturday, 7:00 AM – 6:00 PM</div>
+            </div>
+          </div>
+
+          <div class="quote-form-wrap">
+            <form class="quote-form" id="quote-form"
+                  action="https://formspree.io/f/xaewpyaq"
+                  method="POST"
+                  enctype="multipart/form-data">
+              <input type="hidden" name="source_page" value="/service-areas/broward-county/" />
+<input type="hidden" name="county" value="Broward County" />
+              <div class="field-row">
+                <div class="field">
+                  <label for="q-name">Name</label>
+                  <input id="q-name" name="name" type="text" autocomplete="name" placeholder="Your name" required />
+                </div>
+                <div class="field">
+                  <label for="q-phone">Phone</label>
+                  <input id="q-phone" name="phone" type="tel" autocomplete="tel" placeholder="(954) 000-0000" required />
+                </div>
+              </div>
+              <div class="field-row">
+                <div class="field">
+                  <label for="q-email">Email</label>
+                  <input id="q-email" name="email" type="email" autocomplete="email" placeholder="[email protected]" />
+                </div>
+                <div class="field">
+                  <label for="q-city">City</label>
+                  <input id="q-city" name="city" type="text" autocomplete="address-level2" placeholder="Fort Lauderdale" />
+                </div>
+              </div>
+              <div class="field-row">
+                <div class="field">
+                  <label for="q-service">Service needed</label>
+                  <select id="q-service" name="service">
+                    <option>Pressure washing</option>
+                    <option>Paver sealing</option>
+                    <option>Paver repair</option>
+                    <option>Roof cleaning</option>
+                    <option>House wash</option>
+                    <option>Pool deck or patio</option>
+                    <option>Commercial / recurring</option>
+                    <option>Not sure yet</option>
+                  </select>
+                </div>
+                <div class="field">
+                  <label for="q-property">Property type</label>
+                  <select id="q-property" name="property">
+                    <option>Residential</option>
+                    <option>Commercial</option>
+                    <option>HOA / multi-family</option>
+                  </select>
+                </div>
+              </div>
+              <div class="field">
+                <label for="q-message">What needs cleaning?</label>
+                <textarea id="q-message" name="message" placeholder="Approximate size, roof material, when it was last cleaned, or anything else that will help us quote the job."></textarea>
+              </div>
+              <div class="field">
+                <label for="q-photos">Show us the surface <span aria-hidden="true">·</span> Optional</label>
+                <input class="photo-input" id="q-photos" name="photos" type="file" accept="image/*" multiple
+                       aria-describedby="q-photos-help q-photos-status" />
+                <label class="photo-picker" for="q-photos">
+                  <span class="photo-picker__action">Add photos</span>
+                  <span class="photo-picker__note">One at a time or several together</span>
+                </label>
+                <p class="field-help" id="q-photos-help">Add up to 5 photos. You can open the picker again to add more. Maximum 25 MB each and 90 MB total.</p>
+                <ul class="photo-list" id="q-photo-list" aria-label="Selected photos" hidden></ul>
+                <p class="photo-status" id="q-photos-status" aria-live="polite"></p>
+              </div>
+              <div class="form-error" id="form-error" role="alert" hidden></div>
+              <button class="btn btn--primary btn--block" id="quote-submit" type="submit">Request an estimate</button>
+              <p class="form-note">Prefer to talk? Call or text (954) 401-3301 during business hours.</p>
+            </form>
+
+            <div class="form-success" id="form-success" role="status" aria-live="polite" tabindex="-1" hidden>
+              <div>
+                <div class="success-mark" aria-hidden="true">
+                  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
+                    <path d="m5 12 4 4L19 6" />
+                  </svg>
+                </div>
+                <p class="eyebrow">Request received</p>
+                <h3>Thanks, <span id="success-name">we’ve got it</span>.</h3>
+                <p>We’ll call or text to confirm the details and arrange a walkthrough if one is needed.</p>
+                <a class="quote-value" href="tel:+19544013301">Need us sooner? Call (954) 401-3301</a>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+    </section><section class="band band--tinted"><div class="wrap"><div class="section-head"><p class="eyebrow">Across South Florida</p><h2 class="h2">Other service areas</h2></div><div class="page-two-grid"><article class="service"><h3 class="h3"><a class="service-title-link" href="/service-areas/miami-dade-county/">Miami-Dade County</a></h3><p>Pressure washing, paver sealing and repair, and roof cleaning across Miami-Dade County.</p><a class="page-link" href="/service-areas/miami-dade-county/">Explore miami-dade county <span aria-hidden="true">↗</span></a></article>
+<article class="service"><h3 class="h3"><a class="service-title-link" href="/service-areas/palm-beach-county/">Palm Beach County</a></h3><p>Pressure washing, paver sealing and repair, and roof cleaning across Palm Beach County.</p><a class="page-link" href="/service-areas/palm-beach-county/">Explore palm beach county <span aria-hidden="true">↗</span></a></article></div></div></section></main>
+  <footer class="footer">
+    <div class="wrap">
+      <div class="footer-inner">
+        <div>
+          <img src="/logo.png" alt="Vold Services" width="168" height="87" />
+          <p>
+            Exterior cleaning for homes, HOAs, and commercial properties across Broward,
+            Miami-Dade, and Palm Beach counties.
+          </p>
+          <div class="social-links" aria-label="Vold Services social links">
+            <a class="social-link" href="https://www.instagram.com/voldservices/" target="_blank" rel="noopener noreferrer" aria-label="Vold Services on Instagram" title="Instagram">
+              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" aria-hidden="true">
+                <rect x="3" y="3" width="18" height="18" rx="5" />
+                <circle cx="12" cy="12" r="4" />
+                <circle cx="17.4" cy="6.6" r="1" fill="currentColor" stroke="none" />
+              </svg>
+            </a>
+            <a class="social-link" href="https://www.facebook.com/p/VOLD-Services-61553817020348/" target="_blank" rel="noopener noreferrer" aria-label="Vold Services on Facebook" title="Facebook">
+              <svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
+                <path d="M14.2 8H17V4h-3.2C10.6 4 9 5.9 9 9v2H6v4h3v7h4v-7h3.2l.8-4h-4V9.4c0-1 .3-1.4 1.2-1.4Z" />
+              </svg>
+            </a>
+            <a class="social-link" href="https://share.google/Gy96TtpQu6SzJoTp2" target="_blank" rel="noopener noreferrer" aria-label="Vold Services on Google" title="Google">
+              <svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
+                <path d="M12.48 10.92v3.28h4.58c-.18 1.1-1.37 3.23-4.58 3.23-2.75 0-5-2.28-5-5.07s2.25-5.07 5-5.07c1.57 0 2.62.67 3.22 1.25l2.2-2.13C16.48 5.1 14.66 4.3 12.48 4.3 8.02 4.3 4.4 7.9 4.4 12.36s3.62 8.06 8.08 8.06c4.66 0 7.75-3.27 7.75-7.89 0-.53-.06-.93-.13-1.61h-7.62Z" />
+              </svg>
+            </a>
+          </div>
+        </div>
+        <div>
+          <h4>Services</h4>
+          <ul>
+            <li><a href="/services/pressure-washing/">Pressure washing</a></li>
+            <li><a href="/services/paver-sealing/">Paver sealing</a></li>
+            <li><a href="/services/paver-repair/">Paver repair</a></li>
+            <li><a href="/services/roof-cleaning/">Roof cleaning</a></li>
+            <li><a href="/services/pressure-washing/">House &amp; building wash</a></li>
+            <li><a href="/services/pressure-washing/">Commercial cleaning</a></li>
+          </ul>
+        </div>
+        <div>
+          <h4>Company</h4>
+          <ul>
+            <li><a href="/#results">Before &amp; after</a></li>
+            <li><a href="/#work">Recent work</a></li>
+            <li><a href="/service-areas/broward-county/">Broward County</a></li>
+            <li><a href="/service-areas/miami-dade-county/">Miami-Dade County</a></li>
+            <li><a href="/service-areas/palm-beach-county/">Palm Beach County</a></li>
+            <li><a href="#quote">Contact</a></li>
+            <li><a href="tel:+19544013301">(954) 401-3301</a></li>
+          </ul>
+        </div>
+      </div>
+      <div class="footer-base">
+        <span>© <span id="year">2026</span> Vold Services. All rights reserved.</span>
+        <span>Broward · Miami-Dade · Palm Beach · Licensed &amp; insured</span>
+      </div>
+    </div>
+  </footer>
+  <div class="sticky-cta" id="sticky-cta">
+    <a class="btn btn--primary" href="tel:+19544013301">
+      <svg viewBox="0 0 24 24" width="15" height="15" fill="currentColor" aria-hidden="true"><path d="M6.6 10.8c1.4 2.7 3.6 4.9 6.3 6.3l2.1-2.1c.3-.3.8-.4 1.1-.2 1.1.4 2.3.6 3.5.6.5 0 .9.4.9.9V20c0 .5-.4.9-.9.9C10.7 20.9 3.1 13.3 3.1 4c0-.5.4-.9.9-.9h3.7c.5 0 .9.4.9.9 0 1.2.2 2.4.6 3.5.1.4.1.8-.2 1.1L6.6 10.8z"/></svg>
+      (954) 401-3301
+    </a>
+    <a class="btn btn--ghost" href="#quote">Get estimate</a>
+  </div>
+<script src="/assets/site.js"></script>
+</body>
+</html>
diff --git a/docs/service-areas/miami-dade-county/index.html b/docs/service-areas/miami-dade-county/index.html
new file mode 100644
index 0000000..3abaaea
--- /dev/null
+++ b/docs/service-areas/miami-dade-county/index.html
@@ -0,0 +1,455 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8" />
+<meta name="viewport" content="width=device-width, initial-scale=1.0" />
+<title>Pressure Washing &amp; Paver Sealing in Miami-Dade County | Vold Services</title>
+<meta name="description" content="Exterior cleaning in Miami-Dade County: pressure washing, paver sealing, paver repair, and roof cleaning for homes, commercial properties, and HOAs." />
+<meta name="robots" content="index, follow, max-image-preview:large" />
+<link rel="canonical" href="https://voldservices.com/service-areas/miami-dade-county/" />
+<meta property="og:type" content="website" />
+<meta property="og:site_name" content="Vold Services" />
+<meta property="og:title" content="Pressure Washing &amp; Paver Sealing in Miami-Dade County | Vold Services" />
+<meta property="og:description" content="Exterior cleaning in Miami-Dade County: pressure washing, paver sealing, paver repair, and roof cleaning for homes, commercial properties, and HOAs." />
+<meta property="og:url" content="https://voldservices.com/service-areas/miami-dade-county/" />
+<meta property="og:image" content="https://voldservices.com/og-card-v2.jpg" />
+<meta property="og:image:alt" content="Vold Services exterior cleaning in South Florida" />
+<meta name="twitter:card" content="summary_large_image" />
+<meta name="twitter:title" content="Pressure Washing &amp; Paver Sealing in Miami-Dade County | Vold Services" />
+<meta name="twitter:description" content="Exterior cleaning in Miami-Dade County: pressure washing, paver sealing, paver repair, and roof cleaning for homes, commercial properties, and HOAs." />
+<meta name="twitter:image" content="https://voldservices.com/og-card-v2.jpg" />
+<link rel="icon" href="/favicon.png" type="image/png" />
+<link rel="apple-touch-icon" href="/favicon.png" />
+  <link rel="preconnect" href="https://fonts.googleapis.com" />
+  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
+  <link href="https://fonts.googleapis.com/css2?family=Manrope:wght@400;500;600&family=Roboto+Mono:wght@400;500&family=Teko:wght@500;600&display=swap" rel="stylesheet" />
+<link rel="stylesheet" href="/assets/site.css" />
+<link rel="stylesheet" href="/assets/pages.css" />
+<noscript><style>.reveal { opacity: 1; transform: none; }</style></noscript>
+<script type="application/ld+json">{
+  "@context": "https://schema.org",
+  "@graph": [
+    {
+      "@type": "WebPage",
+      "@id": "https://voldservices.com/service-areas/miami-dade-county/#webpage",
+      "url": "https://voldservices.com/service-areas/miami-dade-county/",
+      "name": "Pressure Washing & Paver Sealing in Miami-Dade County | Vold Services",
+      "description": "Exterior cleaning in Miami-Dade County: pressure washing, paver sealing, paver repair, and roof cleaning for homes, commercial properties, and HOAs.",
+      "isPartOf": {
+        "@id": "https://voldservices.com/#website"
+      },
+      "about": {
+        "@id": "https://voldservices.com/service-areas/miami-dade-county/#service"
+      },
+      "breadcrumb": {
+        "@id": "https://voldservices.com/service-areas/miami-dade-county/#breadcrumb"
+      }
+    },
+    {
+      "@type": "BreadcrumbList",
+      "@id": "https://voldservices.com/service-areas/miami-dade-county/#breadcrumb",
+      "itemListElement": [
+        {
+          "@type": "ListItem",
+          "position": 1,
+          "name": "Home",
+          "item": "https://voldservices.com/"
+        },
+        {
+          "@type": "ListItem",
+          "position": 2,
+          "name": "Service areas",
+          "item": "https://voldservices.com/#areas"
+        },
+        {
+          "@type": "ListItem",
+          "position": 3,
+          "name": "Miami-Dade County",
+          "item": "https://voldservices.com/service-areas/miami-dade-county/"
+        }
+      ]
+    },
+    {
+      "@type": "Service",
+      "@id": "https://voldservices.com/service-areas/miami-dade-county/#service",
+      "name": "Exterior cleaning in Miami-Dade County",
+      "serviceType": [
+        "Pressure washing",
+        "Paver sealing",
+        "Paver repair",
+        "Roof cleaning"
+      ],
+      "url": "https://voldservices.com/service-areas/miami-dade-county/",
+      "description": "Exterior cleaning in Miami-Dade County: pressure washing, paver sealing, paver repair, and roof cleaning for homes, commercial properties, and HOAs.",
+      "provider": {
+        "@id": "https://voldservices.com/#business"
+      },
+      "areaServed": [
+        {
+          "@type": "AdministrativeArea",
+          "name": "Miami-Dade County, Florida"
+        }
+      ]
+    },
+    {
+      "@type": [
+        "LocalBusiness",
+        "HomeAndConstructionBusiness"
+      ],
+      "@id": "https://voldservices.com/#business",
+      "name": "Vold Services",
+      "url": "https://voldservices.com/",
+      "telephone": "+1-954-401-3301",
+      "logo": "https://voldservices.com/logo.png",
+      "image": "https://voldservices.com/og-card-v2.jpg",
+      "sameAs": [
+        "https://www.instagram.com/voldservices/",
+        "https://www.facebook.com/p/VOLD-Services-61553817020348/",
+        "https://share.google/Gy96TtpQu6SzJoTp2"
+      ],
+      "areaServed": [
+        {
+          "@type": "AdministrativeArea",
+          "name": "Broward County, Florida"
+        },
+        {
+          "@type": "AdministrativeArea",
+          "name": "Miami-Dade County, Florida"
+        },
+        {
+          "@type": "AdministrativeArea",
+          "name": "Palm Beach County, Florida"
+        },
+        {
+          "@type": "City",
+          "name": "Fort Lauderdale"
+        },
+        {
+          "@type": "City",
+          "name": "Pembroke Pines"
+        },
+        {
+          "@type": "City",
+          "name": "Hollywood"
+        },
+        {
+          "@type": "City",
+          "name": "Miramar"
+        },
+        {
+          "@type": "City",
+          "name": "Coral Springs"
+        },
+        {
+          "@type": "City",
+          "name": "Davie"
+        },
+        {
+          "@type": "City",
+          "name": "Plantation"
+        },
+        {
+          "@type": "City",
+          "name": "Sunrise"
+        },
+        {
+          "@type": "City",
+          "name": "Weston"
+        },
+        {
+          "@type": "City",
+          "name": "Pompano Beach"
+        },
+        {
+          "@type": "City",
+          "name": "Deerfield Beach"
+        },
+        {
+          "@type": "City",
+          "name": "Parkland"
+        },
+        {
+          "@type": "City",
+          "name": "Boca Raton"
+        },
+        {
+          "@type": "City",
+          "name": "Miami"
+        }
+      ],
+      "openingHoursSpecification": [
+        {
+          "@type": "OpeningHoursSpecification",
+          "dayOfWeek": [
+            "Monday",
+            "Tuesday",
+            "Wednesday",
+            "Thursday",
+            "Friday",
+            "Saturday"
+          ],
+          "opens": "07:00",
+          "closes": "18:00"
+        }
+      ]
+    },
+    {
+      "@type": "WebSite",
+      "@id": "https://voldservices.com/#website",
+      "url": "https://voldservices.com/",
+      "name": "Vold Services",
+      "publisher": {
+        "@id": "https://voldservices.com/#business"
+      }
+    }
+  ]
+}</script>
+</head>
+<body class="inner-page">
+<a class="skip-link" href="#main">Skip to content</a>
+  <header class="nav" id="nav">
+    <div class="wrap nav-inner">
+      <a class="brand" href="/" aria-label="Vold Services home">
+        <img src="/logo.png" alt="Vold Services" width="188" height="97" />
+      </a>
+
+      <div class="nav-actions">
+        <a class="nav-call" href="tel:+19544013301">
+          <svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M6.6 10.8c1.4 2.7 3.6 4.9 6.3 6.3l2.1-2.1c.3-.3.8-.4 1.1-.2 1.1.4 2.3.6 3.5.6.5 0 .9.4.9.9V20c0 .5-.4.9-.9.9C10.7 20.9 3.1 13.3 3.1 4c0-.5.4-.9.9-.9h3.7c.5 0 .9.4.9.9 0 1.2.2 2.4.6 3.5.1.4.1.8-.2 1.1L6.6 10.8z"/></svg>
+          (954) 401-3301
+        </a>
+        <button class="nav-toggle" type="button" aria-label="Open menu" aria-controls="nav-links" aria-expanded="false">
+          <span></span><span></span><span></span>
+        </button>
+      </div>
+
+      <nav class="nav-links" id="nav-links" aria-label="Primary">
+        <a href="/#services">Services</a>
+        <a href="/#results">Results</a>
+        <a href="/#work">Recent Work</a>
+        <a href="/#areas">Service Areas</a>
+        <a href="/#reviews">Reviews</a>
+        <a href="#quote">Contact</a>
+      </nav>
+    </div>
+    <div class="nav-progress" id="nav-progress" aria-hidden="true"></div>
+  </header>
+<main id="main"><section class="page-hero" id="top"><div class="wrap">
+<nav class="breadcrumbs" aria-label="Breadcrumb"><a href="/">Home</a><span aria-hidden="true">/</span><a href="/#areas">Service areas</a><span aria-hidden="true">/</span><span aria-current="page">Miami-Dade County</span></nav>
+<div class="page-hero-grid"><div class="page-hero-copy"><p class="eyebrow">Residential · Commercial · HOA</p><h1>Exterior cleaning<span class="accent">Miami-Dade County.</span></h1><p class="lead">Keep a Miami-Dade home, storefront, or shared property looking cared for. Request pressure washing, paver sealing and repair, or roof cleaning from Miami and Aventura to Doral and Homestead.</p><div class="page-actions"><a class="btn btn--primary" href="#quote">Request an estimate</a><a class="btn btn--ghost" href="tel:+19544013301">Call (954) 401-3301</a></div><p class="page-hero-note">Pressure washing · Paver care · Roof cleaning</p></div><figure class="page-hero-photo"><img src="/img/after-patio.jpg" alt="Paver patio and walkway after cleaning and joint sand replacement" width="746" height="829" fetchpriority="high" /><figcaption>From our South Florida project gallery.</figcaption></figure></div></div></section><section class="band"><div class="wrap"><div class="section-head"><p class="eyebrow">Your property. Your project.</p><h2 class="h2">Exterior care for homes and shared spaces</h2></div><div class="page-detail-grid"><p class="lead">A front walkway and a commercial exterior have different access needs, even when both need a thorough clean. Tell us whether the property is residential, commercial, or HOA / multi-family, and which surfaces need work. We use that information to discuss the right cleaning or paver service.</p><div class="area"><h3 class="h3">Make access part of the estimate</h3><p class="lead">If the property has controlled entry, shared parking, a busy storefront, or a building contact, include those details with the address. For commercial or recurring cleaning, identify the areas to be cleaned and your preferred timing. Scheduling and access arrangements are confirmed for the individual job.</p></div></div></div></section><section class="band band--tinted" id="services"><div class="wrap"><div class="section-head"><p class="eyebrow">Services in Miami-Dade County</p><h2 class="h2">Choose the work you need</h2></div><div class="service-grid"><article class="service"><h3 class="h3"><a class="service-title-link" href="/services/pressure-washing/">Pressure washing</a></h3><p>From a darkened driveway to a tired pool deck, the right wash makes a visible difference. We clean concrete, pavers, and exterior surfaces with pressure and treatment selected for the material.</p><a class="page-link" href="/services/pressure-washing/">Explore pressure washing <span aria-hidden="true">↗</span></a></article>
+<article class="service"><h3 class="h3"><a class="service-title-link" href="/services/paver-sealing/">Paver sealing</a></h3><p>Give your driveway, walkway, or pool deck a finish that suits the property. We clean the pavers, replace missing joint sand, and seal once the surface is ready.</p><a class="page-link" href="/services/paver-sealing/">Explore paver sealing <span aria-hidden="true">↗</span></a></article>
+<article class="service"><h3 class="h3"><a class="service-title-link" href="/services/paver-repair/">Paver repair</a></h3><p>Loose borders, sunken sections, and uneven joints need attention beneath the surface. We lift the affected pavers, correct the base, and reset the area.</p><a class="page-link" href="/services/paver-repair/">Explore paver repair <span aria-hidden="true">↗</span></a></article>
+<article class="service"><h3 class="h3"><a class="service-title-link" href="/services/roof-cleaning/">Roof cleaning</a></h3><p>Give a roof marked by dark streaks and organic buildup a fresh start. We use a low-pressure soft wash for tile, shingle, and metal roofs, with care for the landscaping below.</p><a class="page-link" href="/services/roof-cleaning/">Explore roof cleaning <span aria-hidden="true">↗</span></a></article></div></div></section><section class="band" id="areas"><div class="wrap"><div class="section-head"><p class="eyebrow">Local coverage</p><h2 class="h2">Miami-Dade County communities</h2></div><p class="lead">We serve Miami-Dade County, including the communities below. Send your property address with your request so we can confirm the job details and scheduling.</p><ul class="page-cities"><li>Miami</li><li>Aventura</li><li>Miami Beach</li><li>Doral</li><li>Hialeah</li><li>Kendall</li><li>Coral Gables</li><li>Miami Lakes</li><li>North Miami</li><li>Pinecrest</li><li>Palmetto Bay</li><li>Homestead</li></ul><a class="page-link" href="#quote">Tell us about your property <span aria-hidden="true">↗</span></a></div></section><section class="band band--tinted"><div class="wrap"><div class="section-head"><p class="eyebrow">Before you book</p><h2 class="h2">Planning your service</h2></div><div class="page-faq"><details><summary>Which parts of Miami-Dade do you cover?</summary><p>Our coverage includes Miami, Miami Beach, Aventura, Doral, Hialeah, and the other communities listed on this page, including Homestead. Send the address so we can discuss your project.</p></details><details><summary>Do you clean storefronts and commercial exterior areas?</summary><p>Yes. Storefronts and dumpster pads are among our pressure washing services. Choose Commercial on the form and describe the surfaces and access requirements.</p></details><details><summary>What if a manager needs to coordinate access?</summary><p>Include the building or property contact and any entry arrangements in your message. We can confirm the job details and access requirements when following up on the estimate.</p></details></div></div></section><section class="band band--tinted" id="quote">
+      <div class="wrap">
+        <div class="section-head reveal">
+          <h2 class="h2">Request an estimate</h2>
+          <p class="lead">
+            Send the address, the surface, and any details you know. We'll call or text to confirm
+            the job and arrange a walkthrough if one is needed.
+          </p>
+        </div>
+
+        <div class="quote-grid reveal">
+          <div class="quote-side">
+            <div class="quote-row">
+              <div class="quote-label">Call or text</div>
+              <a class="quote-phone" href="tel:+19544013301">(954) 401-3301</a>
+            </div>
+            <div class="quote-row">
+              <div class="quote-label">Find us online</div>
+              <div class="social-links" aria-label="Vold Services social links">
+                <a class="social-link" href="https://www.instagram.com/voldservices/" target="_blank" rel="noopener noreferrer" aria-label="Vold Services on Instagram" title="Instagram">
+                  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" aria-hidden="true">
+                    <rect x="3" y="3" width="18" height="18" rx="5" />
+                    <circle cx="12" cy="12" r="4" />
+                    <circle cx="17.4" cy="6.6" r="1" fill="currentColor" stroke="none" />
+                  </svg>
+                </a>
+                <a class="social-link" href="https://www.facebook.com/p/VOLD-Services-61553817020348/" target="_blank" rel="noopener noreferrer" aria-label="Vold Services on Facebook" title="Facebook">
+                  <svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
+                    <path d="M14.2 8H17V4h-3.2C10.6 4 9 5.9 9 9v2H6v4h3v7h4v-7h3.2l.8-4h-4V9.4c0-1 .3-1.4 1.2-1.4Z" />
+                  </svg>
+                </a>
+                <a class="social-link" href="https://share.google/Gy96TtpQu6SzJoTp2" target="_blank" rel="noopener noreferrer" aria-label="Vold Services on Google" title="Google">
+                  <svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
+                    <path d="M12.48 10.92v3.28h4.58c-.18 1.1-1.37 3.23-4.58 3.23-2.75 0-5-2.28-5-5.07s2.25-5.07 5-5.07c1.57 0 2.62.67 3.22 1.25l2.2-2.13C16.48 5.1 14.66 4.3 12.48 4.3 8.02 4.3 4.4 7.9 4.4 12.36s3.62 8.06 8.08 8.06c4.66 0 7.75-3.27 7.75-7.89 0-.53-.06-.93-.13-1.61h-7.62Z" />
+                  </svg>
+                </a>
+              </div>
+            </div>
+            <div class="quote-row">
+              <div class="quote-label">Services</div>
+              <div class="quote-value">Pressure washing · Paver sealing · Paver repair · Roof cleaning</div>
+            </div>
+            <div class="quote-row">
+              <div class="quote-label">Service area</div>
+              <div class="quote-value">Broward, Miami-Dade, and Palm Beach counties</div>
+            </div>
+            <div class="quote-row">
+              <div class="quote-label">Property types</div>
+              <div class="quote-value">Residential, commercial, HOA and multi-family</div>
+            </div>
+            <div class="quote-row">
+              <div class="quote-label">Hours</div>
+              <div class="quote-value">Monday–Saturday, 7:00 AM – 6:00 PM</div>
+            </div>
+          </div>
+
+          <div class="quote-form-wrap">
+            <form class="quote-form" id="quote-form"
+                  action="https://formspree.io/f/xaewpyaq"
+                  method="POST"
+                  enctype="multipart/form-data">
+              <input type="hidden" name="source_page" value="/service-areas/miami-dade-county/" />
+<input type="hidden" name="county" value="Miami-Dade County" />
+              <div class="field-row">
+                <div class="field">
+                  <label for="q-name">Name</label>
+                  <input id="q-name" name="name" type="text" autocomplete="name" placeholder="Your name" required />
+                </div>
+                <div class="field">
+                  <label for="q-phone">Phone</label>
+                  <input id="q-phone" name="phone" type="tel" autocomplete="tel" placeholder="(954) 000-0000" required />
+                </div>
+              </div>
+              <div class="field-row">
+                <div class="field">
+                  <label for="q-email">Email</label>
+                  <input id="q-email" name="email" type="email" autocomplete="email" placeholder="[email protected]" />
+                </div>
+                <div class="field">
+                  <label for="q-city">City</label>
+                  <input id="q-city" name="city" type="text" autocomplete="address-level2" placeholder="Fort Lauderdale" />
+                </div>
+              </div>
+              <div class="field-row">
+                <div class="field">
+                  <label for="q-service">Service needed</label>
+                  <select id="q-service" name="service">
+                    <option>Pressure washing</option>
+                    <option>Paver sealing</option>
+                    <option>Paver repair</option>
+                    <option>Roof cleaning</option>
+                    <option>House wash</option>
+                    <option>Pool deck or patio</option>
+                    <option>Commercial / recurring</option>
+                    <option>Not sure yet</option>
+                  </select>
+                </div>
+                <div class="field">
+                  <label for="q-property">Property type</label>
+                  <select id="q-property" name="property">
+                    <option>Residential</option>
+                    <option>Commercial</option>
+                    <option>HOA / multi-family</option>
+                  </select>
+                </div>
+              </div>
+              <div class="field">
+                <label for="q-message">What needs cleaning?</label>
+                <textarea id="q-message" name="message" placeholder="Approximate size, roof material, when it was last cleaned, or anything else that will help us quote the job."></textarea>
+              </div>
+              <div class="field">
+                <label for="q-photos">Show us the surface <span aria-hidden="true">·</span> Optional</label>
+                <input class="photo-input" id="q-photos" name="photos" type="file" accept="image/*" multiple
+                       aria-describedby="q-photos-help q-photos-status" />
+                <label class="photo-picker" for="q-photos">
+                  <span class="photo-picker__action">Add photos</span>
+                  <span class="photo-picker__note">One at a time or several together</span>
+                </label>
+                <p class="field-help" id="q-photos-help">Add up to 5 photos. You can open the picker again to add more. Maximum 25 MB each and 90 MB total.</p>
+                <ul class="photo-list" id="q-photo-list" aria-label="Selected photos" hidden></ul>
+                <p class="photo-status" id="q-photos-status" aria-live="polite"></p>
+              </div>
+              <div class="form-error" id="form-error" role="alert" hidden></div>
+              <button class="btn btn--primary btn--block" id="quote-submit" type="submit">Request an estimate</button>
+              <p class="form-note">Prefer to talk? Call or text (954) 401-3301 during business hours.</p>
+            </form>
+
+            <div class="form-success" id="form-success" role="status" aria-live="polite" tabindex="-1" hidden>
+              <div>
+                <div class="success-mark" aria-hidden="true">
+                  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
+                    <path d="m5 12 4 4L19 6" />
+                  </svg>
+                </div>
+                <p class="eyebrow">Request received</p>
+                <h3>Thanks, <span id="success-name">we’ve got it</span>.</h3>
+                <p>We’ll call or text to confirm the details and arrange a walkthrough if one is needed.</p>
+                <a class="quote-value" href="tel:+19544013301">Need us sooner? Call (954) 401-3301</a>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+    </section><section class="band band--tinted"><div class="wrap"><div class="section-head"><p class="eyebrow">Across South Florida</p><h2 class="h2">Other service areas</h2></div><div class="page-two-grid"><article class="service"><h3 class="h3"><a class="service-title-link" href="/service-areas/broward-county/">Broward County</a></h3><p>Pressure washing, paver sealing and repair, and roof cleaning across Broward County.</p><a class="page-link" href="/service-areas/broward-county/">Explore broward county <span aria-hidden="true">↗</span></a></article>
+<article class="service"><h3 class="h3"><a class="service-title-link" href="/service-areas/palm-beach-county/">Palm Beach County</a></h3><p>Pressure washing, paver sealing and repair, and roof cleaning across Palm Beach County.</p><a class="page-link" href="/service-areas/palm-beach-county/">Explore palm beach county <span aria-hidden="true">↗</span></a></article></div></div></section></main>
+  <footer class="footer">
+    <div class="wrap">
+      <div class="footer-inner">
+        <div>
+          <img src="/logo.png" alt="Vold Services" width="168" height="87" />
+          <p>
+            Exterior cleaning for homes, HOAs, and commercial properties across Broward,
+            Miami-Dade, and Palm Beach counties.
+          </p>
+          <div class="social-links" aria-label="Vold Services social links">
+            <a class="social-link" href="https://www.instagram.com/voldservices/" target="_blank" rel="noopener noreferrer" aria-label="Vold Services on Instagram" title="Instagram">
+              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" aria-hidden="true">
+                <rect x="3" y="3" width="18" height="18" rx="5" />
+                <circle cx="12" cy="12" r="4" />
+                <circle cx="17.4" cy="6.6" r="1" fill="currentColor" stroke="none" />
+              </svg>
+            </a>
+            <a class="social-link" href="https://www.facebook.com/p/VOLD-Services-61553817020348/" target="_blank" rel="noopener noreferrer" aria-label="Vold Services on Facebook" title="Facebook">
+              <svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
+                <path d="M14.2 8H17V4h-3.2C10.6 4 9 5.9 9 9v2H6v4h3v7h4v-7h3.2l.8-4h-4V9.4c0-1 .3-1.4 1.2-1.4Z" />
+              </svg>
+            </a>
+            <a class="social-link" href="https://share.google/Gy96TtpQu6SzJoTp2" target="_blank" rel="noopener noreferrer" aria-label="Vold Services on Google" title="Google">
+              <svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
+                <path d="M12.48 10.92v3.28h4.58c-.18 1.1-1.37 3.23-4.58 3.23-2.75 0-5-2.28-5-5.07s2.25-5.07 5-5.07c1.57 0 2.62.67 3.22 1.25l2.2-2.13C16.48 5.1 14.66 4.3 12.48 4.3 8.02 4.3 4.4 7.9 4.4 12.36s3.62 8.06 8.08 8.06c4.66 0 7.75-3.27 7.75-7.89 0-.53-.06-.93-.13-1.61h-7.62Z" />
+              </svg>
+            </a>
+          </div>
+        </div>
+        <div>
+          <h4>Services</h4>
+          <ul>
+            <li><a href="/services/pressure-washing/">Pressure washing</a></li>
+            <li><a href="/services/paver-sealing/">Paver sealing</a></li>
+            <li><a href="/services/paver-repair/">Paver repair</a></li>
+            <li><a href="/services/roof-cleaning/">Roof cleaning</a></li>
+            <li><a href="/services/pressure-washing/">House &amp; building wash</a></li>
+            <li><a href="/services/pressure-washing/">Commercial cleaning</a></li>
+          </ul>
+        </div>
+        <div>
+          <h4>Company</h4>
+          <ul>
+            <li><a href="/#results">Before &amp; after</a></li>
+            <li><a href="/#work">Recent work</a></li>
+            <li><a href="/service-areas/broward-county/">Broward County</a></li>
+            <li><a href="/service-areas/miami-dade-county/">Miami-Dade County</a></li>
+            <li><a href="/service-areas/palm-beach-county/">Palm Beach County</a></li>
+            <li><a href="#quote">Contact</a></li>
+            <li><a href="tel:+19544013301">(954) 401-3301</a></li>
+          </ul>
+        </div>
+      </div>
+      <div class="footer-base">
+        <span>© <span id="year">2026</span> Vold Services. All rights reserved.</span>
+        <span>Broward · Miami-Dade · Palm Beach · Licensed &amp; insured</span>
+      </div>
+    </div>
+  </footer>
+  <div class="sticky-cta" id="sticky-cta">
+    <a class="btn btn--primary" href="tel:+19544013301">
+      <svg viewBox="0 0 24 24" width="15" height="15" fill="currentColor" aria-hidden="true"><path d="M6.6 10.8c1.4 2.7 3.6 4.9 6.3 6.3l2.1-2.1c.3-.3.8-.4 1.1-.2 1.1.4 2.3.6 3.5.6.5 0 .9.4.9.9V20c0 .5-.4.9-.9.9C10.7 20.9 3.1 13.3 3.1 4c0-.5.4-.9.9-.9h3.7c.5 0 .9.4.9.9 0 1.2.2 2.4.6 3.5.1.4.1.8-.2 1.1L6.6 10.8z"/></svg>
+      (954) 401-3301
+    </a>
+    <a class="btn btn--ghost" href="#quote">Get estimate</a>
+  </div>
+<script src="/assets/site.js"></script>
+</body>
+</html>
diff --git a/docs/service-areas/palm-beach-county/index.html b/docs/service-areas/palm-beach-county/index.html
new file mode 100644
index 0000000..e47d78b
--- /dev/null
+++ b/docs/service-areas/palm-beach-county/index.html
@@ -0,0 +1,455 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8" />
+<meta name="viewport" content="width=device-width, initial-scale=1.0" />
+<title>Pressure Washing &amp; Paver Sealing in Palm Beach County | Vold Services</title>
+<meta name="description" content="Pressure washing, paver sealing and repair, and soft wash roof cleaning in Palm Beach County. Serving Boca Raton, Delray Beach, West Palm Beach, and more." />
+<meta name="robots" content="index, follow, max-image-preview:large" />
+<link rel="canonical" href="https://voldservices.com/service-areas/palm-beach-county/" />
+<meta property="og:type" content="website" />
+<meta property="og:site_name" content="Vold Services" />
+<meta property="og:title" content="Pressure Washing &amp; Paver Sealing in Palm Beach County | Vold Services" />
+<meta property="og:description" content="Pressure washing, paver sealing and repair, and soft wash roof cleaning in Palm Beach County. Serving Boca Raton, Delray Beach, West Palm Beach, and more." />
+<meta property="og:url" content="https://voldservices.com/service-areas/palm-beach-county/" />
+<meta property="og:image" content="https://voldservices.com/og-card-v2.jpg" />
+<meta property="og:image:alt" content="Vold Services exterior cleaning in South Florida" />
+<meta name="twitter:card" content="summary_large_image" />
+<meta name="twitter:title" content="Pressure Washing &amp; Paver Sealing in Palm Beach County | Vold Services" />
+<meta name="twitter:description" content="Pressure washing, paver sealing and repair, and soft wash roof cleaning in Palm Beach County. Serving Boca Raton, Delray Beach, West Palm Beach, and more." />
+<meta name="twitter:image" content="https://voldservices.com/og-card-v2.jpg" />
+<link rel="icon" href="/favicon.png" type="image/png" />
+<link rel="apple-touch-icon" href="/favicon.png" />
+  <link rel="preconnect" href="https://fonts.googleapis.com" />
+  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
+  <link href="https://fonts.googleapis.com/css2?family=Manrope:wght@400;500;600&family=Roboto+Mono:wght@400;500&family=Teko:wght@500;600&display=swap" rel="stylesheet" />
+<link rel="stylesheet" href="/assets/site.css" />
+<link rel="stylesheet" href="/assets/pages.css" />
+<noscript><style>.reveal { opacity: 1; transform: none; }</style></noscript>
+<script type="application/ld+json">{
+  "@context": "https://schema.org",
+  "@graph": [
+    {
+      "@type": "WebPage",
+      "@id": "https://voldservices.com/service-areas/palm-beach-county/#webpage",
+      "url": "https://voldservices.com/service-areas/palm-beach-county/",
+      "name": "Pressure Washing & Paver Sealing in Palm Beach County | Vold Services",
+      "description": "Pressure washing, paver sealing and repair, and soft wash roof cleaning in Palm Beach County. Serving Boca Raton, Delray Beach, West Palm Beach, and more.",
+      "isPartOf": {
+        "@id": "https://voldservices.com/#website"
+      },
+      "about": {
+        "@id": "https://voldservices.com/service-areas/palm-beach-county/#service"
+      },
+      "breadcrumb": {
+        "@id": "https://voldservices.com/service-areas/palm-beach-county/#breadcrumb"
+      }
+    },
+    {
+      "@type": "BreadcrumbList",
+      "@id": "https://voldservices.com/service-areas/palm-beach-county/#breadcrumb",
+      "itemListElement": [
+        {
+          "@type": "ListItem",
+          "position": 1,
+          "name": "Home",
+          "item": "https://voldservices.com/"
+        },
+        {
+          "@type": "ListItem",
+          "position": 2,
+          "name": "Service areas",
+          "item": "https://voldservices.com/#areas"
+        },
+        {
+          "@type": "ListItem",
+          "position": 3,
+          "name": "Palm Beach County",
+          "item": "https://voldservices.com/service-areas/palm-beach-county/"
+        }
+      ]
+    },
+    {
+      "@type": "Service",
+      "@id": "https://voldservices.com/service-areas/palm-beach-county/#service",
+      "name": "Exterior cleaning in Palm Beach County",
+      "serviceType": [
+        "Pressure washing",
+        "Paver sealing",
+        "Paver repair",
+        "Roof cleaning"
+      ],
+      "url": "https://voldservices.com/service-areas/palm-beach-county/",
+      "description": "Pressure washing, paver sealing and repair, and soft wash roof cleaning in Palm Beach County. Serving Boca Raton, Delray Beach, West Palm Beach, and more.",
+      "provider": {
+        "@id": "https://voldservices.com/#business"
+      },
+      "areaServed": [
+        {
+          "@type": "AdministrativeArea",
+          "name": "Palm Beach County, Florida"
+        }
+      ]
+    },
+    {
+      "@type": [
+        "LocalBusiness",
+        "HomeAndConstructionBusiness"
+      ],
+      "@id": "https://voldservices.com/#business",
+      "name": "Vold Services",
+      "url": "https://voldservices.com/",
+      "telephone": "+1-954-401-3301",
+      "logo": "https://voldservices.com/logo.png",
+      "image": "https://voldservices.com/og-card-v2.jpg",
+      "sameAs": [
+        "https://www.instagram.com/voldservices/",
+        "https://www.facebook.com/p/VOLD-Services-61553817020348/",
+        "https://share.google/Gy96TtpQu6SzJoTp2"
+      ],
+      "areaServed": [
+        {
+          "@type": "AdministrativeArea",
+          "name": "Broward County, Florida"
+        },
+        {
+          "@type": "AdministrativeArea",
+          "name": "Miami-Dade County, Florida"
+        },
+        {
+          "@type": "AdministrativeArea",
+          "name": "Palm Beach County, Florida"
+        },
+        {
+          "@type": "City",
+          "name": "Fort Lauderdale"
+        },
+        {
+          "@type": "City",
+          "name": "Pembroke Pines"
+        },
+        {
+          "@type": "City",
+          "name": "Hollywood"
+        },
+        {
+          "@type": "City",
+          "name": "Miramar"
+        },
+        {
+          "@type": "City",
+          "name": "Coral Springs"
+        },
+        {
+          "@type": "City",
+          "name": "Davie"
+        },
+        {
+          "@type": "City",
+          "name": "Plantation"
+        },
+        {
+          "@type": "City",
+          "name": "Sunrise"
+        },
+        {
+          "@type": "City",
+          "name": "Weston"
+        },
+        {
+          "@type": "City",
+          "name": "Pompano Beach"
+        },
+        {
+          "@type": "City",
+          "name": "Deerfield Beach"
+        },
+        {
+          "@type": "City",
+          "name": "Parkland"
+        },
+        {
+          "@type": "City",
+          "name": "Boca Raton"
+        },
+        {
+          "@type": "City",
+          "name": "Miami"
+        }
+      ],
+      "openingHoursSpecification": [
+        {
+          "@type": "OpeningHoursSpecification",
+          "dayOfWeek": [
+            "Monday",
+            "Tuesday",
+            "Wednesday",
+            "Thursday",
+            "Friday",
+            "Saturday"
+          ],
+          "opens": "07:00",
+          "closes": "18:00"
+        }
+      ]
+    },
+    {
+      "@type": "WebSite",
+      "@id": "https://voldservices.com/#website",
+      "url": "https://voldservices.com/",
+      "name": "Vold Services",
+      "publisher": {
+        "@id": "https://voldservices.com/#business"
+      }
+    }
+  ]
+}</script>
+</head>
+<body class="inner-page">
+<a class="skip-link" href="#main">Skip to content</a>
+  <header class="nav" id="nav">
+    <div class="wrap nav-inner">
+      <a class="brand" href="/" aria-label="Vold Services home">
+        <img src="/logo.png" alt="Vold Services" width="188" height="97" />
+      </a>
+
+      <div class="nav-actions">
+        <a class="nav-call" href="tel:+19544013301">
+          <svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M6.6 10.8c1.4 2.7 3.6 4.9 6.3 6.3l2.1-2.1c.3-.3.8-.4 1.1-.2 1.1.4 2.3.6 3.5.6.5 0 .9.4.9.9V20c0 .5-.4.9-.9.9C10.7 20.9 3.1 13.3 3.1 4c0-.5.4-.9.9-.9h3.7c.5 0 .9.4.9.9 0 1.2.2 2.4.6 3.5.1.4.1.8-.2 1.1L6.6 10.8z"/></svg>
+          (954) 401-3301
+        </a>
+        <button class="nav-toggle" type="button" aria-label="Open menu" aria-controls="nav-links" aria-expanded="false">
+          <span></span><span></span><span></span>
+        </button>
+      </div>
+
+      <nav class="nav-links" id="nav-links" aria-label="Primary">
+        <a href="/#services">Services</a>
+        <a href="/#results">Results</a>
+        <a href="/#work">Recent Work</a>
+        <a href="/#areas">Service Areas</a>
+        <a href="/#reviews">Reviews</a>
+        <a href="#quote">Contact</a>
+      </nav>
+    </div>
+    <div class="nav-progress" id="nav-progress" aria-hidden="true"></div>
+  </header>
+<main id="main"><section class="page-hero" id="top"><div class="wrap">
+<nav class="breadcrumbs" aria-label="Breadcrumb"><a href="/">Home</a><span aria-hidden="true">/</span><a href="/#areas">Service areas</a><span aria-hidden="true">/</span><span aria-current="page">Palm Beach County</span></nav>
+<div class="page-hero-grid"><div class="page-hero-copy"><p class="eyebrow">Residential · Commercial · HOA</p><h1>Exterior cleaning<span class="accent">Palm Beach County.</span></h1><p class="lead">Refresh the outdoor spaces you use every day. Vold Services provides pressure washing, paver sealing and repair, and roof cleaning across Palm Beach County, including Boca Raton, Delray Beach, West Palm Beach, and Jupiter.</p><div class="page-actions"><a class="btn btn--primary" href="#quote">Request an estimate</a><a class="btn btn--ghost" href="tel:+19544013301">Call (954) 401-3301</a></div><p class="page-hero-note">Pressure washing · Paver care · Roof cleaning</p></div><figure class="page-hero-photo"><img src="/img/after-pool-deck.jpg" alt="Travertine pool deck after cleaning and sealing" width="746" height="829" fetchpriority="high" /><figcaption>From our South Florida project gallery.</figcaption></figure></div></div></section><section class="band"><div class="wrap"><div class="section-head"><p class="eyebrow">Your property. Your project.</p><h2 class="h2">Plan the care your outdoor surfaces need</h2></div><div class="page-detail-grid"><p class="lead">A pool deck, screened lanai, and paver driveway can all be included in an exterior cleaning request. If the paving has worn sealer or uneven sections, tell us before the work is planned. We can assess whether the surface needs cleaning alone or preparation for repair and sealing.</p><div class="area"><h3 class="h3">Tell us how you want to use the space</h3><p class="lead">For sealing projects, include the finish you prefer and any known history of previous sealing. Let us know about pool access, outdoor furniture, and gates so preparation can be discussed. Drying and use instructions depend on the actual project and will be confirmed when scheduling the work.</p></div></div></div></section><section class="band band--tinted" id="services"><div class="wrap"><div class="section-head"><p class="eyebrow">Services in Palm Beach County</p><h2 class="h2">Choose the work you need</h2></div><div class="service-grid"><article class="service"><h3 class="h3"><a class="service-title-link" href="/services/pressure-washing/">Pressure washing</a></h3><p>From a darkened driveway to a tired pool deck, the right wash makes a visible difference. We clean concrete, pavers, and exterior surfaces with pressure and treatment selected for the material.</p><a class="page-link" href="/services/pressure-washing/">Explore pressure washing <span aria-hidden="true">↗</span></a></article>
+<article class="service"><h3 class="h3"><a class="service-title-link" href="/services/paver-sealing/">Paver sealing</a></h3><p>Give your driveway, walkway, or pool deck a finish that suits the property. We clean the pavers, replace missing joint sand, and seal once the surface is ready.</p><a class="page-link" href="/services/paver-sealing/">Explore paver sealing <span aria-hidden="true">↗</span></a></article>
+<article class="service"><h3 class="h3"><a class="service-title-link" href="/services/paver-repair/">Paver repair</a></h3><p>Loose borders, sunken sections, and uneven joints need attention beneath the surface. We lift the affected pavers, correct the base, and reset the area.</p><a class="page-link" href="/services/paver-repair/">Explore paver repair <span aria-hidden="true">↗</span></a></article>
+<article class="service"><h3 class="h3"><a class="service-title-link" href="/services/roof-cleaning/">Roof cleaning</a></h3><p>Give a roof marked by dark streaks and organic buildup a fresh start. We use a low-pressure soft wash for tile, shingle, and metal roofs, with care for the landscaping below.</p><a class="page-link" href="/services/roof-cleaning/">Explore roof cleaning <span aria-hidden="true">↗</span></a></article></div></div></section><section class="band" id="areas"><div class="wrap"><div class="section-head"><p class="eyebrow">Local coverage</p><h2 class="h2">Palm Beach County communities</h2></div><p class="lead">We serve Palm Beach County, including the communities below. Send your property address with your request so we can confirm the job details and scheduling.</p><ul class="page-cities"><li>Boca Raton</li><li>Delray Beach</li><li>Boynton Beach</li><li>West Palm Beach</li><li>Wellington</li><li>Jupiter</li><li>Royal Palm Beach</li><li>Lake Worth</li><li>Palm Beach Gardens</li><li>Greenacres</li></ul><a class="page-link" href="#quote">Tell us about your property <span aria-hidden="true">↗</span></a></div></section><section class="band band--tinted"><div class="wrap"><div class="section-head"><p class="eyebrow">Before you book</p><h2 class="h2">Planning your service</h2></div><div class="page-faq"><details><summary>Do you serve northern Palm Beach County?</summary><p>Our listed service area includes Jupiter and Palm Beach Gardens as well as West Palm Beach and the southern county communities shown here. Include your address when requesting an estimate.</p></details><details><summary>Can you clean and seal a travertine pool deck?</summary><p>Pool deck cleaning and paver sealing are part of our services, and our project photos include travertine surfaces. Send photos and describe the existing finish so we can assess the preparation needed.</p></details><details><summary>Can roof cleaning be included with driveway work?</summary><p>Yes. We offer both services. Select the main service on the estimate form and describe the roof and driveway in your message so both can be considered.</p></details></div></div></section><section class="band band--tinted" id="quote">
+      <div class="wrap">
+        <div class="section-head reveal">
+          <h2 class="h2">Request an estimate</h2>
+          <p class="lead">
+            Send the address, the surface, and any details you know. We'll call or text to confirm
+            the job and arrange a walkthrough if one is needed.
+          </p>
+        </div>
+
+        <div class="quote-grid reveal">
+          <div class="quote-side">
+            <div class="quote-row">
+              <div class="quote-label">Call or text</div>
+              <a class="quote-phone" href="tel:+19544013301">(954) 401-3301</a>
+            </div>
+            <div class="quote-row">
+              <div class="quote-label">Find us online</div>
+              <div class="social-links" aria-label="Vold Services social links">
+                <a class="social-link" href="https://www.instagram.com/voldservices/" target="_blank" rel="noopener noreferrer" aria-label="Vold Services on Instagram" title="Instagram">
+                  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" aria-hidden="true">
+                    <rect x="3" y="3" width="18" height="18" rx="5" />
+                    <circle cx="12" cy="12" r="4" />
+                    <circle cx="17.4" cy="6.6" r="1" fill="currentColor" stroke="none" />
+                  </svg>
+                </a>
+                <a class="social-link" href="https://www.facebook.com/p/VOLD-Services-61553817020348/" target="_blank" rel="noopener noreferrer" aria-label="Vold Services on Facebook" title="Facebook">
+                  <svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
+                    <path d="M14.2 8H17V4h-3.2C10.6 4 9 5.9 9 9v2H6v4h3v7h4v-7h3.2l.8-4h-4V9.4c0-1 .3-1.4 1.2-1.4Z" />
+                  </svg>
+                </a>
+                <a class="social-link" href="https://share.google/Gy96TtpQu6SzJoTp2" target="_blank" rel="noopener noreferrer" aria-label="Vold Services on Google" title="Google">
+                  <svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
+                    <path d="M12.48 10.92v3.28h4.58c-.18 1.1-1.37 3.23-4.58 3.23-2.75 0-5-2.28-5-5.07s2.25-5.07 5-5.07c1.57 0 2.62.67 3.22 1.25l2.2-2.13C16.48 5.1 14.66 4.3 12.48 4.3 8.02 4.3 4.4 7.9 4.4 12.36s3.62 8.06 8.08 8.06c4.66 0 7.75-3.27 7.75-7.89 0-.53-.06-.93-.13-1.61h-7.62Z" />
+                  </svg>
+                </a>
+              </div>
+            </div>
+            <div class="quote-row">
+              <div class="quote-label">Services</div>
+              <div class="quote-value">Pressure washing · Paver sealing · Paver repair · Roof cleaning</div>
+            </div>
+            <div class="quote-row">
+              <div class="quote-label">Service area</div>
+              <div class="quote-value">Broward, Miami-Dade, and Palm Beach counties</div>
+            </div>
+            <div class="quote-row">
+              <div class="quote-label">Property types</div>
+              <div class="quote-value">Residential, commercial, HOA and multi-family</div>
+            </div>
+            <div class="quote-row">
+              <div class="quote-label">Hours</div>
+              <div class="quote-value">Monday–Saturday, 7:00 AM – 6:00 PM</div>
+            </div>
+          </div>
+
+          <div class="quote-form-wrap">
+            <form class="quote-form" id="quote-form"
+                  action="https://formspree.io/f/xaewpyaq"
+                  method="POST"
+                  enctype="multipart/form-data">
+              <input type="hidden" name="source_page" value="/service-areas/palm-beach-county/" />
+<input type="hidden" name="county" value="Palm Beach County" />
+              <div class="field-row">
+                <div class="field">
+                  <label for="q-name">Name</label>
+                  <input id="q-name" name="name" type="text" autocomplete="name" placeholder="Your name" required />
+                </div>
+                <div class="field">
+                  <label for="q-phone">Phone</label>
+                  <input id="q-phone" name="phone" type="tel" autocomplete="tel" placeholder="(954) 000-0000" required />
+                </div>
+              </div>
+              <div class="field-row">
+                <div class="field">
+                  <label for="q-email">Email</label>
+                  <input id="q-email" name="email" type="email" autocomplete="email" placeholder="[email protected]" />
+                </div>
+                <div class="field">
+                  <label for="q-city">City</label>
+                  <input id="q-city" name="city" type="text" autocomplete="address-level2" placeholder="Fort Lauderdale" />
+                </div>
+              </div>
+              <div class="field-row">
+                <div class="field">
+                  <label for="q-service">Service needed</label>
+                  <select id="q-service" name="service">
+                    <option>Pressure washing</option>
+                    <option>Paver sealing</option>
+                    <option>Paver repair</option>
+                    <option>Roof cleaning</option>
+                    <option>House wash</option>
+                    <option>Pool deck or patio</option>
+                    <option>Commercial / recurring</option>
+                    <option>Not sure yet</option>
+                  </select>
+                </div>
+                <div class="field">
+                  <label for="q-property">Property type</label>
+                  <select id="q-property" name="property">
+                    <option>Residential</option>
+                    <option>Commercial</option>
+                    <option>HOA / multi-family</option>
+                  </select>
+                </div>
+              </div>
+              <div class="field">
+                <label for="q-message">What needs cleaning?</label>
+                <textarea id="q-message" name="message" placeholder="Approximate size, roof material, when it was last cleaned, or anything else that will help us quote the job."></textarea>
+              </div>
+              <div class="field">
+                <label for="q-photos">Show us the surface <span aria-hidden="true">·</span> Optional</label>
+                <input class="photo-input" id="q-photos" name="photos" type="file" accept="image/*" multiple
+                       aria-describedby="q-photos-help q-photos-status" />
+                <label class="photo-picker" for="q-photos">
+                  <span class="photo-picker__action">Add photos</span>
+                  <span class="photo-picker__note">One at a time or several together</span>
+                </label>
+                <p class="field-help" id="q-photos-help">Add up to 5 photos. You can open the picker again to add more. Maximum 25 MB each and 90 MB total.</p>
+                <ul class="photo-list" id="q-photo-list" aria-label="Selected photos" hidden></ul>
+                <p class="photo-status" id="q-photos-status" aria-live="polite"></p>
+              </div>
+              <div class="form-error" id="form-error" role="alert" hidden></div>
+              <button class="btn btn--primary btn--block" id="quote-submit" type="submit">Request an estimate</button>
+              <p class="form-note">Prefer to talk? Call or text (954) 401-3301 during business hours.</p>
+            </form>
+
+            <div class="form-success" id="form-success" role="status" aria-live="polite" tabindex="-1" hidden>
+              <div>
+                <div class="success-mark" aria-hidden="true">
+                  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
+                    <path d="m5 12 4 4L19 6" />
+                  </svg>
+                </div>
+                <p class="eyebrow">Request received</p>
+                <h3>Thanks, <span id="success-name">we’ve got it</span>.</h3>
+                <p>We’ll call or text to confirm the details and arrange a walkthrough if one is needed.</p>
+                <a class="quote-value" href="tel:+19544013301">Need us sooner? Call (954) 401-3301</a>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+    </section><section class="band band--tinted"><div class="wrap"><div class="section-head"><p class="eyebrow">Across South Florida</p><h2 class="h2">Other service areas</h2></div><div class="page-two-grid"><article class="service"><h3 class="h3"><a class="service-title-link" href="/service-areas/broward-county/">Broward County</a></h3><p>Pressure washing, paver sealing and repair, and roof cleaning across Broward County.</p><a class="page-link" href="/service-areas/broward-county/">Explore broward county <span aria-hidden="true">↗</span></a></article>
+<article class="service"><h3 class="h3"><a class="service-title-link" href="/service-areas/miami-dade-county/">Miami-Dade County</a></h3><p>Pressure washing, paver sealing and repair, and roof cleaning across Miami-Dade County.</p><a class="page-link" href="/service-areas/miami-dade-county/">Explore miami-dade county <span aria-hidden="true">↗</span></a></article></div></div></section></main>
+  <footer class="footer">
+    <div class="wrap">
+      <div class="footer-inner">
+        <div>
+          <img src="/logo.png" alt="Vold Services" width="168" height="87" />
+          <p>
+            Exterior cleaning for homes, HOAs, and commercial properties across Broward,
+            Miami-Dade, and Palm Beach counties.
+          </p>
+          <div class="social-links" aria-label="Vold Services social links">
+            <a class="social-link" href="https://www.instagram.com/voldservices/" target="_blank" rel="noopener noreferrer" aria-label="Vold Services on Instagram" title="Instagram">
+              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" aria-hidden="true">
+                <rect x="3" y="3" width="18" height="18" rx="5" />
+                <circle cx="12" cy="12" r="4" />
+                <circle cx="17.4" cy="6.6" r="1" fill="currentColor" stroke="none" />
+              </svg>
+            </a>
+            <a class="social-link" href="https://www.facebook.com/p/VOLD-Services-61553817020348/" target="_blank" rel="noopener noreferrer" aria-label="Vold Services on Facebook" title="Facebook">
+              <svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
+                <path d="M14.2 8H17V4h-3.2C10.6 4 9 5.9 9 9v2H6v4h3v7h4v-7h3.2l.8-4h-4V9.4c0-1 .3-1.4 1.2-1.4Z" />
+              </svg>
+            </a>
+            <a class="social-link" href="https://share.google/Gy96TtpQu6SzJoTp2" target="_blank" rel="noopener noreferrer" aria-label="Vold Services on Google" title="Google">
+              <svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
+                <path d="M12.48 10.92v3.28h4.58c-.18 1.1-1.37 3.23-4.58 3.23-2.75 0-5-2.28-5-5.07s2.25-5.07 5-5.07c1.57 0 2.62.67 3.22 1.25l2.2-2.13C16.48 5.1 14.66 4.3 12.48 4.3 8.02 4.3 4.4 7.9 4.4 12.36s3.62 8.06 8.08 8.06c4.66 0 7.75-3.27 7.75-7.89 0-.53-.06-.93-.13-1.61h-7.62Z" />
+              </svg>
+            </a>
+          </div>
+        </div>
+        <div>
+          <h4>Services</h4>
+          <ul>
+            <li><a href="/services/pressure-washing/">Pressure washing</a></li>
+            <li><a href="/services/paver-sealing/">Paver sealing</a></li>
+            <li><a href="/services/paver-repair/">Paver repair</a></li>
+            <li><a href="/services/roof-cleaning/">Roof cleaning</a></li>
+            <li><a href="/services/pressure-washing/">House &amp; building wash</a></li>
+            <li><a href="/services/pressure-washing/">Commercial cleaning</a></li>
+          </ul>
+        </div>
+        <div>
+          <h4>Company</h4>
+          <ul>
+            <li><a href="/#results">Before &amp; after</a></li>
+            <li><a href="/#work">Recent work</a></li>
+            <li><a href="/service-areas/broward-county/">Broward County</a></li>
+            <li><a href="/service-areas/miami-dade-county/">Miami-Dade County</a></li>
+            <li><a href="/service-areas/palm-beach-county/">Palm Beach County</a></li>
+            <li><a href="#quote">Contact</a></li>
+            <li><a href="tel:+19544013301">(954) 401-3301</a></li>
+          </ul>
+        </div>
+      </div>
+      <div class="footer-base">
+        <span>© <span id="year">2026</span> Vold Services. All rights reserved.</span>
+        <span>Broward · Miami-Dade · Palm Beach · Licensed &amp; insured</span>
+      </div>
+    </div>
+  </footer>
+  <div class="sticky-cta" id="sticky-cta">
+    <a class="btn btn--primary" href="tel:+19544013301">
+      <svg viewBox="0 0 24 24" width="15" height="15" fill="currentColor" aria-hidden="true"><path d="M6.6 10.8c1.4 2.7 3.6 4.9 6.3 6.3l2.1-2.1c.3-.3.8-.4 1.1-.2 1.1.4 2.3.6 3.5.6.5 0 .9.4.9.9V20c0 .5-.4.9-.9.9C10.7 20.9 3.1 13.3 3.1 4c0-.5.4-.9.9-.9h3.7c.5 0 .9.4.9.9 0 1.2.2 2.4.6 3.5.1.4.1.8-.2 1.1L6.6 10.8z"/></svg>
+      (954) 401-3301
+    </a>
+    <a class="btn btn--ghost" href="#quote">Get estimate</a>
+  </div>
+<script src="/assets/site.js"></script>
+</body>
+</html>
diff --git a/docs/services/paver-repair/index.html b/docs/services/paver-repair/index.html
new file mode 100644
index 0000000..e8f143e
--- /dev/null
+++ b/docs/services/paver-repair/index.html
@@ -0,0 +1,457 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8" />
+<meta name="viewport" content="width=device-width, initial-scale=1.0" />
+<title>Paver repair in South Florida | Vold Services</title>
+<meta name="description" content="Repair loose, sunken, and uneven pavers in South Florida. Vold Services handles small-area lift and relay, base correction, and damaged paver replacement." />
+<meta name="robots" content="index, follow, max-image-preview:large" />
+<link rel="canonical" href="https://voldservices.com/services/paver-repair/" />
+<meta property="og:type" content="website" />
+<meta property="og:site_name" content="Vold Services" />
+<meta property="og:title" content="Paver repair in South Florida | Vold Services" />
+<meta property="og:description" content="Repair loose, sunken, and uneven pavers in South Florida. Vold Services handles small-area lift and relay, base correction, and damaged paver replacement." />
+<meta property="og:url" content="https://voldservices.com/services/paver-repair/" />
+<meta property="og:image" content="https://voldservices.com/og-card-v2.jpg" />
+<meta property="og:image:alt" content="Vold Services exterior cleaning in South Florida" />
+<meta name="twitter:card" content="summary_large_image" />
+<meta name="twitter:title" content="Paver repair in South Florida | Vold Services" />
+<meta name="twitter:description" content="Repair loose, sunken, and uneven pavers in South Florida. Vold Services handles small-area lift and relay, base correction, and damaged paver replacement." />
+<meta name="twitter:image" content="https://voldservices.com/og-card-v2.jpg" />
+<link rel="icon" href="/favicon.png" type="image/png" />
+<link rel="apple-touch-icon" href="/favicon.png" />
+  <link rel="preconnect" href="https://fonts.googleapis.com" />
+  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
+  <link href="https://fonts.googleapis.com/css2?family=Manrope:wght@400;500;600&family=Roboto+Mono:wght@400;500&family=Teko:wght@500;600&display=swap" rel="stylesheet" />
+<link rel="stylesheet" href="/assets/site.css" />
+<link rel="stylesheet" href="/assets/pages.css" />
+<noscript><style>.reveal { opacity: 1; transform: none; }</style></noscript>
+<script type="application/ld+json">{
+  "@context": "https://schema.org",
+  "@graph": [
+    {
+      "@type": "WebPage",
+      "@id": "https://voldservices.com/services/paver-repair/#webpage",
+      "url": "https://voldservices.com/services/paver-repair/",
+      "name": "Paver repair in South Florida | Vold Services",
+      "description": "Repair loose, sunken, and uneven pavers in South Florida. Vold Services handles small-area lift and relay, base correction, and damaged paver replacement.",
+      "isPartOf": {
+        "@id": "https://voldservices.com/#website"
+      },
+      "about": {
+        "@id": "https://voldservices.com/services/paver-repair/#service"
+      },
+      "breadcrumb": {
+        "@id": "https://voldservices.com/services/paver-repair/#breadcrumb"
+      }
+    },
+    {
+      "@type": "BreadcrumbList",
+      "@id": "https://voldservices.com/services/paver-repair/#breadcrumb",
+      "itemListElement": [
+        {
+          "@type": "ListItem",
+          "position": 1,
+          "name": "Home",
+          "item": "https://voldservices.com/"
+        },
+        {
+          "@type": "ListItem",
+          "position": 2,
+          "name": "Services",
+          "item": "https://voldservices.com/#services"
+        },
+        {
+          "@type": "ListItem",
+          "position": 3,
+          "name": "Paver repair",
+          "item": "https://voldservices.com/services/paver-repair/"
+        }
+      ]
+    },
+    {
+      "@type": "Service",
+      "@id": "https://voldservices.com/services/paver-repair/#service",
+      "name": "Paver repair",
+      "serviceType": "Paver repair",
+      "url": "https://voldservices.com/services/paver-repair/",
+      "description": "Repair loose, sunken, and uneven pavers in South Florida. Vold Services handles small-area lift and relay, base correction, and damaged paver replacement.",
+      "provider": {
+        "@id": "https://voldservices.com/#business"
+      },
+      "areaServed": [
+        {
+          "@type": "AdministrativeArea",
+          "name": "Broward County, Florida"
+        },
+        {
+          "@type": "AdministrativeArea",
+          "name": "Miami-Dade County, Florida"
+        },
+        {
+          "@type": "AdministrativeArea",
+          "name": "Palm Beach County, Florida"
+        }
+      ]
+    },
+    {
+      "@type": [
+        "LocalBusiness",
+        "HomeAndConstructionBusiness"
+      ],
+      "@id": "https://voldservices.com/#business",
+      "name": "Vold Services",
+      "url": "https://voldservices.com/",
+      "telephone": "+1-954-401-3301",
+      "logo": "https://voldservices.com/logo.png",
+      "image": "https://voldservices.com/og-card-v2.jpg",
+      "sameAs": [
+        "https://www.instagram.com/voldservices/",
+        "https://www.facebook.com/p/VOLD-Services-61553817020348/",
+        "https://share.google/Gy96TtpQu6SzJoTp2"
+      ],
+      "areaServed": [
+        {
+          "@type": "AdministrativeArea",
+          "name": "Broward County, Florida"
+        },
+        {
+          "@type": "AdministrativeArea",
+          "name": "Miami-Dade County, Florida"
+        },
+        {
+          "@type": "AdministrativeArea",
+          "name": "Palm Beach County, Florida"
+        },
+        {
+          "@type": "City",
+          "name": "Fort Lauderdale"
+        },
+        {
+          "@type": "City",
+          "name": "Pembroke Pines"
+        },
+        {
+          "@type": "City",
+          "name": "Hollywood"
+        },
+        {
+          "@type": "City",
+          "name": "Miramar"
+        },
+        {
+          "@type": "City",
+          "name": "Coral Springs"
+        },
+        {
+          "@type": "City",
+          "name": "Davie"
+        },
+        {
+          "@type": "City",
+          "name": "Plantation"
+        },
+        {
+          "@type": "City",
+          "name": "Sunrise"
+        },
+        {
+          "@type": "City",
+          "name": "Weston"
+        },
+        {
+          "@type": "City",
+          "name": "Pompano Beach"
+        },
+        {
+          "@type": "City",
+          "name": "Deerfield Beach"
+        },
+        {
+          "@type": "City",
+          "name": "Parkland"
+        },
+        {
+          "@type": "City",
+          "name": "Boca Raton"
+        },
+        {
+          "@type": "City",
+          "name": "Miami"
+        }
+      ],
+      "openingHoursSpecification": [
+        {
+          "@type": "OpeningHoursSpecification",
+          "dayOfWeek": [
+            "Monday",
+            "Tuesday",
+            "Wednesday",
+            "Thursday",
+            "Friday",
+            "Saturday"
+          ],
+          "opens": "07:00",
+          "closes": "18:00"
+        }
+      ]
+    },
+    {
+      "@type": "WebSite",
+      "@id": "https://voldservices.com/#website",
+      "url": "https://voldservices.com/",
+      "name": "Vold Services",
+      "publisher": {
+        "@id": "https://voldservices.com/#business"
+      }
+    }
+  ]
+}</script>
+</head>
+<body class="inner-page">
+<a class="skip-link" href="#main">Skip to content</a>
+  <header class="nav" id="nav">
+    <div class="wrap nav-inner">
+      <a class="brand" href="/" aria-label="Vold Services home">
+        <img src="/logo.png" alt="Vold Services" width="188" height="97" />
+      </a>
+
+      <div class="nav-actions">
+        <a class="nav-call" href="tel:+19544013301">
+          <svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M6.6 10.8c1.4 2.7 3.6 4.9 6.3 6.3l2.1-2.1c.3-.3.8-.4 1.1-.2 1.1.4 2.3.6 3.5.6.5 0 .9.4.9.9V20c0 .5-.4.9-.9.9C10.7 20.9 3.1 13.3 3.1 4c0-.5.4-.9.9-.9h3.7c.5 0 .9.4.9.9 0 1.2.2 2.4.6 3.5.1.4.1.8-.2 1.1L6.6 10.8z"/></svg>
+          (954) 401-3301
+        </a>
+        <button class="nav-toggle" type="button" aria-label="Open menu" aria-controls="nav-links" aria-expanded="false">
+          <span></span><span></span><span></span>
+        </button>
+      </div>
+
+      <nav class="nav-links" id="nav-links" aria-label="Primary">
+        <a href="/#services">Services</a>
+        <a href="/#results">Results</a>
+        <a href="/#work">Recent Work</a>
+        <a href="/#areas">Service Areas</a>
+        <a href="/#reviews">Reviews</a>
+        <a href="#quote">Contact</a>
+      </nav>
+    </div>
+    <div class="nav-progress" id="nav-progress" aria-hidden="true"></div>
+  </header>
+<main id="main"><section class="page-hero" id="top"><div class="wrap">
+<nav class="breadcrumbs" aria-label="Breadcrumb"><a href="/">Home</a><span aria-hidden="true">/</span><a href="/#services">Services</a><span aria-hidden="true">/</span><span aria-current="page">Paver repair</span></nav>
+<div class="page-hero-grid"><div class="page-hero-copy"><p class="eyebrow">Broward · Miami-Dade · Palm Beach</p><h1>Paver repair<span class="accent">Done with care.</span></h1><p class="lead">Loose borders, sunken sections, and uneven joints need attention beneath the surface. We lift the affected pavers, correct the base, and reset the area.</p><div class="page-actions"><a class="btn btn--primary" href="#quote">Request an estimate</a><a class="btn btn--ghost" href="tel:+19544013301">Call (954) 401-3301</a></div><p class="page-hero-note">Reset the pavers. Restore the surface.</p></div><figure class="page-hero-photo"><img src="/img/work-driveway-install.jpg" alt="Paver driveway restoration in progress" width="746" height="829" fetchpriority="high" /><figcaption>Paver restoration work in progress. The scope of each repair depends on the existing surface.</figcaption></figure></div></div></section><section class="band"><div class="wrap"><div class="section-head"><p class="eyebrow">Built around the material</p><h2 class="h2">Address the area that has moved</h2></div><div class="page-detail-grid"><p class="lead">Fresh joint sand alone will not correct a sunken section. We assess the affected area, lift the pavers that need resetting, and work on the base before relaying them. When pieces are damaged, replacement depends on finding a suitable match. Send a close-up and a wider view so we can see how the repair fits into the surrounding surface.</p><div class="area"><h3 class="h3">What we can help with</h3><ul class="page-surface-list"><li>Sunken or uneven driveway sections</li><li>Loose edge and border pavers</li><li>Separated pavers in patios and walkways</li><li>Small areas needing lift and relay</li><li>Damaged pieces where a match is available</li></ul></div></div></div></section><section class="band band--tinted"><div class="wrap"><div class="section-head"><p class="eyebrow">What to expect</p><h2 class="h2">From estimate to finished surface</h2></div><div class="page-three-grid"><article class="service"><p class="eyebrow">Step 1</p><h3 class="h3">Identify the affected area</h3><p>Send photos of the uneven section and the surrounding paving. Note whether pieces rock, separate, or have visible damage. We confirm the repair scope after reviewing the condition.</p></article><article class="service"><p class="eyebrow">Step 2</p><h3 class="h3">Lift and correct the base</h3><p>We remove the affected pavers and correct the base before resetting them. Damaged pieces are replaced when a suitable match is available.</p></article><article class="service"><p class="eyebrow">Step 3</p><h3 class="h3">Reset and finish the joints</h3><p>We relay the pavers, add joint sand, and give the area a final rinse. If cleaning or sealing is also needed, we discuss it as part of the overall project.</p></article></div></div></section><section class="band band--tinted"><div class="wrap"><div class="section-head"><p class="eyebrow">Before you book</p><h2 class="h2">Paver repair questions</h2></div><div class="page-faq"><details><summary>Do you need to replace the whole driveway?</summary><p>Our listed repair services focus on small-area lift and relay and affected sections. Photos or a walkthrough help establish whether that approach fits your project.</p></details><details><summary>Will replacement pavers match?</summary><p>Replacement depends on availability. Share photos of the existing pieces and let us know whether you have spare pavers so we can assess the options.</p></details><details><summary>Can you clean and seal after a repair?</summary><p>Yes, we also offer pressure washing and paver sealing. Include those requests with the repair details so the work can be considered together.</p></details><details><summary>What photos help you assess the repair?</summary><p>Send a close-up of loose or damaged pieces and a wider photo showing the area around them. Include an approximate size and describe where the surface has sunk or separated.</p></details></div></div></section><section class="band band--tinted" id="quote">
+      <div class="wrap">
+        <div class="section-head reveal">
+          <h2 class="h2">Request an estimate</h2>
+          <p class="lead">
+            Send the addr

[Diff truncated. Use the raw view or local clone for the full content.]