patx/demo
add vold services
Commit c668528 · patx · 2026-08-16T02:00:36-04:00
Comments
No comments yet.
Diff
diff --git a/docs/frontline-1.png b/docs/frontline-1.png
deleted file mode 100644
index 466860e..0000000
Binary files a/docs/frontline-1.png and /dev/null differ
diff --git a/docs/frontline-2.png b/docs/frontline-2.png
deleted file mode 100644
index 577e5ef..0000000
Binary files a/docs/frontline-2.png and /dev/null differ
diff --git a/docs/frontline-3.png b/docs/frontline-3.png
deleted file mode 100644
index d3c7cbe..0000000
Binary files a/docs/frontline-3.png and /dev/null differ
diff --git a/docs/frontline-4.png b/docs/frontline-4.png
deleted file mode 100644
index 9dc0ec5..0000000
Binary files a/docs/frontline-4.png and /dev/null differ
diff --git a/docs/frontline-5.png b/docs/frontline-5.png
deleted file mode 100644
index 5dc3732..0000000
Binary files a/docs/frontline-5.png and /dev/null differ
diff --git a/docs/frontline-6.png b/docs/frontline-6.png
deleted file mode 100644
index d76125f..0000000
Binary files a/docs/frontline-6.png and /dev/null differ
diff --git a/docs/frontline-hero.png b/docs/frontline-hero.png
deleted file mode 100644
index 5cf6801..0000000
Binary files a/docs/frontline-hero.png and /dev/null differ
diff --git a/docs/frontline-logo.jpg b/docs/frontline-logo.jpg
deleted file mode 100644
index cea541f..0000000
Binary files a/docs/frontline-logo.jpg and /dev/null differ
diff --git a/docs/frontline-logo.png b/docs/frontline-logo.png
deleted file mode 100644
index b3d11b7..0000000
Binary files a/docs/frontline-logo.png and /dev/null differ
diff --git a/docs/frontline-og_card.png b/docs/frontline-og_card.png
deleted file mode 100644
index ac40674..0000000
Binary files a/docs/frontline-og_card.png and /dev/null differ
diff --git a/docs/frontlineboats.html b/docs/frontlineboats.html
deleted file mode 100644
index 70fb5df..0000000
--- a/docs/frontlineboats.html
+++ /dev/null
@@ -1,1808 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
- <meta charset="UTF-8" />
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
- <title>Frontline Boat Services — Miami, FL</title>
- <meta name="description" content="Frontline Boat Services provides marine electrical installations, rewires, maintenance, audio, GPS, and electronics service across Miami-Dade and Broward." />
- <meta property="og:type" content="website" />
- <meta property="og:title" content="Frontline Boat Services — Miami, FL" />
- <meta property="og:description" content="Marine electrical installations, rewires, maintenance, audio, GPS, and electronics service across Miami-Dade and Broward." />
- <meta property="og:image" content="frontline-og_card.png" />
- <meta property="og:image:width" content="1731" />
- <meta property="og:image:height" content="909" />
- <meta property="og:image:alt" content="Frontline Boat Services social preview card" />
- <meta name="twitter:card" content="summary_large_image" />
- <meta name="twitter:title" content="Frontline Boat Services — Miami, FL" />
- <meta name="twitter:description" content="Marine electrical installations, rewires, maintenance, audio, GPS, and electronics service across Miami-Dade and Broward." />
- <meta name="twitter:image" content="frontline-og_card.png" />
- <meta name="twitter:image:alt" content="Frontline Boat Services social preview card" />
- <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=Bebas+Neue&family=Inter:wght@300;400;500;600&family=Oswald:wght@400;500;600;700&display=swap" rel="stylesheet" />
- <style>
- /* ── TOKEN SYSTEM ─────────────────────────────────────────────────────── */
- :root {
- --flame: #D62B2B;
- --ember: #FF5C1A;
- --smoke: #1A1A1A;
- --ash: #2E2E2E;
- --steel: #3D3D3D;
- --mist: #B0B0B0;
- --white: #F0EDE8;
- --gold: #C9A84C;
-
- --font-display: 'Bebas Neue', sans-serif;
- --font-heading: 'Oswald', sans-serif;
- --font-body: 'Inter', sans-serif;
- }
-
- *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
-
- html { scroll-behavior: smooth; }
-
- body {
- background: var(--smoke);
- color: var(--white);
- font-family: var(--font-body);
- font-size: 16px;
- line-height: 1.6;
- overflow-x: hidden;
- }
-
- /* ── NAV ──────────────────────────────────────────────────────────────── */
- nav {
- position: fixed;
- top: 0; left: 0; right: 0;
- z-index: 100;
- display: flex;
- align-items: center;
- justify-content: space-between;
- padding: 0 5vw;
- height: 112px;
- background: rgba(20,20,20,0.72);
- backdrop-filter: blur(8px);
- border-bottom: 1px solid transparent;
- transition: height 0.25s ease, background 0.25s ease, border-color 0.25s ease, box-shadow 0.25s ease;
- }
-
- nav.is-scrolled,
- nav.is-open {
- height: 64px;
- background: rgba(20,20,20,0.92);
- border-bottom-color: var(--ash);
- box-shadow: 0 4px 24px rgba(0,0,0,0.5);
- }
-
- .nav-logo {
- display: inline-flex;
- align-items: center;
- text-decoration: none;
- }
-
- .nav-logo img {
- width: 250px;
- height: auto;
- object-fit: contain;
- display: block;
- transition: width 0.25s ease;
- }
-
- nav.is-scrolled .nav-logo img,
- nav.is-open .nav-logo img {
- width: 135px;
- }
-
- .nav-links {
- display: flex;
- gap: 2rem;
- list-style: none;
- }
-
- .nav-links a {
- position: relative;
- font-family: var(--font-heading);
- font-size: 0.8rem;
- letter-spacing: 0.12em;
- text-transform: uppercase;
- color: var(--mist);
- text-decoration: none;
- transition: color 0.2s;
- }
-
- .nav-links a::after {
- content: '';
- position: absolute;
- left: 0;
- bottom: -0.45rem;
- width: 28px;
- height: 2px;
- background: var(--flame);
- transform: scaleX(0);
- transform-origin: left;
- transition: transform 0.2s ease;
- }
-
- .nav-links a:hover,
- .nav-links a.is-active { color: var(--flame); }
-
- .nav-links a:hover::after,
- .nav-links a.is-active::after { transform: scaleX(1); }
-
- .nav-actions {
- display: flex;
- align-items: center;
- gap: 0.75rem;
- }
-
- .nav-cta {
- font-family: var(--font-heading);
- font-size: 0.75rem;
- letter-spacing: 0.12em;
- text-transform: uppercase;
- background: var(--flame);
- color: #fff;
- padding: 0.5rem 1.25rem;
- border: none;
- cursor: pointer;
- text-decoration: none;
- transition: background 0.2s;
- }
-
- .nav-cta:hover { background: var(--ember); }
-
- .nav-cta-call {
- background: transparent;
- border: 1px solid var(--flame);
- color: var(--white);
- }
-
- .nav-cta-call:hover {
- background: var(--flame);
- color: #fff;
- }
-
- .nav-toggle {
- display: none;
- width: 44px;
- height: 44px;
- border: 1px solid var(--steel);
- background: transparent;
- color: var(--white);
- cursor: pointer;
- align-items: center;
- justify-content: center;
- flex-direction: column;
- gap: 5px;
- }
-
- .nav-toggle span {
- width: 20px;
- height: 2px;
- background: currentColor;
- transition: transform 0.2s ease, opacity 0.2s ease;
- }
-
- .nav-toggle[aria-expanded="true"] span:nth-child(1) {
- transform: translateY(7px) rotate(45deg);
- }
-
- .nav-toggle[aria-expanded="true"] span:nth-child(2) {
- opacity: 0;
- }
-
- .nav-toggle[aria-expanded="true"] span:nth-child(3) {
- transform: translateY(-7px) rotate(-45deg);
- }
-
- .nav-toggle:focus-visible,
- .image-modal-close:focus-visible,
- .project-tile:focus-visible {
- outline: 2px solid var(--ember);
- outline-offset: 4px;
- }
-
- /* ── HERO ─────────────────────────────────────────────────────────────── */
- .hero {
- position: relative;
- min-height: 100vh;
- display: flex;
- align-items: flex-end;
- padding: 0 5vw 8vh;
- overflow: hidden;
- }
-
- .hero-bg {
- position: absolute;
- inset: 0;
- background:
- linear-gradient(to right, rgba(10,10,10,0.95) 40%, rgba(10,10,10,0.5) 100%),
- url('frontline-hero.png') center/cover no-repeat;
- }
-
- /* Signature element: diagonal red slash that bleeds off the right edge */
- .hero-slash {
- position: absolute;
- top: 0; right: -60px;
- width: 180px;
- height: 100%;
- background: var(--flame);
- transform: skewX(-8deg);
- opacity: 0.08;
- pointer-events: none;
- }
-
- .hero-slash::after {
- content: '';
- position: absolute;
- top: 0; left: -100px;
- width: 60px;
- height: 100%;
- background: var(--ember);
- opacity: 0.5;
- }
-
- .hero-content {
- position: relative;
- z-index: 2;
- max-width: 680px;
- width: 100%;
- }
-
- .hero-eyebrow {
- display: inline-flex;
- align-items: center;
- gap: 0.6rem;
- font-family: var(--font-heading);
- font-size: 0.72rem;
- letter-spacing: 0.2em;
- text-transform: uppercase;
- color: var(--flame);
- margin-bottom: 1rem;
- }
-
- .hero-eyebrow::before {
- content: '';
- display: block;
- width: 28px;
- height: 2px;
- background: var(--flame);
- }
-
- .hero-title {
- font-family: var(--font-display);
- font-size: clamp(4rem, 10vw, 8rem);
- line-height: 0.92;
- letter-spacing: 0.02em;
- color: var(--white);
- margin-bottom: 0.5rem;
- }
-
- .hero-title .accent { color: var(--flame); }
-
- .hero-sub {
- font-family: var(--font-heading);
- font-size: clamp(1rem, 2.5vw, 1.4rem);
- font-weight: 400;
- letter-spacing: 0.1em;
- text-transform: uppercase;
- color: var(--mist);
- margin-bottom: 2rem;
- }
-
- .hero-body {
- font-size: 1rem;
- font-weight: 300;
- color: var(--mist);
- max-width: 480px;
- margin-bottom: 2.5rem;
- line-height: 1.7;
- }
-
- .hero-body strong {
- font-family: var(--font-heading);
- font-size: 1.08em;
- font-weight: 700;
- letter-spacing: 0.08em;
- text-transform: uppercase;
- color: var(--flame);
- }
-
- .hero-actions {
- display: flex;
- gap: 1rem;
- flex-wrap: wrap;
- align-items: center;
- }
-
- .btn-primary {
- font-family: var(--font-heading);
- font-size: 0.8rem;
- letter-spacing: 0.15em;
- text-transform: uppercase;
- background: var(--flame);
- color: #fff;
- padding: 1rem 2rem;
- border: none;
- cursor: pointer;
- text-decoration: none;
- transition: background 0.2s, transform 0.15s;
- display: inline-block;
- }
-
- .btn-primary:hover { background: var(--ember); transform: translateY(-1px); }
-
- .btn-ghost {
- font-family: var(--font-heading);
- font-size: 0.8rem;
- letter-spacing: 0.15em;
- text-transform: uppercase;
- background: transparent;
- color: var(--white);
- padding: 1rem 2rem;
- border: 1px solid var(--steel);
- cursor: pointer;
- text-decoration: none;
- transition: border-color 0.2s, color 0.2s;
- display: inline-block;
- }
-
- .btn-ghost:hover { border-color: var(--flame); color: var(--flame); }
-
- /* ── TRUST BAR ────────────────────────────────────────────────────────── */
- .trust-bar {
- background: var(--ash);
- border-top: 1px solid var(--steel);
- border-bottom: 1px solid var(--steel);
- padding: 1.25rem 5vw;
- display: flex;
- align-items: center;
- gap: 2.5rem;
- flex-wrap: wrap;
- justify-content: center;
- }
-
- .trust-item {
- display: flex;
- align-items: center;
- gap: 0.6rem;
- font-family: var(--font-heading);
- font-size: 0.75rem;
- letter-spacing: 0.12em;
- text-transform: uppercase;
- color: var(--mist);
- }
-
- .trust-item svg { flex-shrink: 0; }
-
- .trust-divider {
- width: 1px;
- height: 20px;
- background: var(--steel);
- }
-
- /* ── SECTIONS SHARED ──────────────────────────────────────────────────── */
- section {
- padding: 7rem 5vw;
- scroll-margin-top: 84px;
- }
-
- .section-eyebrow {
- font-family: var(--font-heading);
- font-size: 0.7rem;
- letter-spacing: 0.2em;
- text-transform: uppercase;
- color: var(--flame);
- margin-bottom: 0.75rem;
- }
-
- .section-title {
- font-family: var(--font-display);
- font-size: clamp(2.4rem, 5vw, 4rem);
- line-height: 1;
- color: var(--white);
- margin-bottom: 1.25rem;
- }
-
- .section-body {
- font-size: 1rem;
- font-weight: 300;
- color: var(--mist);
- max-width: 560px;
- line-height: 1.75;
- }
-
- /* ── SERVICES ─────────────────────────────────────────────────────────── */
- .services-section {
- background: var(--smoke);
- }
-
- .services-header {
- margin-bottom: 4rem;
- }
-
- .services-grid {
- display: grid;
- grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
- gap: 1px;
- background: var(--steel);
- }
-
- .service-card {
- background: var(--ash);
- padding: 2.5rem 2rem;
- transition: background 0.25s;
- position: relative;
- overflow: hidden;
- }
-
- .service-card::before {
- content: '';
- position: absolute;
- bottom: 0; left: 0;
- width: 100%;
- height: 3px;
- background: var(--flame);
- transform: scaleX(0);
- transform-origin: left;
- transition: transform 0.3s ease;
- }
-
- .service-card:hover::before { transform: scaleX(1); }
- .service-card:hover { background: var(--steel); }
-
- .service-icon {
- width: 44px;
- height: 44px;
- margin-bottom: 1.25rem;
- color: var(--flame);
- }
-
- .service-name {
- font-family: var(--font-heading);
- font-size: 1.05rem;
- font-weight: 600;
- letter-spacing: 0.05em;
- text-transform: uppercase;
- color: var(--white);
- margin-bottom: 0.6rem;
- }
-
- .service-desc {
- font-size: 0.88rem;
- font-weight: 300;
- color: var(--mist);
- line-height: 1.65;
- }
-
- /* ── ABOUT / FIRST RESPONDER ──────────────────────────────────────────── */
- .about-section {
- background: var(--ash);
- display: grid;
- grid-template-columns: 1fr 1fr;
- gap: 5rem;
- align-items: stretch;
- padding: 0 5vw 0 0;
- }
-
- .about-visual {
- position: relative;
- width: 100%;
- min-height: clamp(560px, 72vh, 760px);
- }
-
- .about-img {
- width: 100%;
- height: 100%;
- min-height: inherit;
- object-fit: cover;
- display: block;
- background:
- linear-gradient(135deg, #1a1a1a 0%, #2e2e2e 100%);
- }
-
- .about-img-real {
- width: 100%;
- height: 100%;
- min-height: inherit;
- object-fit: cover;
- display: block;
- object-position: center center;
- }
-
- /* First Responder badge */
- .fr-badge {
- position: absolute;
- bottom: 1rem;
- right: -1rem;
- background: var(--smoke);
- border: 2px solid var(--flame);
- padding: 1rem 1.25rem;
- display: flex;
- align-items: center;
- gap: 0.75rem;
- }
-
- .fr-badge-flag {
- width: 44px;
- flex-shrink: 0;
- }
-
- .fr-badge-text {
- font-family: var(--font-heading);
- font-size: 0.72rem;
- letter-spacing: 0.12em;
- text-transform: uppercase;
- color: var(--flame);
- line-height: 1.3;
- }
-
- .about-content .section-body {
- margin-bottom: 1.5rem;
- }
-
- .about-content {
- align-self: center;
- padding: 7rem 0;
- }
-
- .about-stat-row {
- display: flex;
- gap: 2.5rem;
- margin-top: 2.5rem;
- flex-wrap: wrap;
- }
-
- .stat {
- display: flex;
- flex-direction: column;
- gap: 0.25rem;
- }
-
- .stat-num {
- font-family: var(--font-display);
- font-size: 2.6rem;
- color: var(--flame);
- line-height: 1;
- }
-
- .stat-label {
- font-family: var(--font-heading);
- font-size: 0.7rem;
- letter-spacing: 0.15em;
- text-transform: uppercase;
- color: var(--mist);
- }
-
- /* ── FLAG SVG ─────────────────────────────────────────────────────────── */
- /* Inline thin-red-line flag */
-
- /* ── PROJECTS / GALLERY ───────────────────────────────────────────────── */
- .projects-section {
- background: #151515;
- }
-
- .projects-header {
- display: flex;
- justify-content: space-between;
- align-items: end;
- gap: 3rem;
- margin-bottom: 3rem;
- }
-
- .projects-header .section-body {
- max-width: 480px;
- }
-
- .projects-mosaic {
- display: grid;
- grid-template-columns: 1.1fr 0.9fr 0.9fr;
- grid-auto-rows: minmax(210px, 26vw);
- gap: 1px;
- background: var(--steel);
- }
-
- .project-tile {
- position: relative;
- min-height: 220px;
- border: 0;
- color: var(--white);
- background: var(--ash);
- overflow: hidden;
- cursor: pointer;
- display: flex;
- isolation: isolate;
- }
-
- .project-tile.tall {
- grid-row: span 2;
- }
-
- .project-tile::after {
- content: '';
- position: absolute;
- inset: 0;
- z-index: 0;
- background: linear-gradient(135deg, rgba(214,43,43,0.14), transparent 46%);
- opacity: 0.7;
- pointer-events: none;
- }
-
- .tile-image {
- position: absolute;
- inset: 0;
- z-index: -1;
- width: 100%;
- height: 100%;
- object-fit: cover;
- filter: saturate(0.86) contrast(1.04);
- transform: scale(1.02);
- transition: transform 0.45s ease, filter 0.45s ease;
- }
-
- .project-tile:hover .tile-image {
- filter: saturate(1) contrast(1.08);
- transform: scale(1.07);
- }
-
- .image-modal {
- position: fixed;
- inset: 0;
- z-index: 1000;
- display: grid;
- place-items: center;
- padding: clamp(1rem, 4vw, 3rem);
- background: rgba(10,10,10,0.5);
- backdrop-filter: blur(18px);
- -webkit-backdrop-filter: blur(18px);
- opacity: 0;
- visibility: hidden;
- pointer-events: none;
- transition: opacity 0.2s ease, visibility 0.2s ease;
- }
-
- .image-modal.is-open {
- opacity: 1;
- visibility: visible;
- pointer-events: auto;
- }
-
- .image-modal img {
- max-width: 100%;
- max-height: 92vh;
- object-fit: contain;
- }
-
- .image-modal-close {
- position: fixed;
- top: 1rem;
- right: 1rem;
- width: 44px;
- height: 44px;
- border: 0;
- background: transparent;
- color: var(--white);
- font: 300 2.5rem/1 var(--font-body);
- cursor: pointer;
- }
-
- body.modal-open {
- overflow: hidden;
- }
-
- /* ── SERVICE AREAS ─────────────────────────────────────────────────────── */
- .service-areas-section {
- background: var(--smoke);
- }
-
- .service-areas-grid {
- display: grid;
- grid-template-columns: repeat(2, minmax(0, 1fr));
- gap: 1px;
- margin-top: 4rem;
- background: var(--steel);
- }
-
- .service-area-card {
- position: relative;
- min-height: 260px;
- padding: 2.5rem;
- background: var(--ash);
- overflow: hidden;
- }
-
- .service-area-name {
- font-family: var(--font-display);
- font-size: clamp(2.8rem, 6vw, 5rem);
- line-height: 1;
- color: var(--white);
- margin-bottom: 0.5rem;
- }
-
- .service-area-label {
- font-family: var(--font-heading);
- font-size: 0.78rem;
- font-weight: 600;
- letter-spacing: 0.14em;
- text-transform: uppercase;
- color: var(--flame);
- margin-bottom: 1.25rem;
- }
-
- .service-area-copy {
- font-size: 0.95rem;
- font-weight: 300;
- color: var(--mist);
- line-height: 1.7;
- max-width: 34rem;
- }
-
- .service-area-note {
- margin-top: 2rem;
- padding-left: 1rem;
- border-left: 3px solid var(--flame);
- max-width: 760px;
- }
-
- /* ── CONTACT ──────────────────────────────────────────────────────────── */
- .contact-section {
- background: var(--ash);
- display: grid;
- grid-template-columns: 1fr 1fr;
- gap: 5rem;
- align-items: start;
- }
-
- .contact-info {
- display: flex;
- flex-direction: column;
- gap: 1.75rem;
- }
-
- .contact-row {
- display: flex;
- align-items: flex-start;
- gap: 1rem;
- }
-
- .contact-icon {
- width: 20px;
- height: 20px;
- color: var(--flame);
- flex-shrink: 0;
- margin-top: 2px;
- }
-
- .contact-label {
- font-family: var(--font-heading);
- font-size: 0.65rem;
- letter-spacing: 0.18em;
- text-transform: uppercase;
- color: var(--mist);
- margin-bottom: 0.2rem;
- }
-
- .contact-value {
- font-size: 1rem;
- font-weight: 400;
- color: var(--white);
- text-decoration: none;
- }
-
- .contact-value:hover { color: var(--flame); }
-
- /* ── STICKY CALL CTA ─────────────────────────────────────────────────────── */
- .sticky-call-cta {
- position: fixed;
- left: 50%;
- bottom: 1.25rem;
- z-index: 90;
- display: inline-flex;
- align-items: center;
- gap: 0.85rem;
- min-width: min(92vw, 420px);
- padding: 0.85rem 1rem;
- background: #111;
- border: 1px solid var(--flame);
- box-shadow: 0 16px 34px rgba(0,0,0,0.45);
- color: var(--white);
- text-decoration: none;
- transform: translate(-50%, calc(100% + 2rem));
- opacity: 0;
- pointer-events: none;
- transition: transform 0.25s ease, opacity 0.25s ease;
- }
-
- .sticky-call-cta.is-visible {
- transform: translate(-50%, 0);
- opacity: 1;
- pointer-events: auto;
- }
-
- .sticky-call-icon {
- width: 42px;
- height: 42px;
- display: inline-flex;
- align-items: center;
- justify-content: center;
- flex-shrink: 0;
- background: var(--flame);
- color: #fff;
- }
-
- .sticky-call-copy {
- display: flex;
- flex-direction: column;
- line-height: 1.2;
- }
-
- .sticky-call-label {
- font-family: var(--font-heading);
- font-size: 0.68rem;
- letter-spacing: 0.16em;
- text-transform: uppercase;
- color: var(--mist);
- }
-
- .sticky-call-number {
- font-family: var(--font-heading);
- font-size: 1.05rem;
- letter-spacing: 0.04em;
- color: var(--white);
- }
-
- /* Social row */
- .social-row {
- display: flex;
- gap: 1rem;
- margin-top: 0.5rem;
- }
-
- .social-btn {
- display: inline-flex;
- align-items: center;
- gap: 0.5rem;
- font-family: var(--font-heading);
- font-size: 0.72rem;
- letter-spacing: 0.1em;
- text-transform: uppercase;
- color: var(--mist);
- border: 1px solid var(--steel);
- padding: 0.5rem 0.9rem;
- text-decoration: none;
- transition: border-color 0.2s, color 0.2s;
- }
-
- .social-btn:hover { border-color: var(--flame); color: var(--flame); }
-
- /* Quote form */
- .quote-form {
- display: flex;
- flex-direction: column;
- gap: 1rem;
- }
-
- .quote-form.is-submitted > :not(#form-success) {
- display: none;
- }
-
- .form-label {
- font-family: var(--font-heading);
- font-size: 0.65rem;
- letter-spacing: 0.18em;
- text-transform: uppercase;
- color: var(--mist);
- margin-bottom: 0.35rem;
- display: block;
- }
-
- .form-field {
- display: flex;
- flex-direction: column;
- }
-
- .form-input,
- .form-select,
- .form-textarea {
- background: var(--smoke);
- border: 1px solid var(--steel);
- color: var(--white);
- font-family: var(--font-body);
- font-size: 0.95rem;
- padding: 0.75rem 1rem;
- outline: none;
- transition: border-color 0.2s;
- width: 100%;
- }
-
- .form-input::placeholder,
- .form-textarea::placeholder { color: var(--steel); }
- .form-input:focus,
- .form-select:focus,
- .form-textarea:focus { border-color: var(--flame); }
-
- .form-select {
- appearance: none;
- cursor: pointer;
- }
-
- .form-textarea { resize: vertical; min-height: 110px; }
-
- .form-row {
- display: grid;
- grid-template-columns: 1fr 1fr;
- gap: 1rem;
- }
-
- #form-success {
- display: none;
- text-align: center;
- padding: 1rem;
- color: var(--flame);
- font-family: var(--font-heading);
- font-size: 0.85rem;
- letter-spacing: 0.1em;
- text-transform: uppercase;
- }
-
- /* ── FOOTER ───────────────────────────────────────────────────────────── */
- footer {
- background: #111;
- border-top: 1px solid var(--ash);
- padding: 2rem 5vw;
- display: flex;
- align-items: center;
- justify-content: space-between;
- flex-wrap: wrap;
- gap: 1rem;
- }
-
- .footer-logo {
- display: inline-flex;
- align-items: center;
- }
-
- .footer-logo img {
- width: 240px;
- height: auto;
- object-fit: contain;
- display: block;
- }
-
- .footer-note {
- font-size: 0.78rem;
- color: var(--steel);
- font-weight: 300;
- }
-
- /* ── RESPONSIVE ───────────────────────────────────────────────────────── */
- @media (max-width: 800px) {
- nav {
- height: auto;
- min-height: 96px;
- flex-wrap: wrap;
- padding: 0.5rem 5vw;
- }
-
- nav.is-scrolled,
- nav.is-open {
- min-height: 64px;
- }
-
- .nav-logo img {
- width: min(58vw, 210px);
- height: auto;
- }
-
- nav.is-scrolled .nav-logo img,
- nav.is-open .nav-logo img {
- width: 135px;
- }
-
- .nav-logo {
- flex: 1;
- min-width: 0;
- }
-
- .nav-toggle {
- display: flex;
- position: relative;
- z-index: 2;
- border-color: rgba(240, 237, 232, 0.28);
- background: rgba(17, 17, 17, 0.72);
- }
-
- .nav-links {
- order: 3;
- width: 100%;
- flex-direction: column;
- align-items: stretch;
- gap: 0.25rem;
- max-height: 0;
- margin-top: 0;
- padding: 0;
- overflow: hidden;
- opacity: 0;
- visibility: hidden;
- pointer-events: none;
- background: #111;
- border-top: 1px solid transparent;
- transition: max-height 0.28s ease, margin-top 0.28s ease, padding 0.28s ease, opacity 0.2s ease, visibility 0.2s ease, border-color 0.2s ease;
- }
-
- nav.is-open .nav-links {
- display: flex;
- max-height: 24rem;
- margin-top: 0.5rem;
- padding: 0.75rem;
- opacity: 1;
- visibility: visible;
- pointer-events: auto;
- border-top-color: var(--ash);
- box-shadow: 0 18px 30px rgba(0,0,0,0.45);
- }
-
- .nav-links a {
- display: block;
- padding: 0.9rem 0.75rem;
- background: #1A1A1A;
- border: 1px solid transparent;
- transition: background 0.2s ease, border-color 0.2s ease, color 0.2s ease;
- }
-
- .nav-links a:hover,
- .nav-links a.is-active {
- background: rgba(214,43,43,0.12);
- border-color: rgba(214,43,43,0.35);
- }
-
- .nav-links a::after {
- display: none;
- }
-
- .nav-cta {
- display: block;
- width: 100%;
- text-align: center;
- max-height: 0;
- margin-top: 0;
- padding: 0;
- overflow: hidden;
- opacity: 0;
- visibility: hidden;
- pointer-events: none;
- background: var(--flame);
- transition: max-height 0.28s ease, margin-top 0.28s ease, padding 0.28s ease, opacity 0.2s ease, visibility 0.2s ease, background 0.2s ease;
- }
-
- .nav-actions {
- order: 4;
- width: 100%;
- flex-direction: column;
- gap: 0;
- }
-
- nav.is-open .nav-cta {
- display: block;
- max-height: 4rem;
- margin-top: 0.5rem;
- padding: 0.9rem 1rem;
- opacity: 1;
- visibility: visible;
- pointer-events: auto;
- }
-
- nav.is-open .nav-cta-call {
- background: #1A1A1A;
- border: 1px solid var(--flame);
- }
-
- .about-section,
- .contact-section {
- grid-template-columns: 1fr;
- gap: 3rem;
- }
-
- .about-section {
- padding: 5rem 5vw;
- }
-
- .about-visual {
- min-height: clamp(420px, 65vh, 620px);
- }
-
- .about-content {
- padding: 0;
- }
-
- .projects-header {
- display: block;
- }
-
- .projects-header .section-body {
- max-width: none;
- margin-top: 1rem;
- }
-
- .projects-mosaic {
- grid-template-columns: 1fr;
- grid-auto-rows: auto;
- }
-
- .project-tile,
- .project-tile.tall {
- min-height: 260px;
- grid-row: auto;
- }
-
- .fr-badge { right: 1rem; bottom: 1rem; }
-
- .service-areas-grid { grid-template-columns: 1fr; }
-
- .form-row { grid-template-columns: 1fr; }
-
- .trust-divider { display: none; }
- }
-
- @media (max-width: 560px) {
- section {
- padding: 4.5rem 5vw;
- }
-
- .about-section {
- padding: 4.5rem 5vw;
- }
-
- .hero {
- min-height: 100svh;
- align-items: flex-start;
- padding-top: calc(96px + 2rem);
- padding-bottom: 4rem;
- }
-
- .hero-content {
- max-width: 24rem;
- }
-
- .hero-eyebrow {
- font-size: 0.62rem;
- letter-spacing: 0.16em;
- }
-
- .hero-title {
- font-size: clamp(2.9rem, 19vw, 4rem);
- line-height: 0.88;
- }
-
- .hero-sub {
- margin-bottom: 1.5rem;
- }
-
- .hero-body {
- margin-bottom: 2rem;
- }
-
- .hero-actions {
- align-items: stretch;
- }
-
- .btn-primary,
- .btn-ghost {
- width: 100%;
- text-align: center;
- padding: 0.95rem 1rem;
- }
-
- .trust-bar {
- justify-content: flex-start;
- }
-
- .sticky-call-cta {
- left: 5vw;
- right: 5vw;
- bottom: 0.75rem;
- min-width: 0;
- width: auto;
- transform: translateY(calc(100% + 1.5rem));
- }
-
- .sticky-call-cta.is-visible {
- transform: translateY(0);
- }
-
- .fr-badge {
- right: 0.75rem;
- bottom: 0.75rem;
- max-width: calc(100% - 1.5rem);
- padding: 0.8rem 0.9rem;
- }
-
- .service-area-card {
- min-height: 220px;
- padding: 2rem;
- }
-
- footer {
- align-items: flex-start;
- }
- }
-
- @media (prefers-reduced-motion: reduce) {
- * { transition: none !important; animation: none !important; }
- }
- </style>
-</head>
-<body>
-
- <!-- NAV -->
- <nav>
- <a class="nav-logo" href="#hero" aria-label="Frontline Boat Services home">
- <img src="frontline-logo.png" alt="Frontline Boat Services">
- </a>
- <button class="nav-toggle" type="button" aria-label="Open navigation" aria-controls="primary-navigation" aria-expanded="false">
- <span aria-hidden="true"></span>
- <span aria-hidden="true"></span>
- <span aria-hidden="true"></span>
- </button>
- <ul class="nav-links" id="primary-navigation">
- <li><a href="#services">Services</a></li>
- <li><a href="#about">About</a></li>
- <li><a href="#projects">Gallery</a></li>
- <li><a href="#service-areas">Areas</a></li>
- <li><a href="#contact">Contact</a></li>
- </ul>
- <div class="nav-actions">
- <a class="nav-cta nav-cta-call" href="tel:+17862780478">Call (786) 278-0478</a>
- <a class="nav-cta" href="#contact">Get a Quote</a>
- </div>
- </nav>
-
- <!-- HERO -->
- <section id="hero" class="hero">
- <div class="hero-bg"></div>
- <div class="hero-slash"></div>
- <div class="hero-content">
- <div class="hero-eyebrow">Miami, FL — First Responder Owned & Operated</div>
- <h1 class="hero-title">
- FULL SERVICE <br><span class="accent">MARINE</span> SOLUTIONS
- </h1>
- <p class="hero-body">
- <strong>Frontline Boat Services</strong> specializes in marine electrical installations, rewires, maintenance, & more! We provide reliable, expert solutions to keep your vessel in top condition.
- </p>
- <div class="hero-actions">
- <a class="btn-primary" href="#contact">Get a Free Quote</a>
- <a class="btn-ghost" href="#services">Our Services</a>
- </div>
- </div>
- </section>
-
- <!-- TRUST BAR -->
- <div class="trust-bar">
- <div class="trust-item">
- <!-- shield icon -->
- <svg class="trust-item-icon" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24" color="#D62B2B"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg>
- First Responder Owned
- </div>
- <div class="trust-divider"></div>
- <div class="trust-item">
- <svg class="trust-item-icon" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24" color="#D62B2B"><circle cx="12" cy="12" r="10"/><path d="M12 6v6l4 2"/></svg>
- Fast Turnaround
- </div>
- <div class="trust-divider"></div>
- <div class="trust-item">
- <svg class="trust-item-icon" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24" color="#D62B2B"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/><polyline points="22 4 12 14.01 9 11.01"/></svg>
- Quality Guaranteed
- </div>
- <div class="trust-divider"></div>
- <div class="trust-item">
- <svg class="trust-item-icon" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24" color="#D62B2B"><path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"/><circle cx="12" cy="10" r="3"/></svg>
- Miami & South Florida
- </div>
- <div class="trust-divider"></div>
- <div class="trust-item">
- <svg class="trust-item-icon" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24" color="#D62B2B"><path d="M3 18v-6a9 9 0 0 1 18 0v6"/><path d="M21 19a2 2 0 0 1-2 2h-1a2 2 0 0 1-2-2v-3a2 2 0 0 1 2-2h3zM3 19a2 2 0 0 0 2 2h1a2 2 0 0 0 2-2v-3a2 2 0 0 0-2-2H3z"/></svg>
- Full-Service Shop
- </div>
- </div>
-
- <!-- SERVICES -->
- <section id="services" class="services-section">
- <div class="services-header">
- <p class="section-eyebrow">What We Do</p>
- <h2 class="section-title">EVERY SYSTEM,<br>HANDLED RIGHT</h2>
- <p class="section-body">
- From a single gauge to a full electronics overhaul, we bring the same
- first-responder standard of accuracy and accountability to every job.
- </p>
- </div>
-
- <div class="services-grid">
-
- <div class="service-card">
- <svg class="service-icon" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24">
- <circle cx="12" cy="12" r="3"/><path d="M12 1v2M12 21v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M1 12h2M21 12h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42"/>
- </svg>
- <div class="service-name">Marine Electronics</div>
- <div class="service-desc">Chartplotters, depth finders, VHF radios, autopilots, and full NMEA 2000 network builds. If it has a wire, we can install it.</div>
- </div>
-
- <div class="service-card">
- <svg class="service-icon" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24">
- <path d="M13 2L3 14h9l-1 8 10-12h-9l1-8z"/>
- </svg>
- <div class="service-name">Full Rewiring</div>
- <div class="service-desc">Complete electrical system replacement or repair. We chase every ghost fault, eliminate every corroded connection, and build to NMEA standards.</div>
- </div>
-
- <div class="service-card">
- <svg class="service-icon" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24">
- <path d="M9 18V5l12-2v13"/><circle cx="6" cy="18" r="3"/><circle cx="18" cy="16" r="3"/>
- </svg>
- <div class="service-name">Audio Installation</div>
- <div class="service-desc">Marine-grade speakers, amplifiers, subwoofers, and head units. Crystal clear sound that holds up against saltwater, sun, and wind.</div>
- </div>
-
- <div class="service-card">
- <svg class="service-icon" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24">
- <path d="M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7z"/><circle cx="12" cy="9" r="2.5"/>
- </svg>
- <div class="service-name">GPS Systems</div>
- <div class="service-desc">Single and multi-station GPS installation, sensor integration, and satellite compass setup for reliable on-water navigation.</div>
- </div>
-
- <div class="service-card">
- <svg class="service-icon" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24">
- <rect x="2" y="3" width="20" height="14" rx="2"/><path d="M8 21h8M12 17v4"/>
- </svg>
- <div class="service-name">Displays & Instruments</div>
- <div class="service-desc">Multi-function display installs, gauge clusters, acrylic panels, digital switching panels, and helm layouts built for the way you actually run your boat.</div>
- </div>
-
- <div class="service-card">
- <svg class="service-icon" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24">
- <path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z"/>
- </svg>
- <div class="service-name">And More</div>
- <div class="service-desc">Shore power, battery systems, bilge pumps, lighting, camera systems. Tell us what your boat needs — we'll sort it out.</div>
- </div>
-
- </div>
- </section>
-
- <!-- ABOUT / FIRST RESPONDER -->
- <section id="about" class="about-section">
- <div class="about-visual">
- <!-- Placeholder image with a styled background; in production replace src with a real photo -->
- <img
- class="about-img-real"
- src="frontline-1.png"
- alt="Firefighter and boat technician at work"
- onerror="this.style.display='none'; this.nextElementSibling.style.display='flex';"
- />
- <div class="about-img" style="display:none; align-items:center; justify-content:center;">
- <svg width="64" height="64" fill="none" stroke="#3D3D3D" stroke-width="1.5" viewBox="0 0 24 24"><rect x="3" y="3" width="18" height="18" rx="2"/><circle cx="8.5" cy="8.5" r="1.5"/><polyline points="21 15 16 10 5 21"/></svg>
- </div>
- <div class="fr-badge">
- <!-- Inline thin-red-line flag SVG -->
- <svg class="fr-badge-flag" viewBox="0 0 60 36" fill="none" xmlns="http://www.w3.org/2000/svg">
- <rect width="60" height="36" fill="#1A1A1A"/>
- <!-- stripes -->
- <rect y="0" width="60" height="4" fill="#555"/>
- <rect y="4" width="60" height="4" fill="#1A1A1A"/>
- <rect y="8" width="60" height="4" fill="#555"/>
- <rect y="12" width="60" height="4" fill="#1A1A1A"/>
- <!-- thin red line -->
- <rect y="16" width="60" height="4" fill="#D62B2B"/>
- <rect y="20" width="60" height="4" fill="#1A1A1A"/>
- <rect y="24" width="60" height="4" fill="#555"/>
- <rect y="28" width="60" height="4" fill="#1A1A1A"/>
- <rect y="32" width="60" height="4" fill="#555"/>
- <!-- canton overlay -->
- <rect width="24" height="20" fill="#1A1A1A" opacity="0.6"/>
- </svg>
- <div class="fr-badge-text">First Responder<br>Owned & Operated</div>
- </div>
- </div>
-
- <div class="about-content">
- <p class="section-eyebrow">About Frontline</p>
- <h2 class="section-title">TRAINED TO<br>NEVER FAIL</h2>
- <p class="section-body">
- Frontline Boat Services was founded by owner Brian Frias, an active firefighter
- who built the same habits off the truck as on it: no shortcuts, no guesswork,
- no half-measures.
- </p>
- <p class="section-body" style="margin-top: 1rem;">
- Brian is NMEA certified as a Basic NMEA 2000 Installer and an Advanced Marine
- Electronics Installer (AMEI), bringing trained marine electronics standards to
- every install, rewire, and diagnostic job.
- </p>
- <p class="section-body" style="margin-top: 1rem;">
- Working out of Miami, FL, we serve boaters across South Florida who are tired of
- sloppy installs and chasing repeat electrical issues season after season. When we hand
- your boat back, every system works — and keeps working.
- </p>
- <div class="about-stat-row">
- <div class="stat">
- <span class="stat-num">100%</span>
- <span class="stat-label">First Responder Owned</span>
- </div>
- <div class="stat">
- <span class="stat-num">Miami</span>
- <span class="stat-label">Based in South FL</span>
- </div>
- <div class="stat">
- <span class="stat-num">0</span>
- <span class="stat-label">Shortcuts Taken</span>
- </div>
- </div>
- </div>
- </section>
-
- <!-- PROJECTS / GALLERY -->
- <section id="projects" class="projects-section">
- <div class="projects-header">
- <div>
- <p class="section-eyebrow">Recent Work</p>
- <h2 class="section-title">SYSTEMS BUILT<br>FOR THE WATER</h2>
- </div>
- <p class="section-body">
- A closer look at the type of clean installs, helm layouts, wiring work,
- and marine electronics projects Frontline handles for South Florida boaters.
- </p>
- </div>
-
- <div class="projects-mosaic">
- <div class="project-tile tall" role="button" tabindex="0" aria-label="View full size image of a Frontline marine electronics install">
- <img class="tile-image" src="frontline-2.png" alt="Frontline marine electronics install">
- </div>
-
- <div class="project-tile" role="button" tabindex="0" aria-label="View full size image of Frontline dockside diagnostics work">
- <img class="tile-image" src="frontline-3.png" alt="Frontline dockside diagnostics work">
- </div>
-
- <div class="project-tile" role="button" tabindex="0" aria-label="View full size image of a Frontline helm control layout">
- <img class="tile-image" src="frontline-4.png" alt="Frontline helm control layout">
- </div>
-
- <div class="project-tile" role="button" tabindex="0" aria-label="View full size image of Frontline water-tested marine systems">
- <img class="tile-image" src="frontline-5.png" alt="Frontline water-tested marine systems">
- </div>
-
- <div class="project-tile" role="button" tabindex="0" aria-label="View full size image of a Frontline marine audio upgrade">
- <img class="tile-image" src="frontline-6.png" alt="Frontline marine audio upgrade">
- </div>
- </div>
- </section>
-
- <!-- SERVICE AREAS -->
- <section id="service-areas" class="service-areas-section">
- <p class="section-eyebrow">Service Areas</p>
- <h2 class="section-title">MIAMI-DADE<br>& BROWARD</h2>
- <p class="section-body">
- Frontline Boat Services works across South Florida for boaters who need clean
- marine electronics, wiring, audio, GPS, and electrical service done correctly.
- </p>
-
- <div class="service-areas-grid">
- <div class="service-area-card">
- <div class="service-area-name">Miami-Dade</div>
- <div class="service-area-label">Primary Service County</div>
- <p class="service-area-copy">
- Based in Miami and serving boat owners, marinas, and dockside projects
- throughout Miami-Dade County.
- </p>
- </div>
- <div class="service-area-card">
- <div class="service-area-name">Broward</div>
- <div class="service-area-label">North Coverage Area</div>
- <p class="service-area-copy">
- Available for installs, repairs, diagnostics, and upgrades throughout
- Broward County.
- </p>
- </div>
- </div>
-
- <p class="section-body service-area-note">
- Call, text, or email with what is going on or what you want upgraded. We listen,
- assess the work, give a straight quote, build with marine-grade components,
- test everything before signoff, and send you back on the water knowing exactly
- what was done.
- </p>
- </section>
-
- <!-- CONTACT -->
- <section id="contact" class="contact-section">
- <div>
- <p class="section-eyebrow">Get In Touch</p>
- <h2 class="section-title">MESSAGE US<br>TODAY</h2>
- <p class="section-body" style="margin-bottom: 3rem;">
- Ready for a quote or just have a question? Reach out by phone, email, or the form.
- We get back to every message.
- </p>
-
- <div class="contact-info">
- <div class="contact-row">
- <svg class="contact-icon" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
- <path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07A19.5 19.5 0 0 1 4.69 12 19.79 19.79 0 0 1 1.61 3.38C1.61 2.18 2.6 1 3.8 1h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L7.91 8.91a16 16 0 0 0 6.06 6.06l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z"/>
- </svg>
- <div>
- <div class="contact-label">Phone / Text</div>
- <a class="contact-value" href="tel:+17862780478">(786) 278-0478</a>
- </div>
- </div>
-
- <div class="contact-row">
- <svg class="contact-icon" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
- <path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"/><polyline points="22,6 12,13 2,6"/>
- </svg>
- <div>
- <div class="contact-label">Email</div>
- <a class="contact-value" href="mailto:[email protected]">[email protected]</a>
- </div>
- </div>
-
- <div class="contact-row">
- <svg class="contact-icon" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
- <path d="M21 10c0 7-9 13-9 13S3 17 3 10a9 9 0 0 1 18 0z"/><circle cx="12" cy="10" r="3"/>
- </svg>
- <div>
- <div class="contact-label">Location</div>
- <span class="contact-value">Miami, FL & South Florida</span>
- </div>
- </div>
-
- <div class="social-row">
- <a class="social-btn" href="https://instagram.com/frontlineboats" target="_blank" rel="noopener">
- <svg width="14" height="14" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><rect x="2" y="2" width="20" height="20" rx="5"/><path d="M16 11.37A4 4 0 1 1 12.63 8 4 4 0 0 1 16 11.37z"/><line x1="17.5" y1="6.5" x2="17.51" y2="6.5"/></svg>
- @FrontlineBoats
- </a>
- <a class="social-btn" href="https://facebook.com" target="_blank" rel="noopener">
- <svg width="14" height="14" fill="currentColor" viewBox="0 0 24 24"><path d="M18 2h-3a5 5 0 0 0-5 5v3H7v4h3v8h4v-8h3l1-4h-4V7a1 1 0 0 1 1-1h3z"/></svg>
- Frontline Boat Services
- </a>
- </div>
- </div>
- </div>
-
- <div>
- <form class="quote-form" onsubmit="handleSubmit(event)">
- <div class="form-row">
- <div class="form-field">
- <label class="form-label" for="fname">First Name</label>
- <input class="form-input" type="text" id="fname" placeholder="John" />
- </div>
- <div class="form-field">
- <label class="form-label" for="lname">Last Name</label>
- <input class="form-input" type="text" id="lname" placeholder="Smith" />
- </div>
- </div>
- <div class="form-field">
- <label class="form-label" for="email">Email</label>
- <input class="form-input" type="email" id="email" placeholder="[email protected]" />
- </div>
- <div class="form-field">
- <label class="form-label" for="phone">Phone / Text</label>
- <input class="form-input" type="tel" id="phone" placeholder="(305) 000-0000" />
- </div>
- <div class="form-field">
- <label class="form-label" for="service">Service Needed</label>
- <select class="form-select" id="service">
- <option value="" disabled selected>Select a service…</option>
- <option>Marine Electronics Installation</option>
- <option>Full Rewiring</option>
- <option>Audio Installation</option>
- <option>GPS / Navigation</option>
- <option>Displays & Instruments</option>
- <option>General Electrical Repair</option>
- <option>Other / Not Sure</option>
- </select>
- </div>
- <div class="form-field">
- <label class="form-label" for="message">Tell Us About Your Boat</label>
- <textarea class="form-textarea" id="message" placeholder="Year, make, model, and what you're looking to have done…"></textarea>
- </div>
- <button class="btn-primary" type="submit" style="width:100%; font-size:0.85rem; padding: 1.1rem;">Request a Free Quote</button>
- <div id="form-success">Message sent. We'll be in touch shortly.</div>
- </form>
- </div>
- </section>
-
- <!-- FOOTER -->
- <footer>
- <div class="footer-logo">
- <img src="frontline-logo.png" alt="Frontline Boat Services">
- </div>
- <div class="footer-note">Miami, FL · First Responder Owned · [email protected]</div>
- <div class="footer-note">© 2025 Frontline Boat Services. All rights reserved.</div>
- </footer>
-
- <a class="sticky-call-cta" href="tel:+17862780478" aria-hidden="true" tabindex="-1">
- <span class="sticky-call-icon" aria-hidden="true">
- <svg width="20" height="20" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
- <path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07A19.5 19.5 0 0 1 4.69 12 19.79 19.79 0 0 1 1.61 3.38C1.61 2.18 2.6 1 3.8 1h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L7.91 8.91a16 16 0 0 0 6.06 6.06l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z"/>
- </svg>
- </span>
- <span class="sticky-call-copy">
- <span class="sticky-call-label">Call or Text</span>
- <span class="sticky-call-number">(786) 278-0478</span>
- </span>
- </a>
-
- <div class="image-modal" id="image-modal" role="dialog" aria-modal="true" aria-hidden="true">
- <button class="image-modal-close" type="button" aria-label="Close full screen image">×</button>
- <img id="image-modal-img" src="" alt="">
- </div>
-
- <script>
- function handleSubmit(e) {
- e.preventDefault();
- const form = e.target;
- const successMessage = document.getElementById('form-success');
-
- form.reset();
- form.classList.add('is-submitted');
- form.querySelectorAll('input, select, textarea, button[type="submit"]').forEach((control) => {
- control.disabled = true;
- });
- successMessage.style.display = 'block';
- successMessage.setAttribute('tabindex', '-1');
- successMessage.focus();
- }
-
- const siteNav = document.querySelector('nav');
- const navToggle = document.querySelector('.nav-toggle');
- const primaryNavigation = document.getElementById('primary-navigation');
- const heroSection = document.getElementById('hero');
- const siteFooter = document.querySelector('footer');
- const stickyCallCta = document.querySelector('.sticky-call-cta');
- const navSectionLinks = Array.from(document.querySelectorAll('.nav-links a[href^="#"]'));
- const navSections = navSectionLinks
- .map((link) => ({ link, section: document.querySelector(link.getAttribute('href')) }))
- .filter(({ section }) => section);
-
- function syncMobileNavA11y() {
- const isMobileNav = window.matchMedia('(max-width: 800px)').matches;
- primaryNavigation.setAttribute('aria-hidden', String(isMobileNav && !siteNav.classList.contains('is-open')));
- }
-
- function setMobileNav(open) {
- siteNav.classList.toggle('is-open', open);
- navToggle.setAttribute('aria-expanded', String(open));
- navToggle.setAttribute('aria-label', open ? 'Close navigation' : 'Open navigation');
- syncMobileNavA11y();
- }
-
- function updateStickyCallCta() {
- const isPastHero = heroSection.getBoundingClientRect().bottom <= 0;
- const isFooterVisible = siteFooter.getBoundingClientRect().top < window.innerHeight;
- const shouldShow = isPastHero && !isFooterVisible;
- stickyCallCta.classList.toggle('is-visible', shouldShow);
- stickyCallCta.setAttribute('aria-hidden', String(!shouldShow));
- stickyCallCta.tabIndex = shouldShow ? 0 : -1;
- }
-
- function setActiveNavLink(activeId) {
- navSections.forEach(({ link, section }) => {
- const isActive = section.id === activeId;
- link.classList.toggle('is-active', isActive);
-
- if (isActive) {
- link.setAttribute('aria-current', 'location');
- } else {
- link.removeAttribute('aria-current');
- }
- });
- }
-
- function updateActiveNavLink() {
- const navOffset = siteNav.offsetHeight + 24;
- const isAtPageEnd = window.innerHeight + window.scrollY >= document.documentElement.scrollHeight - 2;
- let activeId = '';
-
- navSections.forEach(({ section }) => {
- if (section.getBoundingClientRect().top <= navOffset) {
- activeId = section.id;
- }
- });
-
- if (isAtPageEnd && navSections.length) {
- activeId = navSections[navSections.length - 1].section.id;
- }
-
- setActiveNavLink(activeId);
- siteNav.classList.toggle('is-scrolled', window.scrollY > 40);
- updateStickyCallCta();
- }
-
- navToggle.addEventListener('click', () => {
- setMobileNav(!siteNav.classList.contains('is-open'));
- });
-
- document.querySelectorAll('.nav-links a, .nav-cta').forEach((link) => {
- link.addEventListener('click', () => {
- const targetId = link.getAttribute('href')?.slice(1);
-
- if (targetId) {
- setActiveNavLink(targetId);
- }
-
- setMobileNav(false);
- });
- });
-
- window.addEventListener('scroll', updateActiveNavLink, { passive: true });
- window.addEventListener('resize', () => {
- updateActiveNavLink();
- syncMobileNavA11y();
- updateStickyCallCta();
- });
- window.addEventListener('load', updateActiveNavLink);
- updateActiveNavLink();
- syncMobileNavA11y();
-
- const modal = document.getElementById('image-modal');
- const modalImage = document.getElementById('image-modal-img');
- const closeModalButton = modal.querySelector('.image-modal-close');
- let lastFocusedElement = null;
-
- function openImageModal(image) {
- lastFocusedElement = document.activeElement;
- modalImage.src = image.currentSrc || image.src;
- modalImage.alt = image.alt;
- modal.classList.add('is-open');
- modal.setAttribute('aria-hidden', 'false');
- document.body.classList.add('modal-open');
- closeModalButton.focus();
- }
-
- function closeImageModal() {
- modal.classList.remove('is-open');
- modal.setAttribute('aria-hidden', 'true');
- document.body.classList.remove('modal-open');
- modalImage.removeAttribute('src');
- modalImage.alt = '';
-
- if (lastFocusedElement) {
- lastFocusedElement.focus();
- }
- }
-
- document.querySelectorAll('.project-tile').forEach((tile) => {
- tile.addEventListener('click', () => {
- openImageModal(tile.querySelector('.tile-image'));
- });
-
- tile.addEventListener('keydown', (event) => {
- if (event.key === 'Enter' || event.key === ' ') {
- event.preventDefault();
- openImageModal(tile.querySelector('.tile-image'));
- }
- });
- });
-
- closeModalButton.addEventListener('click', closeImageModal);
-
- modal.addEventListener('click', (event) => {
- if (event.target === modal) {
- closeImageModal();
- }
- });
-
- document.addEventListener('keydown', (event) => {
- if (event.key !== 'Escape') {
- return;
- }
-
- if (modal.classList.contains('is-open')) {
- closeImageModal();
- }
-
- if (siteNav.classList.contains('is-open')) {
- setMobileNav(false);
- navToggle.focus();
- }
- });
- </script>
-</body>
-</html>
diff --git a/docs/index.html b/docs/index.html
index 1d353df..0116495 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -19,6 +19,7 @@
<li><a href="/demo/jdb">jdb</a></li>
<li><a href="/demo/crossroads">crossroads</a></li>
<li><a href="/demo/prima">prima</a></li>
+<li><a href="/demo/voldservices">voldservices</a></li>
</ul>
</body>
</html>
diff --git a/docs/voldservices/HERO-VIDEO-BRIEF.md b/docs/voldservices/HERO-VIDEO-BRIEF.md
new file mode 100644
index 0000000..70eeda0
--- /dev/null
+++ b/docs/voldservices/HERO-VIDEO-BRIEF.md
@@ -0,0 +1,22 @@
+# Vold Services hero video brief
+
+## Shot
+
+- Record one continuous 12–15 second pressure-washing pass in landscape at 4K.
+- Use a tripod or stable gimbal with locked focus, exposure, and white balance.
+- Hold on the visibly dirty surface for 1–2 seconds.
+- Move the wand left to right and keep the clean line clearly visible for 7–9 seconds.
+- Hold on the finished surface for at least 3 seconds; this final frame becomes the poster.
+- Keep the wand and clean line inside the center 45% of the frame so a vertical mobile crop works.
+- Leave the left side visually quiet when possible. Avoid faces, addresses, license plates, jump cuts, and fast camera moves.
+
+## Delivery
+
+- Supply the original camera file without music, text, filters, or baked-in branding.
+- Preferred capture: 3840×2160, 30 or 60 fps, standard dynamic range.
+- Final web exports: 1920×1080 desktop MP4/WebM and a 720×1280 center-cropped mobile version.
+- Target 12–15 seconds and keep each web file below roughly 5 MB without visible blocking.
+
+## Website handoff
+
+The site uses `hero-scroll.mp4`, an audio-free, frequent-keyframe derivative of `hero.mp4`, with `img/hero-poster-v2.jpg`. The video stays paused and its playhead is mapped directly to hero scroll progress. For a future replacement, keep frequent seek points (roughly every 0.1 seconds), muted/plays-inline behavior, and the poster fallback.
diff --git a/docs/voldservices/IMG_4990.JPG b/docs/voldservices/IMG_4990.JPG
new file mode 100644
index 0000000..922d3ff
Binary files /dev/null and b/docs/voldservices/IMG_4990.JPG differ
diff --git a/docs/voldservices/favicon.png b/docs/voldservices/favicon.png
new file mode 100644
index 0000000..425ab92
Binary files /dev/null and b/docs/voldservices/favicon.png differ
diff --git a/docs/voldservices/hero-scroll.mp4 b/docs/voldservices/hero-scroll.mp4
new file mode 100644
index 0000000..3a12173
Binary files /dev/null and b/docs/voldservices/hero-scroll.mp4 differ
diff --git a/docs/voldservices/hero-scroll1.mp4 b/docs/voldservices/hero-scroll1.mp4
new file mode 100644
index 0000000..c3ad935
Binary files /dev/null and b/docs/voldservices/hero-scroll1.mp4 differ
diff --git a/docs/voldservices/hero-scrub.mp4 b/docs/voldservices/hero-scrub.mp4
new file mode 100644
index 0000000..ceb9686
Binary files /dev/null and b/docs/voldservices/hero-scrub.mp4 differ
diff --git a/docs/voldservices/hero.mp4 b/docs/voldservices/hero.mp4
new file mode 100644
index 0000000..3931126
Binary files /dev/null and b/docs/voldservices/hero.mp4 differ
diff --git a/docs/voldservices/hero.webm b/docs/voldservices/hero.webm
new file mode 100644
index 0000000..9e003a6
Binary files /dev/null and b/docs/voldservices/hero.webm differ
diff --git a/docs/voldservices/img/_originals/Screenshot From 2026-08-10 15-55-24.png b/docs/voldservices/img/_originals/Screenshot From 2026-08-10 15-55-24.png
new file mode 100644
index 0000000..f01c019
Binary files /dev/null and b/docs/voldservices/img/_originals/Screenshot From 2026-08-10 15-55-24.png differ
diff --git a/docs/voldservices/img/_originals/Screenshot From 2026-08-10 15-55-35.png b/docs/voldservices/img/_originals/Screenshot From 2026-08-10 15-55-35.png
new file mode 100644
index 0000000..71b526a
Binary files /dev/null and b/docs/voldservices/img/_originals/Screenshot From 2026-08-10 15-55-35.png differ
diff --git a/docs/voldservices/img/_originals/Screenshot From 2026-08-10 15-57-10.png b/docs/voldservices/img/_originals/Screenshot From 2026-08-10 15-57-10.png
new file mode 100644
index 0000000..caedeb3
Binary files /dev/null and b/docs/voldservices/img/_originals/Screenshot From 2026-08-10 15-57-10.png differ
diff --git a/docs/voldservices/img/_originals/Screenshot From 2026-08-10 15-57-28.png b/docs/voldservices/img/_originals/Screenshot From 2026-08-10 15-57-28.png
new file mode 100644
index 0000000..a29acac
Binary files /dev/null and b/docs/voldservices/img/_originals/Screenshot From 2026-08-10 15-57-28.png differ
diff --git a/docs/voldservices/img/_originals/Screenshot From 2026-08-10 15-57-48.png b/docs/voldservices/img/_originals/Screenshot From 2026-08-10 15-57-48.png
new file mode 100644
index 0000000..8cdc9b3
Binary files /dev/null and b/docs/voldservices/img/_originals/Screenshot From 2026-08-10 15-57-48.png differ
diff --git a/docs/voldservices/img/_originals/Screenshot From 2026-08-10 15-57-58.png b/docs/voldservices/img/_originals/Screenshot From 2026-08-10 15-57-58.png
new file mode 100644
index 0000000..67a3c66
Binary files /dev/null and b/docs/voldservices/img/_originals/Screenshot From 2026-08-10 15-57-58.png differ
diff --git a/docs/voldservices/img/_originals/Screenshot From 2026-08-10 15-58-22.png b/docs/voldservices/img/_originals/Screenshot From 2026-08-10 15-58-22.png
new file mode 100644
index 0000000..53f8b38
Binary files /dev/null and b/docs/voldservices/img/_originals/Screenshot From 2026-08-10 15-58-22.png differ
diff --git a/docs/voldservices/img/_originals/Screenshot From 2026-08-10 15-58-26.png b/docs/voldservices/img/_originals/Screenshot From 2026-08-10 15-58-26.png
new file mode 100644
index 0000000..ea49ec8
Binary files /dev/null and b/docs/voldservices/img/_originals/Screenshot From 2026-08-10 15-58-26.png differ
diff --git a/docs/voldservices/img/_originals/Screenshot From 2026-08-10 16-00-09.png b/docs/voldservices/img/_originals/Screenshot From 2026-08-10 16-00-09.png
new file mode 100644
index 0000000..dab74db
Binary files /dev/null and b/docs/voldservices/img/_originals/Screenshot From 2026-08-10 16-00-09.png differ
diff --git a/docs/voldservices/img/_originals/Screenshot From 2026-08-10 16-00-13.png b/docs/voldservices/img/_originals/Screenshot From 2026-08-10 16-00-13.png
new file mode 100644
index 0000000..49f6a24
Binary files /dev/null and b/docs/voldservices/img/_originals/Screenshot From 2026-08-10 16-00-13.png differ
diff --git a/docs/voldservices/img/after-driveway.jpg b/docs/voldservices/img/after-driveway.jpg
new file mode 100644
index 0000000..e6706a3
Binary files /dev/null and b/docs/voldservices/img/after-driveway.jpg differ
diff --git a/docs/voldservices/img/after-lanai.jpg b/docs/voldservices/img/after-lanai.jpg
new file mode 100644
index 0000000..c9d58e4
Binary files /dev/null and b/docs/voldservices/img/after-lanai.jpg differ
diff --git a/docs/voldservices/img/after-patio.jpg b/docs/voldservices/img/after-patio.jpg
new file mode 100644
index 0000000..152e978
Binary files /dev/null and b/docs/voldservices/img/after-patio.jpg differ
diff --git a/docs/voldservices/img/after-pool-deck.jpg b/docs/voldservices/img/after-pool-deck.jpg
new file mode 100644
index 0000000..f7e7bb0
Binary files /dev/null and b/docs/voldservices/img/after-pool-deck.jpg differ
diff --git a/docs/voldservices/img/before-driveway.jpg b/docs/voldservices/img/before-driveway.jpg
new file mode 100644
index 0000000..290882d
Binary files /dev/null and b/docs/voldservices/img/before-driveway.jpg differ
diff --git a/docs/voldservices/img/before-lanai.jpg b/docs/voldservices/img/before-lanai.jpg
new file mode 100644
index 0000000..0939650
Binary files /dev/null and b/docs/voldservices/img/before-lanai.jpg differ
diff --git a/docs/voldservices/img/before-patio.jpg b/docs/voldservices/img/before-patio.jpg
new file mode 100644
index 0000000..4975c32
Binary files /dev/null and b/docs/voldservices/img/before-patio.jpg differ
diff --git a/docs/voldservices/img/before-pool-deck.jpg b/docs/voldservices/img/before-pool-deck.jpg
new file mode 100644
index 0000000..35d312a
Binary files /dev/null and b/docs/voldservices/img/before-pool-deck.jpg differ
diff --git a/docs/voldservices/img/hero-poster-v2.jpg b/docs/voldservices/img/hero-poster-v2.jpg
new file mode 100644
index 0000000..542c7ed
Binary files /dev/null and b/docs/voldservices/img/hero-poster-v2.jpg differ
diff --git a/docs/voldservices/img/hero-poster.jpg b/docs/voldservices/img/hero-poster.jpg
new file mode 100644
index 0000000..c26b44f
Binary files /dev/null and b/docs/voldservices/img/hero-poster.jpg differ
diff --git a/docs/voldservices/img/hero-scrub-poster.jpg b/docs/voldservices/img/hero-scrub-poster.jpg
new file mode 100644
index 0000000..502c506
Binary files /dev/null and b/docs/voldservices/img/hero-scrub-poster.jpg differ
diff --git a/docs/voldservices/img/work-driveway-install.jpg b/docs/voldservices/img/work-driveway-install.jpg
new file mode 100644
index 0000000..7aadd14
Binary files /dev/null and b/docs/voldservices/img/work-driveway-install.jpg differ
diff --git a/docs/voldservices/img/work-driveway-travertine.jpg b/docs/voldservices/img/work-driveway-travertine.jpg
new file mode 100644
index 0000000..d0538ca
Binary files /dev/null and b/docs/voldservices/img/work-driveway-travertine.jpg differ
diff --git a/docs/voldservices/index.html b/docs/voldservices/index.html
new file mode 100644
index 0000000..9a4e941
--- /dev/null
+++ b/docs/voldservices/index.html
@@ -0,0 +1,2194 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+
+ <title>Pressure Washing Broward County | Paver Sealing & Roof Cleaning | Vold Services</title>
+ <meta name="description" content="Pressure washing, paver sealing and repair, and soft wash roof cleaning across Broward, Miami-Dade, and Palm Beach counties. Call or text (954) 401-3301." />
+ <meta name="robots" content="index, follow, max-image-preview:large" />
+ <link rel="canonical" href="https://voldservices.com/" />
+
+ <meta name="geo.region" content="US-FL" />
+ <meta name="geo.placename" content="Fort Lauderdale, Florida" />
+ <meta name="geo.position" content="26.1224;-80.1373" />
+ <meta name="ICBM" content="26.1224, -80.1373" />
+
+ <meta property="og:type" content="website" />
+ <meta property="og:site_name" content="Vold Services" />
+ <meta property="og:title" content="Pressure Washing, Paver Sealing & Roof Cleaning | Vold Services" />
+ <meta property="og:description" content="Pressure washing, paver sealing and repair, and roof cleaning for homes and commercial properties across South Florida. Call or text (954) 401-3301." />
+ <meta property="og:url" content="https://voldservices.com/" />
+ <meta property="og:image" content="https://voldservices.com/og-card-v2.jpg" />
+ <meta property="og:image:secure_url" content="https://voldservices.com/og-card-v2.jpg" />
+ <meta property="og:image:type" content="image/jpeg" />
+ <meta property="og:image:width" content="1200" />
+ <meta property="og:image:height" content="630" />
+ <meta property="og:image:alt" content="Vold Services — pressure washing, paver sealing, and roof cleaning in South Florida" />
+ <meta property="og:locale" content="en_US" />
+ <meta name="twitter:card" content="summary_large_image" />
+ <meta name="twitter:title" content="Pressure Washing, Paver Sealing & Roof Cleaning | Vold Services" />
+ <meta name="twitter:description" content="Pressure washing, paver sealing and repair, and roof cleaning across South Florida. Call or text (954) 401-3301." />
+ <meta name="twitter:image" content="https://voldservices.com/og-card-v2.jpg" />
+ <meta name="twitter:image:alt" content="Vold Services — pressure washing, paver sealing, and roof cleaning in South Florida" />
+
+ <meta name="theme-color" content="#080808" />
+ <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="preload" as="image" href="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: rgba(8, 8, 8, .2);
+ backdrop-filter: blur(14px);
+ -webkit-backdrop-filter: blur(14px);
+ 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: 400vh;
+ height: 400svh;
+ 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 {
+ 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::after {
+ content: "";
+ position: absolute;
+ inset: 0;
+ z-index: 1;
+ 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 {
+ 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 { display: grid; gap: 18px; }
+ .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; }
+
+ .form-note {
+ font-family: var(--mono);
+ font-size: .72rem;
+ color: var(--muted-dim);
+ margin: 0;
+ }
+ .form-success {
+ display: none;
+ padding: 14px 16px;
+ border: 1px solid rgba(88, 189, 236, .45);
+ border-radius: 3px;
+ background: rgba(7, 142, 209, .16);
+ font-family: var(--mono);
+ font-size: .82rem;
+ color: var(--bone);
+ }
+ .form-success.is-shown { display: block; }
+
+ /* ── 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: 400vh; height: 400svh; }
+ .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>
+</head>
+<body>
+ <a class="skip-link" href="#main">Skip to content</a>
+
+ <header class="nav" id="nav">
+ <div class="wrap nav-inner">
+ <a class="brand" href="#top" 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">
+ <!-- ── hero ────────────────────────────────────────────────── -->
+ <section class="hero" id="top">
+ <div class="hero-sticky" id="hero-sticky">
+ <div class="hero-media">
+ <video
+ id="hero-video"
+ poster="img/hero-scrub-poster.jpg"
+ muted playsinline preload="auto"
+ aria-hidden="true" tabindex="-1">
+ <source src="hero-scrub.mp4" type="video/mp4" />
+ <img class="hero-fallback" src="img/hero-scrub-poster.jpg" alt="" />
+ </video>
+ </div>
+ <div class="hero-grain" aria-hidden="true"></div>
+
+ <div class="wrap">
+ <div class="hero-inner">
+ <p class="eyebrow hero-eyebrow">Broward · Miami-Dade · Palm Beach</p>
+ <h1>
+ <span class="hero-title-line"><span class="hero-title-inner">Pressure washing.</span></span>
+ <span class="hero-title-line"><span class="hero-title-inner">Paver sealing.</span></span>
+ <span class="hero-title-line accent"><span class="hero-title-inner">Roof cleaning.</span></span>
+ </h1>
+ <p class="lead hero-lead">
+ <strong>Exterior cleaning and sealing</strong> for South Florida homes and commercial properties. Boost your property value, restore curb appeal and protect your investment with VOLD Services.
+ </p>
+
+ <div class="btn-row hero-primary-actions" id="hero-actions" aria-hidden="true" inert>
+ <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>
+ </div>
+ </div>
+
+ <a class="hero-cue" href="#services">Scroll</a>
+ </div>
+ </section>
+
+ <!-- ── credential strip ────────────────────────────────────── -->
+ <div class="strip">
+ <div class="strip-viewport">
+ <div class="wrap strip-inner">
+ <div class="strip-group">
+ <span>South Florida homes & businesses</span>
+ <span>Licensed & insured</span>
+ <span>Free estimates</span>
+ </div>
+ <div class="strip-group strip-group--clone" aria-hidden="true">
+ <span>South Florida homes & businesses</span>
+ <span>Licensed & insured</span>
+ <span>Free estimates</span>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <!-- ── services ────────────────────────────────────────────── -->
+ <section class="band" id="services">
+ <div class="wrap">
+ <div class="section-head reveal">
+ <h2 class="h2">Services offered</h2>
+ <p class="lead">
+ Concrete, pavers, paint, tile, and shingles do not get cleaned the same way.
+ We choose the pressure and treatment for the material, then protect the areas around it.
+ </p>
+ </div>
+
+ <div class="service-grid">
+ <article class="service service--wash reveal">
+ <div class="service-icon" aria-hidden="true">
+ <svg viewBox="0 0 48 48" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
+ <path d="M30 12h10l4 6-4 6H30z"/><path d="M30 18h-8v-4a3 3 0 0 0-3-3h-3"/>
+ <path d="M22 18v18a4 4 0 0 1-4 4h-2a4 4 0 0 1-4-4V18z"/>
+ <path d="M8 26h-3M8 32h-5M8 20h-4"/>
+ </svg>
+ </div>
+ <h3 class="h3">Pressure washing</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.
+ </p>
+ <ul class="service-list">
+ <li>Driveways, walkways, sidewalks</li>
+ <li>Pool decks, patios, lanais</li>
+ <li>House and building washes</li>
+ <li>Fences, screen enclosures, gutters</li>
+ <li>Dumpster pads & storefronts</li>
+ </ul>
+ </article>
+
+ <article class="service service--seal reveal">
+ <div class="service-icon" aria-hidden="true">
+ <svg viewBox="0 0 48 48" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
+ <path d="M24 6s10 11 10 17a10 10 0 0 1-20 0c0-6 10-17 10-17z"/>
+ <path d="M6 40h36M6 44h36"/>
+ </svg>
+ </div>
+ <h3 class="h3">Paver sealing</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.
+ </p>
+ <ul class="service-list">
+ <li>Deep clean & efflorescence removal</li>
+ <li>Joint sand replacement</li>
+ <li>Wet-look, semi-gloss, or natural finishes</li>
+ <li>Driveways, pool decks, walkways</li>
+ <li>Resealing for worn pavers</li>
+ </ul>
+ </article>
+
+ <article class="service service--repair reveal">
+ <div class="service-icon" aria-hidden="true">
+ <svg viewBox="0 0 48 48" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
+ <rect x="5" y="7" width="17" height="12" rx="1"/>
+ <rect x="26" y="7" width="17" height="12" rx="1"/>
+ <rect x="5" y="24" width="17" height="12" rx="1"/>
+ <path d="M27 34h16M35 24v18M30 29l5-5 5 5"/>
+ </svg>
+ </div>
+ <h3 class="h3">Paver repair</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.
+ </p>
+ <ul class="service-list">
+ <li>Sunken and uneven pavers</li>
+ <li>Loose edge and border pavers</li>
+ <li>Small-area lift and relay</li>
+ <li>Damaged paver replacement</li>
+ <li>Joint sand and final rinse</li>
+ </ul>
+ </article>
+
+ <article class="service service--roof reveal">
+ <div class="service-icon" aria-hidden="true">
+ <svg viewBox="0 0 48 48" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
+ <path d="M4 24 24 8l20 16"/><path d="M8 22v18h32V22"/>
+ <path d="M16 40V28h8v12"/><path d="M30 28h6v6h-6z"/>
+ </svg>
+ </div>
+ <h3 class="h3">Roof cleaning</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.
+ </p>
+ <ul class="service-list">
+ <li>Barrel and flat tile</li>
+ <li>Asphalt shingle and metal</li>
+ <li>Low-pressure application</li>
+ <li>Landscaping watered before and rinsed after</li>
+ <li>Photos available for HOA notices</li>
+ </ul>
+ </article>
+ </div>
+ </div>
+ </section>
+
+ <!-- ── signature: the wand line ────────────────────────────── -->
+ <section class="band band--tinted" id="results">
+ <div class="wrap">
+ <div class="section-head results-head reveal">
+ <h2 class="h2">Real results: See the before and after</h2>
+ </div>
+
+ <div class="wand-comparisons">
+ <article class="wand-project reveal">
+ <div class="wand">
+ <div class="wand-layer">
+ <img 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 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>
+
+ <span class="wand-tag wand-tag--before">Before</span>
+ <span class="wand-tag wand-tag--after">After</span>
+
+ <input class="wand-range" type="range" min="0" max="100" value="50" step="0.1"
+ aria-label="Compare the paver driveway before on the left and after on the right. Use the arrow keys to move the divider." />
+
+ <div class="wand-seam" aria-hidden="true"></div>
+ <div class="wand-handle" aria-hidden="true">
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round">
+ <path d="M9 6 4 12l5 6M15 6l5 6-5 6"/>
+ </svg>
+ </div>
+ </div>
+ </article>
+
+ <article class="wand-project reveal">
+ <div class="wand">
+ <div class="wand-layer">
+ <img 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 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>
+
+ <span class="wand-tag wand-tag--before">Before</span>
+ <span class="wand-tag wand-tag--after">After</span>
+
+ <input class="wand-range" type="range" min="0" max="100" value="50" step="0.1"
+ aria-label="Compare the travertine pool deck before on the left and after on the right. Use the arrow keys to move the divider." />
+
+ <div class="wand-seam" aria-hidden="true"></div>
+ <div class="wand-handle" aria-hidden="true">
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round">
+ <path d="M9 6 4 12l5 6M15 6l5 6-5 6"/>
+ </svg>
+ </div>
+ </div>
+ </article>
+ </div>
+ </div>
+ </section>
+
+ <!-- ── work ────────────────────────────────────────────────── -->
+ <section class="band" id="work">
+ <div class="wrap">
+ <div class="work-heading reveal">
+ <div class="section-head">
+ <h2 class="h2">View some of our recent work</h2>
+ </div>
+ <a class="work-instagram" href="https://www.instagram.com/voldservices/" target="_blank" rel="noopener noreferrer">
+ More jobs on 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>
+ </div>
+
+ <div class="work-grid reveal">
+ <button class="work-tile" type="button">
+ <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 & seal</b><span>Paver sealing</span></span>
+ </button>
+ <button class="work-tile" type="button">
+ <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="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="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 & walkway</b><span>Pressure washing</span></span>
+ </button>
+ <button class="work-tile" type="button">
+ <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 & taped off</span></span>
+ </button>
+ <button class="work-tile" type="button">
+ <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>
+ </div>
+ </section>
+
+ <!-- ── service areas ───────────────────────────────────────── -->
+ <section class="band band--tinted" id="areas">
+ <div class="wrap">
+ <div class="section-head reveal">
+ <h2 class="h2">Areas Serviced</h2>
+ <p class="lead">
+ We service all of Broward, West Palm, and Miami-Dade. No matter where you are located in South Florida, we can make your space shine!
+ </p>
+ </div>
+
+ <div class="areas-grid reveal">
+ <div class="area area--primary">
+ <h3>Broward County</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>
+ <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>
+ </div>
+
+ <div class="area">
+ <h3>Miami-Dade County</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>
+ <li>North Miami</li><li>Pinecrest</li><li>Palmetto Bay</li><li>Homestead</li>
+ </ul>
+ </div>
+
+ <div class="area">
+ <h3>Palm Beach County</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>
+ <li>Palm Beach Gardens</li><li>Greenacres</li>
+ </ul>
+ </div>
+ </div>
+ </div>
+ </section>
+
+ <!-- ── reviews ─────────────────────────────────────────────── -->
+ <section class="band" id="reviews">
+ <div class="wrap">
+ <div class="section-head reveal">
+ <h2 class="h2">100 five star reviews and counting</h2>
+ </div>
+
+ <div class="reviews reveal">
+ <figure class="review">
+ <div class="stars" aria-label="5 out of 5 stars">★★★★★</div>
+ <blockquote>Don't hesitate. These guys are pros. From unbelievably quick response to immaculate prep work to superior sealant, you will not be disappointed. You get what you pay for and Nano Seal is worth every penny.</blockquote>
+ <figcaption>Julie Walsh</figcaption>
+ </figure>
+ <figure class="review">
+ <div class="stars" aria-label="5 out of 5 stars">★★★★★</div>
+ <blockquote>A good friend recommended Vold to me and I had a great experience. Jack showed up on time to give an estimate and came several days later to pressure clean my pavers front and back. A great job at a reasonable price, I highly recommend this company!</blockquote>
+ <figcaption>Christopher Cooper</figcaption>
+ </figure>
+ <figure class="review">
+ <div class="stars" aria-label="5 out of 5 stars">★★★★★</div>
+ <blockquote>Absolutely exceptional. The level of professionalism, precision, and attention to detail truly sets this company apart. From start to finish, everything reflects a commitment to excellence and high standards. It’s rare to find a business that delivers with this level of care and consistency. If you’re looking for a premium, top-tier experience, this is the company to trust </blockquote>
+ <figcaption>Skye Proferes</figcaption>
+ </figure>
+ </div>
+
+ <p class="placeholder-note reveal">
+ See all of our reviews on <a href="https://share.google/Gy96TtpQu6SzJoTp2">Google</a>.
+ </p>
+ </div>
+ </section>
+
+ <!-- ── quote ───────────────────────────────────────────────── -->
+ <section class="band band--tinted" id="quote">
+ <div class="wrap">
+ <div class="section-head reveal">
+ <h2 class="h2">Contact us today!</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>
+
+ <form class="quote-form" id="quote-form" novalidate>
+ <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>
+ <button class="btn btn--primary btn--block" type="submit">Request an estimate</button>
+ <p class="form-note">Prefer to talk? Call or text (954) 401-3301 during business hours.</p>
+ <div class="form-success" id="form-success" role="status"></div>
+ </form>
+ </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</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 & building wash</a></li>
+ <li><a href="#services">Commercial cleaning</a></li>
+ </ul>
+ </div>
+ <div>
+ <h4>Company</h4>
+ <ul>
+ <li><a href="#results">Before & after</a></li>
+ <li><a href="#work">Recent work</a></li>
+ <li><a href="#areas">Service areas</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 & insured</span>
+ </div>
+ </div>
+ </footer>
+
+ <!-- Mobile-only bottom bar; slides up once the hero is out of view. -->
+ <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>
+
+ <div class="lightbox" id="lightbox" role="dialog" aria-modal="true" aria-label="Project photo">
+ <button class="lightbox-close" type="button" aria-label="Close photo">×</button>
+ <img id="lightbox-img" alt="" />
+ </div>
+
+ <!-- ── structured data ───────────────────────────────────────── -->
+ <script type="application/ld+json">
+ {
+ "@context": "https://schema.org",
+ "@graph": [
+ {
+ "@type": ["LocalBusiness", "HomeAndConstructionBusiness"],
+ "@id": "https://voldservices.com/#business",
+ "name": "Vold Services",
+ "description": "Pressure washing, paver sealing and repair, and roof cleaning for residential and commercial properties in Broward, Miami-Dade, and Palm Beach counties, Florida.",
+ "url": "https://voldservices.com/",
+ "telephone": "+1-954-401-3301",
+ "image": "https://voldservices.com/og-card-v2.jpg",
+ "logo": "https://voldservices.com/logo.png",
+ "sameAs": [
+ "https://www.instagram.com/voldservices/",
+ "https://www.facebook.com/p/VOLD-Services-61553817020348/",
+ "https://share.google/Gy96TtpQu6SzJoTp2"
+ ],
+ "priceRange": "$$",
+ "currenciesAccepted": "USD",
+ "address": {
+ "@type": "PostalAddress",
+ "addressLocality": "Fort Lauderdale",
+ "addressRegion": "FL",
+ "addressCountry": "US"
+ },
+ "geo": { "@type": "GeoCoordinates", "latitude": 26.1224, "longitude": -80.1373 },
+ "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"
+ }
+ ],
+ "hasOfferCatalog": {
+ "@type": "OfferCatalog",
+ "name": "Exterior cleaning services",
+ "itemListElement": [
+ {
+ "@type": "Offer",
+ "itemOffered": {
+ "@type": "Service",
+ "name": "Pressure Washing",
+ "serviceType": "Pressure washing",
+ "description": "Driveways, walkways, pool decks, patios, house washes, fences, and commercial flatwork cleaned at surface-appropriate pressure.",
+ "areaServed": "Broward County, Florida"
+ }
+ },
+ {
+ "@type": "Offer",
+ "itemOffered": {
+ "@type": "Service",
+ "name": "Paver Sealing",
+ "serviceType": "Paver sealing",
+ "description": "Paver cleaning, efflorescence removal, polymeric joint sand replacement, and wet-look or matte sealing for driveways and pool decks.",
+ "areaServed": "Broward County, Florida"
+ }
+ },
+ {
+ "@type": "Offer",
+ "itemOffered": {
+ "@type": "Service",
+ "name": "Paver Repair",
+ "serviceType": "Paver repair",
+ "description": "Repair for sunken, uneven, loose, separated, or damaged pavers, including small-area lift and relay, base correction, replacement, and joint sand.",
+ "areaServed": "Broward County, Florida"
+ }
+ },
+ {
+ "@type": "Offer",
+ "itemOffered": {
+ "@type": "Service",
+ "name": "Roof Cleaning",
+ "serviceType": "Roof cleaning",
+ "description": "Low-pressure soft wash roof cleaning for barrel tile, flat tile, asphalt shingle, and metal roofs to remove algae streaking.",
+ "areaServed": "Broward County, Florida"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "@type": "WebSite",
+ "@id": "https://voldservices.com/#website",
+ "url": "https://voldservices.com/",
+ "name": "Vold Services",
+ "publisher": { "@id": "https://voldservices.com/#business" },
+ "inLanguage": "en-US"
+ }
+ ]
+ }
+ </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 heroVideo = document.getElementById('hero-video');
+ var heroVideoReady = false;
+ var heroVideoProgress = 0;
+
+ 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);
+ var targetTime = usableDuration * heroVideoProgress;
+ if (!force && (heroVideo.seeking || Math.abs(heroVideo.currentTime - targetTime) < (1 / 48))) return;
+ heroVideo.currentTime = targetTime;
+ }
+
+ heroVideo.addEventListener('loadedmetadata', function () {
+ heroVideo.pause();
+ heroVideoReady = true;
+ syncHeroVideo(heroVideoProgress, true);
+ });
+
+ // 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 () {
+ syncHeroVideo(heroVideoProgress, false);
+ });
+
+ 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;
+
+ document.querySelectorAll('.work-tile').forEach(function (tile) {
+ tile.addEventListener('click', function () {
+ var img = tile.querySelector('img');
+ if (!img) return;
+ lastFocused = tile;
+ lightboxImg.src = img.currentSrc || img.src;
+ lightboxImg.alt = img.alt;
+ lightbox.classList.add('is-open');
+ document.body.classList.add('is-locked');
+ lightboxClose.focus();
+ });
+ });
+
+ 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 ───────────────────────────────────────────
+ Demo only: no backend is wired up yet. Point this at a form
+ endpoint (Formspree, Netlify Forms, or an email handler)
+ before launch. */
+ var form = document.getElementById('quote-form');
+ var success = document.getElementById('form-success');
+
+ form.addEventListener('submit', function (e) {
+ e.preventDefault();
+ var name = form.querySelector('#q-name');
+ var phone = form.querySelector('#q-phone');
+
+ if (!name.value.trim() || !phone.value.trim()) {
+ success.classList.add('is-shown');
+ success.textContent = 'Enter your name and phone number.';
+ (!name.value.trim() ? name : phone).focus();
+ return;
+ }
+
+ form.querySelectorAll('input, select, textarea, button').forEach(function (c) {
+ c.disabled = true;
+ });
+ success.classList.add('is-shown');
+ success.textContent = 'Thanks. We’ll call or text to confirm the details. Need us sooner? Call (954) 401-3301.';
+ });
+
+ document.getElementById('year').textContent = new Date().getFullYear();
+ })();
+ </script>
+</body>
+</html>
diff --git a/docs/voldservices/logo.png b/docs/voldservices/logo.png
new file mode 100644
index 0000000..f682d3a
Binary files /dev/null and b/docs/voldservices/logo.png differ
diff --git a/docs/voldservices/og-card-v2.jpg b/docs/voldservices/og-card-v2.jpg
new file mode 100644
index 0000000..de1548a
Binary files /dev/null and b/docs/voldservices/og-card-v2.jpg differ
diff --git a/docs/voldservices/og-card.jpg b/docs/voldservices/og-card.jpg
new file mode 100644
index 0000000..9a16d79
Binary files /dev/null and b/docs/voldservices/og-card.jpg differ