patx/demo
improve/finish frontlineboats
Commit 9cf679e · patx · 2026-06-16T13:15:23-04:00
Comments
No comments yet.
Diff
diff --git a/docs/frontline-1.png b/docs/frontline-1.png
new file mode 100644
index 0000000..466860e
Binary files /dev/null and b/docs/frontline-1.png differ
diff --git a/docs/frontline-2.png b/docs/frontline-2.png
new file mode 100644
index 0000000..577e5ef
Binary files /dev/null and b/docs/frontline-2.png differ
diff --git a/docs/frontline-3.png b/docs/frontline-3.png
new file mode 100644
index 0000000..d3c7cbe
Binary files /dev/null and b/docs/frontline-3.png differ
diff --git a/docs/frontline-4.png b/docs/frontline-4.png
new file mode 100644
index 0000000..9dc0ec5
Binary files /dev/null and b/docs/frontline-4.png differ
diff --git a/docs/frontline-5.png b/docs/frontline-5.png
new file mode 100644
index 0000000..5dc3732
Binary files /dev/null and b/docs/frontline-5.png differ
diff --git a/docs/frontline-6.png b/docs/frontline-6.png
new file mode 100644
index 0000000..d76125f
Binary files /dev/null and b/docs/frontline-6.png differ
diff --git a/docs/frontline-hero.png b/docs/frontline-hero.png
new file mode 100644
index 0000000..5cf6801
Binary files /dev/null and b/docs/frontline-hero.png differ
diff --git a/docs/frontline-logo.jpg b/docs/frontline-logo.jpg
new file mode 100644
index 0000000..cea541f
Binary files /dev/null and b/docs/frontline-logo.jpg differ
diff --git a/docs/frontline-logo.png b/docs/frontline-logo.png
new file mode 100644
index 0000000..b3d11b7
Binary files /dev/null and b/docs/frontline-logo.png differ
diff --git a/docs/frontline-og_card.png b/docs/frontline-og_card.png
new file mode 100644
index 0000000..ac40674
Binary files /dev/null and b/docs/frontline-og_card.png differ
diff --git a/docs/frontlineboats.html b/docs/frontlineboats.html
index 207b3e4..70fb5df 100644
--- a/docs/frontlineboats.html
+++ b/docs/frontlineboats.html
@@ -4,6 +4,19 @@
<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" />
@@ -46,21 +59,39 @@
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);
- backdrop-filter: blur(8px);
- border-bottom: 1px solid var(--ash);
+ border-bottom-color: var(--ash);
+ box-shadow: 0 4px 24px rgba(0,0,0,0.5);
}
.nav-logo {
- font-family: var(--font-display);
- font-size: 1.5rem;
- letter-spacing: 0.08em;
- color: var(--white);
+ display: inline-flex;
+ align-items: center;
text-decoration: none;
}
- .nav-logo span { color: var(--flame); }
+ .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;
@@ -98,6 +129,12 @@
.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;
@@ -114,6 +151,17 @@
.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;
@@ -169,7 +217,7 @@
inset: 0;
background:
linear-gradient(to right, rgba(10,10,10,0.95) 40%, rgba(10,10,10,0.5) 100%),
- url('https://images.unsplash.com/photo-1605281317010-fe5ffe798166?w=1600&q=80') center/cover no-repeat;
+ url('frontline-hero.png') center/cover no-repeat;
}
/* Signature element: diagonal red slash that bleeds off the right edge */
@@ -198,6 +246,7 @@
position: relative;
z-index: 2;
max-width: 680px;
+ width: 100%;
}
.hero-eyebrow {
@@ -250,6 +299,15 @@
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;
@@ -423,16 +481,20 @@
display: grid;
grid-template-columns: 1fr 1fr;
gap: 5rem;
- align-items: center;
+ align-items: stretch;
+ padding: 0 5vw 0 0;
}
.about-visual {
position: relative;
+ width: 100%;
+ min-height: clamp(560px, 72vh, 760px);
}
.about-img {
width: 100%;
- aspect-ratio: 4/5;
+ height: 100%;
+ min-height: inherit;
object-fit: cover;
display: block;
background:
@@ -441,26 +503,18 @@
.about-img-real {
width: 100%;
- aspect-ratio: 4/5;
+ height: 100%;
+ min-height: inherit;
object-fit: cover;
display: block;
- }
-
- /* thin red stripe accent on image */
- .about-stripe {
- position: absolute;
- top: 2rem;
- left: -12px;
- width: 4px;
- height: calc(100% - 4rem);
- background: var(--flame);
+ object-position: center center;
}
/* First Responder badge */
.fr-badge {
position: absolute;
- bottom: -1.5rem;
- right: -1.5rem;
+ bottom: 1rem;
+ right: -1rem;
background: var(--smoke);
border: 2px solid var(--flame);
padding: 1rem 1.25rem;
@@ -487,6 +541,11 @@
margin-bottom: 1.5rem;
}
+ .about-content {
+ align-self: center;
+ padding: 7rem 0;
+ }
+
.about-stat-row {
display: flex;
gap: 2.5rem;
@@ -552,10 +611,7 @@
overflow: hidden;
cursor: pointer;
display: flex;
- align-items: end;
- padding: 1.5rem;
isolation: isolate;
- text-align: left;
}
.project-tile.tall {
@@ -567,9 +623,9 @@
position: absolute;
inset: 0;
z-index: 0;
- background:
- linear-gradient(to top, rgba(10,10,10,0.92) 0%, rgba(10,10,10,0.45) 54%, rgba(10,10,10,0.08) 100%),
- linear-gradient(135deg, rgba(214,43,43,0.28), transparent 44%);
+ background: linear-gradient(135deg, rgba(214,43,43,0.14), transparent 46%);
+ opacity: 0.7;
+ pointer-events: none;
}
.tile-image {
@@ -589,29 +645,6 @@
transform: scale(1.07);
}
- .tile-content {
- position: relative;
- z-index: 1;
- text-shadow: 0 2px 18px rgba(0,0,0,0.45);
- }
-
- .tile-tag {
- font-family: var(--font-heading);
- font-size: 0.65rem;
- letter-spacing: 0.18em;
- text-transform: uppercase;
- color: var(--flame);
- margin-bottom: 0.25rem;
- }
-
- .tile-title {
- font-family: var(--font-heading);
- font-size: 1rem;
- font-weight: 600;
- letter-spacing: 0.06em;
- text-transform: uppercase;
- }
-
.image-modal {
position: fixed;
inset: 0;
@@ -657,72 +690,58 @@
overflow: hidden;
}
- /* ── PROCESS ──────────────────────────────────────────────────────────── */
- .process-section {
+ /* ── SERVICE AREAS ─────────────────────────────────────────────────────── */
+ .service-areas-section {
background: var(--smoke);
}
- .process-grid {
+ .service-areas-grid {
display: grid;
- grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
- gap: 0;
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+ gap: 1px;
margin-top: 4rem;
- position: relative;
- }
-
- .process-grid::before {
- content: '';
- position: absolute;
- top: 2.2rem;
- left: 2rem;
- right: 2rem;
- height: 1px;
- background: linear-gradient(to right, var(--flame), var(--steel));
- z-index: 0;
+ background: var(--steel);
}
- .process-step {
+ .service-area-card {
position: relative;
- z-index: 1;
- padding: 0 1.5rem;
- padding-top: 4.5rem;
- }
-
- .step-dot {
- position: absolute;
- top: 1.45rem;
- left: 1.5rem;
- width: 16px;
- height: 16px;
- border-radius: 50%;
- background: var(--flame);
- border: 3px solid var(--smoke);
- outline: 1px solid var(--flame);
+ min-height: 260px;
+ padding: 2.5rem;
+ background: var(--ash);
+ overflow: hidden;
}
- .step-num {
+ .service-area-name {
font-family: var(--font-display);
- font-size: 3.5rem;
- color: var(--steel);
+ font-size: clamp(2.8rem, 6vw, 5rem);
line-height: 1;
+ color: var(--white);
margin-bottom: 0.5rem;
}
- .step-title {
+ .service-area-label {
font-family: var(--font-heading);
- font-size: 0.9rem;
+ font-size: 0.78rem;
font-weight: 600;
- letter-spacing: 0.08em;
+ letter-spacing: 0.14em;
text-transform: uppercase;
- color: var(--white);
- margin-bottom: 0.5rem;
+ color: var(--flame);
+ margin-bottom: 1.25rem;
}
- .step-desc {
- font-size: 0.85rem;
+ .service-area-copy {
+ font-size: 0.95rem;
font-weight: 300;
color: var(--mist);
- line-height: 1.6;
+ 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 ──────────────────────────────────────────────────────────── */
@@ -772,6 +791,66 @@
.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;
@@ -879,13 +958,16 @@
}
.footer-logo {
- font-family: var(--font-display);
- font-size: 1.2rem;
- letter-spacing: 0.08em;
- color: var(--white);
+ display: inline-flex;
+ align-items: center;
}
- .footer-logo span { color: var(--flame); }
+ .footer-logo img {
+ width: 240px;
+ height: auto;
+ object-fit: contain;
+ display: block;
+ }
.footer-note {
font-size: 0.78rem;
@@ -897,9 +979,24 @@
@media (max-width: 800px) {
nav {
height: auto;
- min-height: 64px;
+ min-height: 96px;
flex-wrap: wrap;
- padding: 0.75rem 5vw;
+ 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 {
@@ -909,41 +1006,95 @@
.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 {
- display: none;
order: 3;
width: 100%;
flex-direction: column;
align-items: stretch;
- gap: 0;
- padding-top: 0.75rem;
- border-top: 1px solid var(--ash);
+ 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.85rem 0;
+ 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 {
- bottom: 0.55rem;
+ display: none;
}
.nav-cta {
- display: none;
- order: 4;
+ 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,
@@ -952,6 +1103,18 @@
gap: 3rem;
}
+ .about-section {
+ padding: 5rem 5vw;
+ }
+
+ .about-visual {
+ min-height: clamp(420px, 65vh, 620px);
+ }
+
+ .about-content {
+ padding: 0;
+ }
+
.projects-header {
display: block;
}
@@ -972,9 +1135,9 @@
grid-row: auto;
}
- .fr-badge { right: 0; bottom: -1rem; }
+ .fr-badge { right: 1rem; bottom: 1rem; }
- .process-grid::before { display: none; }
+ .service-areas-grid { grid-template-columns: 1fr; }
.form-row { grid-template-columns: 1fr; }
@@ -986,13 +1149,37 @@
padding: 4.5rem 5vw;
}
+ .about-section {
+ padding: 4.5rem 5vw;
+ }
+
.hero {
- min-height: 92vh;
- padding-bottom: 6vh;
+ 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(3.4rem, 18vw, 4.4rem);
+ font-size: clamp(2.9rem, 19vw, 4rem);
+ line-height: 0.88;
+ }
+
+ .hero-sub {
+ margin-bottom: 1.5rem;
+ }
+
+ .hero-body {
+ margin-bottom: 2rem;
}
.hero-actions {
@@ -1010,17 +1197,29 @@
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 {
- position: relative;
- right: auto;
- bottom: auto;
- margin-top: -1.5rem;
- width: calc(100% - 1.5rem);
+ right: 0.75rem;
+ bottom: 0.75rem;
+ max-width: calc(100% - 1.5rem);
+ padding: 0.8rem 0.9rem;
}
- .process-step {
- padding-left: 0;
- padding-right: 0;
+ .service-area-card {
+ min-height: 220px;
+ padding: 2rem;
}
footer {
@@ -1037,7 +1236,9 @@
<!-- NAV -->
<nav>
- <a class="nav-logo" href="#hero">FRONTLINE <span>BOATS</span></a>
+ <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>
@@ -1047,10 +1248,13 @@
<li><a href="#services">Services</a></li>
<li><a href="#about">About</a></li>
<li><a href="#projects">Gallery</a></li>
- <li><a href="#process">Process</a></li>
+ <li><a href="#service-areas">Areas</a></li>
<li><a href="#contact">Contact</a></li>
</ul>
- <a class="nav-cta" href="#contact">Get a Quote</a>
+ <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 -->
@@ -1060,12 +1264,10 @@
<div class="hero-content">
<div class="hero-eyebrow">Miami, FL — First Responder Owned & Operated</div>
<h1 class="hero-title">
- FRONT<br><span class="accent">LINE</span><br>BOAT<br>SERVICES
+ FULL SERVICE <br><span class="accent">MARINE</span> SOLUTIONS
</h1>
- <p class="hero-sub">Marine Electronics Specialists</p>
<p class="hero-body">
- Built on the discipline of the firehouse. Every wire, every connection,
- every system treated like a life depends on it — because on the water, it might.
+ <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>
@@ -1129,7 +1331,7 @@
<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 ABYC standards.</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">
@@ -1153,7 +1355,7 @@
<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, digital switching panels, and helm layouts built for the way you actually run your boat.</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">
@@ -1170,11 +1372,10 @@
<!-- ABOUT / FIRST RESPONDER -->
<section id="about" class="about-section">
<div class="about-visual">
- <div class="about-stripe"></div>
<!-- Placeholder image with a styled background; in production replace src with a real photo -->
<img
class="about-img-real"
- src="https://images.unsplash.com/photo-1544551763-92ab472cad5d?w=800&q=80"
+ src="frontline-1.png"
alt="Firefighter and boat technician at work"
onerror="this.style.display='none'; this.nextElementSibling.style.display='flex';"
/>
@@ -1207,8 +1408,14 @@
<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 an active firefighter who built the same
- habits off the truck as on it: no shortcuts, no guesswork, no half-measures.
+ 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
@@ -1246,78 +1453,62 @@
</div>
<div class="projects-mosaic">
- <div class="project-tile tall" role="button" tabindex="0" aria-label="View full size image of a center console boat underway">
- <img class="tile-image" src="https://images.unsplash.com/photo-1605281317010-fe5ffe798166?w=1200&q=82" alt="Center console boat underway in clear water">
- <div class="tile-content">
- <div class="tile-tag">Navigation</div>
- <div class="tile-title">Electronics Ready Helms</div>
- </div>
+ <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 a boat docked at a marina">
- <img class="tile-image" src="https://images.unsplash.com/photo-1544551763-92ab472cad5d?w=1000&q=82" alt="Boat docked at a marina">
- <div class="tile-content">
- <div class="tile-tag">Service</div>
- <div class="tile-title">Dockside Diagnostics</div>
- </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 marine instruments and controls">
- <img class="tile-image" src="https://images.unsplash.com/photo-1567899378494-47b22a2ae96a?w=1000&q=82" alt="Marine helm instruments and controls">
- <div class="tile-content">
- <div class="tile-tag">Displays</div>
- <div class="tile-title">Clean Control Layouts</div>
- </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 a powerboat on open water">
- <img class="tile-image" src="https://images.unsplash.com/photo-1500530855697-b586d89ba3ee?w=1000&q=82" alt="Powerboat running on open water">
- <div class="tile-content">
- <div class="tile-tag">Reliability</div>
- <div class="tile-title">Water-Tested Systems</div>
- </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 boat at sunset">
- <img class="tile-image" src="https://images.unsplash.com/photo-1507525428034-b723cf961d3e?w=1000&q=82" alt="Boat silhouetted near sunset on the water">
- <div class="tile-content">
- <div class="tile-tag">Audio</div>
- <div class="tile-title">Weekend Ready Upgrades</div>
- </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>
- <!-- PROCESS -->
- <section id="process" class="process-section">
- <p class="section-eyebrow">How It Works</p>
- <h2 class="section-title">CLEAR CHAIN<br>OF COMMAND</h2>
- <div class="process-grid">
- <div class="process-step">
- <div class="step-dot"></div>
- <div class="step-num">01</div>
- <div class="step-title">Tell Us What's Going On</div>
- <div class="step-desc">Call, text, or email. Describe the issue or the upgrade — no need to know the technical terms. We listen.</div>
+ <!-- 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="process-step">
- <div class="step-dot"></div>
- <div class="step-num">02</div>
- <div class="step-title">Get a Straight Quote</div>
- <div class="step-desc">We assess the work and give you a clear, no-surprises estimate before any wrenches turn.</div>
- </div>
- <div class="process-step">
- <div class="step-dot"></div>
- <div class="step-num">03</div>
- <div class="step-title">We Get to Work</div>
- <div class="step-desc">Every job is done to ABYC standards with quality marine-grade components. No cheap substitutions.</div>
- </div>
- <div class="process-step">
- <div class="step-dot"></div>
- <div class="step-num">04</div>
- <div class="step-title">You Get Back on the Water</div>
- <div class="step-desc">We test everything before you sign off. Your boat leaves ready to perform, and you know exactly what was done.</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 -->
@@ -1337,7 +1528,7 @@
</svg>
<div>
<div class="contact-label">Phone / Text</div>
- <a class="contact-value" href="tel:+13054780000">(305) ___-0478</a>
+ <a class="contact-value" href="tel:+17862780478">(786) 278-0478</a>
</div>
</div>
@@ -1419,11 +1610,25 @@
<!-- FOOTER -->
<footer>
- <div class="footer-logo">FRONTLINE <span>BOAT SERVICES</span></div>
+ <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="">
@@ -1447,15 +1652,34 @@
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) {
@@ -1473,6 +1697,7 @@
function updateActiveNavLink() {
const navOffset = siteNav.offsetHeight + 24;
+ const isAtPageEnd = window.innerHeight + window.scrollY >= document.documentElement.scrollHeight - 2;
let activeId = '';
navSections.forEach(({ section }) => {
@@ -1481,8 +1706,13 @@
}
});
+ if (isAtPageEnd && navSections.length) {
+ activeId = navSections[navSections.length - 1].section.id;
+ }
+
setActiveNavLink(activeId);
- siteNav.style.boxShadow = window.scrollY > 40 ? '0 4px 24px rgba(0,0,0,0.5)' : 'none';
+ siteNav.classList.toggle('is-scrolled', window.scrollY > 40);
+ updateStickyCallCta();
}
navToggle.addEventListener('click', () => {
@@ -1502,9 +1732,14 @@
});
window.addEventListener('scroll', updateActiveNavLink, { passive: true });
- window.addEventListener('resize', updateActiveNavLink);
+ 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');