Add digital e-signature waiver + update How It Works to 5 steps

- waiver.php: full rental agreement with canvas e-signature pad, 6 required
  checkboxes, typed name field; stores sig image + IP + timestamp in DB;
  emails signed confirmation to customer and admin
- bookings table: add waiver_signed, waiver_signed_at, waiver_ip, waiver_name,
  waiver_sig columns
- contact.php: confirmation email now includes Sign Rental Agreement button/link
- admin/index.php: Waiver column shows Signed (date) or Pending + Send Link
- index.html: How It Works expanded to 5 steps (added Get Approved + Sign Waiver
  before Hit the Road); insurance updated to Proof of insurance required; FAQ
  and JSON-LD updated to match

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-22 13:49:31 +00:00
parent fb7b510ee3
commit 85448d18c5
4 changed files with 398 additions and 13 deletions
+11 -1
View File
@@ -195,7 +195,7 @@ textarea.notes-ta{width:100%;font-size:.8rem;border:1px solid #e5e7eb;border-rad
<thead> <thead>
<tr> <tr>
<th>Ref</th><th>Customer</th><th>Package</th><th>Date</th> <th>Ref</th><th>Customer</th><th>Package</th><th>Date</th>
<th>Amount</th><th>Status</th><th>Admin Notes</th><th>Received</th> <th>Amount</th><th>Status</th><th>Waiver</th><th>Admin Notes</th><th>Received</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@@ -225,6 +225,16 @@ textarea.notes-ta{width:100%;font-size:.8rem;border:1px solid #e5e7eb;border-rad
<?php endforeach; ?> <?php endforeach; ?>
</select> </select>
</td> </td>
<td>
<?php if ($b['waiver_signed']): ?>
<span class="badge" style="background:#dcfce7;color:#14532d">&#10003; Signed</span>
<br><span style="font-size:.72rem;color:#9ca3af"><?= date('M j g:ia', strtotime($b['waiver_signed_at'])) ?></span>
<?php else: ?>
<a href="https://parkerslingshotrentals.com/waiver.php?ref=<?= urlencode($b['booking_ref']) ?>" target="_blank"
style="font-size:.78rem;color:#f97316;text-decoration:none">Send Link &#8599;</a>
<br><span class="badge" style="background:#fef3c7;color:#92400e;margin-top:.25rem">Pending</span>
<?php endif; ?>
</td>
<td> <td>
<textarea class="notes-ta" data-id="<?= $b['id'] ?>"><?= htmlspecialchars($b['admin_notes'] ?? '') ?></textarea> <textarea class="notes-ta" data-id="<?= $b['id'] ?>"><?= htmlspecialchars($b['admin_notes'] ?? '') ?></textarea>
<button class="save-btn" onclick="saveNotes(this)">Save</button> <button class="save-btn" onclick="saveNotes(this)">Save</button>
+5
View File
@@ -100,6 +100,11 @@ $confirmHtml = "<div style='max-width:600px;margin:0 auto;font-family:Arial,sans
<p style='margin:4px 0;font-size:14px;color:#374151'><strong>Requested Date:</strong> {$dateLabel}</p> <p style='margin:4px 0;font-size:14px;color:#374151'><strong>Requested Date:</strong> {$dateLabel}</p>
<p style='margin:4px 0;font-size:14px;color:#374151'><strong>Total:</strong> {$amountLabel}</p> <p style='margin:4px 0;font-size:14px;color:#374151'><strong>Total:</strong> {$amountLabel}</p>
</div> </div>
<div style='margin:20px 0;padding:16px;background:#fff7ed;border:1px solid #fed7aa;border-radius:10px;text-align:center'>
<p style='margin:0 0 10px;font-size:14px;font-weight:700;color:#111'>Next Step: Sign Your Rental Agreement</p>
<p style='margin:0 0 14px;font-size:13px;color:#6b7280'>Once your booking is confirmed you'll sign our digital waiver online — no printer needed. Your link:</p>
<a href='https://parkerslingshotrentals.com/waiver.php?ref={$ref}' style='display:inline-block;background:#f97316;color:#fff;text-decoration:none;padding:10px 24px;border-radius:6px;font-weight:700;font-size:14px'>Sign Rental Agreement &rarr;</a>
</div>
<p style='color:#374151'>Questions? Call or text <strong>(817) 555-0199</strong> or reply to this email.</p> <p style='color:#374151'>Questions? Call or text <strong>(817) 555-0199</strong> or reply to this email.</p>
<p style='color:#374151'>Ride on,<br><strong>The Parker County Slingshot Team</strong></p> <p style='color:#374151'>Ride on,<br><strong>The Parker County Slingshot Team</strong></p>
</div> </div>
+17 -12
View File
@@ -132,7 +132,7 @@
"name": "What is included in the rental?", "name": "What is included in the rental?",
"acceptedAnswer": { "acceptedAnswer": {
"@type": "Answer", "@type": "Answer",
"text": "Every rental includes the Polaris Slingshot, helmets for all riders, a safety orientation, a suggested route map, roadside assistance, and comprehensive insurance coverage." "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."
} }
}, },
{ {
@@ -609,7 +609,7 @@
<li>DOT helmets included</li> <li>DOT helmets included</li>
<li>Safety orientation</li> <li>Safety orientation</li>
<li>Route map & guide</li> <li>Route map & guide</li>
<li>Full insurance coverage</li> <li>Proof of insurance required</li>
<li>Roadside assistance</li> <li>Roadside assistance</li>
</ul> </ul>
<a href="#contact" class="btn-primary" style="display:block;width:100%;text-align:center;">Book Half Day</a> <a href="#contact" class="btn-primary" style="display:block;width:100%;text-align:center;">Book Half Day</a>
@@ -624,7 +624,7 @@
<li>DOT helmets included</li> <li>DOT helmets included</li>
<li>Safety orientation</li> <li>Safety orientation</li>
<li>Route map & guide</li> <li>Route map & guide</li>
<li>Full insurance coverage</li> <li>Proof of insurance required</li>
<li>Roadside assistance</li> <li>Roadside assistance</li>
</ul> </ul>
<a href="#contact" class="btn-primary" style="display:block;width:100%;text-align:center;">Book Full Day</a> <a href="#contact" class="btn-primary" style="display:block;width:100%;text-align:center;">Book Full Day</a>
@@ -638,7 +638,7 @@
<li>DOT helmets included</li> <li>DOT helmets included</li>
<li>Safety orientation</li> <li>Safety orientation</li>
<li>Route map & guide</li> <li>Route map & guide</li>
<li>Full insurance coverage</li> <li>Proof of insurance required</li>
<li>24/7 roadside assistance</li> <li>24/7 roadside assistance</li>
</ul> </ul>
<a href="#contact" class="btn-primary" style="display:block;width:100%;text-align:center;">Book Weekend</a> <a href="#contact" class="btn-primary" style="display:block;width:100%;text-align:center;">Book Weekend</a>
@@ -652,7 +652,7 @@
<section class="how" id="how" aria-label="How the rental process works"> <section class="how" id="how" aria-label="How the rental process works">
<div class="container"> <div class="container">
<p class="section-label">The Process</p> <p class="section-label">The Process</p>
<h2 class="section-title">Ready in 4 Simple Steps</h2> <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> <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="steps">
<div class="step"> <div class="step">
@@ -662,18 +662,23 @@
</div> </div>
<div class="step"> <div class="step">
<div class="step-num">2</div> <div class="step-num">2</div>
<h3>Book & Confirm</h3> <h3>Book & Submit</h3>
<p>Fill out our simple booking form or give us a call. We'll confirm your reservation within 24 hours.</p> <p>Fill out our simple booking form online or give us a call. We'll review your request right away.</p>
</div> </div>
<div class="step"> <div class="step">
<div class="step-num">3</div> <div class="step-num">3</div>
<h3>Show Up & Roll Out</h3> <h3>Get Approved</h3>
<p>Arrive at pickup, complete your safety briefing, grab your helmets and route map, and hit the road.</p> <p>We'll confirm availability and reach out within a few hours. Once approved, you're officially on the calendar.</p>
</div> </div>
<div class="step"> <div class="step">
<div class="step-num">4</div> <div class="step-num">4</div>
<h3>Return & Relive</h3> <h3>Sign Your Waiver</h3>
<p>Return the Slingshot at the agreed time. Tell everyone about the best day you've had in Texas.</p> <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> </div>
</div> </div>
@@ -723,7 +728,7 @@
</details> </details>
<details> <details>
<summary>What's included in every rental?</summary> <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, roadside assistance, and comprehensive insurance coverage.</p> <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>
<details> <details>
<summary>How many people can ride in a Polaris Slingshot?</summary> <summary>How many people can ride in a Polaris Slingshot?</summary>
+365
View File
@@ -0,0 +1,365 @@
<?php
require_once __DIR__ . '/db.php';
header('X-Frame-Options: DENY');
header('X-Content-Type-Options: nosniff');
$ref = strtoupper(trim($_GET['ref'] ?? ''));
$error = '';
$booking = null;
$signed = false;
if ($ref) {
$stmt = db()->prepare("SELECT * FROM bookings WHERE booking_ref = ?");
$stmt->execute([$ref]);
$booking = $stmt->fetch();
if (!$booking) {
$error = 'Booking reference not found. Please check your confirmation email.';
} elseif ($booking['status'] === 'cancelled') {
$error = 'This booking has been cancelled. Please contact us if you have questions.';
} elseif ($booking['waiver_signed']) {
$signed = true;
}
}
// Handle submission
if ($_SERVER['REQUEST_METHOD'] === 'POST' && $booking && !$signed) {
$sigName = trim(strip_tags($_POST['sig_name'] ?? ''));
$sigData = $_POST['sig_data'] ?? ''; // base64 canvas PNG
$checks = (array)($_POST['checks'] ?? []);
$required = ['age','license','insurance','rules','damage','waiver'];
$missing = array_diff($required, $checks);
if (!$sigName) {
$error = 'Please type your full name to sign.';
} elseif ($missing) {
$error = 'Please check all required boxes before signing.';
} elseif (!$sigData || strpos($sigData, 'data:image/png;base64,') !== 0) {
$error = 'Please draw your signature in the box above.';
} else {
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'] ?? $_SERVER['REMOTE_ADDR'] ?? '';
$ip = explode(',', $ip)[0];
db()->prepare(
"UPDATE bookings SET waiver_signed=1, waiver_signed_at=NOW(), waiver_ip=?, waiver_name=?, waiver_sig=? WHERE booking_ref=?"
)->execute([trim($ip), $sigName, $sigData, $ref]);
$pkg = PACKAGES[$booking['package']] ?? ['label'=>$booking['package']];
$dateLabel = date('F j, Y', strtotime($booking['rental_date']));
$adminHtml = "<div style='font-family:Arial,sans-serif;max-width:600px;margin:0 auto'>
<div style='background:#f97316;padding:20px;text-align:center'>
<h1 style='color:#fff;margin:0;font-size:18px'>Waiver Signed {$ref}</h1>
</div>
<div style='padding:24px;background:#fff;border:1px solid #e5e7eb'>
<p><strong>" . htmlspecialchars($booking['name']) . "</strong> signed the rental waiver for booking <strong>{$ref}</strong>.</p>
<table style='width:100%;font-size:14px'>
<tr><td style='color:#6b7280;padding:6px 0;width:110px'>Package</td><td style='padding:6px 0'>" . htmlspecialchars($pkg['label']) . "</td></tr>
<tr><td style='color:#6b7280;padding:6px 0'>Date</td><td style='padding:6px 0'>{$dateLabel}</td></tr>
<tr><td style='color:#6b7280;padding:6px 0'>Signed by</td><td style='padding:6px 0'>" . htmlspecialchars($sigName) . "</td></tr>
<tr><td style='color:#6b7280;padding:6px 0'>IP</td><td style='padding:6px 0'>" . htmlspecialchars($ip) . "</td></tr>
<tr><td style='color:#6b7280;padding:6px 0'>Timestamp</td><td style='padding:6px 0'>" . date('F j, Y g:i A') . " CT</td></tr>
</table>
<img src='{$sigData}' style='margin-top:16px;border:1px solid #e5e7eb;border-radius:6px;max-width:100%;height:auto' alt='Signature' />
</div>
</div>";
$custHtml = "<div style='font-family:Arial,sans-serif;max-width:600px;margin:0 auto'>
<div style='background:#0d0d0d;padding:24px;text-align:center'>
<h1 style='color:#f97316;margin:0;font-size:20px'>Parker County Slingshot Rentals</h1>
</div>
<div style='padding:32px;background:#fff'>
<h2 style='margin-top:0'>Waiver Signed You're All Set!</h2>
<p style='color:#374151'>Hey " . htmlspecialchars($booking['name']) . ", your rental agreement for booking <strong>{$ref}</strong> is signed and on file. See you on <strong>{$dateLabel}</strong>!</p>
<p style='color:#374151'>Remember to bring:</p>
<ul style='color:#374151'>
<li>Valid driver's license</li>
<li>Proof of personal auto insurance</li>
</ul>
<p style='color:#374151'>Questions? Call or text <strong>(817) 555-0199</strong>.</p>
<p style='color:#374151'>Ride on,<br><strong>The Parker County Slingshot Team</strong></p>
</div>
<div style='background:#f3f4f6;padding:16px;text-align:center'>
<p style='margin:0;font-size:12px;color:#9ca3af'>&copy; " . date('Y') . " Parker County Slingshot Rentals &mdash; Weatherford, TX</p>
</div>
</div>";
sendEmail(ADMIN_EMAIL, 'Parker Slingshot Admin', "Waiver Signed: {$ref}" . $booking['name'], $adminHtml);
sendEmail($booking['email'], $booking['name'], "Rental Agreement Signed — {$ref}", $custHtml);
$signed = true;
}
}
$pkgLabel = $booking ? (PACKAGES[$booking['package']]['label'] ?? $booking['package']) : '';
$dateLabel = $booking ? date('F j, Y', strtotime($booking['rental_date'])) : '';
?><!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Rental Agreement Parker County Slingshot Rentals</title>
<meta name="robots" content="noindex,nofollow" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Barlow+Condensed:wght@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; }
body { font-family: 'Inter', sans-serif; background: #f3f4f6; color: #111; line-height: 1.6; }
header { background: var(--black); padding: 1.25rem 2rem; display: flex; align-items: center; justify-content: space-between; }
header a { font-family: 'Barlow Condensed', sans-serif; font-size: 1.3rem; font-weight: 800; color: var(--orange); text-decoration: none; }
header span { font-size: 0.85rem; color: rgba(255,255,255,0.4); }
.wrap { max-width: 760px; margin: 2.5rem auto; padding: 0 1rem 4rem; }
.card { background: #fff; border-radius: 12px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); padding: 2rem 2.5rem; margin-bottom: 1.5rem; }
@media (max-width: 600px) { .card { padding: 1.5rem; } }
h1 { font-family: 'Barlow Condensed', sans-serif; font-size: 2rem; font-weight: 800; margin-bottom: 0.25rem; }
h2 { font-size: 1rem; font-weight: 700; color: var(--orange); text-transform: uppercase; letter-spacing: 1px; margin: 1.75rem 0 0.75rem; }
p { color: #374151; font-size: 0.95rem; margin-bottom: 0.75rem; }
.booking-banner { background: #fff7ed; border: 1px solid #fed7aa; border-radius: 10px; padding: 1.25rem 1.5rem; margin-bottom: 1.75rem; display: flex; gap: 2rem; flex-wrap: wrap; }
.bb-item { font-size: 0.9rem; }
.bb-label { color: #9ca3af; font-size: 0.75rem; text-transform: uppercase; letter-spacing: 1px; margin-bottom: 0.2rem; }
.bb-value { font-weight: 700; color: #111; }
.bb-ref { color: var(--orange); font-size: 1.1rem; }
.clause { display: flex; gap: 0.85rem; align-items: flex-start; padding: 0.85rem 0; border-bottom: 1px solid #f3f4f6; }
.clause:last-child { border-bottom: none; }
.clause input[type=checkbox] { margin-top: 3px; width: 18px; height: 18px; accent-color: var(--orange); flex-shrink: 0; cursor: pointer; }
.clause label { font-size: 0.92rem; color: #374151; cursor: pointer; }
.clause label strong { color: #111; }
.sig-wrap { border: 2px dashed #d1d5db; border-radius: 8px; overflow: hidden; position: relative; background: #fafafa; margin-top: 0.5rem; }
#sigCanvas { display: block; width: 100%; height: 160px; cursor: crosshair; touch-action: none; }
.sig-clear { position: absolute; top: 8px; right: 8px; background: rgba(0,0,0,0.06); border: none; border-radius: 6px; padding: 4px 10px; font-size: 0.78rem; cursor: pointer; color: #6b7280; }
.sig-clear:hover { background: rgba(239,68,68,0.1); color: #ef4444; }
.sig-hint { font-size: 0.78rem; color: #9ca3af; margin-top: 0.4rem; }
input[type=text] { width: 100%; border: 1px solid #d1d5db; border-radius: 8px; padding: 0.75rem 1rem; font-size: 1rem; font-family: inherit; outline: none; transition: border-color 0.2s; margin-top: 0.4rem; }
input[type=text]:focus { border-color: var(--orange); }
.btn-sign { display: block; width: 100%; background: var(--orange); color: white; border: none; border-radius: 8px; padding: 1rem; font-size: 1.05rem; font-weight: 700; cursor: pointer; transition: background 0.2s; margin-top: 1.5rem; }
.btn-sign:hover { background: var(--orange-dark); }
.btn-sign:disabled { background: #d1d5db; cursor: not-allowed; }
.alert { padding: 0.9rem 1.1rem; border-radius: 8px; font-size: 0.9rem; margin-bottom: 1rem; }
.alert-error { background: rgba(239,68,68,0.08); border: 1px solid rgba(239,68,68,0.25); color: #dc2626; }
.alert-success { background: rgba(34,197,94,0.08); border: 1px solid rgba(34,197,94,0.25); color: #16a34a; }
.success-icon { font-size: 3rem; text-align: center; margin-bottom: 1rem; }
.success-box { text-align: center; padding: 1rem 0; }
.success-box h1 { color: #16a34a; margin-bottom: 0.5rem; }
.success-box p { color: #374151; max-width: 480px; margin: 0 auto 1rem; }
.checklist { text-align: left; display: inline-block; margin: 1rem auto; }
.checklist li { padding: 0.35rem 0; color: #374151; font-size: 0.95rem; list-style: none; }
.checklist li::before { content: '✓ '; color: #16a34a; font-weight: 700; }
.back-link { text-align: center; margin-top: 1.5rem; }
.back-link a { color: var(--orange); text-decoration: none; font-weight: 600; font-size: 0.9rem; }
</style>
</head>
<body>
<header>
<a href="/">Parker County Slingshot Rentals</a>
<span>Rental Agreement</span>
</header>
<div class="wrap">
<?php if (!$ref || $error === 'Booking reference not found. Please check your confirmation email.'): ?>
<!-- No valid ref show lookup form -->
<div class="card">
<h1>Rental Agreement</h1>
<p style="margin:0.75rem 0 1.5rem;color:#6b7280;">Enter your booking reference from your confirmation email to access your rental agreement.</p>
<?php if ($error): ?><div class="alert alert-error"><?= htmlspecialchars($error) ?></div><?php endif; ?>
<form method="get" action="/waiver.php">
<label style="font-weight:600;font-size:0.9rem;display:block;margin-bottom:0.4rem;">Booking Reference</label>
<input type="text" name="ref" placeholder="PSR-XXXXXX" value="<?= htmlspecialchars($ref) ?>" style="text-transform:uppercase" maxlength="12" required />
<button type="submit" class="btn-sign" style="margin-top:1rem;">Look Up My Booking</button>
</form>
</div>
<?php elseif ($signed): ?>
<!-- Already signed or just signed -->
<div class="card">
<div class="success-icon"></div>
<div class="success-box">
<h1>You're All Set!</h1>
<p>Your rental agreement for booking <strong><?= htmlspecialchars($ref) ?></strong> is signed and on file. We'll see you on <strong><?= htmlspecialchars($dateLabel) ?></strong>!</p>
<p style="color:#6b7280;font-size:0.88rem;">A confirmation was sent to <?= htmlspecialchars($booking['email']) ?>.</p>
<p style="font-weight:700;margin-top:1rem;margin-bottom:0.25rem;">Remember to bring:</p>
<ul class="checklist">
<li>Valid driver's license</li>
<li>Proof of personal auto insurance</li>
</ul>
</div>
<div class="back-link"><a href="/"> Back to parkerslingshotrentals.com</a></div>
</div>
<?php elseif ($booking): ?>
<!-- Waiver form -->
<?php if ($error): ?><div class="alert alert-error"><?= htmlspecialchars($error) ?></div><?php endif; ?>
<div class="card">
<h1>Rental Agreement</h1>
<p style="color:#6b7280;margin-top:0.25rem;margin-bottom:1.5rem;">Please read and sign the agreement below for your upcoming rental.</p>
<div class="booking-banner">
<div class="bb-item"><div class="bb-label">Booking Ref</div><div class="bb-value bb-ref"><?= htmlspecialchars($booking['booking_ref']) ?></div></div>
<div class="bb-item"><div class="bb-label">Name</div><div class="bb-value"><?= htmlspecialchars($booking['name']) ?></div></div>
<div class="bb-item"><div class="bb-label">Package</div><div class="bb-value"><?= htmlspecialchars($pkgLabel) ?></div></div>
<div class="bb-item"><div class="bb-label">Rental Date</div><div class="bb-value"><?= htmlspecialchars($dateLabel) ?></div></div>
</div>
<h2>Rental Terms & Conditions</h2>
<p>This Rental Agreement ("Agreement") is entered into between Parker County Slingshot Rentals ("Company") and the renter identified above ("Renter"). By signing below, Renter agrees to all terms stated herein.</p>
<h2>Eligibility Requirements</h2>
<p>Renter must be at least 25 years of age and hold a valid Class C driver's license (or equivalent) issued by a U.S. state or territory. Renter must not have any DUI/DWI convictions within the past 5 years.</p>
<h2>Insurance Requirement</h2>
<p>Renter is required to carry and provide proof of valid personal auto insurance at the time of vehicle pickup. The Company maintains a fleet insurance policy covering the vehicle; however, Renter's personal insurance is primary for liability arising from Renter's operation of the vehicle. Renter accepts financial responsibility for any deductible, damages, or losses not covered by either policy.</p>
<h2>Vehicle Use & Rules</h2>
<p>Renter agrees to operate the Polaris Slingshot in a safe, lawful manner and specifically agrees to:</p>
<ul style="color:#374151;font-size:0.92rem;padding-left:1.25rem;margin-bottom:0.75rem;">
<li style="margin-bottom:0.35rem;">Obey all applicable traffic laws and speed limits</li>
<li style="margin-bottom:0.35rem;">Never operate the vehicle under the influence of alcohol, drugs, or any impairing substance</li>
<li style="margin-bottom:0.35rem;">Never allow an unauthorized third party to operate the vehicle</li>
<li style="margin-bottom:0.35rem;">Wear the provided DOT-approved helmet at all times while operating the vehicle</li>
<li style="margin-bottom:0.35rem;">Not take the vehicle off paved roads or outside the approved driving area</li>
<li>Return the vehicle at the agreed-upon time and location in the same condition it was received</li>
</ul>
<h2>Damage & Security Deposit</h2>
<p>A refundable security deposit is required at pickup. Renter is financially responsible for any damage to the vehicle, including but not limited to collision damage, tire damage, interior damage, and any fines or citations incurred during the rental period. The Company reserves the right to apply the security deposit toward any such costs.</p>
<h2>Assumption of Risk & Release of Liability</h2>
<p>Renter acknowledges that operating a Polaris Slingshot involves inherent risks including, but not limited to, physical injury or death. Renter voluntarily assumes all such risks and, to the fullest extent permitted by Texas law, releases and holds harmless Parker County Slingshot Rentals, its owners, employees, and agents from any and all claims, damages, or liability arising out of Renter's use of the vehicle.</p>
<h2>Cancellation Policy</h2>
<p>Cancellations made more than 24 hours before the rental start time are fully refunded. Cancellations within 24 hours of the rental start time are subject to a 50% cancellation fee.</p>
</div>
<form method="post" action="/waiver.php?ref=<?= urlencode($ref) ?>" id="waiverForm">
<input type="hidden" name="sig_data" id="sigDataInput" />
<div class="card">
<h2 style="margin-top:0">Acknowledgments</h2>
<p style="margin-bottom:1rem;color:#6b7280;font-size:0.88rem;">Check each box to confirm you have read and agree to that section.</p>
<div class="clause">
<input type="checkbox" name="checks[]" value="age" id="ck_age" required />
<label for="ck_age"><strong>Age & License:</strong> I confirm I am 25 years of age or older and hold a valid driver's license.</label>
</div>
<div class="clause">
<input type="checkbox" name="checks[]" value="insurance" id="ck_ins" required />
<label for="ck_ins"><strong>Insurance:</strong> I will provide proof of valid personal auto insurance at pickup and understand it is required.</label>
</div>
<div class="clause">
<input type="checkbox" name="checks[]" value="rules" id="ck_rules" required />
<label for="ck_rules"><strong>Vehicle Rules:</strong> I agree to operate the Slingshot safely, lawfully, and sober, and to wear the provided helmet at all times.</label>
</div>
<div class="clause">
<input type="checkbox" name="checks[]" value="damage" id="ck_dmg" required />
<label for="ck_dmg"><strong>Damage Responsibility:</strong> I understand I am financially responsible for any damage or fines incurred during my rental period.</label>
</div>
<div class="clause">
<input type="checkbox" name="checks[]" value="license" id="ck_lic" required />
<label for="ck_lic"><strong>License Verification:</strong> I consent to Parker County Slingshot Rentals verifying my driver's license at pickup.</label>
</div>
<div class="clause">
<input type="checkbox" name="checks[]" value="waiver" id="ck_waiver" required />
<label for="ck_waiver"><strong>Assumption of Risk:</strong> I have read and understand the Assumption of Risk and Release of Liability section and agree to its terms.</label>
</div>
</div>
<div class="card">
<h2 style="margin-top:0">Your Signature</h2>
<label style="font-weight:600;font-size:0.9rem;display:block;margin-bottom:0.2rem;">Full Legal Name</label>
<input type="text" name="sig_name" id="sigName" placeholder="Type your full name as it appears on your license" required />
<p style="margin:1.25rem 0 0.4rem;font-weight:600;font-size:0.9rem;">Draw Your Signature</p>
<div class="sig-wrap">
<canvas id="sigCanvas"></canvas>
<button type="button" class="sig-clear" id="clearBtn">Clear</button>
</div>
<p class="sig-hint">Use your mouse or finger to sign in the box above.</p>
<p style="margin-top:1.5rem;font-size:0.82rem;color:#9ca3af;">
By clicking "Sign &amp; Submit" below, you confirm that you have read this entire Rental Agreement, that all acknowledgments above are checked, and that your typed name and drawn signature constitute a legally binding electronic signature under the ESIGN Act and Texas law. Signed: <span id="sigDateDisplay"><?= date('F j, Y') ?></span>.
</p>
<button type="submit" class="btn-sign" id="submitBtn">Sign &amp; Submit Rental Agreement</button>
</div>
</form>
<?php endif; ?>
</div><!-- /.wrap -->
<script>
(function() {
const canvas = document.getElementById('sigCanvas');
if (!canvas) return;
// Size canvas to its CSS width
function resizeCanvas() {
const rect = canvas.getBoundingClientRect();
canvas.width = rect.width * window.devicePixelRatio;
canvas.height = rect.height * window.devicePixelRatio;
canvas.getContext('2d').scale(window.devicePixelRatio, window.devicePixelRatio);
}
resizeCanvas();
const ctx = canvas.getContext('2d');
let drawing = false;
let hasDrawn = false;
ctx.strokeStyle = '#111';
ctx.lineWidth = 2.2;
ctx.lineCap = 'round';
ctx.lineJoin = 'round';
function getPos(e) {
const r = canvas.getBoundingClientRect();
const src = e.touches ? e.touches[0] : e;
return { x: src.clientX - r.left, y: src.clientY - r.top };
}
function startDraw(e) {
e.preventDefault();
drawing = true;
const p = getPos(e);
ctx.beginPath();
ctx.moveTo(p.x, p.y);
}
function draw(e) {
if (!drawing) return;
e.preventDefault();
const p = getPos(e);
ctx.lineTo(p.x, p.y);
ctx.stroke();
hasDrawn = true;
}
function endDraw() { drawing = false; }
canvas.addEventListener('mousedown', startDraw);
canvas.addEventListener('mousemove', draw);
canvas.addEventListener('mouseup', endDraw);
canvas.addEventListener('mouseleave', endDraw);
canvas.addEventListener('touchstart', startDraw, { passive: false });
canvas.addEventListener('touchmove', draw, { passive: false });
canvas.addEventListener('touchend', endDraw);
document.getElementById('clearBtn').addEventListener('click', () => {
ctx.clearRect(0, 0, canvas.width, canvas.height);
hasDrawn = false;
document.getElementById('sigDataInput').value = '';
});
document.getElementById('waiverForm').addEventListener('submit', function(e) {
if (!hasDrawn) {
e.preventDefault();
alert('Please draw your signature before submitting.');
canvas.style.borderColor = '#ef4444';
return;
}
// Export canvas to base64 PNG
document.getElementById('sigDataInput').value = canvas.toDataURL('image/png');
});
})();
</script>
</body>
</html>