PageSourceSearch

https://farebookings.com/index.php

html farebookings.com collected 2026-10-01 14:09:09 UTC 108,991 bytes, 1,629 lines download raw bytes

1<!DOCTYPE html>
2<html lang="en" class="scroll-smooth">
3<head>
4  <meta charset="UTF-8">
5  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6  <title>FareBookings — Taxi Fleet Dispatch &amp; Booking Software</title>
7  <meta name="description" content="The dispatch and booking software running 1,000+ taxi fleets since 2012. Native driver and passenger apps, online payments and real-time fare calculation.">
8  <meta name="theme-color" content="#08080a">
9  <link rel="icon" type="image/svg+xml" href="/assets/img/favicon.svg">
10  <link rel="icon" type="image/png" sizes="32x32" href="/assets/img/favicon-32x32.png">
11  <link rel="icon" type="image/png" sizes="16x16" href="/assets/img/favicon-16x16.png">
12  <link rel="icon" href="/favicon.ico" sizes="any">
13  <link rel="apple-touch-icon" sizes="180x180" href="/assets/img/apple-touch-icon.png">
14  <link rel="canonical" href="https://farebookings.com/index.php">
15
16  <!-- Open Graph / Twitter — reuses the same title+description as
17       above, so there's only ever one place to update copy for a page.
18       og-default.webp doesn't exist yet; drop a real 1200x630 image
19       there (or set $pageImage per-page) before this goes live. -->
20  <meta property="og:type" content="website">
21  <meta property="og:url" content="https://farebookings.com/index.php">
22  <meta property="og:title" content="FareBookings — Taxi Fleet Dispatch &amp; Booking Software">
23  <meta property="og:description" content="The dispatch and booking software running 1,000+ taxi fleets since 2012. Native driver and passenger apps, online payments and real-time fare calculation.">
24  <meta property="og:image" content="https://farebookings.com/assets/img/og-default.webp">
25  <meta property="og:locale" content="en_GB">
26  <meta name="twitter:card" content="summary_large_image">
27  <meta name="twitter:title" content="FareBookings — Taxi Fleet Dispatch &amp; Booking Software">
28  <meta name="twitter:description" content="The dispatch and booking software running 1,000+ taxi fleets since 2012. Native driver and passenger apps, online payments and real-time fare calculation.">
29  <meta name="twitter:image" content="https://farebookings.com/assets/img/og-default.webp">
30
31  <!-- Preconnect + Google Fonts -->
32  <link rel="preconnect" href="https://fonts.googleapis.com">
33  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
34  <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=Space+Grotesk:wght@500;600;700&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet">
35
36  <!-- Tailwind CSS — compiled build, not the dev CDN. Source at
37       src/input.css; rebuild after any class change with:
38       npx @tailwindcss/cli -i ./src/input.css -o ./assets/css/tailwind.css --minify
39       Cache-busted with filemtime() so re-uploading tailwind.css always
40       forces browsers to fetch the new version instead of serving a
41       cached copy under the same filename. -->
42  <link rel="stylesheet" href="assets/css/tailwind.css?v=1789469279">
43
44  <!-- Google Consent Mode v2 defaults — set BEFORE any analytics/ads
45       tags load, so if/when GA4 or Google Ads get added to this site,
46       they respect cookie consent from the very first page load
47       instead of firing before the user has chosen. The cookie banner
48       (includes/cookie-banner.php) calls gtag('consent','update',...)
49       once the user picks Accept/Reject/Customize.
50
51       Bug fixed here: a returning visitor who already accepted cookies
52       was still getting 'denied' on this very first call, because the
53       banner lives in footer.php and only restores their saved choice
54       once Alpine loads — often after GA4's own config call already
55       fired. Per Google's own docs, a later consent 'update' does NOT
56       retroactively resend that lost hit, so the site was effectively
57       undercounting nearly every visit, accepted or not. Reading the
58       saved choice synchronously here, before the default fires, means
59       a returning visitor's first hit of the session is correct from
60       the start instead of racing the banner to load. -->
61  
61<script type="a9f260de584e6f830f646f33-text/javascript">
62    window.dataLayer = window.dataLayer || [];
63    function gtag(){ dataLayer.push(arguments); }
64
65    var fbSavedConsent = null;
66    try { fbSavedConsent = JSON.parse(localStorage.getItem('fb_consent')); } catch (e) {}
67
68    gtag('consent', 'default', {
69      analytics_storage: (fbSavedConsent && fbSavedConsent.analytics) ? 'granted' : 'denied',
70      ad_storage: (fbSavedConsent && fbSavedConsent.marketing) ? 'granted' : 'denied',
71      ad_user_data: (fbSavedConsent && fbSavedConsent.marketing) ? 'granted' : 'denied',
72      ad_personalization: (fbSavedConsent && fbSavedConsent.marketing) ? 'granted' : 'denied',
73      wait_for_update: 500
74    });
75  </script>
75
76
77  <!-- GA4 — the script itself loads on every page (that's normal and
78       expected), but thanks to Consent Mode above, it won't actually
79       send real analytics data until the cookie banner calls
80       gtag('consent','update', {analytics_storage:'granted'}) on
81       Accept. Reject = the config call below still fires, but Google's
82       own library holds back real hits per the denied consent signal —
83       this is the standard, correct pattern, not a bug. -->
vendor: 66 bytes, lines 83-84
83
84  <script async src="https://www.googletagmanager.com/gtag/js?id=
84G-VV6QJ6F7PT
vendor: 62 bytes, lines 84-85
84" type="a9f260de584e6f830f646f33-text/javascript"></script>
85  
85<script type="a9f260de584e6f830f646f33-text/javascript">
86    gtag('js', new Date());
87    gtag('config', 'G-VV6QJ6F7PT');
88  </script>
88
89
90  <!-- Organization + WebSite JSON-LD — global, every page. Facts here
91       are the confirmed real ones (address/phone/email); nothing
92       fabricated. AggregateRating deliberately NOT included anywhere
93       on the site yet — no real Google Business reviews to point to. -->
94  
94<script type="application/ld+json">
95  {
96    "@context": "https://schema.org",
97    "@type": "ProfessionalService",
98    "name": "FareBookings",
99    "url": "https://farebookings.com",
100    "telephone": "+447480051101",
101    "email": "[email protected]",
102    "address": {
103      "@type": "PostalAddress",
104      "streetAddress": "2 Gordon View",
105      "addressLocality": "Leeds",
106      "addressRegion": "West Yorkshire",
107      "postalCode": "LS6 4FB",
108      "addressCountry": "GB"
109    },
110    "areaServed": "Worldwide",
111    "description": "Dispatch and booking software for taxi and VTC fleets, running since 2012."
112  }
113  </script>
113
114  
114<script type="application/ld+json">
115  {
116    "@context": "https://schema.org",
117    "@type": "WebSite",
118    "name": "FareBookings",
119    "url": "https://farebookings.com"
120  }
121  </script>
121
122
123  <!-- Alpine.js — used only for: mobile menu, FAQ accordion,
124       pricing view/currency toggles, and the hero fare counter -->
125  
125<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/cdn.min.js" defer type="a9f260de584e6f830f646f33-text/javascript"></script>
125
126
127  <link rel="preload" as="image" href="assets/img/hero-map.webp" fetchpriority="high"></head>
128<body class="bg-ink-950 text-zinc-300 font-sans antialiased">
129
130  <!-- Scroll-linked ambient background: two fixed blurred orbs whose
131       opacity crossfades cyan -> violet as the page scrolls, driven by
132       the scroll handler in includes/footer.php. Sits behind everything
133       (-z-10, fixed) so it reads as one continuous atmosphere, not a
134       per-section background. -->
135  <div class="fixed inset-0 -z-10 pointer-events-none overflow-hidden">
136    <div id="bg-orb-cyan" class="animate-drift absolute top-[8%] left-[10%] w-[720px] h-[720px] bg-cyan-500 rounded-full blur-[180px]" style="opacity:.16"></div>
137    <div id="bg-orb-violet" class="animate-drift-reverse absolute bottom-[6%] right-[8%] w-[720px] h-[720px] bg-violet-500 rounded-full blur-[180px]" style="opacity:0"></div>
138  </div>
139<header
140  x-data="{ mobileOpen: false, scrolled: false }"
141  x-init="window.addEventListener('scroll', () => scrolled = window.scrollY > 12)"
142  class="fixed top-0 inset-x-0 z-50 transition-colors duration-300"
143  :class="scrolled ? 'bg-ink-950/80 backdrop-blur-lg border-b border-white/10' : 'bg-transparent border-b border-transparent'"
144>
145  <nav class="max-w-7xl mx-auto px-6 lg:px-8 flex items-center justify-between py-4">
146
147    <!-- Logo -->
148    <a href="index.php" class="fb-logo fb-md shrink-0">
149  <svg class="fb-pin" viewBox="4 2 24 32">
150    <g class="fb-pin-group">
151      <path class="fb-pin-shape" d="M16 4 C 10.5 4, 6 8.5, 6 14 C 6 21.5, 16 32, 16 32 S 26 21.5, 26 14 C 26 8.5, 21.5 4, 16 4 Z" />
152      <circle cx="16" cy="14" r="4.6" fill="#08080a" />
153    </g>
154  </svg>
155  <span class="fb-wordblock">
156    <span class="fb-wordmark">Fare<span class="fb-light">Bookings</span></span>
157    <svg class="fb-route-svg" viewBox="0 0 160 8" preserveAspectRatio="none">
158      <path class="fb-route" d="M0 3 C 35 3, 80 5, 160 4" />
159      <circle class="fb-travel-dot" r="1.5">
160        <animateMotion dur="2.6s" repeatCount="indefinite" path="M0 3 C 35 3, 80 5, 160 4" />
161      </circle>
162    </svg>
163  </span>
164</a>
165
166    <!-- Links (desktop) -->
167    <div class="hidden lg:flex items-center gap-8 font-medium text-sm text-zinc-400">
168      <a href="index.php" class="hover:text-white transition-colors">Home</a>
169      <a href="features.php" class="hover:text-white transition-colors">Features</a>
170      <a href="how-it-works.php" class="hover:text-white transition-colors">How It Works</a>
171      <a href="pricing.php" class="hover:text-white transition-colors">Pricing</a>
172
173      <!-- Product dropdown — these pages get real but secondary traffic
174           (per GA4: online-taxi-booking 1.69%, dispatch-software 1.12%,
175           each well below pricing/registration/contact), so they're
176           grouped here instead of each claiming their own top-level
177           slot. -->
178      <div x-data="{ open: false }" @mouseleave="open = false" class="relative">
179        <button @click="open = !open" @mouseenter="open = true" class="flex items-center gap-1 hover:text-white transition-colors">
180          Product
181          <svg class="h-3.5 w-3.5 transition-transform" :class="open && 'rotate-180'" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"/></svg>
182        </button>
183        <div
184          x-show="open"
185          x-cloak
186          x-transition:enter="transition ease-out duration-150"
187          x-transition:enter-start="opacity-0 -translate-y-1"
188          x-transition:enter-end="opacity-100 translate-y-0"
189          class="absolute top-full left-1/2 -translate-x-1/2 pt-3 w-64"
190        >
191          <div class="rounded-xl border border-white/10 bg-ink-900/95 backdrop-blur-lg shadow-2xl p-2">
192            <a href="online-taxi-booking.php" class="block rounded-lg px-3.5 py-2.5 text-sm text-zinc-300 hover:text-white hover:bg-white/5 transition-colors">Online Booking</a>
193            <a href="dispatch-software-for-taxis.php" class="block rounded-lg px-3.5 py-2.5 text-sm text-zinc-300 hover:text-white hover:bg-white/5 transition-colors">Dispatch Software</a>
194            <a href="fare-calculator.php" class="block rounded-lg px-3.5 py-2.5 text-sm text-zinc-300 hover:text-white hover:bg-white/5 transition-colors">Fare Calculator</a>
195            <a href="private-hire-booking-software.php" class="block rounded-lg px-3.5 py-2.5 text-sm text-zinc-300 hover:text-white hover:bg-white/5 transition-colors">Private Hire (PHV)</a>
196
197            <!-- Nested submenu — Turnkey Websites has its own flyout for
198                 the 3 platform comparisons. Kept as a DOM descendant of
199                 the outer "Product" dropdown (not a sibling), so hovering
200                 into it never triggers the parent's @mouseleave — CSS
201                 hover/mouseleave treat descendants as still "inside" the
202                 ancestor regardless of this being position:absolute and
203                 rendering outside the ancestor's own box. A short close
204                 delay (not an instant mouseleave) forgives the diagonal
205                 mouse path from the label into the flyout. -->
206            <div
207              x-data="{ subOpen: false, closeTimer: null }"
208              @mouseenter="clearTimeout(closeTimer); subOpen = true"
209              @mouseleave="closeTimer = setTimeout(() => subOpen = false, 250)"
210              class="relative"
211            >
212              <a href="turnkey.php" class="flex items-center justify-between rounded-lg px-3.5 py-2.5 text-sm text-zinc-300 hover:text-white hover:bg-white/5 transition-colors">
213                Turnkey Websites
214                <svg class="h-3.5 w-3.5 -rotate-90 shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
214<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"/></svg>
215              </a>
216              <div
217                x-show="subOpen"
218                x-cloak
219                x-transition:enter="transition ease-out duration-150"
220                x-transition:enter-start="opacity-0 -translate-x-1"
221                x-transition:enter-end="opacity-100 translate-x-0"
222                class="absolute top-0 left-full pl-2 w-60"
223              >
224                <div class="rounded-xl border border-white/10 bg-ink-900/95 backdrop-blur-lg shadow-2xl p-2">
225                  <p class="px-3.5 pt-1.5 pb-1 font-mono text-[10px] uppercase tracking-widest text-zinc-600">Compare</p>
226                  <a href="compare-wordpress.php" class="block rounded-lg px-3.5 py-2.5 text-sm text-zinc-300 hover:text-white hover:bg-white/5 transition-colors">vs. WordPress</a>
227                  <a href="compare-wix.php" class="block rounded-lg px-3.5 py-2.5 text-sm text-zinc-300 hover:text-white hover:bg-white/5 transition-colors">vs. Wix</a>
228                  <a href="compare-squarespace.php" class="block rounded-lg px-3.5 py-2.5 text-sm text-zinc-300 hover:text-white hover:bg-white/5 transition-colors">vs. Squarespace</a>
229                </div>
230              </div>
231            </div>
232
233            <a href="https://demo.farebookings.com" class="block rounded-lg px-3.5 py-2.5 text-sm text-zinc-300 hover:text-white hover:bg-white/5 transition-colors">Live Demo</a>
234            <a href="clients.php" class="block rounded-lg px-3.5 py-2.5 text-sm text-zinc-300 hover:text-white hover:bg-white/5 transition-colors">Client Showcase</a>
235            <a href="we-develop-apps.php" class="block rounded-lg px-3.5 py-2.5 text-sm text-zinc-300 hover:text-white hover:bg-white/5 transition-colors">Apps (PWA)</a>
236            <a href="seo-growth-plan.php" class="block rounded-lg px-3.5 py-2.5 text-sm text-zinc-300 hover:text-white hover:bg-white/5 transition-colors">SEO Growth Plan</a>
237          </div>
238        </div>
239      </div>
240
241      <a href="integrations.php" class="hover:text-white transition-colors">Integrations</a>
242      <a href="faq.php" class="hover:text-white transition-colors">FAQ</a>
243      <a href="contact.php" class="hover:text-white transition-colors">Contact</a>
244    </div>
245
246    <!-- CTA (desktop) — was two buttons (See Demo + Start Free Trial),
247         collapsed into one now that get-started.php covers the whole
248         journey (demo, client showcase, trial, integrations, manual)
249         instead of just the two. -->
250    <div class="hidden lg:flex items-center gap-3">
251      <a href="get-started.php" class="text-sm font-semibold text-ink-950 bg-cyan-400 hover:bg-cyan-300 px-4 py-2.5 rounded-lg shadow-glow-cyan-sm transition-all hover:-translate-y-0.5">Get Started</a>
252    </div>
253
254    <!-- Mobile toggle -->
255    <button @click="mobileOpen = !mobileOpen" class="lg:hidden text-zinc-300 p-2" aria-label="Open menu">
256      <svg x-show="!mobileOpen" class="h-6 w-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
257        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.75" d="M4 6h16M4 12h16M4 18h16"/>
258      </svg>
259      <svg x-show="mobileOpen" x-cloak class="h-6 w-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
260        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.75" d="M6 18L18 6M6 6l12 12"/>
261      </svg>
262    </button>
263  </nav>
264
265  <!-- Mobile menu -->
266  <div
267    x-show="mobileOpen"
268    x-cloak
269    x-transition:enter="transition ease-out duration-200"
270    x-transition:enter-start="opacity-0 -translate-y-2"
271    x-transition:enter-end="opacity-100 translate-y-0"
272    @click.outside="mobileOpen = false"
273    class="lg:hidden bg-ink-950/95 backdrop-blur-lg border-b border-white/10 px-6 py-6 flex flex-col gap-5"
274  >
275    <a href="index.php" @click="mobileOpen=false" class="text-zinc-300 font-medium">Home</a>
276    <a href="features.php" @click="mobileOpen=false" class="text-zinc-300 font-medium">Features</a>
277    <a href="how-it-works.php" @click="mobileOpen=false" class="text-zinc-300 font-medium">How It Works</a>
278    <a href="pricing.php" @click="mobileOpen=false" class="text-zinc-300 font-medium">Pricing</a>
279
280    <div class="pt-1" x-data="{ turnkeySubOpen: false }">
281      <p class="text-xs font-mono uppercase tracking-widest text-zinc-600 mb-3">Product</p>
282      <div class="flex flex-col gap-4 pl-1">
283        <a href="online-taxi-booking.php" @click="mobileOpen=false" class="text-zinc-400 text-sm">Online Booking</a>
284        <a href="dispatch-software-for-taxis.php" @click="mobileOpen=false" class="text-zinc-400 text-sm">Dispatch Software</a>
285        <a href="fare-calculator.php" @click="mobileOpen=false" class="text-zinc-400 text-sm">Fare Calculator</a>
286        <a href="private-hire-booking-software.php" @click="mobileOpen=false" class="text-zinc-400 text-sm">Private Hire (PHV)</a>
287
288        <!-- Turnkey Websites — nested accordion for the 3 comparisons -->
289        <div>
290          <div class="flex items-center justify-between">
291            <a href="turnkey.php" @click="mobileOpen=false" class="text-zinc-400 text-sm">Turnkey Websites</a>
292            <button @click="turnkeySubOpen = !turnkeySubOpen" class="text-zinc-500 p-1" aria-label="Toggle comparisons">
293              <svg class="h-4 w-4 transition-transform" :class="turnkeySubOpen && 'rotate-180'" fill="none" stroke="currentColor" viewBox="0 0 24 24">
293<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"/></svg>
294            </button>
295          </div>
296          <div x-show="turnkeySubOpen" x-cloak x-transition class="flex flex-col gap-3 pl-3 mt-3 border-l border-white/10">
297            <a href="compare-wordpress.php" @click="mobileOpen=false" class="text-zinc-500 text-sm">vs. WordPress</a>
298            <a href="compare-wix.php" @click="mobileOpen=false" class="text-zinc-500 text-sm">vs. Wix</a>
299            <a href="compare-squarespace.php" @click="mobileOpen=false" class="text-zinc-500 text-sm">vs. Squarespace</a>
300          </div>
301        </div>
302
303        <a href="https://demo.farebookings.com" @click="mobileOpen=false" class="text-zinc-400 text-sm">Live Demo</a>
304        <a href="clients.php" @click="mobileOpen=false" class="text-zinc-400 text-sm">Client Showcase</a>
305        <a href="we-develop-apps.php" @click="mobileOpen=false" class="text-zinc-400 text-sm">Apps (PWA)</a>
306        <a href="seo-growth-plan.php" @click="mobileOpen=false" class="text-zinc-400 text-sm">SEO Growth Plan</a>
307      </div>
308    </div>
309
310    <a href="integrations.php" @click="mobileOpen=false" class="text-zinc-300 font-medium pt-1">Integrations</a>
311    <a href="faq.php" @click="mobileOpen=false" class="text-zinc-300 font-medium pt-1">FAQ</a>
312    <a href="contact.php" @click="mobileOpen=false" class="text-zinc-300 font-medium">Contact</a>
313    <div class="pt-4 border-t border-white/10">
314      <a href="get-started.php" @click="mobileOpen=false" class="block text-center text-sm font-semibold text-ink-950 bg-cyan-400 rounded-lg py-2.5">Get Started</a>
315    </div>
316  </div>
317</header>
318
319<!-- FAQPage JSON-LD — mirrors the 5 real questions/answers in the FAQ
320     section below word-for-word. Never let this drift out of sync
321     with the visible content (Google penalises schema that doesn't
322     match what's actually on the page). -->
323<script type="application/ld+json">
324{
325  "@context": "https://schema.org",
326  "@type": "FAQPage",
327  "mainEntity": [
328    {
329      "@type": "Question",
330      "name": "How long does implementation take?",
331      "acceptedAnswer": {
332        "@type": "Answer",
333        "text": "Most fleets are up and running in 5-7 working days, including rate setup, service zones and app publishing."
334      }
335    },
336    {
337      "@type": "Question",
338      "name": "Can I migrate data from my current system?",
339      "acceptedAnswer": {
340        "@type": "Answer",
341        "text": "Yes. Our team helps you import vehicles, drivers, rates and, where possible, your booking history."
342      }
343    },
344    {
345      "@type": "Question",
346      "name": "What do my drivers need to use the app?",
347      "acceptedAnswer": {
348        "@type": "Answer",
349        "text": "An Android or iOS smartphone with a data connection. The app can be downloaded from the official store or from a direct link you share."
350      }
351    },
352    {
353      "@type": "Question",
354      "name": "Does FareBookings charge commission on each trip?",
355      "acceptedAnswer": {
356        "@type": "Answer",
357        "text": "No. You only pay your plan fee. Payment gateways (Stripe, PayPal) apply their standard processing fees, but FareBookings never adds any extra commission per trip."
358      }
359    },
360    {
361      "@type": "Question",
362      "name": "Is there a minimum contract term?",
363      "acceptedAnswer": {
364        "@type": "Answer",
365        "text": "No lock-in. Plans are billed annually, whichever way you choose to view the price."
366      }
367    }
368  ]
369}
370</script>
370
371
372<main>
373
374  <!-- ================================================================
375       1. HERO
376       Signature element: live dispatch console. The moving dot lives
377       INSIDE the SVG and is animated with native <animateMotion> along
378       the exact same <path> used for the dashed line — both share one
379       coordinate system, so they always stay aligned even though the
380       SVG is stretched (preserveAspectRatio="none") to fill the card.
381  ================================================================= -->
382  <section class="relative pt-36 pb-24 lg:pt-48 lg:pb-32 px-6 lg:px-8 overflow-hidden bg-grid">
383    <div class="section-glow-1"></div>
384    <div class="section-glow-2"></div>
385    <div class="grid-highlight-1"></div>
386    <div class="grid-highlight-2"></div>
387    <div class="absolute top-0 left-1/2 -translate-x-1/2 w-[900px] h-[500px] bg-cyan-500/10 blur-[120px] rounded-full pointer-events-none"></div>
388
389    <div class="relative max-w-7xl mx-auto grid lg:grid-cols-2 gap-16 items-center">
390
391      <!-- Copy -->
392      <div>
393        <div class="reveal inline-flex items-center gap-2 rounded-full border border-cyan-400/25 bg-cyan-400/5 px-3.5 py-1.5 mb-6">
394          <span class="h-1.5 w-1.5 rounded-full bg-cyan-400 animate-pulse"></span>
395          <span class="font-mono text-xs tracking-widest text-cyan-300 uppercase">Dispatching since 2012 · 1,000+ active fleets</span>
396        </div>
397
398        <h1 class="reveal font-display text-4xl sm:text-5xl lg:text-[3.4rem] leading-[1.08] font-semibold text-white tracking-tight">
399          The real-time operations hub for your taxi fleet, <span class="gradient-text">always in sync</span>.
400        </h1>
401
402        <p class="reveal mt-6 text-lg text-zinc-400 leading-relaxed max-w-xl">
403          Dispatch and booking software that assigns trips, calculates fares and takes payment automatically. Native apps for drivers and passengers. All from a single control panel.
404        </p>
405
406        <div class="reveal mt-9 flex flex-col sm:flex-row gap-3.5">
407          <a href="https://demo.farebookings.com" class="group inline-flex items-center justify-center gap-2 rounded-lg bg-cyan-400 hover:bg-cyan-300 text-ink-950 font-semibold px-6 py-3.5 shadow-glow-cyan transition-all hover:-translate-y-0.5">
408            See Live Demo
409            <svg class="h-4 w-4 transition-transform group-hover:translate-x-1" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 8l4 4m0 0l-4 4m4-4H3"/></svg>
410          </a>
411          <a href="get-started.php" class="inline-flex items-center justify-center gap-2 rounded-lg border border-white/15 hover:border-white/30 hover:bg-white/5 text-white font-semibold px-6 py-3.5 transition-all">
412            Start Free 7-Day Trial
413          </a>
414        </div>
415
416        <p class="reveal mt-6 text-sm text-zinc-500 font-mono">$ no lock-in contracts · no credit card required</p>
417      </div>
418
419      <!-- Mockup: live dispatch console -->
420      <div
421        class="reveal relative pb-20"
422        x-data="{ fare: 12.40 }"
423        x-init="setInterval(() => { fare = fare + 0.10 <= 18.90 ? +(fare + 0.10).toFixed(2) : 12.40 }, 700)"
424      >
425        <div class="relative rounded-2xl border border-white/10 bg-ink-900/80 backdrop-blur-xl shadow-2xl overflow-hidden">
426
427          <!-- window chrome -->
428          <div class="flex items-center justify-between px-4 py-3 border-b border-white/10 bg-white/[0.02]">
429            <div class="flex items-center gap-1.5">
430              <span class="h-2.5 w-2.5 rounded-full bg-[#FF5F57]"></span>
431              <span class="h-2.5 w-2.5 rounded-full bg-[#FEBC2E]"></span>
432              <span class="h-2.5 w-2.5 rounded-full bg-[#28C840]"></span>
433            </div>
434            <div class="flex items-center gap-2">
435              <span class="h-1.5 w-1.5 rounded-full bg-emerald-400 animate-pulse"></span>
436              <span class="font-mono text-[11px] text-zinc-500 uppercase tracking-wider">Live dispatch</span>
437            </div>
438          </div>
439
440          <!-- route map — STEP 1: background locked to the image's exact
441               native aspect ratio (1833:858) via CSS aspect-ratio, NOT a
442               fixed height + object-cover. This means the full image is
443               ALWAYS visible, never cropped, and scales uniformly — so the
444               SVG viewBox="0 0 1833 858" below maps 1:1 to it at any
445               render width. No resizing/cropping step is applied yet;
446               that comes later, once this is confirmed correct. -->
447          <!-- route map, final approved version (was iterated + verified
448               in a standalone preview before landing here):
449               - 14 exact waypoints (user-measured, pixel-verified)
450               - ball itself bumps size at each waypoint (radius keyframes)
451               - 14 independent flash rings, each with its own rise/hold/
452                 fade — no more "wraps and cuts off the last one" bug
453               - whole cycle is JS-orchestrated: blurred -> focus in ->
454                 play the route once -> blur out -> pause -> repeat
455                 (see the cycle() function in footer.php)
456               - hand illustration was tried and then dropped per feedback -->
457          <div class="relative w-full border-b border-white/10 overflow-hidden" style="aspect-ratio: 1833 / 858;">
458            <img id="heroMapImg" src="assets/img/hero-map.webp" alt="" width="1833" height="858" fetchpriority="high" class="absolute inset-0 w-full h-full hero-map-blur">
459            <svg class="absolute inset-0 w-full h-full" viewBox="0 0 1833 858">
460              <circle r="0" opacity="0">
461                <animate id="heroTrigger" attributeName="opacity" begin="indefinite" dur="0.01s" values="0;0" fill="freeze"/>
462              </circle>
463              <circle cx="98" cy="476" r="0" fill="none" stroke="#8CE9FF" stroke-width="4" opacity="0">
464  <animate attributeName="r" begin="heroTrigger.begin" dur="8.400s" fill="freeze" calcMode="linear" keyTimes="0.0000;0.0060;0.0357;1.0000" values="0;26;0;0"/>
465  <animate attributeName="opacity" begin="heroTrigger.begin" dur="8.400s" fill="freeze" calcMode="linear" keyTimes="0.0000;0.0060;0.0357;1.0000" values="0;1;0;0"/>
466</circle>
467      <circle cx="190" cy="514" r="0" fill="none" stroke="#8CE9FF" stroke-width="2.5" opacity="0">
468  <animate attributeName="r" begin="heroTrigger.begin" dur="8.400s" fill="freeze" calcMode="linear" keyTimes="0.0000;0.0453;0.0561;0.0620;0.0918;
4681.0000" values="0;0;26;26;0;0"/>
469  <animate attributeName="opacity" begin="heroTrigger.begin" dur="8.400s" fill="freeze" calcMode="linear" keyTimes="0.0000;0.0453;0.0561;0.0620;0.0918;1.0000" values="0;0;1;1;0;0"/>
470</circle>
471      <circle cx="344" cy="508" r="0" fill="none" stroke="#8CE9FF" stroke-width="2.5" opacity="0">
472  <animate attributeName="r" begin="heroTrigger.begin" dur="8.400s" fill="freeze" calcMode="linear" keyTimes="0.0000;0.1321;0.1428;0.1488;0.1786;1.0000" values="0;0;26;26;0;0"/>
473  <animate attributeName="opacity" begin="heroTrigger.begin" dur="8.400s" fill="freeze" calcMode="linear" keyTimes="0.0000;0.1321;0.1428;0.1488;0.1786;1.0000" values="0;0;1;1;0;0"/>
474</circle>
475      <circle cx="473" cy="544" r="0" fill="none" stroke="#8CE9FF" stroke-width="2.5" opacity="0">
476  <animate attributeName="r" begin="heroTrigger.begin" dur="8.400s" fill="freeze" calcMode="linear" keyTimes="0.0000;0.2075;0.2183;0.2242;0.2540;1.0000" values="0;0;26;26;0;0"/>
477  <animate attributeName="opacity" begin="heroTrigger.begin" dur="8.400s" fill="freeze" calcMode="linear" keyTimes="0.0000;0.2075;0.2183;0.2242;0.2540;1.0000" values="0;0;1;1;0;0"/>
478</circle>
479      <circle cx="581" cy="523" r="0" fill="none" stroke="#8CE9FF" stroke-width="2.5" opacity="0">
480  <animate attributeName="r" begin="heroTrigger.begin" dur="8.400s" fill="freeze" calcMode="linear" keyTimes="0.0000;0.2695;0.2802;0.2862;0.3159;1.0000" values="0;0;26;26;0;0"/>
481  <animate attributeName="opacity" begin="heroTrigger.begin" dur="8.400s" fill="freeze" calcMode="linear" keyTimes="0.0000;0.2695;0.2802;0.2862;0.3159;1.0000" values="0;0;1;1;0;0"/>
482</circle>
483      <circle cx="663" cy="556" r="0" fill="none" stroke="#8CE9FF" stroke-width="2.5" opacity="0">
484  <animate attributeName="r" begin="heroTrigger.begin" dur="8.400s" fill="freeze" calcMode="linear" keyTimes="0.0000;0.3193;0.3300;0.3360;0.3657;1.0000" values="0;0;26;26;0;0"/>
485  <animate attributeName="opacity" begin="heroTrigger.begin" dur="8.400s" fill="freeze" calcMode="linear" keyTimes="0.0000;0.3193;0.3300;0.3360;0.3657;1.0000" values="0;0;1;1;0;0"/>
486</circle>
487      <circle cx="838" cy="534" r="0" fill="none" stroke="#8CE9FF" stroke-width="2.5" opacity="0">
488  <animate attributeName="r" begin="heroTrigger.begin" dur="8.400s" fill="freeze" calcMode="linear" keyTimes="0.0000;0.4186;0.4293;0.4353;0.4650;1.0000" values="0;0;26;26;0;0"/>
489  <animate attributeName="opacity" begin="heroTrigger.begin" dur="8.400s" fill="freeze" calcMode="linear" keyTimes="0.0000;0.4186;0.4293;0.4353;0.4650;1.0000" values="0;0;1;1;0;0"/>
490</circle>
491      <circle cx="950" cy="587" r="0" fill="none" stroke="#8CE9FF" stroke-width="2.5" opacity="0">
492  <animate attributeName="r" begin="heroTrigger.begin" dur="8.400s" fill="freeze" calcMode="linear" keyTimes="0.0000;0.4884;0.4991;0.5051;0.5348;1.0000" values="0;0;26;26;0;0"/>
493  <animate attributeName="opacity" begin="heroTrigger.begin" dur="8.400s" fill="freeze" calcMode="linear" keyTimes="0.0000;0.4884;0.4991;0.5051;0.5348;1.0000" values="0;0;1;1;0;0"/>
494</circle>
495      <circle cx="1124" cy="564" r="0" fill="none" stroke="#8CE9FF" stroke-width="2.5" opacity="0">
496  <animate attributeName="r" begin="heroTrigger.begin" dur="8.400s" fill="freeze" calcMode="linear" keyTimes="0.0000;0.5872;0.5979;0.6039;0.6337;1.0000" values="0;0;26;26;0;0"/>
497  <animate attributeName="opacity" begin="heroTrigger.begin" dur="8.400s" fill="freeze" calcMode="linear" keyTimes="0.0000;0.5872;0.5979;0.6039;0.6337;1.0000" values="0;0;1;1;0;0"/>
498</circle>
499      <circle cx="1191" cy="622" r="0" fill="none" stroke="#8CE9FF" stroke-width="2.5" opacity="0">
500  <animate attributeName="r" begin="heroTrigger.begin" dur="8.400s" fill="freeze" calcMode="linear" keyTimes="0.0000;0.6371;0.6478;0.6538;0.6836;1.0000" values="0;0;26;26;0;0"/>
501  <animate attributeName="opacity" begin="heroTrigger.begin" dur="8.400s" fill="freeze" calcMode="linear" keyTimes="0.0000;0.6371;0.6478;0.6538;0.6836;1.0000" values="0;0;1;1;0;0"/>
502</circle>
503      <circle cx="1358" cy="620" r="0" fill="none" stroke="#8CE9FF" stroke-width="2.5" opacity="0">
504  <animate attributeName="r" begin="heroTrigger.begin" dur="8.400s" fill="freeze" calcMode="linear" keyTimes="0.0000;0.7312;0.7419;0.7478;0.7776;1.0000" values="0;0;26;26;0;0"/>
505  <animate attributeName="opacity" begin="heroTrigger.begin" dur="8.400s" fill="freeze" calcMode="linear" keyTimes="0.0000;0.7312;0.7419;0.7478;0.7776;1.0000" values="0;0;1;1;0;0"/>
506</circle>
507      <circle cx="1411" cy="686" r="0" fill="none" stroke="#8CE9FF" stroke-width="2.5" opacity="0">
508  <animate attributeName="r" begin="heroTrigger.begin" dur="8.400s" fill="freeze" calcMode="linear" keyTimes="0.0000;0.7788;0.7896;0.7955;0.8253;1.0000" values="0;0;26;26;0;0"/>
509  <animate attributeName="opacity" begin="heroTrigger.begin" dur="8.400s" fill="freeze" calcMode="linear" keyTimes="0.0000;0.7788;0.7896;0.7955;0.8253;1.0000" values="0;0;1;1;0;0"/>
510</circle>
511      <circle cx="1581" cy="666" r="0" fill="none" stroke="#8CE9FF" stroke-width="2.5" opacity="0">
512  <animate attributeName="r" begin="heroTrigger.begin" dur="8.400s" fill="freeze" calcMode="linear" keyTimes="0.0000;0.8752;0.8860;0.8919;0.9217;1.0000" values="0;0;26;26;0;0"/>
513  <animate attributeName="opacity" begin="heroTrigger.begin" dur="8.400s" fill="freeze" calcMode="linear" keyTimes="0.0000;0.8752;0.8860;0.8919;0.9217;1.0000" values="0;0;1;1;0;0"/>
514</circle>
515      <circle cx="1698" cy="681" r="0" fill="none" stroke="#8CE9FF" stroke-width="4" opacity="0">
516  <animate attributeName="r" begin="heroTrigger.begin" dur="8.400s" fill="freeze" calcMode="linear" keyTimes="0.0000;0.9417;0.9524;0.9583;0.9881;1.0000" values="0;0;26;26;0;0"/>
517  <animate attributeName="opacity" begin="heroTrigger.begin" dur="8.400s" fill="freeze" calcMode="linear" keyTimes="0.0000;0.9417;0.9524;0.9583;0.9881;1.0000" values="0;0;1;1;0;0"/>
518</circle>
519              <circle r="10" fill="#e0f7fa" style="filter:drop-shadow(0 0 10px #22d3ee) drop-shadow(0 0 22px #22d3ee)">
520                <animate attributeName="r" begin="heroTrigger.begin" dur="8s" fill="freeze" keyTimes="0.0000;0.0112;0.0476;0.0589;0.0701;0.1387;0.1500;0.1612;0.2179;0.2292;0.2404;0.2830;0.2942;0.3055;0.3352;0.3465;0.3577;0.4395;0.4508;0.4620;0.5128;0.5241;0.5353;0.6166;0.6278;0.6391;0.6690;0.6802;0.6915;0.7677;0.7790;0.7902;0.8178;0.8290;0.8403;0.9190;0.9303;0.9415;0.9888;1.0000" values="18;10;10;18;10;10;18;10;10;18;10;10;18;10;10;18;10;10;18;10;10;18;10;10;18;10;10;18;10;10;18;10;10;18;10;10;18;10;10;18"/>
521                <animateMotion begin="heroTrigger.begin" dur="8s" fill="freeze" path="M98,476 L190,514 L344,508 L473,544 L581,523 L663,556 L838,534 L950,587 L1124,564 L1191,622 L1358,620 L1411,686 L1581,666 L1698,681"/>
522              </circle>
523            </svg>
524            <div class="absolute left-4 top-4 rounded-lg bg-ink-900/90 border border-white/10 px-3 py-2 backdrop-blur-sm">
525              <p class="font-mono text-[11px] text-zinc-500">DRIVER</p>
526              <p class="text-sm text-white font-medium">Ana G. · ETA 3 min</p>
527            </div>
528          </div>
529
530          <!-- current fare -->
531          <div class="flex items-center justify-between px-5 py-4">
532            <div>
533              <p class="font-mono text-[11px] text-zinc-500 uppercase tracking-wider">Current fare</p>
534              <p class="font-mono text-2xl text-white font-medium" x-text="'£' + fare.toFixed(2)"></p>
535            </div>
536            <span class="inline-flex items-center gap-1.5 rounded-full bg-emerald-400/10 border border-emerald-400/25 px-3 py-1.5 font-mono text-xs text-emerald-300">
537              Payment confirmed ✓
538            </span>
539          </div>
540        </div>
541
542        <!-- floating badge: sits in the pb-20 space reserved on the
543             wrapper above, so it never overlaps the fare/payment row -->
544        <div class="hidden sm:flex absolute -right-6 bottom-2 items-center gap-3 rounded-xl border border-white/10 bg-ink-900/90 backdrop-blur-xl px-4 py-3 shadow-2xl">
545          <span class="flex h-9 w-9 items-center justify-center rounded-lg bg-cyan-400/10 border border-cyan-400/25 shrink-0">
546            <svg class="h-4 w-4 text-cyan-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"/></svg>
547          </span>
548          <div>
549            <p class="text-xs text-zinc-500">New booking alert</p>
550            <p class="text-sm text-white font-medium">Sent to every driver</p>
551          </div>
552        </div>
553      </div>
554    </div>
555  </section>
556
557  <!-- ================================================================
558       2. TRUST BAR
559  ================================================================= -->
560  <section class="relative border-y border-white/10 bg-ink-900/40">
561    <div class="knight-scan-top"><span class="knight-scan-l"></span><span class="knight-scan-r"></span></div>
562    <div class="knight-scan-bottom"><span class="knight-scan-l"></span><span class="knight-scan-r"></span></div>
563    <div class="max-w-7xl mx-auto px-6 lg:px-8 py-8 grid grid-cols-2 lg:grid-cols-4 gap-8">
564      <div class="reveal text-center lg:text-left">
565        <p class="font-mono text-2xl sm:text-3xl text-white font-semibold">2012</p>
566        <p class="text-sm text-zinc-500 mt-1">Founded</p>
567      </div>
568      <div class="reveal text-center lg:text-left">
569        <p class="font-mono text-2xl sm:text-3xl text-white font-semibold"><span data-counter data-target="1000" data-format="comma">0</span>+</p>
570        <p class="text-sm text-zinc-500 mt-1">Active fleets</p>
571      </div>
572      <div class="reveal text-center lg:text-left">
573        <p class="font-mono text-2xl sm:text-3xl text-white font-semibold">iOS · Android</p>
574        <p class="text-sm text-zinc-500 mt-1">Native apps</p>
575      </div>
576      <div class="reveal text-center lg:text-left">
577        <p class="font-mono text-2xl sm:text-3xl text-white font-semibold">Direct</p>
578        <p class="text-sm text-zinc-500 mt-1">Phone, email &amp; WhatsApp support</p>
579      </div>
580    </div>
581  </section>
582
583  <!-- ================================================================
584       3. FEATURES
585  ================================================================= -->
586  <section id="features" class="py-24 lg:py-32 px-6 lg:px-8">
587    <div class="max-w-7xl mx-auto">
588      <div class="reveal max-w-2xl mb-16">
589        <span class="font-mono text-xs tracking-widest text-cyan-400 uppercase">// Features</span>
590        <h2 class="font-display text-3xl sm:text-4xl font-semibold text-white mt-3 tracking-tight">Everything a modern fleet needs, in one system.</h2>
591        <p class="mt-4 text-zinc-400 leading-relaxed">From the first booking to payment, FareBookings connects passengers, drivers and administrators in real time.</p>
592      </div>
593
594      <div class="grid sm:grid-cols-2 lg:grid-cols-3 gap-5">
595
596        <!-- Real-time dispatch -->
597        <div class="reveal group tilt-card rounded-2xl border border-white/10 bg-ink-900/40 backdrop-blur-xl p-6 hover:border-cyan-400/30 hover:bg-ink-900/70 transition-all duration-300">
598          <div class="tilt-shine"></div>
599          <div class="h-11 w-11 rounded-lg bg-cyan-400/10 border border-cyan-400/25 flex items-center justify-center mb-5 group-hover:shadow-glow-cyan-sm transition-shadow">
600            <svg class="h-5 w-5 text-cyan-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
600<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.75" d="M12 12a3 3 0 100-6 3 3 0 000 6z"/><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.75" d="M12 2v3m0 14v3M4.2 4.2l2.1 2.1m11.4 11.4l2.1 2.1M2 12h3m14 0h3M4.2 19.8l2.1-2.1m11.4-11.4l2.1-2.1"/></svg>
601          </div>
602          <h3 class="text-white font-semibold text-lg">Instant driver alerts</h3>
603          <p class="mt-2 text-sm text-zinc-400 leading-relaxed">Every driver gets a push notification the moment a booking lands. First to accept takes the job, with manual assignment and partner overflow as backup.</p>
604          <a href="dispatch-software-for-taxis.php" class="mt-4 inline-flex items-center gap-1 text-sm text-cyan-400 hover:text-cyan-300 font-medium">More info <span aria-hidden="true">→</span></a>
605        </div>
606
607        <!-- Native apps -->
608        <div class="reveal group tilt-card rounded-2xl border border-white/10 bg-ink-900/40 backdrop-blur-xl p-6 hover:border-cyan-400/30 hover:bg-ink-900/70 transition-all duration-300">
609          <div class="tilt-shine"></div>
610          <div class="h-11 w-11 rounded-lg bg-cyan-400/10 border border-cyan-400/25 flex items-center justify-center mb-5 group-hover:shadow-glow-cyan-sm transition-shadow">
611            <svg class="h-5 w-5 text-cyan-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"><rect x="7" y="2.5" width="10" height="19" rx="2" stroke-width="1.75"/><path stroke-linecap="round" stroke-width="1.75" d="M11 18h2"/></svg>
612          </div>
613          <h3 class="text-white font-semibold text-lg">Native Android &amp; iOS apps</h3>
614          <p class="mt-2 text-sm text-zinc-400 leading-relaxed">One app for your drivers, another for your passengers, branded as yours and published on both stores.</p>
615          <a href="we-develop-apps.php" class="mt-4 inline-flex items-center gap-1 text-sm text-cyan-400 hover:text-cyan-300 font-medium">More info <span aria-hidden="true">→</span></a>
616        </div>
617
618        <!-- Live fare calculator -->
619        <div class="reveal group tilt-card rounded-2xl border border-white/10 bg-ink-900/40 backdrop-blur-xl p-6 hover:border-cyan-400/30 hover:bg-ink-900/70 transition-all duration-300">
620          <div class="tilt-shine"></div>
621          <div class="h-11 w-11 rounded-lg bg-cyan-400/10 border border-cyan-400/25 flex items-center justify-center mb-5 group-hover:shadow-glow-cyan-sm transition-shadow">
622            <svg class="h-5 w-5 text-cyan-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"><rect x="5" y="2.5" width="14" height="19" rx="2" stroke-width="1.75"/><path stroke-linecap="round" stroke-width="1.75" d="M8 7h8M8 11h.01M12 11h.01M16 11h.01M8 15h.01M12 15h.01M16 15h.01"/></svg>
623          </div>
624          <h3 class="text-white font-semibold text-lg">Live fare calculator</h3>
625          <p class="mt-2 text-sm text-zinc-400 leading-relaxed">Automatically calculates price by distance, time and zone, using your own configured rates.</p>
626          <a href="features.php#pricing" class="mt-4 inline-flex items-center gap-1 text-sm text-cyan-400 hover:text-cyan-300 font-medium">More info <span aria-hidden="true">→</span></a>
627        </div>
628
629        <!-- Online payments -->
630        <div class="reveal group tilt-card rounded-2xl border border-white/10 bg-ink-900/40 backdrop-blur-xl p-6 hover:border-cyan-400/30 hover:bg-ink-900/70 transition-all duration-300">
631          <div class="tilt-shine"></div>
632          <div class="h-11 w-11 rounded-lg bg-cyan-400/10 border border-cyan-400/25 flex items-center justify-center mb-5 group-hover:shadow-glow-cyan-sm transition-shadow">
633            <svg class="h-5 w-5 text-cyan-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"><rect x="2.5" y="5" width="19" height="14" rx="2" stroke-width="1.75"/><path stroke-linecap="round" stroke-width="1.75" d="M2.5 9.5h19"/></svg>
634          </div>
635          <h3 class="text-white font-semibold text-lg">Integrated online payments</h3>
636          <p class="mt-2 text-sm text-zinc-400 leading-relaxed">Stripe, PayPal and other gateways connected natively. Automatic charge when each trip ends.</p>
637          <a href="features.php#payments" class="mt-4 inline-flex items-center gap-1 text-sm text-cyan-400 hover:text-cyan-300 font-medium">More info <span aria-hidden="true">→</span></a>
638        </div>
639
640        <!-- Admin dashboard -->
641        <div class="reveal group tilt-card rounded-2xl border border-white/10 bg-ink-900/40 backdrop-blur-xl p-6 hover:border-cyan-400/30 hover:bg-ink-900/70 transition-all duration-300">
642          <div class="tilt-shine"></div>
643          <div class="h-11 w-11 rounded-lg bg-cyan-400/10 border border-cyan-400/25 flex items-center justify-center mb-5 group-hover:shadow-glow-cyan-sm transition-shadow">
644            <svg class="h-5 w-5 text-cyan-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"><rect x="3" y="3.5" width="8" height="8" rx="1.5" stroke-width="1.75"/><rect x="13" y="3.5" width="8" height="5" rx="1.5" stroke-width="1.75"/><rect x="13" y="10.5" width="8" height="10" rx="1.5" stroke-width="1.75"/><rect x="3" y="13.5" width="8" height="7" rx="1.5" stroke-width="1.75"/></svg>
645          </div>
646          <h3 class="text-white font-semibold text-lg">Admin dashboard</h3>
647          <p class="mt-2 text-sm text-zinc-400 leading-relaxed">Full control of bookings, drivers and fleet from a dashboard built for daily operations.</p>
648          <a href="manual.php" class="mt-4 inline-flex items-center gap-1 text-sm text-cyan-400 hover:text-cyan-300 font-medium">See the admin manual <span aria-hidden="true">→</span></a>
649        </div>
650
651        <!-- Fleet management -->
652        <div class="reveal group tilt-card rounded-2xl border border-white/10 bg-ink-900/40 backdrop-blur-xl p-6 hover:border-cyan-400/30 hover:bg-ink-900/70 transition-all duration-300">
653          <div class="tilt-shine"></div>
654          <div class="h-11 w-11 rounded-lg bg-cyan-400/10 border border-cyan-400/25 flex items-center justify-center mb-5 group-hover:shadow-glow-cyan-sm transition-shadow">
655            <svg class="h-5 w-5 text-cyan-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
655<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.75" d="M3 13l1.5-5.5A2 2 0 016.4 6h11.2a2 2 0 011.9 1.5L21 13m-18 0v5a1 1 0 001 1h1a1 1 0 001-1v-1h12v1a1 1 0 001 1h1a1 1 0 001-1v-5m-18 0h18"/><circle cx="7" cy="16" r="1"/><circle cx="17" cy="16" r="1"/></svg>
656          </div>
657          <h3 class="text-white font-semibold text-lg">Fleet management</h3>
658          <p class="mt-2 text-sm text-zinc-400 leading-relaxed">Vehicles, shifts, service zones and driver documentation, all centralised.</p>
659          <a href="features.php#fleet" class="mt-4 inline-flex items-center gap-1 text-sm text-cyan-400 hover:text-cyan-300 font-medium">More info <span aria-hidden="true">→</span></a>
660        </div>
661
662      </div>
663    </div>
664  </section>
665
666  <!-- ================================================================
667       4. NEW, IMPROVED PLATFORM
668  ================================================================= -->
669  <section id="platform" class="relative py-24 lg:py-32 px-6 lg:px-8 bg-ink-900/30 border-y border-white/10">
670    <div class="knight-scan-top"><span class="knight-scan-l"></span><span class="knight-scan-r"></span></div>
671    <div class="knight-scan-bottom"><span class="knight-scan-l"></span><span class="knight-scan-r"></span></div>
672    <div class="max-w-7xl mx-auto grid lg:grid-cols-2 gap-16 items-center">
673
674      <!-- Dashboard mockup -->
675      <div class="reveal order-2 lg:order-1">
676        <div class="rounded-2xl border border-white/10 bg-ink-950 shadow-2xl overflow-hidden">
677          <div class="flex items-center gap-2 px-4 py-3 border-b border-white/10 bg-white/[0.02]">
678            <span class="h-2.5 w-2.5 rounded-full bg-[#FF5F57]"></span>
679            <span class="h-2.5 w-2.5 rounded-full bg-[#FEBC2E]"></span>
680            <span class="h-2.5 w-2.5 rounded-full bg-[#28C840]"></span>
681            <span class="ml-2 font-mono text-[11px] text-zinc-500">admin.farebookings.com</span>
682            <span class="ml-auto flex items-center gap-1.5">
683              <span class="h-1.5 w-1.5 rounded-full bg-emerald-400 animate-pulse"></span>
684              <span class="font-mono text-[10px] text-emerald-400 uppercase tracking-wider">Live</span>
685            </span>
686          </div>
687          <div class="p-5 grid grid-cols-3 gap-3">
688            <div class="col-span-2 rounded-lg border border-white/10 bg-ink-900/60 p-4">
689              <p class="font-mono text-[11px] text-zinc-500 uppercase">Trips today</p>
690              <p class="font-mono text-2xl text-white mt-1" data-counter data-target="1284" data-format="comma" data-live-tick>0</p>
691              <div class="flex items-end gap-1 h-16 mt-4" data-live-bars>
692                <div class="w-full bar-fill bg-cyan-400/20 rounded-t" style="--bar-target:40%; transition-delay:0ms"></div>
693                <div class="w-full bar-fill bg-cyan-400/30 rounded-t" style="--bar-target:65%; transition-delay:60ms"></div>
694                <div class="w-full bar-fill bg-cyan-400/50 rounded-t" style="--bar-target:45%; transition-delay:120ms"></div>
695                <div class="w-full bar-fill bg-cyan-400 rounded-t" style="--bar-target:85%; transition-delay:180ms"></div>
696                <div class="w-full bar-fill bg-cyan-400/40 rounded-t" style="--bar-target:55%; transition-delay:240ms"></div>
697                <div class="w-full bar-fill bg-cyan-400/60 rounded-t" style="--bar-target:70%; transition-delay:300ms"></div>
698              </div>
699            </div>
700            <div class="rounded-lg border border-white/10 bg-ink-900/60 p-4">
701              <p class="font-mono text-[11px] text-zinc-500 uppercase">Drivers</p>
702              <p class="font-mono text-2xl text-white mt-1" data-counter data-target="86">0</p>
703              <p class="text-xs text-emerald-400 mt-1 font-mono">↑ 12% active</p>
704            </div>
705            <div class="col-span-3 rounded-lg border border-white/10 bg-ink-900/60 p-4 flex items-center justify-between">
706              <div>
707                <p class="font-mono text-[11px] text-zinc-500 uppercase">Revenue this month</p>
708                <p class="font-mono text-xl text-white mt-1" data-counter data-target="48920" data-format="comma" data-prefix="£" data-live-tick>£0</p>
709              </div>
710              <span class="text-xs font-mono text-emerald-400 bg-emerald-400/10 border border-emerald-400/20 rounded-full px-2.5 py-1">+18.4%</span>
711            </div>
712          </div>
713        </div>
714      </div>
715
716      <!-- Copy -->
717      <div class="reveal order-1 lg:order-2">
718        <span class="inline-block font-mono text-xs tracking-widest text-cyan-400 uppercase border border-cyan-400/25 bg-cyan-400/5 rounded-full px-3 py-1.5 mb-5">2026 Update</span>
719        <h2 class="font-display text-3xl sm:text-4xl font-semibold text-white tracking-tight">A frontend and backend rebuilt from the ground up.</h2>
720        <p class="mt-4 text-zinc-400 leading-relaxed">We've completely redesigned the admin dashboard and the engine behind it, so your team works faster and your passengers wait less.</p>
721
722        <ul class="mt-8 space-y-5">
723          <li class="flex gap-3.5">
724            <svg class="h-5 w-5 text-cyan-400 shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>
725            <div>
726              <p class="text-white font-medium">Redesigned admin dashboard</p>
727              <p class="text-sm text-zinc-400 mt-0.5">A clearer interface for dispatch, bookings and fleet, built for daily use.</p>
728            </div>
729          </li>
730          <li class="flex gap-3.5">
731            <svg class="h-5 w-5 text-cyan-400 shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>
732            <div>
733              <p class="text-white font-medium">Real-time updates</p>
734              <p class="text-sm text-zinc-400 mt-0.5">Trip and driver status reflect instantly across the whole system.</p>
735            </div>
736          </li>
737          <li class="flex gap-3.5">
738            <svg class="h-5 w-5 text-cyan-400 shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>
739            <div>
740              <p class="text-white font-medium">Mobile-first design</p>
741              <p class="text-sm text-zinc-400 mt-0.5">Manage your fleet just as well from a phone as from a desktop.</p>
742            </div>
743          </li>
744          <li class="flex gap-3.5">
745            <svg class="h-5 w-5 text-cyan-400 shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>
746            <div>
747              <p class="text-white font-medium">Up to 3× faster</p>
748              <p class="text-sm text-zinc-400 mt-0.5">Load times cut down thanks to a backend optimised from the ground up.</p>
749            </div>
750          </li>
751        </ul>
752
753        <a href="manual.php" class="mt-8 inline-flex items-center gap-1.5 text-sm text-cyan-400 hover:text-cyan-300 font-medium">See how the admin panel works, tab by tab <span aria-hidden="true">→</span></a>
754      </div>
755    </div>
756  </section>
757
758  <!-- ================================================================
759       4.5 PWA APPS
760       Lottie animation (mobile_apps.lottie) rendered via
761       @lottiefiles/dotlottie-web into a <canvas>, loaded as an ES
762       module in footer.php. PWA-per-operator is still pending on the
763       backend (per project notes) — copy is deliberately phrased as
764       "on the new system" / future rollout, not "available today".
765  ================================================================= -->
766  <section id="pwa" class="py-24 lg:py-32 px-6 lg:px-8">
767    <div class="max-w-7xl mx-auto grid lg:grid-cols-2 gap-16 items-center">
768
769      <!-- Copy -->
770      <div class="reveal">
771        <span class="inline-block font-mono text-xs tracking-widest text-cyan-400 uppercase border border-cyan-400/25 bg-cyan-400/5 rounded-full px-3 py-1.5 mb-5">PWA Apps</span>
772        <h2 class="font-display text-3xl sm:text-4xl font-semibold text-white tracking-tight">Your own branded app, without the App Store headache.</h2>
773        <p class="mt-4 text-zinc-400 leading-relaxed">On the new system, every operator gets a Progressive Web App — installable straight from the browser, no Apple or Google approval needed to get it in your customers' hands.</p>
774
775        <ul class="mt-8 space-y-5">
776          <li class="flex gap-3.5">
777            <svg class="h-5 w-5 text-cyan-400 shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
777<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>
778            <div>
779              <p class="text-white font-medium">Set up in minutes</p>
780              <p class="text-sm text-zinc-400 mt-0.5">Turn it on from the new admin panel — no code, no store submission, no waiting on review.</p>
781            </div>
782          </li>
783          <li class="flex gap-3.5">
784            <svg class="h-5 w-5 text-cyan-400 shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>
785            <div>
786              <p class="text-white font-medium">Push notifications built in</p>
787              <p class="text-sm text-zinc-400 mt-0.5">Connects directly to OneSignal, so you can send coupons, discounts and event alerts straight to your customers' phones.</p>
788            </div>
789          </li>
790          <li class="flex gap-3.5">
791            <svg class="h-5 w-5 text-cyan-400 shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>
792            <div>
793              <p class="text-white font-medium">Close to zero maintenance</p>
794              <p class="text-sm text-zinc-400 mt-0.5">No $99/year Apple Developer fee, no Google Play fee, no re-submitting every update for review — it just works.</p>
795            </div>
796          </li>
797        </ul>
798
799        <a href="we-develop-apps.php" class="mt-8 inline-flex items-center gap-1.5 text-sm text-cyan-400 hover:text-cyan-300 font-medium">More on branded PWA apps <span aria-hidden="true">→</span></a>
800      </div>
801
802      <!-- Lottie showcase -->
803      <div class="reveal relative">
804        <div class="absolute inset-0 bg-cyan-500/10 blur-[100px] rounded-full pointer-events-none"></div>
805        <div class="relative rounded-2xl border border-white/10 bg-white/[0.02] backdrop-blur-xl shadow-2xl overflow-hidden p-8 sm:p-12">
806          <canvas id="pwaLottie" class="w-full h-auto block" style="aspect-ratio: 994 / 738;"></canvas>
807        </div>
808      </div>
809
810    </div>
811  </section>
812  <section id="how-it-works" class="py-24 lg:py-32 px-6 lg:px-8">
813    <div class="max-w-7xl mx-auto">
814      <div class="reveal max-w-2xl mb-20">
815        <span class="font-mono text-xs tracking-widest text-cyan-400 uppercase">// How it works</span>
816        <h2 class="font-display text-3xl sm:text-4xl font-semibold text-white mt-3 tracking-tight">From setup to first trip, in three stops.</h2>
817      </div>
818
819      <div class="relative grid md:grid-cols-3 gap-10 md:gap-6">
820        <div class="hidden md:block absolute top-6 left-[16.6%] right-[16.6%] h-px border-t border-dashed border-white/15"></div>
821
822        <div class="reveal relative">
823          <div class="h-12 w-12 rounded-full bg-ink-900 border border-cyan-400/30 flex items-center justify-center font-mono text-cyan-400 relative z-10">01</div>
824          <h3 class="text-white font-semibold text-lg mt-5">Set up your fleet</h3>
825          <p class="text-sm text-zinc-400 mt-2 leading-relaxed">Add vehicles, drivers, service zones and rates. Import your existing data in minutes.</p>
826        </div>
827
828        <div class="reveal relative">
829          <div class="h-12 w-12 rounded-full bg-ink-900 border border-cyan-400/30 flex items-center justify-center font-mono text-cyan-400 relative z-10">02</div>
830          <h3 class="text-white font-semibold text-lg mt-5">Customise your apps</h3>
831          <p class="text-sm text-zinc-400 mt-2 leading-relaxed">Brand your passenger and driver apps with your identity, your own rates and payment methods.</p>
832        </div>
833
834        <div class="reveal relative">
835          <div class="h-12 w-12 rounded-full bg-ink-900 border border-cyan-400/30 flex items-center justify-center font-mono text-cyan-400 relative z-10">03</div>
836          <h3 class="text-white font-semibold text-lg mt-5">Go live with dispatch</h3>
837          <p class="text-sm text-zinc-400 mt-2 leading-relaxed">Publish your apps, switch on real-time dispatch and start receiving and managing bookings.</p>
838        </div>
839      </div>
840      <p class="reveal text-center mt-14"><a href="how-it-works.php" class="text-sm text-cyan-400 hover:underline">Curious what happens once you're live? See the full booking flow →</a></p>
841    </div>
842  </section>
843
844  <!-- ================================================================
845       6. TESTIMONIALS
846  ================================================================= -->
847  <section class="relative py-24 lg:py-32 px-6 lg:px-8 bg-ink-900/30 border-y border-white/10">
848    <div class="knight-scan-top"><span class="knight-scan-l"></span><span class="knight-scan-r"></span></div>
849    <div class="knight-scan-bottom"><span class="knight-scan-l"></span><span class="knight-scan-r"></span></div>
850    <div class="max-w-7xl mx-auto">
851      <div class="reveal max-w-2xl mb-16">
852        <span class="font-mono text-xs tracking-widest text-cyan-400 uppercase">// Testimonials</span>
853        <h2 class="font-display text-3xl sm:text-4xl font-semibold text-white mt-3 tracking-tight">Fleets already running on FareBookings.</h2>
854      </div>
855
856      <div class="grid md:grid-cols-3 gap-5">
857
858        <div class="reveal tilt-card rounded-2xl border border-white/10 bg-ink-950/70 backdrop-blur-xl p-7 flex flex-col">
859          <div class="tilt-shine"></div>
860          <div class="text-cyan-400 text-sm tracking-wider mb-5">★★★★★</div>
861          <p class="text-zinc-300 leading-relaxed flex-1">"Every driver gets notified the second a booking comes in. No more radio calls, no more missed jobs."</p>
862          <div class="flex items-center gap-3 mt-6 pt-6 border-t border-white/10">
863            <div class="h-10 w-10 rounded-full bg-cyan-400/10 border border-cyan-400/25 flex items-center justify-center font-display text-cyan-400 font-semibold shrink-0">JM</div>
864            <div>
865              <p class="text-white text-sm font-medium">Javier Morales</p>
866              <p class="text-xs text-zinc-500">Operations Director, TaxiExpress Madrid</p>
867            </div>
868          </div>
869        </div>
870
871        <div class="reveal tilt-card rounded-2xl border border-white/10 bg-ink-950/70 backdrop-blur-xl p-7 flex flex-col">
872          <div class="tilt-shine"></div>
873          <div class="text-cyan-400 text-sm tracking-wider mb-5">★★★★★</div>
874          <p class="text-zinc-300 leading-relaxed flex-1">"The new dashboard is so much faster. We're handling twice the bookings with the same dispatch team."</p>
875          <div class="flex items-center gap-3 mt-6 pt-6 border-t border-white/10">
876            <div class="h-10 w-10 rounded-full bg-cyan-400/10 border border-cyan-400/25 flex items-center justify-center font-display text-cyan-400 font-semibold shrink-0">LF</div>
877            <div>
878              <p class="text-white text-sm font-medium">Laura Fernández</p>
879              <p class="text-xs text-zinc-500">Manager, RadioTaxi Valencia</p>
880            </div>
881          </div>
882        </div>
883
884        <div class="reveal tilt-card rounded-2xl border border-white/10 bg-ink-950/70 backdrop-blur-xl p-7 flex flex-col">
885          <div class="tilt-shine"></div>
886          <div class="text-cyan-400 text-sm tracking-wider mb-5">★★★★★</div>
887          <p class="text-zinc-300 leading-relaxed flex-1">"Online payments have all but eliminated billing issues. The driver app is very intuitive."</p>
888          <div class="flex items-center gap-3 mt-6 pt-6 border-t border-white/10">
889            <div class="h-10 w-10 rounded-full bg-cyan-400/10 border border-cyan-400/25 flex items-center justify-center font-display text-cyan-400 font-semibold shrink-0">MB</div>
890            <div>
891              <p class="text-white text-sm font-medium">Marco Bianchi</p>
892              <p class="text-xs text-zinc-500">Founder, CittàTaxi Milano</p>
893            </div>
894          </div>
895        </div>
896
897      </div>
898    </div>
899  </section>
900
901  <!-- ================================================================
902       7. PRICING
903       - view toggle: 'monthly' shows the annual price divided by 12,
904         'annual' shows the raw annual figure. Always billed annually —
905         the toggle only changes how the number is presented.
906       - currency dropdown converts every price from its GBP base using
907         open.er-api.com, with a hardcoded fallback if the API fails.
908         Prices are always derived from the original GBP figure, never
909         from an already-converted number, so repeated switching never
910         drifts from rounding errors.
911  ================================================================= -->
912  <section
913    id="pricing"
914    class="py-24 lg:py-32 px-6 lg:px-8"
915    x-data="{
916      view: 'annual',
917      currency: 'GBP',
918      currencyOpen: false,
919      rates: { GBP: 1 },
920      fallbackRates: { GBP: 1, EUR: 1.17, USD: 1.27, CHF: 1.12, AUD: 1.94 },
921      symbols: { GBP: '£', EUR: '€', USD: '$', CHF: 'Fr', AUD: 'A$' },
922      init() {
923        fetch('https://open.er-api.com/v6/latest/GBP')
924          .then(r => r.json())
925          .then(data => {
926            if (data && data.rates) {
927              this.rates = { GBP: 1, EUR: data.rates.EUR, USD: data.rates.USD, CHF: data.rates.CHF, AUD: data.rates.AUD };
928            } else {
929              this.rates = this.fallbackRates;
930            }
931          })
932          .catch(() => { this.rates = this.fallbackRates; });
933      },
934      price(baseAnnualGBP) {
935        const amount = this.view === 'monthly' ? baseAnnualGBP / 12 : baseAnnualGBP;
936        const converted = amount * (this.rates[this.currency] || 1
936);
937        return (this.symbols[this.currency] || this.currency) + Math.round(converted);
938      }
939    }"
940  >
941    <div class="max-w-7xl mx-auto">
942      <div class="reveal max-w-2xl mx-auto text-center mb-12">
943        <span class="font-mono text-xs tracking-widest text-cyan-400 uppercase">// Pricing</span>
944        <h2 class="font-display text-3xl sm:text-4xl font-semibold text-white mt-3 tracking-tight">A plan for every fleet size.</h2>
945        <p class="mt-4 text-zinc-400">No hidden per-trip commissions. Change plans whenever you like.</p>
946      </div>
947
948      <!-- View toggle (monthly / annual figure) + currency selector -->
949      <div class="reveal flex flex-col sm:flex-row items-center justify-center gap-6 sm:gap-8 mb-14">
950
951        <div class="flex items-center gap-3">
952          <span class="text-sm font-medium" :class="view === 'monthly' ? 'text-white' : 'text-zinc-500'">Monthly</span>
953          <button
954            @click="view = view === 'annual' ? 'monthly' : 'annual'"
955            type="button"
956            class="relative inline-flex h-7 w-14 shrink-0 items-center rounded-full border transition-colors"
957            :class="view === 'annual' ? 'bg-cyan-400/20 border-cyan-400/40' : 'bg-ink-800 border-white/10'"
958            aria-label="Toggle monthly or annual price view"
959          >
960            <span
961              class="absolute left-0.5 h-5 w-5 rounded-full bg-cyan-400 transition-transform duration-200"
962              :class="view === 'annual' ? 'translate-x-7' : 'translate-x-0'"
963            ></span>
964          </button>
965          <span class="text-sm font-medium" :class="view === 'annual' ? 'text-white' : 'text-zinc-500'">Annual</span>
966        </div>
967
968        <div class="hidden sm:block h-6 w-px bg-white/10"></div>
969
970        <!-- Currency dropdown -->
971        <div class="relative" @click.outside="currencyOpen = false">
972          <button
973            @click="currencyOpen = !currencyOpen"
974            type="button"
975            class="flex items-center gap-2 rounded-lg border border-white/10 bg-ink-900/60 px-3.5 py-2 text-sm font-medium text-zinc-300 hover:border-cyan-400/30 hover:text-white transition-colors"
976          >
977            <span>Select your currency:</span>
978            <span class="font-mono text-cyan-400" x-text="symbols[currency] + ' ' + currency"></span>
979            <svg class="h-3.5 w-3.5 text-zinc-500 transition-transform" :class="currencyOpen && 'rotate-180'" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"/></svg>
980          </button>
981          <div
982            x-show="currencyOpen"
983            x-cloak
984            x-transition
985            class="absolute left-1/2 -translate-x-1/2 sm:left-0 sm:translate-x-0 mt-2 w-44 rounded-lg border border-white/10 bg-ink-900 shadow-2xl overflow-hidden z-20"
986          >
987            <template x-for="code in Object.keys(symbols)" :key="code">
988              <button
989                @click="currency = code; currencyOpen = false"
990                type="button"
991                class="w-full flex items-center justify-between gap-2 px-4 py-2.5 text-sm text-left hover:bg-white/5 transition-colors"
992                :class="currency === code ? 'text-cyan-400' : 'text-zinc-300'"
993              >
994                <span class="font-mono" x-text="symbols[code] + ' ' + code"></span>
995                <svg x-show="currency === code" class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>
996              </button>
997            </template>
998          </div>
999        </div>
1000      </div>
1001
1002      <div class="grid lg:grid-cols-3 gap-6 items-start">
1003
1004        <!-- Basic -->
1005        <div class="reveal tilt-card rounded-2xl border border-white/10 bg-ink-900/40 backdrop-blur-xl p-8 flex flex-col h-full">
1006          <div class="tilt-shine"></div>
1007          <h3 class="text-white font-semibold text-lg">Basic</h3>
1008          <p class="text-sm text-zinc-500 mt-1">For fleets starting to go digital.</p>
1009          <div class="mt-6 flex items-baseline gap-1">
1010            <span class="font-mono text-4xl text-white font-semibold" x-text="price(149)"></span>
1011            <span class="text-zinc-500 text-sm" x-text="view === 'annual' ? '/yr' : '/mo'"></span>
1012          </div>
1013          <p class="text-xs text-zinc-500 mt-1 h-4">billed annually</p>
1014          <ul class="mt-6 space-y-3.5 text-sm text-zinc-400 flex-1">
1015            <li class="flex gap-2.5"><svg class="h-4 w-4 text-cyan-400 shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>Unlimited vehicles &amp; drivers</li>
1016            <li class="flex gap-2.5"><svg class="h-4 w-4 text-cyan-400 shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>Instant driver alerts</li>
1017            <li class="flex gap-2.5"><svg class="h-4 w-4 text-cyan-400 shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>Native driver app</li>
1018            <li class="flex gap-2.5"><svg class="h-4 w-4 text-cyan-400 shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>Fare calculator</li>
1019            <li class="flex gap-2.5"><svg class="h-4 w-4 text-cyan-400 shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>Self-setup, full manual + videos</li>
1020            <li class="flex gap-2.5"><svg class="h-4 w-4 text-cyan-400 shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>Email support</li>
1021          </ul>
1022          <a href="registration.php" class="mt-8 text-center rounded-lg border border-white/15 hover:border-white/30 hover:bg-white/5 text-white font-semibold py-3 transition-all">Start with Basic</a>
1023        </div>
1024
1025        <!-- Business (highlighted) -->
1026        <div class="reveal relative tilt-card rounded-2xl border border-cyan-400/40 bg-ink-900/80 backdrop-blur-xl p-8 flex flex-col h-full shadow-glow-cyan lg:-translate-y-3">
1027          <div class="tilt-shine"></div>
1028          <span class="absolute -top-3 left-1/2 -translate-x-1/2 rounded-full bg-cyan-400 text-ink-950 text-xs font-semibold px-3 py-1">Most popular</span>
1029          <h3 class="text-white font-semibold text-lg">Business</h3>
1030          <p class="text-sm text-zinc-500 mt-1">For fleets in active growth.</p>
1031          <div class="mt-6 flex items-baseline gap-1">
1032            <span class="font-mono text-4xl text-white font-semibold" x-text="price(199)"></span>
1033            <span class="text-zinc-500 text-sm" x-text="view === 'annual' ? '/yr' : '/mo'"></span>
1034          </div>
1035          <p class="text-xs text-zinc-500 mt-1 h-4">billed annually</p>
1036          <ul class="mt-6 space-y-3.5 text-sm text-zinc-300 flex-1">
1037            <li class="flex gap-2.5"><svg class="h-4 w-4 text-cyan-400 shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>Everything in Basic</li>
1038            <li class="flex gap-2.5"><svg class="h-4 w-4 text-cyan-400 shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>PWA app, activated for you</li>
1039            <li class="flex gap-2.5"><svg class="h-4 w-4 text-cyan-400 shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>Online payments (Stripe, PayPal &amp; more)</li>
1040            <li class="flex gap-2.5"><svg class="h-4 w-4 text-cyan-400 shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
1040<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>Live setup on a call — we configure it with you</li>
1041            <li class="flex gap-2.5"><svg class="h-4 w-4 text-cyan-400 shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>Premium WhatsApp support</li>
1042          </ul>
1043          <a href="registration.php" class="mt-8 text-center rounded-lg bg-cyan-400 hover:bg-cyan-300 text-ink-950 font-semibold py-3 transition-all">Start with Business</a>
1044        </div>
1045
1046        <!-- Corporate -->
1047        <div class="reveal tilt-card rounded-2xl border border-white/10 bg-ink-900/40 backdrop-blur-xl p-8 flex flex-col h-full">
1048          <div class="tilt-shine"></div>
1049          <h3 class="text-white font-semibold text-lg">Corporate</h3>
1050          <p class="text-sm text-zinc-500 mt-1">Need your own workflow, your own server.</p>
1051          <div class="mt-6 flex items-baseline gap-1">
1052            <span class="font-mono text-4xl text-white font-semibold">Custom</span>
1053          </div>
1054          <p class="text-xs text-zinc-500 mt-1 h-4">pricing based on volume</p>
1055          <ul class="mt-6 space-y-3.5 text-sm text-zinc-400 flex-1">
1056            <li class="flex gap-2.5"><svg class="h-4 w-4 text-cyan-400 shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>Everything in Business</li>
1057            <li class="flex gap-2.5"><svg class="h-4 w-4 text-cyan-400 shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>Independent, dedicated server</li>
1058            <li class="flex gap-2.5"><svg class="h-4 w-4 text-cyan-400 shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>Custom modifications for your workflow</li>
1059            <li class="flex gap-2.5"><svg class="h-4 w-4 text-cyan-400 shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>Direct with the dev team</li>
1060            <li class="flex gap-2.5"><svg class="h-4 w-4 text-cyan-400 shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>API &amp; integrations, quoted separately</li>
1061          </ul>
1062          <a href="contact.php" class="mt-8 text-center rounded-lg border border-white/15 hover:border-white/30 hover:bg-white/5 text-white font-semibold py-3 transition-all">Talk to Sales</a>
1063        </div>
1064
1065      </div>
1066
1067      <p class="reveal text-center text-xs text-zinc-600 font-mono mt-8">Prices shown in GBP by default · converted live, for reference only</p>
1068      <p class="reveal text-center mt-4"><a href="pricing.php" class="text-sm text-cyan-400 hover:underline">See the full plan comparison →</a></p>
1069    </div>
1070  </section>
1071
1072  <!-- ================================================================
1073       8. FAQ
1074  ================================================================= -->
1075  <section id="faq" class="relative py-24 lg:py-32 px-6 lg:px-8 bg-ink-900/30 border-y border-white/10">
1076    <div class="knight-scan-top"><span class="knight-scan-l"></span><span class="knight-scan-r"></span></div>
1077    <div class="knight-scan-bottom"><span class="knight-scan-l"></span><span class="knight-scan-r"></span></div>
1078    <div class="max-w-4xl mx-auto">
1079      <div class="reveal max-w-2xl mb-14">
1080        <span class="font-mono text-xs tracking-widest text-cyan-400 uppercase">// FAQ</span>
1081        <h2 class="font-display text-3xl sm:text-4xl font-semibold text-white mt-3 tracking-tight">Frequently asked questions</h2>
1082      </div>
1083
1084      <div class="space-y-3" x-data="{ open: 1 }">
1085
1086        <div class="reveal rounded-xl border border-white/10 bg-ink-950 overflow-hidden">
1087          <button @click="open = open === 1 ? null : 1" class="w-full flex items-center justify-between gap-4 px-6 py-5 text-left">
1088            <span class="text-white font-medium">How long does implementation take?</span>
1089            <svg class="h-5 w-5 text-cyan-400 shrink-0 transition-transform duration-300" :class="open === 1 && 'rotate-45'" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4"/></svg>
1090          </button>
1091          <div x-show="open === 1" x-transition class="px-6 pb-5 text-sm text-zinc-400 leading-relaxed">
1092            Most fleets are up and running in 5-7 working days, including rate setup, service zones and app publishing.
1093          </div>
1094        </div>
1095
1096        <div class="reveal rounded-xl border border-white/10 bg-ink-950 overflow-hidden">
1097          <button @click="open = open === 2 ? null : 2" class="w-full flex items-center justify-between gap-4 px-6 py-5 text-left">
1098            <span class="text-white font-medium">Can I migrate data from my current system?</span>
1099            <svg class="h-5 w-5 text-cyan-400 shrink-0 transition-transform duration-300" :class="open === 2 && 'rotate-45'" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4"/></svg>
1100          </button>
1101          <div x-show="open === 2" x-transition class="px-6 pb-5 text-sm text-zinc-400 leading-relaxed">
1102            Yes. Our team helps you import vehicles, drivers, rates and, where possible, your booking history.
1103          </div>
1104        </div>
1105
1106        <div class="reveal rounded-xl border border-white/10 bg-ink-950 overflow-hidden">
1107          <button @click="open = open === 3 ? null : 3" class="w-full flex items-center justify-between gap-4 px-6 py-5 text-left">
1108            <span class="text-white font-medium">What do my drivers need to use the app?</span>
1109            <svg class="h-5 w-5 text-cyan-400 shrink-0 transition-transform duration-300" :class="open === 3 && 'rotate-45'" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4"/></svg>
1110          </button>
1111          <div x-show="open === 3" x-transition class="px-6 pb-5 text-sm text-zinc-400 leading-relaxed">
1112            An Android or iOS smartphone with a data connection. The app can be downloaded from the official store or from a direct link y
1112ou share.
1113          </div>
1114        </div>
1115
1116        <div class="reveal rounded-xl border border-white/10 bg-ink-950 overflow-hidden">
1117          <button @click="open = open === 4 ? null : 4" class="w-full flex items-center justify-between gap-4 px-6 py-5 text-left">
1118            <span class="text-white font-medium">Does FareBookings charge commission on each trip?</span>
1119            <svg class="h-5 w-5 text-cyan-400 shrink-0 transition-transform duration-300" :class="open === 4 && 'rotate-45'" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4"/></svg>
1120          </button>
1121          <div x-show="open === 4" x-transition class="px-6 pb-5 text-sm text-zinc-400 leading-relaxed">
1122            No. You only pay your plan fee. Payment gateways (Stripe, PayPal) apply their standard processing fees, but FareBookings never adds any extra commission per trip.
1123          </div>
1124        </div>
1125
1126        <div class="reveal rounded-xl border border-white/10 bg-ink-950 overflow-hidden">
1127          <button @click="open = open === 5 ? null : 5" class="w-full flex items-center justify-between gap-4 px-6 py-5 text-left">
1128            <span class="text-white font-medium">Is there a minimum contract term?</span>
1129            <svg class="h-5 w-5 text-cyan-400 shrink-0 transition-transform duration-300" :class="open === 5 && 'rotate-45'" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4"/></svg>
1130          </button>
1131          <div x-show="open === 5" x-transition class="px-6 pb-5 text-sm text-zinc-400 leading-relaxed">
1132            No lock-in. Plans are billed annually — use the toggle above to view the price as a monthly or annual figure, whichever is easier to plan around.
1133          </div>
1134        </div>
1135
1136      </div>
1137      <p class="reveal text-center mt-8"><a href="faq.php" class="text-sm text-cyan-400 hover:underline">See all questions →</a></p>
1138    </div>
1139  </section>
1140
1141  <!-- ================================================================
1142       9. FINAL CTA
1143  ================================================================= -->
1144  <section id="demo" class="relative py-28 lg:py-36 px-6 lg:px-8 overflow-hidden bg-grid">
1145    <div class="section-glow-1"></div>
1146    <div class="section-glow-2"></div>
1147    <div class="grid-highlight-1"></div>
1148    <div class="grid-highlight-2"></div>
1149    <div class="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[700px] h-[400px] bg-cyan-500/15 blur-[130px] rounded-full pointer-events-none"></div>
1150    <div class="reveal relative max-w-3xl mx-auto text-center">
1151      <h2 class="font-display text-3xl sm:text-4xl lg:text-5xl font-semibold text-white tracking-tight">Put your fleet into <span class="gradient-text">dispatch mode</span> today.</h2>
1152      <p class="mt-5 text-lg text-zinc-400 max-w-xl mx-auto">Try FareBookings free for 7 days. No credit card, no lock-in.</p>
1153      <div class="mt-10 flex flex-col sm:flex-row gap-3.5 justify-center">
1154        <a href="registration.php" aria-label="Start your free FareBookings trial" class="inline-flex items-center justify-center gap-2 rounded-lg bg-cyan-400 hover:bg-cyan-300 text-ink-950 font-semibold px-7 py-4 shadow-glow-cyan transition-all hover:-translate-y-0.5">Start Free Trial</a>
1155        <a href="contact.php" aria-label="Book a live demo of FareBookings" class="inline-flex items-center justify-center gap-2 rounded-lg border border-white/15 hover:border-white/30 hover:bg-white/5 text-white font-semibold px-7 py-4 transition-all">Book a Demo</a>
1156      </div>
1157      <p class="mt-6 text-sm text-zinc-500 font-mono">Trusted by 1,000+ taxi and VTC fleets worldwide</p>
1158    </div>
1159  </section>
1160
1161</main>
1162
1163<!-- Site-wide WhatsApp button: fixed bottom-right, on every page since
1164     this lives in the shared footer include. Standard green + the
1165     recognisable WhatsApp glyph on purpose — people spot this shape
1166     instantly, more than a prettier custom icon would. Swap the
1167     wa.me number below for the real one before this goes live. -->
1168<a
1169  href="https://wa.me/447480051101"
1170  target="_blank"
1171  rel="noopener"
1172  aria-label="Chat with us on WhatsApp"
1173  class="fixed bottom-6 right-6 z-40 flex h-14 w-14 items-center justify-center rounded-full bg-[#25D366] shadow-2xl hover:scale-105 transition-transform"
1174>
1175  <svg viewBox="0 0 32 32" class="h-8 w-8" fill="#ffffff"><path d="M16.004 3C9.377 3 4 8.373 4 15c0 2.386.703 4.605 1.912 6.468L4 29l7.72-1.87A11.94 11.94 0 0016.004 27C22.63 27 28 21.627 28 15S22.63 3 16.004 3zm0 21.818c-1.99 0-3.845-.58-5.407-1.579l-.388-.243-4.583 1.11 1.127-4.464-.253-.402A9.77 9.77 0 016.182 15c0-5.415 4.407-9.818 9.822-9.818 5.415 0 9.818 4.403 9.818 9.818 0 5.415-4.403 9.818-9.818 9.818zm5.383-7.352c-.294-.147-1.741-.86-2.011-.958-.27-.098-.467-.147-.663.147-.196.294-.76.958-.932 1.155-.172.196-.343.22-.637.073-.294-.147-1.242-.458-2.365-1.46-.874-.78-1.464-1.744-1.636-2.038-.172-.294-.018-.453.129-.6.133-.132.294-.343.441-.515.147-.172.196-.294.294-.49.098-.196.049-.368-.024-.515-.073-.147-.663-1.598-.909-2.188-.24-.575-.483-.497-.663-.507l-.564-.01c-.196 0-.515.073-.784.368-.27.294-1.03 1.007-1.03 2.456 0 1.45 1.055 2.85 1.203 3.046.147.196 2.077 3.172 5.032 4.448.703.303 1.251.484 1.679.62.706.224 1.348.192 1.856.117.566-.085 1.741-.712 1.987-1.4.245-.688.245-1.278.172-1.4-.073-.122-.27-.196-.564-.343z"/></svg>
1176</a>
1177
1178<div
1179  id="cookie-banner"
1180  x-data="{
1181    show: false,
1182    panelOpen: false,
1183    analytics: false,
1184    marketing: false,
1185    init() {
1186      const saved = localStorage.getItem('fb_consent');
1187      if (!saved) {
1188        this.show = true;
1189      } else {
1190        const c = JSON.parse(saved);
1191        // false = restoring an existing choice, not a fresh decision.
1192        // header.php already reads this same saved value before GA4's
1193        // first hit fires, so no manual page_view is needed here.
1194        this.applyConsent(c.analytics, c.marketing, false);
1195      }
1196    },
1197    applyConsent(analytics, marketing, isFreshChoice = true) {
1198      localStorage.setItem('fb_consent', JSON.stringify({ necessary: true, analytics, marketing }));
1199      if (window.gtag) {
1200        gtag('consent', 'update', {
1201          analytics_storage: analytics ? 'granted' : 'denied',
1202          ad_storage: marketing ? 'granted' : 'denied',
1203          ad_user_data: marketing ? 'granted' : 'denied',
1204          ad_personalization: marketing ? 'granted' : 'denied',
1205        });
1206        // A consent 'update' does not retroactively resend the hit GA4
1207        // already sent under 'denied' when the page first loaded — so
1208        // on a genuinely fresh Accept, this page's own view would
1209        // otherwise never get counted. Fire it explicitly.
1210        if (analytics && isFreshChoice) {
1211          gtag('event', 'page_view');
1212        }
1213      }
1214      this.show = false;
1215      this.panelOpen = false;
1216    },
1217    acceptAll() { this.applyConsent(true, true); },
1218    rejectAll() { this.applyConsent(false, false); },
1219    saveChoices() { this.applyConsent(this.analytics, this.marketing); }
1220  }"
1221  x-show="show"
1222  x-cloak
1223  x-transition:enter="transition ease-out duration-300"
1224  x-transition:enter-start="opacity-0 translate-y-4"
1225  x-transition:enter-end="opacity-100 translate-y-0"
1226  class="fixed inset-x-0 bottom-0 z-[60] p-4 sm:p-6"
1227>
1228  <div class="max-w-3xl mx-auto rounded-2xl border border-white/10 bg-ink-950/95 backdrop-blur-xl shadow-2xl p-6">
1229
1230    <!-- Simple view -->
1231    <div x-show="!panelOpen">
1232      <p class="text-sm text-zinc-300 leading-relaxed">
1233        We use cookies that are strictly necessary for the site to work, and — only with your permission — cookies for analytics and marketing. See our
1234        <a href="privacy.php" class="text-cyan-400 hover:underline">Privacy Policy</a> for details.
1235      </p>
1236      <div class="flex flex-wrap gap-3 mt-4">
1237        <button @click="acceptAll()" class="rounded-lg bg-cyan-400 hover:bg-cyan-300 text-ink-950 font-semibold text-sm px-5 py-2.5 transition-colors">Accept all</button>
1238        <button @click="rejectAll()" class="rounded-lg border border-white/15 hover:border-white/30 text-white text-sm font-medium px-5 py-2.5 transition-colors">Reject non-essential</button>
1239        <button @click="panelOpen = true" class="rounded-lg text-zinc-400 hover:text-white text-sm font-medium px-5 py-2.5 transition-colors">Customize</button>
1240      </div>
1241    </div>
1242
1243    <!-- Customize view -->
1244    <div x-show="panelOpen" x-cloak>
1245      <p class="text-sm text-white font-medium mb-4">Cookie preferences</p>
1246
1247      <div class="space-y-3">
1248        <div class="flex items-center justify-between rounded-lg border border-white/10 bg-ink-900/60 px-4 py-3">
1249          <div>
1250            <p class="text-sm text-white">Necessary</p>
1251            <p class="text-xs text-zinc-500">Always on — required for the site to function.</p>
1252          </div>
1253          <span class="text-xs font-mono text-zinc-500">Always active</span>
1254        </div>
1255        <div class="flex items-center justify-between rounded-lg border border-white/10 bg-ink-900/60 px-4 py-3">
1256          <div>
1257            <p class="text-sm text-white">Analytics</p>
1258            <p class="text-xs text-zinc-500">Helps us understand how the site is used.</p>
1259          </div>
1260          <button @click="analytics = !analytics" :aria-pressed="analytics.toString()" aria-label="Toggle analytics cookies" :class="analytics ? 'bg-cyan-400' : 'bg-ink-700'" class="relative h-6 w-11 rounded-full transition-colors">
1261            <span :class="analytics ? 'translate-x-5' : 'translate-x-0.5'" class="absolute top-0.5 h-5 w-5 rounded-full bg-white transition-transform"></span>
1262          </button>
1263        </div>
1264        <div class="flex items-center justify-between rounded-lg border border-white/10 bg-ink-900/60 px-4 py-3">
1265          <div>
1266            <p class="text-sm text-white">Marketing</p>
1267            <p class="text-xs text-zinc-500">Used to measure ad campaign performance.</p>
1268          </div>
1269          <button @click="marketing = !marketing" :aria-pressed="marketing.toString()" aria-label="Toggle marketing cookies" :class="marketing ? 'bg-cyan-400' : 'bg-ink-
1269700'" class="relative h-6 w-11 rounded-full transition-colors">
1270            <span :class="marketing ? 'translate-x-5' : 'translate-x-0.5'" class="absolute top-0.5 h-5 w-5 rounded-full bg-white transition-transform"></span>
1271          </button>
1272        </div>
1273      </div>
1274
1275      <div class="flex flex-wrap gap-3 mt-5">
1276        <button @click="saveChoices()" class="rounded-lg bg-cyan-400 hover:bg-cyan-300 text-ink-950 font-semibold text-sm px-5 py-2.5 transition-colors">Save preferences</button>
1277        <button @click="panelOpen = false" class="rounded-lg text-zinc-400 hover:text-white text-sm font-medium px-5 py-2.5 transition-colors">Back</button>
1278      </div>
1279    </div>
1280
1281  </div>
1282</div>
1283
1284<footer class="relative border-t border-white/10 bg-ink-950 pt-16 pb-8 px-6 lg:px-8">
1285  <div class="max-w-7xl mx-auto">
1286    <div class="grid sm:grid-cols-2 lg:grid-cols-6 gap-10 pb-12">
1287
1288      <!-- Brand -->
1289      <div class="lg:col-span-2">
1290        <a href="index.php" class="fb-logo fb-md shrink-0">
1291  <svg class="fb-pin" viewBox="4 2 24 32">
1292    <g class="fb-pin-group">
1293      <path class="fb-pin-shape" d="M16 4 C 10.5 4, 6 8.5, 6 14 C 6 21.5, 16 32, 16 32 S 26 21.5, 26 14 C 26 8.5, 21.5 4, 16 4 Z" />
1294      <circle cx="16" cy="14" r="4.6" fill="#08080a" />
1295    </g>
1296  </svg>
1297  <span class="fb-wordblock">
1298    <span class="fb-wordmark">Fare<span class="fb-light">Bookings</span></span>
1299    <svg class="fb-route-svg" viewBox="0 0 160 8" preserveAspectRatio="none">
1300      <path class="fb-route" d="M0 3 C 35 3, 80 5, 160 4" />
1301      <circle class="fb-travel-dot" r="1.5">
1302        <animateMotion dur="2.6s" repeatCount="indefinite" path="M0 3 C 35 3, 80 5, 160 4" />
1303      </circle>
1304    </svg>
1305  </span>
1306</a>
1307        <p class="mt-4 text-sm text-zinc-500 leading-relaxed max-w-xs">
1308          Dispatch and booking software for taxi and VTC fleets. Running since 2012.
1309        </p>
1310        <p class="mt-3 text-sm text-zinc-500 leading-relaxed max-w-xs">
1311          2 Gordon View, Leeds, West Yorkshire, LS6 4FB
1312        </p>
1313        <div class="flex items-center gap-3 mt-6">
1314          <a href="#" aria-label="LinkedIn" class="h-9 w-9 rounded-lg border border-white/10 flex items-center justify-center text-zinc-500 hover:text-cyan-400 hover:border-cyan-400/30 transition-colors">
1315            <svg class="h-4 w-4" fill="currentColor" viewBox="0 0 24 24"><path d="M4.98 3.5a2.5 2.5 0 11-.02 5.01A2.5 2.5 0 014.98 3.5zM3 9h4v12H3V9zm7 0h3.8v1.7h.05c.53-.98 1.83-2 3.76-2 4.02 0 4.76 2.5 4.76 5.75V21h-4v-5.6c0-1.34-.03-3.06-1.9-3.06-1.9 0-2.19 1.44-2.19 2.96V21h-4V9z"/></svg>
1316          </a>
1317          <a href="#" aria-label="X" class="h-9 w-9 rounded-lg border border-white/10 flex items-center justify-center text-zinc-500 hover:text-cyan-400 hover:border-cyan-400/30 transition-colors">
1318            <svg class="h-4 w-4" fill="currentColor" viewBox="0 0 24 24"><path d="M18.9 3H22l-7.6 8.66L23 21h-6.8l-5.3-6.7L4.8 21H1.7l8.1-9.26L1 3h7l4.8 6.1L18.9 3zm-1.2 16h1.9L7.4 5H5.4l12.3 14z"/></svg>
1319          </a>
1320        </div>
1321      </div>
1322
1323      <!-- Product -->
1324      <div>
1325        <p class="font-mono text-xs uppercase tracking-widest text-zinc-500 mb-4">Product</p>
1326        <ul class="space-y-3 text-sm">
1327          <li><a href="features.php" class="text-zinc-400 hover:text-white transition-colors">Features</a></li>
1328          <li><a href="how-it-works.php" class="text-zinc-400 hover:text-white transition-colors">How It Works</a></li>
1329          <li><a href="pricing.php" class="text-zinc-400 hover:text-white transition-colors">Pricing</a></li>
1330          <li><a href="online-taxi-booking.php" class="text-zinc-400 hover:text-white transition-colors">Online Booking</a></li>
1331          <li><a href="dispatch-software-for-taxis.php" class="text-zinc-400 hover:text-white transition-colors">Dispatch Software</a></li>
1332          <li><a href="fare-calculator.php" class="text-zinc-400 hover:text-white transition-colors">Fare Calculator</a></li>
1333          <li><a href="private-hire-booking-software.php" class="text-zinc-400 hover:text-white transition-colors">Private Hire (PHV)</a></li>
1334          <li><a href="integrations.php" class="text-zinc-400 hover:text-white transition-colors">Integrations</a></li>
1335          <li><a href="manual.php" class="text-zinc-400 hover:text-white transition-colors">Admin Manual</a></li>
1336        </ul>
1337      </div>
1338
1339      <!-- Services -->
1340      <div>
1341        <p class="font-mono text-xs uppercase tracking-widest text-zinc-500 mb-4">Services</p>
1342        <ul class="space-y-3 text-sm">
1343          <li><a href="turnkey.php" class="text-zinc-400 hover:text-white transition-colors">Turnkey Websites</a></li>
1344          <li><a href="hosting.php" class="text-zinc-400 hover:text-white transition-colors">Hosting</a></li>
1345          <li><a href="website-brief.php" class="text-zinc-400 hover:text-white transition-colors">Website Brief Form</a></li>
1346          <li><a href="we-develop-apps.php" class="text-zinc-400 hover:text-white transition-colors">Apps (PWA)</a></li>
1347          <li><a href="seo-growth-plan.php" class="text-zinc-400 hover:text-white transition-colors">SEO Growth Plan</a></li>
1348          <li><a href="faq.php" class="text-zinc-400 hover:text-white transition-colors">FAQ</a></li>
1349          <li><a href="comparisons.php" class="text-zinc-400 hover:text-white transition-colors">Comparisons</a></li>
1350        </ul>
1351      </div>
1352
1353      <!-- Get Started -->
1354      <div>
1355        <p class="font-mono text-xs uppercase tracking-widest text-zinc-500 mb-4">Get Started</p>
1356        <ul class="space-y-3 text-sm">
1357          <li><a href="get-started.php" class="text-cyan-400 hover:text-cyan-300 transition-colors font-medium">See all options →</a></li>
1358          <li><a href="https://demo.farebookings.com" class="text-zinc-400 hover:text-white transition-colors">Live Demo</a></li>
1359          <li><a href="registration.php" class="text-zinc-400 hover:text-white transition-colors">Start Free Trial</a></li>
1360          <li><a href="clients.php" class="text-zinc-400 hover:text-white transition-colors">Client Showcase</a></li>
1361          <li><a href="website-brief.php" class="text-zinc-400 hover:text-white transition-colors">Website Brief Form</a></li>
1362        </ul>
1363      </div>
1364
1365      <!-- Company -->
1366      <div>
1367        <p class="font-mono text-xs uppercase tracking-widest text-zinc-500 mb-4">Company</p>
1368        <ul class="space-y-3 text-sm">
1369          <li><a href="contact.php" class="text-zinc-400 hover:text-white transition-colors">Contact</a></li>
1370        </ul>
1371
1372        <p class="font-mono text-xs uppercase tracking-widest text-zinc-500 mt-8 mb-4">Legal</p>
1373        <ul class="space-y-3 text-sm">
1374          <li><a href="privacy.php" class="text-zinc-400 hover:text-white transition-colors">Privacy</a></li>
1375          <li><a href="terms.php" class="text-zinc-400 hover:text-white transition-colors">Terms</a></li>
1376          <li><a href="privacy.php#8-your-rights" class="text-zinc-400 hover:text-white transition-colors">GDPR / Your Rights</a></li>
1377          <li><a href="data-safety-form.php" class="text-zinc-400 hover:text-white transition-colors">Delete My Data</a></li>
1378        </ul>
1379      </div>
1380    </div>
1381
1382    <div class="pt-8 border-t border-white/10 flex flex-col sm:flex-row items-center justify-between gap-4">
1383      <p class="text-xs text-zinc-600">© 2026 FareBookings. All rights reserved.</p>
1384      <div class="flex items-center gap-5">
1385        <a href="terms.php" class="text-xs text-zinc-600 hover:text-zinc-400 transition-colors">Terms &amp; Conditions</a>
1386        <a href="privacy.php" class="text-xs text-zinc-600 hover:text-zinc-400 transition-colors">Privacy Policy</a>
1387        <a href="site-map.php" class="text-xs text-zinc-600 hover:text-zinc-400 transition-colors">Site Map</a>
1388      </div>
1389      <p class="text-xs text-zinc-600 font-mono">Dispatch software for taxi and VTC fleets since 2012</p>
1390    </div>
1391  </div>
1392</footer>
1393
1394<script type="a9f260de584e6f830f646f33-text/javascript">
1395  // Scroll-reveal: adds .in-view to .reveal elements as they enter the viewport
1396  const revealObserver = new IntersectionObserver((entries) => {
1397    entries.forEach((entry) => {
1398      if (entry.isIntersecting) {
1399        entry.target.classList.add('in-view');
1400        revealObserver.unobserve(entry.target);
1401      }
1402    });
1403  }, { threshold: 0.15, rootMargin: '0px 0px -60px 0px' });
1404
1405  document.querySelectorAll('.reveal').forEach((el) => revealObserver.observe(el));
1406
1407  // Conversion event tracking — WhatsApp and phone clicks, sitewide.
1408  // Event delegation on a single document-level listener catches
1409  // every wa.me/tel: link across the whole site (there are 10+ pages
1410  // with a WhatsApp link), including any added later, without
1411  // needing to touch each page individually. gtag() itself already
1412  // respects Consent Mode — this is a no-op if analytics_storage is
1413  // still denied, so no extra consent check needed here.
1414  document.addEventListener('click', (e) => {
1415    const link = e.target.closest('a[href]');
1416    if (!link) return;
1417    const href = link.getAttribute('href');
1418    if (href.startsWith('https://wa.me/')) {
1419      if (window.gtag) gtag('event', 'whatsapp_click', { link_url: href, page_path: window.location.pathname });
1420    } else if (href.startsWith('tel:')) {
1421      if (window.gtag) gtag('event', 'phone_click', { link_url: href, page_path: window.location.pathname });
1422    }
1423  });
1424
1425  // Registration — the actual form lives in a cross-origin iframe
1426  // (app.farebookings.com/registration2026/), so this page has no
1427  // visibility into what happens inside it; a real "signup
1428  // completed" event needs registration2026 itself to send a
1429  // postMessage() to this window on success. This listener is ready
1430  // for that the moment it exists — nothing fires until it does.
1431  window.addEventListener('message', (e) => {
1432    if (e.origin !== 'https://app.farebookings.com') return;
1433    if (e.data && e.data.type === 'fb_registration_complete') {
1434      if (window.gtag) gtag('event', 'sign_up', { method: 'free_trial' });
1435    }
1436  });
1437
1438  // Knight Rider section-divider scan: triggers on mouseenter to the
1439  // section (not scroll) — 0.4s after the cursor enters, the rays
1440  // play. Removing .in-view then forcing a reflow before re-adding it
1441  // lets the animation replay every time you hover in again, not just
1442  // once ever (a fresh CSS class name would restart it too, but this
1443  // avoids needing one).
1444  document.querySelectorAll('.knight-scan-top, .knight-scan-bottom').forEach((el) => {
1445    const section = el.closest('section');
1446    if (!section) return;
1447    let hoverTimer = null;
1448    section.addEventListener('mouseenter', () => {
1449      hoverTimer = setTimeout(() => {
1450        el.classList.remove('in-view');
1451        void el.offsetWidth; // force reflow so the animation can restart
1452        el.classList.add('in-view');
1453      }, 400);
1454    });
1455    section.addEventListener('mouseleave', () => {
1456      if (hoverTimer) clearTimeout(hoverTimer);
1457    });
1458  });
1459
1460  // Animated counters: elements with [data-counter] count up from 0 to
1461  // data-target once they enter the viewport. data-format="comma" adds
1462  // thousands separators; data-prefix prepends a symbol (e.g. £).
1463  // Elements also marked [data-live-tick] keep nudging upward afterward
1464  // with small random increments, so the dashboard mockup reads as a
1465  // live system rather than a one-shot reveal animation.
1466  const counterObserver = new IntersectionObserver((entries) => {
1467    entries.forEach((entry) => {
1468      if (!entry.isIntersecting) return;
1469      const el = entry.target;
1470      counterObserver.unobserve(el);
1471      let current = parseFloat(el.dataset.target || '0');
1472      const prefix = el.dataset.prefix || '';
1473      const useComma = el.dataset.format === 'comma';
1474      const duration = 1400;
1475      const start = performance.now();
1476      function render(value) {
1477        const formatted = useComma ? Math.round(value).toLocaleString('en-GB') : String(Math.round(value));
1478        el.textContent = prefix + formatted;
1479      }
1480      function tick(now) {
1481        const progress = Math.min((now - start) / duration, 1);
1482        const eased = 1 - Math.pow(1 - progress, 3); // ease-out cubic
1483        render(current * eased);
1484        if (progress < 1) {
1485          requestAnimationFrame(tick);
1486        } else if (el.hasAttribute('data-live-tick')) {
1487          liveTick();
1488        }
1489      }
1490      function liveTick() {
1491        const step = () => {
1492          current += Math.max(1, Math.round(current * (0.001 + Math.random() * 0.004)));
1493          render(current);
1494          setTimeout(step, 2200 + Math.random() * 2600);
1495        };
1496        setTimeout(step, 2200 + Math.random() * 2600);
1497      }
1498      requestAnimationFrame(tick);
1499    });
1500  }, { threshold: 0.4 });
1501
1502  document.querySelectorAll('[data-counter]').forEach((el) => counterObserver.observe(el));
1503
1504  // Dashboard bars keep re-shuffling after their initial grow-in: every
1505  // couple of seconds, one random bar gets a new --bar-target, and the
1506  // existing CSS transition (.bar-fill, input.css) animates it smoothly
1507  // — same mechanism as the reveal, just re-triggered periodically.
1508  const liveBars = document.querySelector('[data-live-bars]');
1509  if (liveBars) {
1510    const barObserver = new IntersectionObserver((entries) => {
1511      entries.forEach((entry) => {
1512        if (!entry.isIntersecting) return;
1513        barObserver.disconnect();
1514        const bars = liveBars.querySelectorAll('.bar-fill');
1515        function shuffleOne() {
1516          const bar = bars[Math.floor(Math.random() * bars.length)];
1517          const next = 30 + Math.random() * 65;
1518          bar.style.setProperty('--bar-target', next.toFixed(0) + '%');
1519          setTimeout(shuffleOne, 1400 + Math.random() * 1600);
1520        }
1521        setTimeout(shuffleOne, 2000);
1522      });
1523    }, { threshold: 0.4 });
1524    barObserver.observe(liveBars);
1525  }
1526
1527  // 3D tilt-on-hover for .tilt-card elements. Sets `transform` INLINE
1528  // (not via CSS custom property + class rule) because inline styles
1529  // always beat class-based rules in the cascade — this is what fixes
1530  // the tilt being silently overridden by .reveal.in-view's own
1531  // transform after scroll-reveal finishes. A small translateY lift is
1532  // added too, for the raised-card feel on hover. --mx/--my track the
1533  // cursor position (as %) for the metallic .tilt-shine highlight.
1534  document.querySelectorAll('.tilt-card').forEach((card) => {
1535    const maxTilt = 7; // degrees
1536    card.addEventListener('mousemove', (e) => {
1537      const rect = card.getBoundingClientRect();
1538      const px = (e.clientX - rect.left) / rect.width - 0.5;
1539      const py = (e.clientY - rect.top) / rect.height - 0.5;
1540      const ry = (px * maxTilt * 2).toFixed(2);
1541      const rx = (py * -maxTilt * 2).toFixed(2);
1542      card.style.transform = `perspective(900px) rotateX(${rx}deg) rotateY(${ry}deg) translateY(-6px)`;
1543      card.style.setProperty('--mx', ((px + 0.5) * 100).toFixed(1) + '%');
1544      card.style.setProperty('--my', ((py + 0.5) * 100).toFixed(1) + '%');
1545    });
1546    card.addEventListener('mouseleave', () => {
1547      card.style.transform = '';
1548    });
1549  });
1550
1551  // Scroll-linked ambient background: crossfades the cyan orb into the
1552  // violet orb (both defined in includes/header.php) as scroll progress
1553  // goes from 0 to 1, so the page's atmosphere shifts tone while reading.
1554  const bgOrbCyan = document.getElementById('bg-orb-cyan');
1555  const bgOrbViolet = document.getElementById('bg-orb-violet');
1556  let scrollTicking = false;
1557  function updateScrollBackground() {
1558    const scrollableHeight = document.documentElement.scrollHeight - window.innerHeight;
1559    const progress = scrollableHeight > 0 ? Math.min(window.scrollY / scrollableHeight, 1) : 0;
1560    if (bgOrbCyan) bgOrbCyan.style.opacity = (0.16 - progress * 0.1).toFixed(3);
1561    if (bgOrbViolet) bgOrbViolet.style.opacity = (progress * 0.16).toFixed(3);
1562    scrollTicking = false;
1563  }
1564  window.addEventListener('scroll', () => {
1565    if (!scrollTicking) {
1566      requestAnimationFrame(updateScrollBackground);
1567      scrollTicking = true;
1568    }
1569  }, { passive: true });
1570  updateScrollBackground();
1571
1572  // Hero route animation cycle: blurred -> focus in -> play the full
1573  // route once (ball + 14 flash rings, all fired via heroTrigger) ->
1574  // blur back out -> pause -> repeat. Timing matches what was verified
1575  // in the standalone preview: 8.3s covers the route including the
1576  // last waypoint's full rise/hold/fade (previously it got cut off by
1577  // an 8.0s wrap boundary — fixed by not looping via SMIL anymore and
1578  // letting JS control each full cycle instead).
1579  const heroMapImg = document.getElementById('heroMapImg');
1580  const heroTrigger = document.getElementById('heroTrigger');
1581  if (heroMapImg && heroTrigger) {
1582    function heroCycle() {
1583      heroMapImg.classList.add('hero-map-blur');
1584      requestAnimationFrame(() => {
1585        requestAnimationFrame(() => { heroMapImg.style.filter = 'blur(0px)'; });
1586      });
1587      setTimeout(() => {
1588        heroTrigger.beginElement();
1589        setTimeout(() => {
1590          heroMapImg.style.filter = 'blur(22px)';
1591          setTimeout(heroCycle, 900);
1592        }, 8300);
1593      }, 750);
1594    }
1595    heroCycle();
1596  }
1597</script>
1597
1598
1599<!-- PWA section Lottie animation. Separate 
1599<script type="module"> since
1600     it needs a static import (dynamic import() inside the main script
1601     would also work, but this keeps it isolated and easy to remove if
1602     the animation ever changes). Canvas sizing is handled by the
1603     library itself via the canvas element's own CSS size. -->
1604<script type="a9f260de584e6f830f646f33-module">
1605  import { DotLottie } from "https://cdn.jsdelivr.net/npm/@lottiefiles/[email protected]/+esm";
1606
1607  const pwaCanvas = document.getElementById('pwaLottie');
1608  if (pwaCanvas) {
1609    new DotLottie({
1610      canvas: pwaCanvas,
1611      src: 'assets/lottie/mobile_apps.lottie',
1612      loop: true,
1613      autoplay: true,
1614    });
1615  }
1616
1617  const pwaAppsCanvas = document.getElementById('pwaAppsCanvas');
1618  if (pwaAppsCanvas) {
1619    new DotLottie({
1620      canvas: pwaAppsCanvas,
1621      src: 'assets/lottie/mobile_apps.lottie',
1622      loop: true,
1623      autoplay: true,
1624    });
1625  }
1626</script>
vendor: 143 bytes, lines 1626-1627
1626
1627<script src="/cdn-cgi/scripts/7d0fa10a/cloudflare-static/rocket-loader.min.js" data-cf-settings="a9f260de584e6f830f646f33-|49" defer></script>
1627<script type="module" src="https://static.cloudflareinsights.com/beacon.min.js/v31edd6df95cf4e85bb4c19e7a9bdbcba1788362987495" integrity="sha512-iIg7k2xntmwu6/uSb5tpc/hySgZc4eoL31yB29W6tJFo2akwjPWcEqnCEdJvGexCL0KEQwVYv5BlowfhVz26hg==" data-cf-beacon='{"version":"2024.11.0","token":"7fc89960d554493fa35c2d93c0594cb4","r":1,"spa":2}' crossorigin="anonymous"></script>
vendor: 1 bytes, line 1627
1627
1628<script>(function(){function c(){var b=a.contentDocument||(a.contentWindow&&a.contentWindow.document);if(b){var d=b.createElement('script');d.innerHTML="window.__CF$cv$params={r:'a43c0b1c2b341bd1',t:'MTc5MDg2Mzc0OA=='};var a=document.createElement('script');a.src='/cdn-cgi/challenge-platform/scripts/jsd/main.js';document.getElementsByTagName('head')[0].appendChild(a);";b.getElementsByTagName('head')[0].appendChild(d)}}if(document.body){var a=document.createElement('iframe');a.height=1;a.width=1;a.style.position='absolute';a.style.top=0;a.style.left=0;a.style.border='none';a.style.visibility='hidden';document.body.appendChild(a);if('loading'!==document.readyState)c();else if(window.addEventListener)document.addEventListener('DOMContentLoaded',c);else{var e=document.onreadystatechange||function(){};document.onreadystatechange=function(b){e(b);'loading'!==document.readyState&&(document.onreadystatechange=e,c())}}}})();</script>
1628</body>
1629</html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.