Files

1245 lines
58 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Parker County Slingshot Rentals | Polaris Slingshot | Weatherford, TX</title>
<meta name="description" content="Rent a Polaris Slingshot in Parker County, TX. Experience the thrill of open-air three-wheel driving through Weatherford and the DFW area. Book online today — daily and weekend rentals available." />
<meta name="keywords" content="Polaris Slingshot rental, Parker County slingshot rental, Weatherford TX slingshot, DFW slingshot rental, three wheel rental Texas, slingshot car rental, open air vehicle rental, adventure rental Weatherford" />
<meta name="robots" content="index, follow" />
<link rel="canonical" href="https://parkerslingshotrentals.com/" />
<!-- Open Graph -->
<meta property="og:type" content="website" />
<meta property="og:site_name" content="Parker County Slingshot Rentals" />
<meta property="og:title" content="Parker County Slingshot Rentals | Polaris Slingshot | Weatherford, TX" />
<meta property="og:description" content="Rent a Polaris Slingshot in Parker County, TX. Daily and weekend rentals. Experience open-air three-wheel driving through the beautiful Texas Hill Country near DFW." />
<meta property="og:url" content="https://parkerslingshotrentals.com/" />
<meta property="og:image" content="https://parkerslingshotrentals.com/assets/og-image.jpg" />
<meta property="og:locale" content="en_US" />
<!-- Twitter Card -->
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="Parker County Slingshot Rentals | Polaris Slingshot | Weatherford, TX" />
<meta name="twitter:description" content="Rent a Polaris Slingshot in Parker County, TX. Daily and weekend rentals available. Book today!" />
<meta name="twitter:image" content="https://parkerslingshotrentals.com/assets/og-image.jpg" />
<!-- JSON-LD Structured Data -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@graph": [
{
"@type": "LocalBusiness",
"@id": "https://parkerslingshotrentals.com/#business",
"name": "Parker County Slingshot Rentals",
"description": "Polaris Slingshot rentals in Parker County, Texas. Daily and weekend rentals available for thrill-seekers near Weatherford and the DFW metroplex.",
"url": "https://parkerslingshotrentals.com",
"telephone": "+1-817-266-2022",
"email": "info@parkerslingshotrentals.com",
"priceRange": "$$",
"currenciesAccepted": "USD",
"paymentAccepted": "Cash, Credit Card",
"address": {
"@type": "PostalAddress",
"addressLocality": "Weatherford",
"addressRegion": "TX",
"postalCode": "76086",
"addressCountry": "US"
},
"geo": {
"@type": "GeoCoordinates",
"latitude": 32.7554,
"longitude": -97.7981
},
"openingHoursSpecification": [
{
"@type": "OpeningHoursSpecification",
"dayOfWeek": ["Monday","Tuesday","Wednesday","Thursday","Friday"],
"opens": "09:00",
"closes": "18:00"
},
{
"@type": "OpeningHoursSpecification",
"dayOfWeek": ["Saturday","Sunday"],
"opens": "08:00",
"closes": "20:00"
}
],
"sameAs": [],
"hasOfferCatalog": {
"@type": "OfferCatalog",
"name": "Slingshot Rental Packages",
"itemListElement": [
{
"@type": "Offer",
"itemOffered": {
"@type": "Product",
"name": "Half-Day Slingshot Rental",
"description": "4-hour Polaris Slingshot rental — perfect for a quick thrill around Parker County."
},
"priceCurrency": "USD",
"price": "80.00"
},
{
"@type": "Offer",
"itemOffered": {
"@type": "Product",
"name": "Full-Day Slingshot Rental",
"description": "8-hour Polaris Slingshot rental — explore Weatherford, Mineral Wells, and beyond."
},
"priceCurrency": "USD",
"price": "150.00"
},
{
"@type": "Offer",
"itemOffered": {
"@type": "Product",
"name": "3 Day Adventure Slingshot Rental",
"description": "72-hour Polaris Slingshot rental — the ultimate Texas road trip experience."
},
"priceCurrency": "USD",
"price": "449.00"
}
]
}
},
{
"@type": "WebSite",
"@id": "https://parkerslingshotrentals.com/#website",
"url": "https://parkerslingshotrentals.com",
"name": "Parker County Slingshot Rentals",
"publisher": {"@id": "https://parkerslingshotrentals.com/#business"},
"potentialAction": {
"@type": "SearchAction",
"target": "https://parkerslingshotrentals.com/?s={search_term_string}",
"query-input": "required name=search_term_string"
}
},
{
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "Do I need a motorcycle license to rent a Polaris Slingshot in Texas?",
"acceptedAnswer": {
"@type": "Answer",
"text": "In Texas, a standard Class C driver's license is sufficient to operate a Polaris Slingshot. No motorcycle endorsement is required. You must be 25 or older to rent."
}
},
{
"@type": "Question",
"name": "What is included in the rental?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Every rental includes the Polaris Slingshot, DOT-approved helmets for driver and passenger, a safety orientation, a suggested scenic route map, and roadside assistance. Renters must provide proof of valid personal auto insurance. We carry a comprehensive fleet policy covering the vehicle."
}
},
{
"@type": "Question",
"name": "How many people can ride in a Polaris Slingshot?",
"acceptedAnswer": {
"@type": "Answer",
"text": "The Polaris Slingshot seats two people — a driver and one passenger. Both will enjoy an open-air, sports-car-style driving experience."
}
},
{
"@type": "Question",
"name": "Where can I drive the Slingshot?",
"acceptedAnswer": {
"@type": "Answer",
"text": "You can drive throughout Parker County and the surrounding DFW area including Weatherford, Mineral Wells, Granbury, and Azle. We provide a recommended scenic route guide with every rental."
}
}
]
}
]
}
</script>
<!-- Fonts & Icons -->
<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=Inter:wght@400;500;600;700&family=Barlow+Condensed:wght@600;700;800&display=swap" rel="stylesheet" />
<style>
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
:root {
--orange: #f97316;
--orange-dark: #ea580c;
--black: #0d0d0d;
--dark: #1a1a2e;
--gray: #6b7280;
--light: #f9fafb;
--white: #ffffff;
--radius: 12px;
}
html { scroll-behavior: smooth; }
body { font-family: 'Inter', sans-serif; background: var(--black); color: var(--white); line-height: 1.6; }
/* NAV */
nav {
position: fixed; top: 0; left: 0; right: 0; z-index: 100;
display: flex; align-items: center; justify-content: space-between;
padding: 1rem 2rem;
background: rgba(13,13,13,0.92);
backdrop-filter: blur(8px);
border-bottom: 1px solid rgba(255,255,255,0.06);
}
.nav-logo { font-family: 'Barlow Condensed', sans-serif; font-size: 1.4rem; font-weight: 800; color: var(--orange); letter-spacing: 0.5px; text-decoration: none; }
.nav-links { display: flex; gap: 2rem; list-style: none; }
.nav-links a { color: rgba(255,255,255,0.8); text-decoration: none; font-weight: 500; font-size: 0.9rem; transition: color 0.2s; }
.nav-links a:hover { color: var(--orange); }
.nav-cta { background: var(--orange); color: white; padding: 0.6rem 1.4rem; border-radius: 6px; text-decoration: none; font-weight: 600; font-size: 0.9rem; transition: background 0.2s; }
.nav-cta:hover { background: var(--orange-dark); }
/* HERO */
.hero {
min-height: 100vh;
display: flex; align-items: center; justify-content: center;
text-align: center;
padding: 6rem 2rem 4rem;
background: linear-gradient(135deg, #0d0d0d 0%, #1a0a00 50%, #0d0d0d 100%);
position: relative; overflow: hidden;
}
.hero::before {
content: '';
position: absolute; inset: 0;
background: radial-gradient(ellipse at center, rgba(249,115,22,0.12) 0%, transparent 70%);
}
.hero-badge {
display: inline-block;
background: rgba(249,115,22,0.15);
border: 1px solid rgba(249,115,22,0.4);
color: var(--orange);
padding: 0.35rem 1rem;
border-radius: 999px;
font-size: 0.8rem;
font-weight: 600;
letter-spacing: 1px;
text-transform: uppercase;
margin-bottom: 1.5rem;
}
.hero h1 {
font-family: 'Barlow Condensed', sans-serif;
font-size: clamp(3rem, 8vw, 6rem);
font-weight: 800;
line-height: 1;
letter-spacing: -1px;
margin-bottom: 1.5rem;
}
.hero h1 span { color: var(--orange); }
.hero p {
font-size: 1.2rem;
color: rgba(255,255,255,0.7);
max-width: 600px;
margin: 0 auto 2.5rem;
}
.hero-btns { display: flex; gap: 1rem; justify-content: center; flex-wrap: wrap; }
.btn-primary {
background: var(--orange); color: white;
padding: 0.85rem 2rem; border-radius: 8px;
text-decoration: none; font-weight: 700; font-size: 1rem;
transition: background 0.2s, transform 0.15s;
display: inline-block;
}
.btn-primary:hover { background: var(--orange-dark); transform: translateY(-2px); }
.btn-secondary {
background: rgba(255,255,255,0.08); color: white;
border: 1px solid rgba(255,255,255,0.2);
padding: 0.85rem 2rem; border-radius: 8px;
text-decoration: none; font-weight: 600; font-size: 1rem;
transition: background 0.2s;
display: inline-block;
}
.btn-secondary:hover { background: rgba(255,255,255,0.14); }
.hero-scroll { margin-top: 4rem; opacity: 0.4; font-size: 0.8rem; letter-spacing: 1px; text-transform: uppercase; }
/* SECTIONS */
section { padding: 5rem 2rem; }
.container { max-width: 1100px; margin: 0 auto; }
.section-label { font-size: 0.75rem; font-weight: 700; letter-spacing: 2px; text-transform: uppercase; color: var(--orange); margin-bottom: 0.75rem; }
.section-title { font-family: 'Barlow Condensed', sans-serif; font-size: clamp(2rem, 4vw, 3rem); font-weight: 800; margin-bottom: 1rem; }
.section-sub { color: rgba(255,255,255,0.6); font-size: 1rem; max-width: 560px; margin-bottom: 3rem; }
/* WHY */
.why { background: #111111; }
.features-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 1.5rem; }
.feature-card {
background: rgba(255,255,255,0.04);
border: 1px solid rgba(255,255,255,0.07);
border-radius: var(--radius);
padding: 2rem;
transition: border-color 0.2s;
}
.feature-card:hover { border-color: rgba(249,115,22,0.4); }
.feature-icon { font-size: 2rem; margin-bottom: 1rem; }
.feature-card h3 { font-size: 1.1rem; font-weight: 700; margin-bottom: 0.5rem; }
.feature-card p { color: rgba(255,255,255,0.55); font-size: 0.9rem; }
/* PRICING */
.pricing { background: var(--black); }
.pricing-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 1.5rem; }
.price-card {
background: rgba(255,255,255,0.04);
border: 1px solid rgba(255,255,255,0.08);
border-radius: var(--radius);
padding: 2.5rem 2rem;
text-align: center;
position: relative;
transition: transform 0.2s, border-color 0.2s;
}
.price-card:hover { transform: translateY(-4px); border-color: rgba(249,115,22,0.3); }
.price-card.featured {
border-color: var(--orange);
background: rgba(249,115,22,0.07);
}
.price-badge {
position: absolute; top: -13px; left: 50%; transform: translateX(-50%);
background: var(--orange); color: white;
padding: 0.25rem 1rem; border-radius: 999px;
font-size: 0.75rem; font-weight: 700; text-transform: uppercase; letter-spacing: 1px;
}
.price-name { font-size: 0.85rem; font-weight: 600; color: var(--orange); text-transform: uppercase; letter-spacing: 1px; margin-bottom: 0.5rem; }
.price-amount { font-family: 'Barlow Condensed', sans-serif; font-size: 3.5rem; font-weight: 800; line-height: 1; margin-bottom: 0.25rem; }
.price-amount sup { font-size: 1.5rem; vertical-align: top; margin-top: 0.5rem; }
.price-duration { color: rgba(255,255,255,0.5); font-size: 0.85rem; margin-bottom: 1.5rem; }
.price-features { list-style: none; text-align: left; margin-bottom: 2rem; }
.price-features li { padding: 0.4rem 0; color: rgba(255,255,255,0.7); font-size: 0.9rem; display: flex; align-items: center; gap: 0.5rem; }
.price-features li::before { content: '✓'; color: var(--orange); font-weight: 700; flex-shrink: 0; }
/* HOW IT WORKS */
.how { background: #111111; }
.steps { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 2rem; counter-reset: steps; }
.step { text-align: center; counter-increment: steps; }
.step-num {
width: 56px; height: 56px; border-radius: 50%;
background: rgba(249,115,22,0.15); border: 2px solid var(--orange);
display: flex; align-items: center; justify-content: center;
font-family: 'Barlow Condensed', sans-serif; font-size: 1.4rem; font-weight: 800; color: var(--orange);
margin: 0 auto 1rem;
}
.step h3 { font-size: 1rem; font-weight: 700; margin-bottom: 0.5rem; }
.step p { color: rgba(255,255,255,0.55); font-size: 0.875rem; }
/* ROUTES */
.routes { background: var(--black); }
.routes-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 1.5rem; }
.route-card {
background: rgba(255,255,255,0.03);
border: 1px solid rgba(255,255,255,0.07);
border-radius: var(--radius); padding: 1.75rem;
}
.route-card h3 { font-size: 1rem; font-weight: 700; margin-bottom: 0.4rem; }
.route-card .miles { font-size: 0.8rem; color: var(--orange); font-weight: 600; margin-bottom: 0.5rem; }
.route-card p { color: rgba(255,255,255,0.5); font-size: 0.875rem; }
/* FAQ */
.faq { background: #111111; }
.faq-list { display: flex; flex-direction: column; gap: 0; max-width: 760px; }
details {
border-bottom: 1px solid rgba(255,255,255,0.08);
padding: 1.25rem 0;
}
details:first-child { border-top: 1px solid rgba(255,255,255,0.08); }
summary {
font-weight: 600; font-size: 1rem; cursor: pointer;
list-style: none; display: flex; justify-content: space-between; align-items: center;
}
summary::-webkit-details-marker { display: none; }
summary::after { content: '+'; font-size: 1.4rem; color: var(--orange); flex-shrink: 0; transition: transform 0.2s; }
details[open] summary::after { transform: rotate(45deg); }
details p { color: rgba(255,255,255,0.6); margin-top: 0.75rem; font-size: 0.95rem; }
/* CONTACT */
.contact { background: var(--black); }
.contact-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 4rem; align-items: start; }
@media (max-width: 700px) { .contact-grid { grid-template-columns: 1fr; gap: 2rem; } }
.contact-info h2 { font-family: 'Barlow Condensed', sans-serif; font-size: 2.5rem; font-weight: 800; margin-bottom: 1rem; }
.contact-info p { color: rgba(255,255,255,0.6); margin-bottom: 2rem; }
.contact-detail { display: flex; align-items: center; gap: 0.75rem; margin-bottom: 1rem; color: rgba(255,255,255,0.7); font-size: 0.95rem; }
.contact-detail span:first-child { font-size: 1.2rem; }
.contact-form { display: flex; flex-direction: column; gap: 1rem; }
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }
@media (max-width: 500px) { .form-row { grid-template-columns: 1fr; } }
.contact-form input, .contact-form select, .contact-form textarea {
background: rgba(255,255,255,0.05);
border: 1px solid rgba(255,255,255,0.1);
border-radius: 8px; padding: 0.85rem 1rem;
color: white; font-family: inherit; font-size: 0.95rem;
outline: none; transition: border-color 0.2s; width: 100%;
}
.contact-form input:focus, .contact-form select:focus, .contact-form textarea:focus { border-color: var(--orange); }
.contact-form select option { background: #1a1a1a; }
.contact-form textarea { resize: vertical; min-height: 120px; }
.contact-form button {
background: var(--orange); color: white;
border: none; border-radius: 8px;
padding: 0.9rem; font-size: 1rem; font-weight: 700;
cursor: pointer; transition: background 0.2s;
}
.contact-form button:hover { background: var(--orange-dark); }
.form-msg { padding: 0.75rem 1rem; border-radius: 8px; font-size: 0.9rem; display: none; }
.form-msg.success { background: rgba(34,197,94,0.15); border: 1px solid rgba(34,197,94,0.3); color: #4ade80; display: block; }
.form-msg.error { background: rgba(239,68,68,0.15); border: 1px solid rgba(239,68,68,0.3); color: #f87171; display: block; }
/* AVAILABILITY CALENDAR */
.cal-wrap { background: rgba(255,255,255,0.04); border: 1px solid rgba(255,255,255,0.08); border-radius: 12px; padding: 1.25rem; margin-bottom: 1.25rem; }
.cal-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 1rem; }
.cal-header h3 { font-family: 'Barlow Condensed', sans-serif; font-size: 1.2rem; font-weight: 700; letter-spacing: 0.5px; }
.cal-nav { background: rgba(255,255,255,0.07); border: none; color: white; border-radius: 6px; width: 32px; height: 32px; cursor: pointer; font-size: 1rem; display: flex; align-items: center; justify-content: center; transition: background 0.2s; }
.cal-nav:hover { background: var(--orange); }
.cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 3px; }
.cal-day-label { text-align: center; font-size: 0.65rem; font-weight: 600; letter-spacing: 1px; color: rgba(255,255,255,0.35); padding: 0.25rem 0; text-transform: uppercase; }
.cal-day { text-align: center; border-radius: 6px; padding: 0.4rem 0.25rem; font-size: 0.8rem; font-weight: 500; min-height: 32px; display: flex; align-items: center; justify-content: center; transition: background 0.15s, color 0.15s; }
.cal-day.empty { background: transparent; }
.cal-day.past { color: rgba(255,255,255,0.2); cursor: default; }
.cal-day.booked { background: rgba(239,68,68,0.18); color: rgba(239,68,68,0.6); cursor: not-allowed; position: relative; }
.cal-day.booked::after { content: ''; position: absolute; bottom: 3px; left: 50%; transform: translateX(-50%); width: 4px; height: 4px; border-radius: 50%; background: rgba(239,68,68,0.5); }
.cal-day.available { background: rgba(255,255,255,0.05); color: rgba(255,255,255,0.85); cursor: pointer; }
.cal-day.available:hover { background: rgba(249,115,22,0.25); color: var(--orange); }
.cal-day.today { border: 1px solid rgba(249,115,22,0.5); }
.cal-day.selected { background: var(--orange) !important; color: white !important; font-weight: 700; }
.cal-legend { display: flex; gap: 1rem; margin-top: 0.75rem; flex-wrap: wrap; }
.cal-legend-item { display: flex; align-items: center; gap: 0.4rem; font-size: 0.72rem; color: rgba(255,255,255,0.45); }
.cal-legend-dot { width: 10px; height: 10px; border-radius: 3px; flex-shrink: 0; }
.cal-loading { text-align: center; padding: 1.5rem; color: rgba(255,255,255,0.3); font-size: 0.85rem; }
/* FOOTER */
footer {
background: #080808;
border-top: 1px solid rgba(255,255,255,0.06);
padding: 2.5rem 2rem;
text-align: center;
}
.footer-logo { font-family: 'Barlow Condensed', sans-serif; font-size: 1.4rem; font-weight: 800; color: var(--orange); margin-bottom: 0.5rem; }
footer p { color: rgba(255,255,255,0.35); font-size: 0.85rem; }
.footer-links { display: flex; gap: 1.5rem; justify-content: center; margin: 1rem 0; flex-wrap: wrap; }
.footer-links a { color: rgba(255,255,255,0.4); text-decoration: none; font-size: 0.85rem; transition: color 0.2s; }
.footer-links a:hover { color: var(--orange); }
/* HAMBURGER / MOBILE NAV */
.nav-hamburger {
display: none;
flex-direction: column;
gap: 5px;
background: none;
border: none;
cursor: pointer;
padding: 6px;
border-radius: 6px;
transition: background 0.2s;
z-index: 101;
}
.nav-hamburger:hover { background: rgba(255,255,255,0.07); }
.nav-hamburger span {
display: block;
width: 24px;
height: 2px;
background: white;
border-radius: 2px;
transition: transform 0.25s, opacity 0.25s;
transform-origin: center;
}
.nav-hamburger.open span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav-hamburger.open span:nth-child(2) { opacity: 0; transform: scaleX(0); }
.nav-hamburger.open span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }
.nav-drawer {
display: none;
position: fixed;
top: 0; left: 0; right: 0; bottom: 0;
z-index: 99;
flex-direction: column;
padding-top: 72px;
background: rgba(13,13,13,0.97);
backdrop-filter: blur(12px);
animation: drawerIn 0.22s ease;
}
@keyframes drawerIn {
from { opacity: 0; transform: translateY(-8px); }
to { opacity: 1; transform: translateY(0); }
}
.nav-drawer.open { display: flex; }
.nav-drawer ul {
list-style: none;
display: flex;
flex-direction: column;
padding: 1.5rem 2rem;
gap: 0;
flex: 1;
}
.nav-drawer ul li a {
display: block;
padding: 1rem 0;
color: rgba(255,255,255,0.85);
text-decoration: none;
font-size: 1.25rem;
font-weight: 600;
border-bottom: 1px solid rgba(255,255,255,0.07);
transition: color 0.2s;
}
.nav-drawer ul li:last-child a { border-bottom: none; }
.nav-drawer ul li a:hover { color: var(--orange); }
.nav-drawer .drawer-cta {
margin: 1rem 2rem 2.5rem;
}
.nav-drawer .drawer-cta a {
display: block;
text-align: center;
background: var(--orange);
color: white;
padding: 1rem;
border-radius: 8px;
font-weight: 700;
font-size: 1.1rem;
text-decoration: none;
transition: background 0.2s;
}
.nav-drawer .drawer-cta a:hover { background: var(--orange-dark); }
@media (max-width: 768px) {
.nav-links { display: none; }
.nav-cta { display: none; }
.nav-hamburger { display: flex; }
}
</style>
</head>
<body>
<!-- Navigation -->
<nav aria-label="Main navigation">
<a href="/" class="nav-logo">Parker County Slingshot</a>
<ul class="nav-links">
<li><a href="#why">Why Us</a></li>
<li><a href="#pricing">Pricing</a></li>
<li><a href="#how">How It Works</a></li>
<li><a href="#routes">Routes</a></li>
<li><a href="#faq">FAQ</a></li>
</ul>
<a href="#contact" class="nav-cta">Book Now</a>
<button class="nav-hamburger" id="navToggle" aria-label="Toggle menu" aria-expanded="false" aria-controls="navDrawer">
<span></span><span></span><span></span>
</button>
</nav>
<!-- Mobile Drawer -->
<div class="nav-drawer" id="navDrawer" role="dialog" aria-label="Mobile navigation">
<ul>
<li><a href="#why">Why Us</a></li>
<li><a href="#pricing">Pricing</a></li>
<li><a href="#how">How It Works</a></li>
<li><a href="#routes">Routes</a></li>
<li><a href="#faq">FAQ</a></li>
<li><a href="#contact">Contact</a></li>
</ul>
<div class="drawer-cta"><a href="#contact">Book Now</a></div>
</div>
<!-- Hero -->
<header class="hero" role="banner">
<div style="position:relative;z-index:1;">
<div class="hero-badge">Weatherford, Texas</div>
<h1>Feel the Road.<br /><span>Rent a Slingshot.</span></h1>
<p>Parker County's premier Polaris Slingshot rental experience. Open-air freedom, three-wheel thrills, Texas roads built for adventure.</p>
<div class="hero-btns">
<a href="#pricing" class="btn-primary">View Rental Packages</a>
<a href="#how" class="btn-secondary">How It Works</a>
</div>
<p class="hero-scroll">Scroll to explore &darr;</p>
</div>
</header>
<!-- Why Choose Us -->
<section class="why" id="why" aria-label="Why choose Parker County Slingshot Rentals">
<div class="container">
<p class="section-label">Why Us</p>
<h2 class="section-title">Built for the Thrill-Seeker</h2>
<p class="section-sub">Everything you need for an unforgettable open-road experience — no hassle, just pure adrenaline.</p>
<div class="features-grid">
<div class="feature-card">
<div class="feature-icon">🏎️</div>
<h3>Polaris Slingshot SL</h3>
<p>Our fleet features the latest Polaris Slingshot models — powerful, fast, and impossible to ignore on Texas roads.</p>
</div>
<div class="feature-card">
<div class="feature-icon">🛡️</div>
<h3>Full Coverage Insurance</h3>
<p>Every rental includes comprehensive coverage. Drive with confidence knowing you're fully protected.</p>
</div>
<div class="feature-card">
<div class="feature-icon">🗺️</div>
<h3>Scenic Route Guides</h3>
<p>We hand you a curated Texas route map — the best backroads, vistas, and stops around Parker County.</p>
</div>
<div class="feature-card">
<div class="feature-icon">⛑️</div>
<h3>Safety First</h3>
<p>DOT-approved helmets included with every rental. Safety orientation for all drivers before you hit the road.</p>
</div>
<div class="feature-card">
<div class="feature-icon">📞</div>
<h3>Roadside Assistance</h3>
<p>24/7 roadside support so you're never stranded. We've got your back from pickup to return.</p>
</div>
<div class="feature-card">
<div class="feature-icon"></div>
<h3>Easy Booking</h3>
<p>Simple online reservation, flexible pickup times, and transparent pricing. No hidden fees — ever.</p>
</div>
</div>
</div>
</section>
<!-- Pricing -->
<section class="pricing" id="pricing" aria-label="Slingshot rental pricing">
<div class="container">
<p class="section-label">Rental Packages</p>
<h2 class="section-title">Pick Your Adventure</h2>
<p class="section-sub">Transparent pricing. No surprise fees. Just you, the open road, and a machine that turns heads.</p>
<div class="pricing-grid">
<div class="price-card">
<p class="price-name">Half Day</p>
<p class="price-amount"><sup>$</sup>80</p>
<p class="price-duration">4 hours of freedom</p>
<ul class="price-features">
<li>Polaris Slingshot SL</li>
<li>DOT helmets included</li>
<li>Safety orientation</li>
<li>Route map & guide</li>
<li>Proof of insurance required</li>
<li>Roadside assistance</li>
</ul>
<a href="#contact" class="btn-primary" style="display:block;width:100%;text-align:center;">Book Half Day</a>
</div>
<div class="price-card featured">
<div class="price-badge">Most Popular</div>
<p class="price-name">Full Day</p>
<p class="price-amount"><sup>$</sup>150</p>
<p class="price-duration">8 hours of adventure</p>
<ul class="price-features">
<li>Polaris Slingshot SL</li>
<li>DOT helmets included</li>
<li>Safety orientation</li>
<li>Route map & guide</li>
<li>Proof of insurance required</li>
<li>Roadside assistance</li>
</ul>
<a href="#contact" class="btn-primary" style="display:block;width:100%;text-align:center;">Book Full Day</a>
</div>
<div class="price-card">
<p class="price-name">3 Day Adventure</p>
<p class="price-amount"><sup>$</sup>449</p>
<p class="price-duration">72-hour adventure</p>
<ul class="price-features">
<li>Polaris Slingshot SL</li>
<li>DOT helmets included</li>
<li>Safety orientation</li>
<li>Route map & guide</li>
<li>Proof of insurance required</li>
<li>24/7 roadside assistance</li>
</ul>
<a href="#contact" class="btn-primary" style="display:block;width:100%;text-align:center;">Book 3 Day Adventure</a>
</div>
</div>
<p style="text-align:center;color:rgba(255,255,255,0.4);font-size:0.85rem;margin-top:2rem;">Must be 25+ with valid driver's license. Security deposit required. Prices include tax.</p>
</div>
</section>
<!-- How It Works -->
<section class="how" id="how" aria-label="How the rental process works">
<div class="container">
<p class="section-label">The Process</p>
<h2 class="section-title">Ready in 5 Simple Steps</h2>
<p class="section-sub">From booking to keys in hand — we make it effortless so you can focus on the fun.</p>
<div class="steps">
<div class="step">
<div class="step-num">1</div>
<h3>Choose Your Package</h3>
<p>Half day, full day, or 3 day adventure — pick the rental that fits your schedule and budget.</p>
</div>
<div class="step">
<div class="step-num">2</div>
<h3>Book & Submit</h3>
<p>Fill out our simple booking form online or give us a call. We'll review your request right away.</p>
</div>
<div class="step">
<div class="step-num">3</div>
<h3>Get Approved</h3>
<p>We'll confirm availability and reach out within a few hours. Once approved, you're officially on the calendar.</p>
</div>
<div class="step">
<div class="step-num">4</div>
<h3>Sign Your Waiver</h3>
<p>You'll receive a link to our digital rental agreement. Sign it online in minutes — no printer needed.</p>
</div>
<div class="step">
<div class="step-num">5</div>
<h3>Hit the Road</h3>
<p>Arrive at pickup with your license and proof of insurance. Complete your safety briefing, grab your helmets, and go.</p>
</div>
</div>
</div>
</section>
<!-- Scenic Routes -->
<section class="routes" id="routes" aria-label="Recommended scenic driving routes">
<div class="container">
<p class="section-label">Scenic Routes</p>
<h2 class="section-title">Texas Roads Worth Driving</h2>
<p class="section-sub">We know the best roads. Every rental comes with a recommended route guide — here's a taste.</p>
<div class="routes-grid">
<div class="route-card">
<h3>The Parker County Loop</h3>
<p class="miles">~45 miles &bull; 1.5 hrs</p>
<p>Roll through Weatherford's historic downtown, Millsap, and back through the rolling Texas plains. The perfect intro ride.</p>
</div>
<div class="route-card">
<h3>Possum Kingdom Run</h3>
<p class="miles">~80 miles &bull; 2.5 hrs</p>
<p>Head northwest toward Mineral Wells and Possum Kingdom Lake. Hill Country scenery, lake views, and open highway.</p>
</div>
<div class="route-card">
<h3>Granbury & Glen Rose</h3>
<p class="miles">~70 miles &bull; 2 hrs</p>
<p>Cruise south to the charming Granbury square and dinosaur country in Glen Rose. Great for couples and history lovers.</p>
</div>
<div class="route-card">
<h3>DFW Sunset Cruise</h3>
<p class="miles">~60 miles &bull; 2 hrs</p>
<p>Head east toward the Fort Worth skyline at golden hour, loop through Azle and back. City lights in an open cockpit.</p>
</div>
</div>
</div>
</section>
<!-- FAQ -->
<section class="faq" id="faq" aria-label="Frequently asked questions">
<div class="container">
<p class="section-label">FAQ</p>
<h2 class="section-title">Questions & Answers</h2>
<p class="section-sub">Everything you need to know before you book.</p>
<div class="faq-list">
<details>
<summary>Do I need a motorcycle license to rent a Polaris Slingshot in Texas?</summary>
<p>In Texas, a standard Class C driver's license is all you need. No motorcycle endorsement required. You must be 25 or older with a clean driving record to rent.</p>
</details>
<details>
<summary>What's included in every rental?</summary>
<p>Every rental includes the Polaris Slingshot, DOT-approved helmets for driver and passenger, a safety orientation, a suggested scenic route map, and roadside assistance. Renters must provide proof of valid personal auto insurance. We carry a comprehensive fleet policy covering the vehicle.</p>
</details>
<details>
<summary>How many people can ride in a Polaris Slingshot?</summary>
<p>The Polaris Slingshot is a two-seater — one driver and one passenger. Both experience the open-air thrill side by side in sports-car-style seats.</p>
</details>
<details>
<summary>Is there a security deposit?</summary>
<p>Yes, a refundable security deposit is required at the time of pickup. The deposit is returned in full upon safe return of the vehicle with no damage.</p>
</details>
<details>
<summary>Can I drive outside of Parker County?</summary>
<p>Yes — you can drive throughout the DFW area including Weatherford, Mineral Wells, Granbury, Azle, and Fort Worth. We'll note any restrictions in your rental agreement.</p>
</details>
<details>
<summary>What if it rains?</summary>
<p>The Polaris Slingshot can be driven in light rain, but we recommend rescheduling in severe weather for your safety and comfort. We offer flexible rescheduling with 24-hour notice.</p>
</details>
<details>
<summary>How do I cancel or reschedule?</summary>
<p>Cancel or reschedule free of charge up to 24 hours before your rental start time. Cancellations within 24 hours are subject to a 50% fee.</p>
</details>
</div>
</div>
</section>
<!-- Contact / Booking -->
<section class="contact" id="contact" aria-label="Contact and booking">
<div class="container">
<div class="contact-grid">
<div class="contact-info">
<p class="section-label">Book Your Rental</p>
<h2>Ready to Ride?</h2>
<p>Send us your preferred date and package and we'll confirm availability within a few hours. Can't wait? Give us a call.</p>
<div class="contact-detail">
<span>📍</span>
<span>Weatherford, TX 76086<br />(Exact pickup address provided at booking)</span>
</div>
<div class="contact-detail">
<span>📞</span>
<a href="tel:+18172662022" style="color:inherit;text-decoration:none;">(817) 266-2022</a>
</div>
<div class="contact-detail">
<span>✉️</span>
<a href="mailto:info@parkerslingshotrentals.com" style="color:inherit;text-decoration:none;">info@parkerslingshotrentals.com</a>
</div>
<div class="contact-detail">
<span>🕐</span>
<span>MonFri: 9am6pm &bull; SatSun: 8am8pm</span>
</div>
</div>
<div>
<!-- Availability Calendar -->
<div class="cal-wrap" id="calWrap">
<div class="cal-header">
<button class="cal-nav" id="calPrev" aria-label="Previous month">&#8249;</button>
<h3 id="calTitle">Loading&hellip;</h3>
<button class="cal-nav" id="calNext" aria-label="Next month">&#8250;</button>
</div>
<div class="cal-grid" id="calGrid">
<div class="cal-loading" style="grid-column:1/-1">Checking availability&hellip;</div>
</div>
<div class="cal-legend">
<div class="cal-legend-item"><div class="cal-legend-dot" style="background:rgba(255,255,255,0.12)"></div> Available</div>
<div class="cal-legend-item"><div class="cal-legend-dot" style="background:var(--orange)"></div> Selected</div>
<div class="cal-legend-item" id="legend-range" style="display:none"><div class="cal-legend-dot" style="background:rgba(249,115,22,0.35)"></div> In Range</div>
<div class="cal-legend-item"><div class="cal-legend-dot" style="background:rgba(239,68,68,0.35)"></div> Unavailable</div>
</div>
<p id="calHint" style="font-size:0.72rem;color:rgba(255,255,255,0.35);margin-top:0.5rem">Click a date to select it — click again to deselect. 3 Day Adventure shows all three days automatically.</p>
</div>
<form class="contact-form" id="bookingForm" novalidate>
<div class="form-row">
<input type="text" name="name" placeholder="Your Name" required />
<input type="email" name="email" placeholder="Email Address" required />
</div>
<input type="tel" name="phone" placeholder="Phone Number" />
<select name="package" required>
<option value="">Select Rental Package</option>
<option value="half-day">Half Day — $80</option>
<option value="full-day">Full Day — $150/day</option>
<option value="weekend">3 Day Adventure — $449</option>
</select>
<div id="rental-days-row" style="display:none">
<select name="rental_days" id="rentalDaysSelect">
<option value="1">1 Day — $150</option>
<option value="2">2 Days — $300</option>
<option value="3">3 Days — $450</option>
</select>
</div>
<input type="date" name="date" required />
<div id="date-unavail-msg" style="display:none;color:#f87171;font-size:.82rem;margin-top:.25rem">That date is already booked or unavailable. Please choose another.</div>
<textarea name="message" placeholder="Anything else we should know? (optional)"></textarea>
<!-- Square deposit card -->
<div style="background:rgba(255,255,255,0.04);border:1px solid rgba(255,255,255,0.1);border-radius:8px;padding:1rem;margin-top:0.25rem">
<div style="display:flex;justify-content:space-between;align-items:baseline;margin-bottom:0.5rem">
<p style="font-size:0.78rem;font-weight:700;text-transform:uppercase;letter-spacing:1px;color:rgba(249,115,22,0.8);margin:0">Deposit — $45 today</p>
<p id="balance-due-label" style="font-size:0.78rem;color:rgba(255,255,255,0.45);margin:0;display:none">Balance at pickup: <strong id="balance-due-amount" style="color:rgba(255,255,255,0.75)"></strong></p>
</div>
<p style="font-size:0.8rem;color:rgba(255,255,255,0.5);margin-bottom:0.85rem;line-height:1.5">A $45 hold is placed on your card to secure your date — <strong style="color:rgba(255,255,255,0.75)">not charged</strong> until confirmed. Remaining balance is due at pickup.</p>
<div id="card-container" style="min-height:44px"></div>
<p id="card-errors" style="color:#f87171;font-size:0.78rem;margin-top:0.4rem;display:none"></p>
<div id="deposit-status" style="display:none;margin-top:0.6rem;font-size:0.82rem;border-radius:6px;padding:0.5rem 0.75rem;line-height:1.5"></div>
</div>
<button type="submit" id="submitBtn">Submit Booking Request</button>
<div class="form-msg" id="formMsg"></div>
</form>
</div>
</div>
</div>
</section>
<!-- Footer -->
<footer>
<p class="footer-logo">Parker County Slingshot Rentals</p>
<div class="footer-links">
<a href="#why">Why Us</a>
<a href="#pricing">Pricing</a>
<a href="#how">How It Works</a>
<a href="#routes">Routes</a>
<a href="#faq">FAQ</a>
<a href="#contact">Contact</a>
</div>
<p>&copy; 2026 Parker County Slingshot Rentals &mdash; Weatherford, Texas. All rights reserved.</p>
<p style="margin-top:0.5rem;">Polaris Slingshot&reg; is a registered trademark of Polaris Inc. We are an independent rental operator.</p>
</footer>
<script src="https://web.squarecdn.com/v1/square.js"></script>
<script>
// ── Mobile nav ───────────────────────────────────────────────────────────────
const navToggle = document.getElementById('navToggle');
const navDrawer = document.getElementById('navDrawer');
function closeDrawer() {
navToggle.classList.remove('open');
navDrawer.classList.remove('open');
navToggle.setAttribute('aria-expanded', 'false');
document.body.style.overflow = '';
}
navToggle.addEventListener('click', () => {
const isOpen = navDrawer.classList.toggle('open');
navToggle.classList.toggle('open', isOpen);
navToggle.setAttribute('aria-expanded', String(isOpen));
document.body.style.overflow = isOpen ? 'hidden' : '';
});
// Close on any link click inside drawer
navDrawer.querySelectorAll('a').forEach(a => a.addEventListener('click', closeDrawer));
// Close on Escape key
document.addEventListener('keydown', e => { if (e.key === 'Escape') closeDrawer(); });
// ── Availability Calendar ────────────────────────────────────────────────────
const dateInput = document.querySelector('input[type="date"]');
const calGrid = document.getElementById('calGrid');
const calTitle = document.getElementById('calTitle');
const DAY_NAMES = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'];
const MONTH_NAMES = ['January','February','March','April','May','June','July','August','September','October','November','December'];
const todayStr = new Date().toISOString().split('T')[0];
if (dateInput) dateInput.min = todayStr;
let calYear = new Date().getFullYear();
let calMonth = new Date().getMonth() + 1; // 1-based
let bookedSet = new Set();
let selectedDates = new Set(); // all pinned start dates
let lastSelectedDate = null; // what goes in the booking form
let selectedPackage = 'half-day';
const availCache = {};
function getEndDateStr(startDate, pkg) {
if (!startDate || pkg !== 'weekend') return startDate;
const d = new Date(startDate + 'T12:00:00');
d.setDate(d.getDate() + 2);
return d.toISOString().split('T')[0];
}
async function fetchAvail(month, year) {
const key = year + '-' + String(month).padStart(2, '0');
if (!availCache[key]) {
const res = await fetch('/availability.php?month=' + month + '&year=' + year);
const data = await res.json();
availCache[key] = new Set(data.booked_dates || []);
}
return availCache[key];
}
async function hasRangeConflict(startDate, pkg) {
const endDate = getEndDateStr(startDate, pkg);
const dates = (endDate && endDate !== startDate) ? [startDate, endDate] : [startDate];
for (const date of dates) {
const [y, m] = date.split('-').map(Number);
const set = await fetchAvail(m, y);
if (set.has(date)) return true;
}
return false;
}
function showDateUnavail() {
const msg = document.getElementById('date-unavail-msg');
if (msg) { msg.style.display = 'block'; setTimeout(() => msg.style.display = 'none', 5000); }
}
function updateLegend() {
const rangeItem = document.getElementById('legend-range');
const hint = document.getElementById('calHint');
const isWknd = selectedPackage === 'weekend';
if (rangeItem) rangeItem.style.display = isWknd ? 'flex' : 'none';
if (hint) hint.textContent = isWknd
? 'Click your start date — all three days highlight automatically.'
: 'Click any available date to select it.';
}
async function loadCalendar(month, year) {
calTitle.textContent = MONTH_NAMES[month - 1] + ' ' + year;
calGrid.innerHTML = '<div class="cal-loading" style="grid-column:1/-1">Checking availability&hellip;</div>';
try {
bookedSet = await fetchAvail(month, year);
renderCalendar(month, year);
} catch {
calGrid.innerHTML = '<div class="cal-loading" style="grid-column:1/-1;color:rgba(239,68,68,0.6)">Could not load availability.</div>';
}
}
function renderCalendar(month, year) {
const fragment = document.createDocumentFragment();
// Day-name headers
DAY_NAMES.forEach(d => {
const el = document.createElement('div');
el.className = 'cal-day-label';
el.textContent = d;
fragment.appendChild(el);
});
const firstDay = new Date(year, month - 1, 1).getDay(); // 0=Sun
const daysInMo = new Date(year, month, 0).getDate();
// Blank cells before first day
for (let i = 0; i < firstDay; i++) {
const el = document.createElement('div');
el.className = 'cal-day empty';
fragment.appendChild(el);
}
// Pre-compute all in-range dates across every selected start date
const inRangeDates = new Set();
for (const start of selectedDates) {
const endD = getEndDateStr(start, selectedPackage);
if (endD && endD !== start) {
const dd = new Date(start + 'T12:00:00'); dd.setDate(dd.getDate() + 1);
while (dd.toISOString().split('T')[0] <= endD) {
inRangeDates.add(dd.toISOString().split('T')[0]); dd.setDate(dd.getDate() + 1);
}
}
}
for (let d = 1; d <= daysInMo; d++) {
const dateStr = year + '-' + String(month).padStart(2,'0') + '-' + String(d).padStart(2,'0');
const el = document.createElement('div');
el.textContent = d;
const isPast = dateStr < todayStr;
const isBooked = bookedSet.has(dateStr);
const isToday = dateStr === todayStr;
const isSel = selectedDates.has(dateStr);
const isInRange = !isSel && inRangeDates.has(dateStr);
if (isSel) {
el.className = 'cal-day selected';
el.addEventListener('click', () => selectDate(dateStr)); // click again to deselect
} else if (isInRange) {
el.className = 'cal-day in-range' + (isBooked ? ' booked' : '');
el.title = isBooked ? 'Conflict — this day is unavailable' : 'In your booking range';
} else if (isPast) {
el.className = 'cal-day past';
} else if (isBooked) {
el.className = 'cal-day booked';
el.title = 'Unavailable';
} else {
el.className = 'cal-day available' + (isToday ? ' today' : '');
el.addEventListener('click', () => selectDate(dateStr));
}
fragment.appendChild(el);
}
calGrid.innerHTML = '';
calGrid.appendChild(fragment);
}
async function selectDate(dateStr) {
if (selectedDates.has(dateStr)) {
// Toggle off — deselect this date
selectedDates.delete(dateStr);
lastSelectedDate = selectedDates.size > 0
? [...selectedDates].sort().reverse()[0] : null;
} else {
if (await hasRangeConflict(dateStr, selectedPackage)) {
showDateUnavail(); return;
}
selectedDates.add(dateStr);
lastSelectedDate = dateStr;
document.getElementById('bookingForm').scrollIntoView({ behavior: 'smooth', block: 'start' });
}
if (dateInput) dateInput.value = lastSelectedDate || '';
renderCalendar(calMonth, calYear);
}
document.getElementById('calPrev').addEventListener('click', () => {
calMonth--;
if (calMonth < 1) { calMonth = 12; calYear--; }
loadCalendar(calMonth, calYear);
});
document.getElementById('calNext').addEventListener('click', () => {
calMonth++;
if (calMonth > 12) { calMonth = 1; calYear++; }
loadCalendar(calMonth, calYear);
});
// Initial load
loadCalendar(calMonth, calYear);
// Keep calendar in sync when user types a date manually; validate against availability
if (dateInput) {
dateInput.addEventListener('change', async () => {
const val = dateInput.value;
if (!val) return;
const [y, m] = val.split('-').map(Number);
if (m !== calMonth || y !== calYear) {
calMonth = m; calYear = y;
await loadCalendar(calMonth, calYear);
}
if (await hasRangeConflict(val, selectedPackage)) {
dateInput.value = lastSelectedDate || '';
showDateUnavail();
} else {
selectedDates.add(val);
lastSelectedDate = val;
const msg = document.getElementById('date-unavail-msg');
if (msg) msg.style.display = 'none';
}
renderCalendar(calMonth, calYear);
});
}
// ── Balance-due display ───────────────────────────────────────────────────────
const PACKAGE_PRICES = { 'half-day': 80, 'full-day': 150, 'weekend': 449 };
const DEPOSIT = 45;
const pkgSelect = document.querySelector('select[name="package"]');
const rentalDaysSelect = document.getElementById('rentalDaysSelect');
const rentalDaysRow = document.getElementById('rental-days-row');
const balLabel = document.getElementById('balance-due-label');
const balAmt = document.getElementById('balance-due-amount');
function calcTotal(pkg, days) {
const base = PACKAGE_PRICES[pkg];
if (!base) return null;
return pkg === 'full-day' ? base * days : base;
}
function updateBalance() {
const pkg = pkgSelect ? pkgSelect.value : '';
const days = rentalDaysSelect ? parseInt(rentalDaysSelect.value) || 1 : 1;
const total = calcTotal(pkg, days);
if (total && balLabel && balAmt) {
balAmt.textContent = '$' + (total - DEPOSIT).toFixed(2).replace(/\.00$/, '');
balLabel.style.display = '';
} else if (balLabel) {
balLabel.style.display = 'none';
}
}
if (pkgSelect) { selectedPackage = pkgSelect.value || 'half-day'; }
if (pkgSelect) {
pkgSelect.addEventListener('change', function() {
selectedPackage = this.value;
updateLegend();
if (rentalDaysRow) rentalDaysRow.style.display = this.value === 'full-day' ? '' : 'none';
if (selectedDates.size > 0) {
Promise.all([...selectedDates].map(d => hasRangeConflict(d, selectedPackage).then(c => c ? d : null)))
.then(conflicts => {
conflicts.filter(Boolean).forEach(d => selectedDates.delete(d));
if (!selectedDates.has(lastSelectedDate)) lastSelectedDate = [...selectedDates].sort().reverse()[0] || null;
if (dateInput) dateInput.value = lastSelectedDate || '';
if (conflicts.some(Boolean)) showDateUnavail();
renderCalendar(calMonth, calYear);
});
} else { renderCalendar(calMonth, calYear); }
updateBalance();
});
}
if (rentalDaysSelect) {
rentalDaysSelect.addEventListener('change', updateBalance);
}
// ── Square Web Payments ───────────────────────────────────────────────────────
let squareCard = null;
async function initSquare() {
if (!window.Square) return;
const cardEl = document.getElementById('card-container');
if (cardEl) cardEl.style.display = '';
try {
const payments = Square.payments('sq0idp-YSM7BU9IVyOWSzpeP-0nzQ', 'L8GZYHYKE95CE');
squareCard = await payments.card({
style: {
'.input-container': { borderColor: 'rgba(255,255,255,0.12)', borderRadius: '6px' },
'.input-container.is-focus': { borderColor: '#f97316' },
'.input-container.is-error': { borderColor: '#ef4444' },
'input': { color: '#ffffff', fontSize: '15px' },
'.message-text': { color: '#f87171' },
}
});
await squareCard.attach('#card-container');
} catch (e) {
console.warn('Square init error:', e);
}
}
initSquare();
// ── Booking Form ─────────────────────────────────────────────────────────────
document.getElementById('bookingForm').addEventListener('submit', async function(e) {
e.preventDefault();
const form = this;
const msg = document.getElementById('formMsg');
const btn = document.getElementById('submitBtn');
const cardErrors = document.getElementById('card-errors');
const depositStatus = document.getElementById('deposit-status');
btn.textContent = 'Processing…';
btn.disabled = true;
msg.className = 'form-msg';
msg.style.display = 'none';
if (cardErrors) { cardErrors.style.display = 'none'; cardErrors.textContent = ''; }
function setDepStatus(text, type) {
if (!depositStatus) return;
if (!text) { depositStatus.style.display = 'none'; depositStatus.textContent = ''; return; }
depositStatus.textContent = text;
depositStatus.style.display = 'block';
const map = {
processing: { background: 'rgba(249,115,22,0.1)', color: 'rgba(249,115,22,0.95)', border: '1px solid rgba(249,115,22,0.25)' },
success: { background: 'rgba(22,163,74,0.15)', color: '#86efac', border: '1px solid rgba(22,163,74,0.35)' },
error: { background: 'rgba(239,68,68,0.1)', color: '#fca5a5', border: '1px solid rgba(239,68,68,0.25)' },
};
Object.assign(depositStatus.style, map[type] || {});
}
try {
let squareToken = null;
if (squareCard) {
setDepStatus('Verifying card…', 'processing');
const result = await squareCard.tokenize();
if (result.status !== 'OK') {
const errMsg = result.errors ? result.errors.map(x => x.message).join(', ') : 'Card error — please check your details.';
if (cardErrors) { cardErrors.textContent = errMsg; cardErrors.style.display = 'block'; }
setDepStatus('', '');
btn.textContent = 'Submit Booking Request';
btn.disabled = false;
return;
}
squareToken = result.token;
setDepStatus('Card verified — authorizing $45 deposit hold…', 'processing');
}
const pkgVal = form.querySelector('[name="package"]').value;
const daysVal = pkgVal === 'full-day' ? (parseInt(form.querySelector('[name="rental_days"]')?.value) || 1) : 1;
const data = {
name: form.querySelector('[name="name"]').value,
email: form.querySelector('[name="email"]').value,
phone: form.querySelector('[name="phone"]').value,
package: pkgVal,
rental_days: daysVal,
date: form.querySelector('[name="date"]').value,
message: form.querySelector('[name="message"]').value,
square_token: squareToken,
};
const res = await fetch('/contact.php', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data) });
const json = await res.json();
if (json.success) {
if (json.deposit_held) {
const holdSuffix = json.square_payment_id ? ' · Confirmation: …' + json.square_payment_id.slice(-10).toUpperCase() : '';
setDepStatus('✓ $45 deposit hold authorized' + holdSuffix, 'success');
const cardEl = document.getElementById('card-container');
if (cardEl) cardEl.style.display = 'none';
} else {
setDepStatus('', '');
}
msg.className = 'form-msg success';
msg.innerHTML = 'Booking request received! Your reference is <strong>' + json.ref + '</strong>. We\'ll be in touch shortly.';
msg.style.display = 'block';
form.reset();
if (squareCard) { squareCard.destroy(); squareCard = null; }
selectedDates.clear(); lastSelectedDate = null;
if (dateInput) dateInput.min = new Date().toISOString().split('T')[0];
btn.textContent = 'Request Sent!';
btn.style.background = '#16a34a';
loadCalendar(calMonth, calYear);
} else {
throw new Error(json.error || 'Something went wrong.');
}
} catch (err) {
setDepStatus('', '');
msg.className = 'form-msg error';
msg.textContent = err.message || 'Something went wrong. Please try again or call us directly.';
msg.style.display = 'block';
btn.textContent = 'Submit Booking Request';
btn.disabled = false;
}
});
</script>
</body>
</html>