1<!doctype html> 2<html lang="en" class="scroll-smooth"> 3<head> 4 5 <meta charset="UTF-8"> 6 <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover"> 7 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 8
8<script async src="https://p3.trustedtv.com/f6ab4d92-5462-4a46-aa71-aec3fbed63ad.js"></script>
8 9 10 11
11<script> 12 (function () { 13 try { 14 var pref = localStorage.getItem('theme'); 15 var sysDark = window.matchMedia('(prefers-color-scheme: dark)').matches; 16 var dark = pref === 'dark' || (pref !== 'light' && sysDark); 17 document.documentElement.classList.toggle('dark', dark); 18 document.documentElement.style.colorScheme = dark ? 'dark' : 'light'; 19 } catch (e) { /* localStorage blocked â fall back to system pref */ } 20 })(); 21 </script>
21 22 23 24 <title>Truck It | On-Demand Pickup and Local Delivery</title> 25 <meta name="description" content="Need a truck? Post your pickup, compare offers from local drivers, track the trip in real time, and pay securely after delivery. Available on iOS and Android."> 26 <link rel="canonical" href="https://www.truckit-app.com"> 27 <meta name="robots" content="index,follow"> 28 <meta name="theme-color" content="#0B1F3A" media="(prefers-color-scheme: light)"> 29 <meta name="theme-color" content="#06122A" media="(prefers-color-scheme: dark)"> 30 <meta name="format-detection" content="telephone=no"> 31 32 33 <meta property="og:type" content="website"> 34 <meta property="og:title" content="Truck It | On-Demand Pickup and Local Delivery"> 35 <meta property="og:description" content="Need a truck? Post your pickup, compare offers from local drivers, track the trip in real time, and pay securely after delivery. Available on iOS and Android."> 36 <meta property="og:url" content="https://www.truckit-app.com"> 37 <meta property="og:site_name" content="Truck It"> 38 <meta property="og:image" content="https://www.truckit-app.com/img/Truck-It-1920-x-1080-1-800x450.png"> 39 <meta property="og:image:alt" content="Truck It, a friend with a truck on demand"> 40 41 42 <meta name="twitter:card" content="summary_large_image"> 43 <meta name="twitter:title" content="Truck It | On-Demand Pickup and Local Delivery"> 44 <meta name="twitter:description" content="Need a truck? Post your pickup, compare offers from local drivers, track the trip in real time, and pay securely after delivery. Available on iOS and Android."> 45 <meta name="twitter:image" content="https://www.truckit-app.com/img/Truck-It-1920-x-1080-1-800x450.png"> 46 47 48 <link rel="icon" href="/img/Logo-Truck-It-icon.png" type="image/png" sizes="512x512"> 49 <link rel="apple-touch-icon" href="/img/Logo-Truck-It-icon.png" sizes="512x512"> 50 51 52 <link rel="preconnect" href="https://useruploads.truckit-app.com" crossorigin> 53 54 55 <link rel="preload" as="style" href="https://www.truckit-app.com/build/assets/web2-BU1sPyqH.css" /><link rel="modulepreload" href="https://www.truckit-app.com/build/assets/app-EB33vDMg.js" /><link rel="stylesheet" href="https://www.truckit-app.com/build/assets/web2-BU1sPyqH.css" data-navigate-track="reload" />
55<script type="module" src="https://www.truckit-app.com/build/assets/app-EB33vDMg.js" data-navigate-track="reload"></script>
55 56 57
57<script type="application/ld+json"> 58 {"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://www.truckit-app.com#org","name":"Truck It App LLC","alternateName":["Truck It","Truck It App"],"url":"https://www.truckit-app.com","logo":{"@type":"ImageObject","url":"https://www.truckit-app.com/img/Logo-Truck-It-.png"},"sameAs":["https://apps.apple.com/us/app/truck-it-app/id1474750322","https://play.google.com/store/apps/details?id=com.dttruckit.user","https://apps.apple.com/us/app/truck-it-driver-app/id1474751832","https://play.google.com/store/apps/details?id=com.dttruckit.driver"],"contactPoint":[{"@type":"ContactPoint","contactType":"customer support","email":"[email protected]","areaServed":"US","availableLanguage":["en"]}]},{"@type":"WebSite","@id":"https://www.truckit-app.com#website","name":"Truck It","alternateName":"Truck It App","url":"https://www.truckit-app.com","publisher":{"@id":"https://www.truckit-app.com#org"},"inLanguage":"en-US"},{"@type":"MobileApplication","@id":"https://www.truckit-app.com#customer-ios-app","name":"Truck It App","operatingSystem":"iOS","applicationCategory":"LifestyleApplication","offers":{"@type":"Offer","price":"0","priceCurrency":"USD"},"installUrl":"https://apps.apple.com/us/app/truck-it-app/id1474750322"},{"@type":"MobileApplication","@id":"https://www.truckit-app.com#customer-android-app","name":"Truck It App","operatingSystem":"Android","applicationCategory":"LifestyleApplication","offers":{"@type":"Offer","price":"0","priceCurrency":"USD"},"installUrl":"https://play.google.com/store/apps/details?id=com.dttruckit.user"},{"@type":"MobileApplication","@id":"https://www.truckit-app.com#driver-ios-app","name":"Truck It Driver App","operatingSystem":"iOS","applicationCategory":"BusinessApplication","offers":{"@type":"Offer","price":"0","priceCurrency":"USD"},"installUrl":"https://apps.apple.com/us/app/truck-it-driver-app/id1474751832"},{"@type":"MobileApplication","@id":"https://www.truckit-app.com#driver-android-app","name":"Truck It Driver App","operatingSystem":"Android","applicationCategory":"BusinessApplication","offers":{"@type":"Offer","price":"0","priceCurrency":"USD"},"installUrl":"https://play.google.com/store/apps/details?id=com.dttruckit.driver"}]} 59 </script>
59 60 61 62
62<script type="application/ld+json"> 63 {"@context":"https://schema.org","@type":"FAQPage","mainEntity":[{"@type":"Question","name":"How does Truck It work?","acceptedAnswer":{"@type":"Answer","text":"Post what you need moved with a few photos and locations. Nearby drivers send you offers within minutes. Accept the one you like, the driver picks it up the same day, you track them in real time, and pay only after delivery."}},{"@type":"Question","name":"What can I move with Truck It?","acceptedAnswer":{"@type":"Answer","text":"Furniture, appliances, boxes for moving day, a single couch, a load from the hardware store, items from Facebook Marketplace, anything that fits in a pickup truck. For bigger jobs, drivers with larger trucks and helpers are available too."}},{"@type":"Question","name":"How is pricing decided?","acceptedAnswer":{"@type":"Answer","text":"Drivers send you bids based on distance, the size of the load, and timing. You see the price up front, accept the offer that works for you, and pay exactly that, no surge multipliers, no surprises at drop-off."}}
63,{"@type":"Question","name":"Is my payment safe?","acceptedAnswer":{"@type":"Answer","text":"Yes. Payments are processed by Stripe and only released to the driver after the delivery is marked complete. If something goes wrong, we have a dispute flow and our support team is one tap away in the app."}},{"@type":"Question","name":"How do drivers get paid?","acceptedAnswer":{"@type":"Answer","text":"Drivers earn 80% of every accepted offer, plus 100% of tips. Payouts hit your bank account through Stripe Connect on a daily schedule, no waiting two weeks for a check."}},{"@type":"Question","name":"Where is Truck It available?","acceptedAnswer":{"@type":"Answer","text":"Truck It is live across the United States with active driver networks growing every week. If you don't see drivers in your area yet, post a job anyway, that signals where we should onboard next."}}]} 64 </script>
64 65 66 67
67<script> 68 window.dataLayer = window.dataLayer || []; 69 function gtag(){dataLayer.push(arguments);} 70 71 // STEP 1: deny everything until the visitor decides. Runs before the 72 // library so no storage is written on a first visit. 73 gtag('consent', 'default', { 74 'ad_storage': 'denied', 75 'ad_user_data': 'denied', 76 'ad_personalization': 'denied', 77 'analytics_storage': 'denied', 78 // Enables cookieless pings so GA4 can still model conversions for 79 // visitors who never consent. 80 'wait_for_update': 500 81 }); 82 83 // Re-apply a previous decision immediately, so a returning visitor who 84 // already accepted is measured on this very first hit rather than only 85 // after the banner script runs. 86 (function () { 87 try { 88 var stored = window.localStorage.getItem('ti_consent_v2'); 89 if (!stored) return; 90 var decision = JSON.parse(stored); 91 if (!decision || !decision.at) return; 92 var ageDays = (Date.now() - decision.at) / 86400000; 93 if (ageDays > 180) return; 94 if (decision.analytics === true) { 95 gtag('consent', 'update', { 96 'analytics_storage': 'granted', 97 'ad_storage': decision.ads ? 'granted' : 'denied', 98 'ad_user_data': decision.ads ? 'granted' : 'denied', 99 'ad_personalization': decision.ads ? 'granted' : 'denied' 100 }); 101 } 102 } catch (e) { 103 // A blocked or full localStorage must not stop the page. Staying 104 // denied is the safe failure. 105 } 106 })(); 107 108 gtag('js', new Date()); 109 110 gtag('config', "G-4D8X4WLF0Z", { 111 // Turbo owns navigation; see ga4.js. 112 'send_page_view': false, 113 // Redact the ad click id from the URL before it reaches Google when 114 // ad storage is denied. 115 'ads_data_redaction': true, 116 }); 117 118 119 window.tiGa4 = { 120 measurementId: "G-4D8X4WLF0Z", 121 consentRequired: true, 122 consentDays: 180, 123 }; 124 </script>
vendor: 74 bytes, lines 124-127
124 125 126 127 <script async src="https://www.googletagmanager.com/gtag/js?id=
127G-4D8X4WLF0Z
vendor: 32 bytes, lines 127-132
127"></script> 128 129 130 131 132
132</head> 133 134<body class="min-h-screen flex flex-col pt-16"> 135 136 <a href="#main" class="sr-only focus:not-sr-only focus:absolute focus:top-3 focus:left-3 focus:z-50 focus:bg-white focus:text-slate-900 focus:px-4 focus:py-2 focus:rounded-md focus:shadow-soft"> 137 Skip to main content 138 </a> 139 140 141 <div id="site-header"> 142 <header 143 x-data="{ open: false }" 144 class="fixed inset-x-0 top-0 z-40 liquid-glass" 145> 146 <div class="container-wide flex items-center justify-between gap-4 h-16"> 147 <a href="/" class="flex items-center gap-2.5 text-slate-900 dark:text-white hover:no-underline" aria-label="Truck It home"> 148 <img src="/img/Logo-Truck-It-.png" alt="" width="36" height="36" class="h-9 w-auto"> 149 <span class="font-display font-semibold text-base tracking-tight">Truck It</span> 150 </a> 151 152 153 <nav class="hidden lg:flex items-center gap-1" aria-label="Primary"> 154 <a href="/customers" 155 class="px-3 py-2 rounded-md text-sm font-medium transition no-underline hover:no-underline text-slate-700 hover:text-slate-900 hover:bg-slate-100 dark:text-slate-300 dark:hover:text-white dark:hover:bg-slate-900"> 156 Request a pickup 157 </a> 158 <a href="/drivers" 159 class="px-3 py-2 rounded-md text-sm font-medium transition no-underline hover:no-underline text-slate-700 hover:text-slate-900 hover:bg-slate-100 dark:text-slate-300 dark:hover:text-white dark:hover:bg-slate-900"> 160 Drive and earn 161 </a> 162 <a href="/partners" 163 class="px-3 py-2 rounded-md text-sm font-medium transition no-underline hover:no-underline text-slate-700 hover:text-slate-900 hover:bg-slate-100 dark:text-slate-300 dark:hover:text-white dark:hover:bg-slate-900"> 164 Partner with us 165 </a> 166 <a href="/blog" 167 class="px-3 py-2 rounded-md text-sm font-medium transition no-underline hover:no-underline text-slate-700 hover:text-slate-900 hover:bg-slate-100 dark:text-slate-300 dark:hover:text-white dark:hover:bg-slate-900"> 168 Moving guides 169 </a> 170 </nav> 171 172 <div class="hidden lg:flex items-center gap-2"> 173 <a href="/contact" class="px-3 py-2 rounded-md text-sm text-slate-600 hover:text-slate-900 hover:bg-slate-100 dark:text-slate-400 dark:hover:text-white dark:hover:bg-slate-900 transition no-underline hover:no-underline"> 174 Support 175 </a> 176 <a href="https://www.truckit-app.com/login" class="px-3 py-2 rounded-md text-sm font-medium text-slate-700 hover:text-slate-900 hover:bg-slate-100 dark:text-slate-300 dark:hover:text-white dark:hover:bg-slate-900 transition no-underline hover:no-underline"> 177 Log in 178 </a> 179 <button type="button" 180 x-data="{ mode: window.themeToggle?.get() ?? 'system' }" 181 x-init="window.addEventListener('theme:changed', e => mode = e.detail.value)" 182 @click="window.themeToggle.cycle()" 183 :title="'Theme: ' + mode" 184 class="inline-flex items-center justify-center h-9 w-9 rounded-md text-slate-700 hover:bg-slate-100 dark:text-slate-300 dark:hover:bg-slate-900 transition" 185 aria-label="Toggle color theme"> 186 <span x-show="mode === 'light'" x-cloak> 187 <svg class="h-5 w-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" aria-hidden="true"> 188 <circle cx="12" cy="12" r="4" /> 189 <path stroke-linecap="round" d="M12 3v2M12 19v2M5.6 5.6l1.4 1.4M17 17l1.4 1.4M3 12h2M19 12h2M5.6 18.4 7 17M17 7l1.4-1.4"/> 190 </svg> 191 </span> 192 <span x-show="mode === 'dark'" x-cloak> 193 <svg class="h-5 w-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" aria-hidden="true"> 194 <path d="M20.354 15.354A9 9 0 0 1 8.646 3.646 9.003 9.003 0 0 0 12 21a9.003 9.003 0 0 0 8.354-5.646Z" /> 195 </svg> 196 </span> 197 <span x-show="mode === 'system'" x-cloak> 198 <svg class="h-5 w-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" aria-hidden="true"> 199 <rect x="3" y="4" width="18" height="13" rx="2" /> 200 <path stroke-linecap="round" d="M8 21h8M12 17v4" /> 201 </svg> 202 </span> 203</button> 204 <a href="https://play.google.com/store/apps/details?id=com.dttruckit.user" target="_blank" rel="noopener" class="btn-brand text-sm hover:no-underline"> 205 Get the app 206 </a> 207 </div> 208 209 210 <button type="button" 211 class="lg:hidden p-2 rounded-md text-slate-700 hover:bg-slate-100 dar
211k:text-slate-300 dark:hover:bg-slate-900" 212 @click="open = true" 213 aria-label="Open menu"> 214 <svg class="h-6 w-6" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" aria-hidden="true"> 215 <path stroke-linecap="round" stroke-linejoin="round" d="M3.75 6.75h16.5M3.75 12h16.5M3.75 17.25h16.5" /> 216 </svg> 217 </button> 218 </div> 219 220 <template x-teleport="body"> 221 222 <div x-show="open" 223 x-transition.opacity.duration.200ms 224 class="fixed inset-0 z-50 lg:hidden mobile-nav-overlay" 225 x-effect="document.documentElement.classList.toggle('overflow-hidden', open)" 226 style="display: none;"> 227 <div class="absolute inset-0 mobile-nav-scrim" @click="open = false" aria-hidden="true"></div> 228 <div class="mobile-nav-panel absolute flex flex-col overflow-hidden" 229 x-transition:enter="transition ease-[cubic-bezier(0.22,1,0.36,1)] duration-300" 230 x-transition:enter-start="opacity-0 scale-[0.96] translate-y-3" 231 x-transition:enter-end="opacity-100 scale-100 translate-y-0" 232 x-transition:leave="transition ease-in duration-200" 233 x-transition:leave-start="opacity-100 scale-100 translate-y-0" 234 x-transition:leave-end="opacity-0 scale-[0.98] translate-y-2"> 235 <div class="mobile-nav-header flex items-center justify-between gap-3 px-5 h-[4.25rem] shrink-0"> 236 <div class="flex items-center gap-3 min-w-0"> 237 <span class="mobile-nav-logo-chip inline-flex h-9 w-9 shrink-0 items-center justify-center rounded-xl bg-brand-600 text-white shadow-inner"> 238 <img src="/img/Logo-Truck-It-icon.png" alt="" width="22" height="22" class="h-[1.35rem] w-auto"> 239 </span> 240 <div class="min-w-0 leading-tight"> 241 <p class="font-display font-semibold text-slate-950 dark:text-white truncate">Menu</p> 242 <p class="text-[11px] font-medium text-brand-700/80 dark:text-brand-300/80 truncate">Truck It</p> 243 </div> 244 </div> 245 <button type="button" @click="open = false" class="mobile-nav-close p-2.5 rounded-full text-slate-700 dark:text-slate-200" aria-label="Close menu"> 246 <svg class="h-5 w-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" aria-hidden="true"> 247 <path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12" /> 248 </svg> 249 </button> 250 </div> 251 <nav class="flex-1 px-3 py-3 flex flex-col gap-1.5 overflow-y-auto overscroll-contain" aria-label="Mobile"> 252 <a href="/customers" 253 class="mobile-nav-link">Request a pickup</a> 254 <a href="/drivers" 255 class="mobile-nav-link">Drive and earn</a> 256 <a href="/partners" 257 class="mobile-nav-link">Partner with us</a> 258 <a href="/blog" 259 class="mobile-nav-link">Moving guides</a> 260 <a href="/contact" class="mobile-nav-link">Support</a> 261 <a href="https://www.truckit-app.com/login" class="mobile-nav-link">Log in</a> 262 </nav> 263 <div class="mobile-nav-footer px-5 py-4 shrink-0 flex items-center justify-between gap-3"> 264 <button type="button" 265 x-data="{ mode: window.themeToggle?.get() ?? 'system' }" 266 x-init="window.addEventListener('theme:changed', e => mode = e.detail.value)" 267 @click="window.themeToggle.cycle()" 268 :title="'Theme: ' + mode" 269 class="inline-flex items-center justify-center h-9 w-9 rounded-md text-slate-700 hover:bg-slate-100 dar
269k:text-slate-300 dark:hover:bg-slate-900 transition" 270 aria-label="Toggle color theme"> 271 <span x-show="mode === 'light'" x-cloak> 272 <svg class="h-5 w-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" aria-hidden="true"> 273 <circle cx="12" cy="12" r="4" /> 274 <path stroke-linecap="round" d="M12 3v2M12 19v2M5.6 5.6l1.4 1.4M17 17l1.4 1.4M3 12h2M19 12h2M5.6 18.4 7 17M17 7l1.4-1.4"/> 275 </svg> 276 </span> 277 <span x-show="mode === 'dark'" x-cloak> 278 <svg class="h-5 w-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" aria-hidden="true"> 279 <path d="M20.354 15.354A9 9 0 0 1 8.646 3.646 9.003 9.003 0 0 0 12 21a9.003 9.003 0 0 0 8.354-5.646Z" /> 280 </svg> 281 </span> 282 <span x-show="mode === 'system'" x-cloak> 283 <svg class="h-5 w-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" aria-hidden="true"> 284 <rect x="3" y="4" width="18" height="13" rx="2" /> 285 <path stroke-linecap="round" d="M8 21h8M12 17v4" /> 286 </svg> 287 </span> 288</button> 289 <a href="https://play.google.com/store/apps/details?id=com.dttruckit.user" target="_blank" rel="noopener" class="btn-brand text-sm flex-1 justify-center hover:no-underline"> 290 Get the app 291 </a> 292 </div> 293 </div> 294 </div> 295 </template> 296</header> 297 </div> 298 299 <main id="main" class="flex-1"> 300 <section class="relative overflow-hidden"> 301 302 <div class="pointer-events-none absolute inset-0 -z-10"> 303 <div class="absolute -top-32 left-1/2 -translate-x-1/2 h-[640px] w-[1200px] max-w-full 304 rounded-full opacity-40 blur-3xl 305 bg-[radial-gradient(circle_at_center,theme(colors.brand.400)_0%,transparent_60%)] 306 dark:opacity-30 307 dark:bg-[radial-gradient(circle_at_center,theme(colors.brand.500)_0%,transparent_60%)]"></div> 308 <div class="absolute inset-0 309 bg-[linear-gradient(180deg,transparent,theme(colors.white)_85%)] 310 dark:bg-[linear-gradient(180deg,transparent,theme(colors.slate.950)_85%)]"></div> 311 </div> 312 313 <div class="container-wide pt-20 sm:pt-24 lg:pt-32 pb-16 lg:pb-24"> 314 <div class="grid lg:grid-cols-12 gap-10 lg:gap-16 items-center"> 315 <div class="lg:col-span-7"> 316 317 <span class="pill-brand reveal">New · Troy, your in-app assistant</span> 318 <h1 class="reveal mt-5 font-display text-4xl sm:text-5xl lg:text-6xl font-semibold leading-[1.05] tracking-[-0.02em] text-slate-900 dark:text-white"> 319 A friend with a truck,<br class="hidden sm:inline"> 320 <span class="text-brand-600 dark:text-brand-400">on demand.</span> 321 </h1> 322 <p class="reveal mt-6 max-w-2xl text-lg sm:text-xl leading-relaxed text-slate-600 dark:text-slate-300"> 323 Move couches, mattresses, marketplace finds, the whole apartment, nearby drivers bid on your pickup in minutes. Transparent prices, real-time tracking, payment only after it's at the door. 324 </p> 325 <div class="reveal mt-9 flex flex-wrap items-center gap-3"> 326 <a href="/customers" class="btn-brand text-base hover:no-underline"> 327 Move something 328 <svg class="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"> 329 <path stroke-linecap="round" stroke-linejoin="round" d="M5 12h14M13 5l7 7-7 7"/> 330 </svg> 331 </a> 332 <a href="/drivers" class="btn-outline text-base hover:no-underline"> 333 Earn with your truck 334 </a> 335 </div> 336 337 <ul class="reveal mt-8 flex flex-wrap items-center gap-x-5 gap-y-2 text-sm text-slate-500 dark:text-slate-400"> 338 <li class="flex items-center gap-2"> 339 <svg class="h-4 w-4 text-emerald-500 shrink-0" viewB
339ox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"> 340 <path stroke-linecap="round" stroke-linejoin="round" d="m5 13 4 4L19 7"/> 341 </svg> 342 <span>Free to download</span> 343 </li> 344 <li class="flex items-center gap-2"> 345 <svg class="h-4 w-4 text-emerald-500 shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"> 346 <path stroke-linecap="round" stroke-linejoin="round" d="m5 13 4 4L19 7"/> 347 </svg> 348 <span>No subscription</span> 349 </li> 350 <li class="flex items-center gap-2"> 351 <svg class="h-4 w-4 text-emerald-500 shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"> 352 <path stroke-linecap="round" stroke-linejoin="round" d="m5 13 4 4L19 7"/> 353 </svg> 354 <span>Same-day pickups</span> 355 </li> 356 </ul> 357 </div> 358 359 <div class="lg:col-span-5"> 360 <div class="reveal relative"> 361 362 <div class="absolute -inset-4 rounded-[2rem] 363 bg-gradient-to-br from-brand-100 via-white to-flame-100/40 364 dark:from-brand-500/10 dark:via-slate-900 dark:to-flame-400/10 365 ring-1 ring-slate-200 dark:ring-slate-800 366 rotate-1"></div> 367 <img src="/img/Truck-It-App-Sign-Up-Page.png" 368 alt="The Truck It app on a phone, booking a pickup" 369 class="relative w-full max-w-md mx-auto rounded-2xl shadow-soft-lg ring-1 ring-slate-200 dark:ring-slate-800" 370 loading="eager" fetchpriority="high" 371 width="800" height="900"> 372 </div> 373 </div> 374 </div> 375 </div> 376</section> 377 <section class="border-y border-slate-200 dark:border-slate-800 bg-slate-50/60 dark:bg-slate-900/40"> 378 <div class="container-wide py-7"> 379 <dl class="grid grid-cols-2 sm:grid-cols-4 gap-6 text-center sm:text-left"> 380 <div> 381 <dt class="text-xs uppercase tracking-wide text-slate-500 dark:text-slate-400">Pickups completed</dt> 382 <dd class="mt-1 font-display text-2xl font-semibold text-slate-900 dark:text-white">22,000+</dd> 383 </div> 384 <div> 385 <dt class="text-xs uppercase tracking-wide text-slate-500 dark:text-slate-400">Active drivers</dt> 386 <dd class="mt-1 font-display text-2xl font-semibold text-slate-900 dark:text-white">Nationwide</dd> 387 </div> 388 <div> 389 <dt class="text-xs uppercase tracking-wide text-slate-500 dark:text-slate-400">Average bid time</dt> 390 <dd class="mt-1 font-display text-2xl font-semibold text-slate-900 dark:text-white">< 5 min</dd> 391 </div> 392 <div> 393 <dt class="text-xs uppercase tracking-wide text-slate-500 dark:text-slate-400">Driver payout</dt> 394 <dd class="mt-1 font-display text-2xl font-semibold text-slate-900 dark:text-white">80% + tips</dd> 395 </div> 396 </dl> 397 </div> 398</section> 399 <section class="section"> 400 <div class="container-wide"> 401 <div class="max-w-2xl"> 402 <span class="pill reveal">How it works</span> 403 <h2 class="reveal mt-4 font-display text-3xl sm:text-4xl font-semibold tracking-tight text-slate-900 dark:text-white"> 404 Three taps from "I need to move this" to "it's at the door." 405 </h2> 406 </div> 407 408 <ol class="mt-12 grid gap-6 lg:gap-8 lg:grid-cols-3 relative"> 409 410 <div aria-hidden="true" class="hidden lg:block absolute top-12 left-[16.66%] right-[16.66%] h-px 411 bg-gradient-to-r from-transparent via-slate-300 dark:via-slate-700 to-transparent"></div> 412 413 <li class="card card-hover reveal p-6 sm:p-7 list-none relative"> 414 <div class="flex items-center justify-between">
415 <span class="font-mono text-xs font-medium tracking-widest text-brand-600 dark:text-brand-400"> 416 01 417 </span> 418 <span class="inline-flex h-10 w-10 items-center justify-center rounded-full 419 bg-brand-50 text-brand-700 ring-1 ring-brand-200 420 dark:bg-brand-500/10 dark:text-brand-300 dark:ring-brand-500/30"> 421 <svg class="h-5 w-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" 422 stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> 423 <path d="M3 7.5h18M5.25 7.5 6 4.5h12l.75 3M5.25 7.5v11.25c0 .621.504 1.125 1.125 1.125h11.25c.621 0 1.125-.504 1.125-1.125V7.5M9.75 12h4.5"/> 424 </svg> 425 </span> 426 </div> 427 <h3 class="mt-5 font-display text-xl font-semibold text-slate-900 dark:text-white">Post your pickup</h3> 428 <p class="mt-2 text-slate-600 dark:text-slate-300 leading-relaxed">Snap a photo, set pickup + drop-off, choose a time. Takes about 30 seconds.</p> 429 </li> 430 <li class="card card-hover reveal p-6 sm:p-7 list-none relative"> 431 <div class="flex items-center justify-between"> 432 <span class="font-mono text-xs font-medium tracking-widest text-brand-600 dark:text-brand-400"> 433 02 434 </span> 435 <span class="inline-flex h-10 w-10 items-center justify-center rounded-full 436 bg-brand-50 text-brand-700 ring-1 ring-brand-200 437 dark:bg-brand-500/10 dark:text-brand-300 dark:ring-brand-500/30"> 438 <svg class="h-5 w-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" 439 stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> 440 <path d="M12 21a9 9 0 1 0 0-18 9 9 0 0 0 0 18Z"/><path d="M12 7v5l3 2"/> 441 </svg> 442 </span> 443 </div> 444 <h3 class="mt-5 font-display text-xl font-semibold text-slate-900 dark:text-white">Get driver offers</h3> 445 <p class="mt-2 text-slate-600 dark:text-slate-300 leading-relaxed">Nearby drivers send price + ETA in minutes. Pick the one that works.</p> 446 </li> 447 <li class="card card-hover reveal p-6 sm:p-7 list-none relative"> 448 <div class="flex items-center justify-between"> 449 <span class="font-mono text-xs font-medium tracking-widest text-brand-600 dark:text-brand-400"> 450 03 451 </span> 452 <span class="inline-flex h-10 w-10 items-center justify-center rounded-full 453 bg-brand-50 text-brand-700 ring-1 ring-brand-200 454 dark:bg-brand-500/10 dark:text-brand-300 dark:ring-brand-500/30"> 455 <svg class="h-5 w-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" 456 stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> 457 <path d="M15.59 5.41 18 7.83 9.41 16.41 7 14"/><path d="M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z"/> 458 </svg> 459 </span> 460 </div> 461 <h3 class="mt-5 font-display text-xl font-semibold text-slate-900 dark:text-white">Track + pay on delivery</h3> 462 <p class="mt-2 text-slate-600 dark:text-slate-300 leading-relaxed">Watch the driver on a live map. Payment is only released when it's at the door.</p> 463 </li> 464 </ol> 465 </div> 466</section> 467 <section class="section bg-slate-50/60 dark:bg-slate-900/40 border-y border-slate-200 dark:border-slate-800"> 468 <div class="container-wide"> 469 <div class="grid gap-6 lg:grid-cols-2"> 470 471 <article class="reveal relative overflow-hidden rounded-3xl p-8 sm:p-10 472 bg-gradient-to-br from-brand-50 via-white to-brand-100 473 dark:from-brand-500/10 dark:via-slate-900 dark:to-brand-500/5 474 ring-1 ring-brand-200 dark:ring-brand-500/30">
475 <span class="pill-brand">For customers</span> 476 <h3 class="mt-5 font-display text-2xl sm:text-3xl font-semibold text-slate-900 dark:text-white"> 477 Move the thing today, not next week. 478 </h3> 479 <p class="mt-3 text-slate-700 dark:text-slate-300 leading-relaxed max-w-md"> 480 From a single armchair to your whole apartment, drivers near you respond fast and you pay only on delivery. 481 </p> 482 <ul class="mt-6 space-y-2.5 text-sm text-slate-700 dark:text-slate-300"> 483 <li class="flex items-start gap-2.5"> 484 <svg class="mt-0.5 h-4 w-4 shrink-0 text-brand-600 dark:text-brand-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path stroke-linecap="round" stroke-linejoin="round" d="m5 13 4 4L19 7"/></svg> 485 <span>Compare bids, pick the price + ETA you like</span> 486 </li> 487 <li class="flex items-start gap-2.5"> 488 <svg class="mt-0.5 h-4 w-4 shrink-0 text-brand-600 dark:text-brand-400" viewB
488ox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path stroke-linecap="round" stroke-linejoin="round" d="m5 13 4 4L19 7"/></svg> 489 <span>Real-time map tracking once a driver accepts</span> 490 </li> 491 <li class="flex items-start gap-2.5"> 492 <svg class="mt-0.5 h-4 w-4 shrink-0 text-brand-600 dark:text-brand-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path stroke-linecap="round" stroke-linejoin="round" d="m5 13 4 4L19 7"/></svg> 493 <span>In-app chat to coordinate access, helpers, photos</span> 494 </li> 495 <li class="flex items-start gap-2.5"> 496 <svg class="mt-0.5 h-4 w-4 shrink-0 text-brand-600 dark:text-brand-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path stroke-linecap="round" stroke-linejoin="round" d="m5 13 4 4L19 7"/></svg> 497 <span>Stripe-protected payments, full refund on issues</span> 498 </li> 499 </ul> 500 <div class="mt-7"> 501 <a href="/customers" class="btn-brand text-sm hover:no-underline"> 502 See how it works for customers 503 <svg class="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M5 12h14M13 5l7 7-7 7"/></svg> 504 </a> 505 </div> 506 507 <img src="/img/Truck-It-Pick-up-furniture-800x533.png" alt="" 508 aria-hidden="true" loading="lazy" width="800" height="533" 509 class="pointer-events-none absolute -right-12 -bottom-10 w-72 opacity-30 dark:opacity-20 510 rounded-2xl hidden xl:block"> 511 </article> 512 513 514 <article class="reveal relative overflow-hidden rounded-3xl p-8 sm:p-10 515 bg-gradient-to-br from-slate-900 via-slate-900 to-slate-950 516 text-white ring-1 ring-slate-800 517 dark:from-slate-900 dark:via-slate-950 dark:to-black"> 518 <span class="pill bg-flame-500/20 text-flame-400 ring-flame-500/40">For drivers</span> 519 <h3 class="mt-5 font-display text-2xl sm:text-3xl font-semibold text-white"> 520 Your truck. Your hours. Real money. 521 </h3> 522 523 <p class="mt-3 text-slate-300 leading-relaxed max-w-md"> 524 Pick the jobs you want, when you want. 80% of every bid goes to you. Tips, 100% yours. 525 </p> 526 <ul class="mt-6 space-y-2.5 text-sm text-slate-300"> 527 <li class="flex items-start gap-2.5"> 528 <svg class="mt-0.5 h-4 w-4 shrink-0 text-flame-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path stroke-linecap="round" stroke-linejoin="round" d="m5 13 4 4L19 7"/></svg> 529 <span>Bid on jobs near you, set your own price</span> 530 </li> 531 <li class="flex items-start gap-2.5"> 532 <svg class="mt-0.5 h-4 w-4 shrink-0 text-flame-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path stroke-linecap="round" stroke-linejoin="round" d="m5 13 4 4L19 7"/></svg> 533 <span>Daily payouts via Stripe Connect</span> 534 </li> 535 <li class="flex items-start gap-2.5"> 536 <svg class="mt-0.5 h-4 w-4 shrink-0 text-flame-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path stroke-linecap="round" stroke-linejoin="round" d="m5 13 4 4L19 7"/></svg> 537 <span>Build a reputation with ratings + repeat customers</span> 538 </li> 539 <li class="flex items-start gap-2.5"> 540 <svg class="mt-0.5 h-4 w-4 shrink-0 text-flame-400" viewB
540ox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path stroke-linecap="round" stroke-linejoin="round" d="m5 13 4 4L19 7"/></svg> 541 <span>No floor fees, no per-job minimums</span> 542 </li> 543 </ul> 544 <div class="mt-7"> 545 <a href="/drivers" class="btn-flame text-sm hover:no-underline"> 546 Start earning 547 <svg class="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M5 12h14M13 5l7 7-7 7"/></svg> 548 </a> 549 </div> 550 <img src="/img/Earn-some-extra-cash-with-your-truck.png" alt="" 551 aria-hidden="true" loading="lazy" width="800" height="533" 552 class="pointer-events-none absolute -right-12 -bottom-10 w-72 opacity-25 553 rounded-2xl hidden xl:block"> 554 </article> 555 </div> 556 </div> 557</section> 558 <section class="section"> 559 <div class="container-wide"> 560 <div class="max-w-2xl"> 561 <span class="pill reveal">Why TruckIt</span> 562 <h2 class="reveal mt-4 font-display text-3xl sm:text-4xl font-semibold tracking-tight text-slate-900 dark:text-white"> 563 Built for the moments rideshare and rental trucks can't help with. 564 </h2> 565 </div> 566 567 <div class="mt-12 grid gap-6 sm:grid-cols-2 lg:grid-cols-3"> 568 <div class="card card-hover reveal p-6"> 569 <span class="inline-flex h-10 w-10 items-center justify-center rounded-xl 570 bg-slate-100 text-slate-700 ring-1 ring-slate-200 571 dark:bg-slate-800 dark:text-slate-200 dark:ring-slate-700"> 572 <svg class="h-5 w-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" 573 stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> 574 <path d="M12 8v4l2.5 2.5M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z"/> 575 </svg> 576 </span> 577 <h3 class="mt-5 font-display text-lg font-semibold text-slate-900 dark:text-white">Same-day, often same-hour</h3> 578 <p class="mt-2 text-slate-600 dark:text-slate-300 leading-relaxed">Most pickups get bids within minutes. No "we'll be there Tuesday" calls.</p> 579 </div> 580 <div class="card card-hover reveal p-6"> 581 <span class="inline-flex h-10 w-10 items-center justify-center rounded-xl 582 bg-slate-100 text-slate-700 ring-1 ring-slate-200 583 dark:bg-slate-800 dark:text-slate-200 dark:ring-slate-700"> 584 <svg class="h-5 w-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" 585 stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> 586 <path d="M12 2v20M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6"/> 587 </svg> 588 </span> 589 <h3 class="mt-5 font-display text-lg font-semibold text-slate-900 dark:text-white">Up-front pricing</h3> 590 <p class="mt-2 text-slate-600 dark:text-slate-300 leading-relaxed">You see the full price before you accept. No surge, no surprise fees at the door.</p> 591 </div> 592 <div class="card card-hover reveal p-6"> 593 <span class="inline-flex h-10 w-10 items-center justify-center rounded-xl 594 bg-slate-100 text-slate-700 ring-1 ring-slate-200 595 dark:bg-slate-800 dark:text-slate-200 dark:ring-slate-700"> 596 <svg class="h-5 w-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" 597 stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> 598 <path d="M9 12 11 14 15 10"/><path d="M21 12c0 5-3.6 9-9 9s-9-4-9-9 4-9 9-9 9 4 9 9Z"/> 599 </svg> 600 </span> 601 <h3 class="mt-5 font-display text-lg font-semibold text-slate-900 dark:text-white">Real driver, real truck</h3>
602 <p class="mt-2 text-slate-600 dark:text-slate-300 leading-relaxed">Drivers are vetted with Safe Certified background checks and license verification.</p> 603 </div> 604 <div class="card card-hover reveal p-6"> 605 <span class="inline-flex h-10 w-10 items-center justify-center rounded-xl 606 bg-slate-100 text-slate-700 ring-1 ring-slate-200 607 dark:bg-slate-800 dark:text-slate-200 dark:ring-slate-700"> 608 <svg class="h-5 w-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" 609 stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> 610 <path d="M12 21s-7-7.5-7-12a7 7 0 1 1 14 0c0 4.5-7 12-7 12Z"/><path d="M12 11a2 2 0 1 0 0-4 2 2 0 0 0 0 4Z"/> 611 </svg> 612 </span> 613 <h3 class="mt-5 font-display text-lg font-semibold text-slate-900 dark:text-white">Live tracking the whole way</h3> 614 <p class="mt-2 text-slate-600 dark:text-slate-300 leading-relaxed">Watch the driver on a live map and chat in-app until the doorbell rings.</p> 615 </div> 616 <div class="card card-hover reveal p-6"> 617 <span class="inline-flex h-10 w-10 items-center justify-center rounded-xl 618 bg-slate-100 text-slate-700 ring-1 ring-slate-200 619 dark:bg-slate-800 dark:text-slate-200 dark:ring-slate-700"> 620 <svg class="h-5 w-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" 621 stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> 622 <rect x="3" y="6" width="18" height="13" rx="2"/><path d="M3 10h18M7 15h4"/> 623 </svg> 624 </span> 625 <h3 class="mt-5 font-display text-lg font-semibold text-slate-900 dark:text-white">Payment only on delivery</h3> 626 <p class="mt-2 text-slate-600 dark:text-slate-300 leading-relaxed">Stripe holds the payment until the driver marks the job complete.</p> 627 </div> 628 <div class="card card-hover reveal p-6"> 629 <span class="inline-flex h-10 w-10 items-center justify-center rounded-xl 630 bg-slate-100 text-slate-700 ring-1 ring-slate-200 631 dark:bg-slate-800 dark:text-slate-200 dark:ring-slate-700"> 632 <svg class="h-5 w-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" 633 stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> 634 <path d="M12 3a9 9 0 0 0-9 9v3a3 3 0 0 0 3 3h1v-7H5v-1a7 7 0 1 1 14 0v1h-2v7h1a3 3 0 0 0 3-3v-3a9 9 0 0 0-9-9Z"/> 635 </svg> 636 </span> 637 <h3 class="mt-5 font-display text-lg font-semibold text-slate-900 dark:text-white">Troy answers questions, day or night</h3> 638 <p class="mt-2 text-slate-600 dark:text-slate-300 leading-relaxed">In-app + on-call AI assistant trained on the whole platform. No phone tree.</p> 639 </div> 640 </div> 641 </div> 642</section> 643 <section class="section bg-slate-950 text-white relative overflow-hidden"> 644 645 <div aria-hidden="true" class="pointer-events-none absolute inset-0"> 646 <div class="absolute -top-40 -right-40 h-[480px] w-[480px] rounded-full opacity-30 blur-3xl 647 bg-[radial-gradient(circle_at_center,theme(colors.brand.500)_0%,transparent_60%)]"></div> 648 <div class="absolute -bottom-40 -left-40 h-[480px] w-[480px] rounded-full opacity-20 blur-3xl 649 bg-[radial-gradient(circle_at_center,theme(colors.flame.500)_0%,transparent_60%)]"></div> 650 </div> 651 652 <div class="container-wide relative"> 653 <div class="grid gap-12 lg:grid-cols-2 lg:gap-16 items-center"> 654 <div>
655 <span class="pill bg-white/10 text-white ring-white/20">Meet Troy</span> 656 <h2 class="reveal mt-4 font-display text-3xl sm:text-4xl font-semibold tracking-tight text-white"> 657 Your in-house concierge. No phone tree, no "press 1 for support." 658 </h2> 659 <p class="reveal mt-5 text-lg text-slate-300 leading-relaxed"> 660 Troy knows the whole platform, pricing, safety, how bids work, how to be a great driver, what to do when a delivery hits a snag. Chat in the app, on the website, or pick up the phone. 661 </p> 662 <div class="reveal mt-8 flex flex-wrap items-center gap-3"> 663 <button type="button" onclick="window.dispatchEvent(new CustomEvent('troy:open'))" 664 class="btn-brand text-base hover:no-underline"> 665 Chat with Troy 666 <svg class="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"> 667 <path stroke-linecap="round" stroke-linejoin="round" d="M21 12a9 9 0 1 1-3.2-6.86L21 3l-1 5h-4"/> 668 </svg> 669 </button> 670 <a href="tel:+15673523609" class="btn-outline border-white/20 text-white hover:bg-white/10 text-base hover:no-underline"> 671 <svg class="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"> 672 <path stroke-linecap="round" stroke-linejoin="round" d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72c.13.92.36 1.82.7 2.68a2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.4-1.27a2 2 0 0 1 2.11-.45c.86.34 1.76.57 2.68.7A2 2 0 0 1 22 16.92Z"/> 673 </svg> 674 Call Troy · +15673523609 675 </a> 676 </div> 677 <p class="reveal mt-4 text-xs text-slate-500"> 678 Troy is in early access and learns from the platform daily. He'll hand off to a human teammate when something needs a human touch. 679 </p> 680 </div> 681 682 683 <div class="reveal"> 684 <div class="rounded-2xl bg-white/[0.04] ring-1 ring-white/10 backdrop-blur-sm p-5 shadow-soft-lg"> 685 <div class="flex items-center gap-3 pb-4 border-b border-white/10"> 686 <span class="inline-flex h-9 w-9 items-center justify-center rounded-full bg-brand-600 font-display font-semibold text-white text-sm">T</span> 687 <div class="leading-tight"> 688 <p class="font-medium">Troy</p> 689 <p class="text-xs text-slate-300 flex items-center gap-1.5"> 690 <span class="inline-block h-1.5 w-1.5 rounded-full bg-emerald-400 animate-subtle-pulse"></span> 691 Online 692 </p> 693 </div> 694 </div> 695 <div class="space-y-3 pt-4 text-sm"> 696 <div class="ml-auto max-w-[80%] rounded-2xl rounded-tr-sm bg-brand-600 text-white px-3.5 py-2.5"> 697 Got a couch to move from Brooklyn to Queens, how much should I expect? 698 </div> 699 <div class="max-w-[85%] rounded-2xl rounded-tl-sm bg-white/[0.06] text-slate-100 px-3.5 py-2.5"> 700 For a single couch across two boroughs you'll usually see bids in the $60â110 range, depending on stairs and time of day. Want me to walk you through posting it? 701 </div> 702 <div class="ml-auto max-w-[80%] rounded-2xl rounded-tr-sm bg-brand-600 text-white px-3.5 py-2.5"> 703 Yes please. 704 </div> 705 <div class="max-w-[85%] rounded-2xl rounded-tl-sm bg-white/[0.06] text-slate-100 px-3.5 py-2.5"> 706 Snap a photo of the couch, set the two addresses, and pick "as soon as possible." I'll wait here, ping me when the first bid comes in. 707 </div> 708 </div> 709 </div> 710 </div> 711 </div> 712 </div> 713</section> 714 <section class="section"> 715 <div class="container-wide grid gap-12 lg:grid-cols-3"> 716 <div class="lg:sticky lg:top-24 self-start">
717 <span class="pill reveal">FAQ</span> 718 <h2 class="reveal mt-4 font-display text-3xl sm:text-4xl font-semibold tracking-tight text-slate-900 dark:text-white"> 719 Quick answers. 720 </h2> 721 <p class="reveal mt-4 text-slate-600 dark:text-slate-300 leading-relaxed"> 722 More questions? Reach our team or ask Troy in the chat, both options are open right now. 723 </p> 724 </div> 725 726 <div class="lg:col-span-2 divide-y divide-slate-200 dark:divide-slate-800 727 border-y border-slate-200 dark:border-slate-800"> 728 <details class="group reveal py-5 marker:hidden [&::-webkit-details-marker]:hidden" 729 open > 730 <summary class="cursor-pointer list-none flex items-start justify-between gap-6 731 font-display text-lg font-medium text-slate-900 dark:text-white 732 hover:text-brand-700 dark:hover:text-brand-300 transition"> 733 <span>How does Truck It work?</span> 734 <span aria-hidden="true" 735 class="mt-1 inline-flex h-7 w-7 shrink-0 items-center justify-center rounded-full 736 ring-1 ring-slate-300 dark:ring-slate-700 text-slate-500 dark:text-slate-400 737 transition group-open:rotate-45 group-open:bg-brand-600 group-open:text-white group-open:ring-brand-600"> 738 <svg class="h-3.5 w-3.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"> 739 <path stroke-linecap="round" stroke-linejoin="round" d="M12 5v14M5 12h14"/> 740 </svg> 741 </span> 742 </summary> 743 <p class="mt-3 max-w-prose text-slate-600 dark:text-slate-300 leading-relaxed"> 744 Post what you need moved with a few photos and locations. Nearby drivers send you offers within minutes. Accept the one you like, the driver picks it up the same day, you track them in real time, and pay only after delivery. 745 </p> 746 </details> 747 <details class="group reveal py-5 marker:hidden [&::-webkit-details-marker]:hidden" 748 > 749 <summary class="cursor-pointer list-none flex items-start justify-between gap-6 750 font-display text-lg font-medium text-slate-900 dark:text-white 751 hover:text-brand-700 dark:hover:text-brand-300 transition"> 752 <span>What can I move with Truck It?</span> 753 <span aria-hidden="true" 754 class="mt-1 inline-flex h-7 w-7 shrink-0 items-center justify-center rounded-full 755 ring-1 ring-slate-300 dark:ring-slate-700 text-slate-500 dark:text-slate-400 756 transition group-open:rotate-45 group-open:bg-brand-600 group-open:text-white group-open:ring-brand-600"> 757 <svg class="h-3.5 w-3.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"> 758 <path stroke-linecap="round" stroke-linejoin="round" d="M12 5v14M5 12h14"/> 759 </svg> 760 </span> 761 </summary> 762 <p class="mt-3 max-w-prose text-slate-600 dark:text-slate-300 leading-relaxed"> 763 Furniture, appliances, boxes for moving day, a single couch, a load from the hardware store, items from Facebook Marketplace, anything that fits in a pickup truck. For bigger jobs, drivers with larger trucks and helpers are available too. 764 </p> 765 </details> 766 <details class="group reveal py-5 marker:hidden [&::-webkit-details-marker]:hidden" 767 > 768 <summary class="cursor-pointer list-none flex items-start justify-between gap-6 769 font-display text-lg font-medium text-slate-900 dark:text-white 770 hover:text-brand-700 dark:hover:text-brand-300 transition">
771 <span>How is pricing decided?</span> 772 <span aria-hidden="true" 773 class="mt-1 inline-flex h-7 w-7 shrink-0 items-center justify-center rounded-full 774 ring-1 ring-slate-300 dark:ring-slate-700 text-slate-500 dark:text-slate-400 775 transition group-open:rotate-45 group-open:bg-brand-600 group-open:text-white group-open:ring-brand-600"> 776 <svg class="h-3.5 w-3.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"> 777 <path stroke-linecap="round" stroke-linejoin="round" d="M12 5v14M5 12h14"/> 778 </svg> 779 </span> 780 </summary> 781 <p class="mt-3 max-w-prose text-slate-600 dark:text-slate-300 leading-relaxed"> 782 Drivers send you bids based on distance, the size of the load, and timing. You see the price up front, accept the offer that works for you, and pay exactly that, no surge multipliers, no surprises at drop-off. 783 </p> 784 </details> 785 <details class="group reveal py-5 marker:hidden [&::-webkit-details-marker]:hidden" 786 > 787 <summary class="cursor-pointer list-none flex items-start justify-between gap-6 788 font-display text-lg font-medium text-slate-900 dark:text-white 789 hover:text-brand-700 dark:hover:text-brand-300 transition"> 790 <span>Is my payment safe?</span> 791 <span aria-hidden="true" 792 class="mt-1 inline-flex h-7 w-7 shrink-0 items-center justify-center rounded-full 793 ring-1 ring-slate-300 dark:ring-slate-700 text-slate-500 dark:text-slate-400 794 transition group-open:rotate-45 group-open:bg-brand-600 group-open:text-white group-open:ring-brand-600"> 795 <svg class="h-3.5 w-3.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"> 796 <path stroke-linecap="round" stroke-linejoin="round" d="M12 5v14M5 12h14"/> 797 </svg> 798 </span> 799 </summary> 800 <p class="mt-3 max-w-prose text-slate-600 dark:text-slate-300 leading-relaxed"> 801 Yes. Payments are processed by Stripe and only released to the driver after the delivery is marked complete. If something goes wrong, we have a dispute flow and our support team is one tap away in the app. 802 </p> 803 </details> 804 <details class="group reveal py-5 marker:hidden [&::-webkit-details-marker]:hidden" 805 > 806 <summary class="cursor-pointer list-none flex items-start justify-between gap-6 807 font-display text-lg font-medium text-slate-900 dark:text-white 808 hover:text-brand-700 dark:hover:text-brand-300 transition"> 809 <span>How do drivers get paid?</span> 810 <span aria-hidden="true" 811 class="mt-1 inline-flex h-7 w-7 shrink-0 items-center justify-center rounded-full 812 ring-1 ring-slate-300 dark:ring-slate-700 text-slate-500 dark:text-slate-400 813 transition group-open:rotate-45 group-open:bg-brand-600 group-open:text-white group-open:ring-brand-600"> 814 <svg class="h-3.5 w-3.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"> 815 <path stroke-linecap="round" stroke-linejoin="round" d="M12 5v14M5 12h14"/> 816 </svg> 817 </span> 818 </summary> 819 <p class="mt-3 max-w-prose text-slate-600 dar
819k:text-slate-300 leading-relaxed"> 820 Drivers earn 80% of every accepted offer, plus 100% of tips. Payouts hit your bank account through Stripe Connect on a daily schedule, no waiting two weeks for a check. 821 </p> 822 </details> 823 <details class="group reveal py-5 marker:hidden [&::-webkit-details-marker]:hidden" 824 > 825 <summary class="cursor-pointer list-none flex items-start justify-between gap-6 826 font-display text-lg font-medium text-slate-900 dark:text-white 827 hover:text-brand-700 dark:hover:text-brand-300 transition"> 828 <span>Where is Truck It available?</span> 829 <span aria-hidden="true" 830 class="mt-1 inline-flex h-7 w-7 shrink-0 items-center justify-center rounded-full 831 ring-1 ring-slate-300 dark:ring-slate-700 text-slate-500 dark:text-slate-400 832 transition group-open:rotate-45 group-open:bg-brand-600 group-open:text-white group-open:ring-brand-600"> 833 <svg class="h-3.5 w-3.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"> 834 <path stroke-linecap="round" stroke-linejoin="round" d="M12 5v14M5 12h14"/> 835 </svg> 836 </span> 837 </summary> 838 <p class="mt-3 max-w-prose text-slate-600 dark:text-slate-300 leading-relaxed"> 839 Truck It is live across the United States with active driver networks growing every week. If you don't see drivers in your area yet, post a job anyway, that signals where we should onboard next. 840 </p> 841 </details> 842 </div> 843 </div> 844</section> 845 <section class="py-14 sm:py-16 lg:py-20" aria-label="We deliver from"> 846 <div class="container-wide"> 847 <p class="reveal text-center text-xs font-semibold uppercase tracking-[0.2em] text-slate-500 dark:text-slate-400"> 848 We deliver from 849 </p> 850 </div> 851 852 <div class="marquee mt-8"> 853 <div class="marquee__track"> 854 855 <ul class="marquee__group" > 856 <li class="marquee__chip"> 857 <img src="/img/stores/costco.svg" alt="Costco" decoding="async"> 858 </li> 859 <li class="marquee__chip"> 860 <img src="/img/stores/homedepot.svg" alt="The Home Depot" decoding="async"> 861 </li> 862 <li class="marquee__chip"> 863 <img src="/img/stores/homegoods.png" alt="HomeGoods" decoding="async"> 864 </li> 865 <li class="marquee__chip"> 866 <img src="/img/stores/lowes.svg" alt="Lowe's" decoding="async"> 867 </li> 868 <li class="marquee__chip"> 869 <img src="/img/stores/fredmeyer.svg" alt="Fred Meyer" decoding="async"> 870 </li> 871 <li class="marquee__chip"> 872 <img src="/img/stores/bjs.svg" alt="BJ's Wholesale Club" decoding="async"> 873 </li> 874 <li class="marquee__chip"> 875 <img src="/img/stores/walmart.svg" alt="Walmart" decoding="async"> 876 </li> 877 <li class="marquee__chip"> 878 <img src="/img/stores/target.svg" alt="Target" decoding="async"> 879 </li> 880 <li class="marquee__chip"> 881 <img src="/img/stores/goodwill.svg" alt="Goodwill" decoding="async"> 882 </li> 883 <li class="marquee__chip"> 884 <img src="/img/stores/roomstogo.jpg" alt="Rooms To Go" decoding="async"> 885 </li> 886 <li class="marquee__chip"> 887 <img src="/img/stores/ikea.svg" alt="IKEA" decoding="async"> 888 </li> 889 <li class="marquee__chip"> 890 <img src="/img/stores/kroger.svg" alt="Kroger" decoding="async"> 891 </li> 892 <li class="marquee__chip"> 893 <img src="/img/stores/samsclub.svg" alt="Sam's Club" decoding="async"> 894 </li> 895 </ul> 896 <ul class="marquee__group" aria-hidden="true" > 897 <li class="marquee__chip"> 898 <img src="/img/stores/costco.svg" alt="" decoding="async"> 899 </li> 900 <li class="marquee__chip"> 901 <img src="/img/stores/homedepot.svg" alt="" decoding="async"> 902 </li> 903 <li class="marquee__chip"> 904 <img src="/img/stores/homegoods.png" alt="" decoding="async"> 905 </li> 906 <li class="marquee__chip"> 907 <img src="/img/stores/lowes.svg" alt="" decoding="async"> 908 </li> 909 <li class="marquee__chip"> 910 <img src="/img/stores/fredmeyer.svg" alt="" decoding="async"> 911 </li> 912 <li class="marquee__chip"> 913 <img src="/img/stores/bjs.svg" alt="" decoding="async"> 914 </li> 915 <li class="marquee__chip"> 916 <img src="/img/stores/walmart.svg" alt="" decoding="async"> 917 </li> 918 <li class="marquee__chip"> 919 <img src="/img/stores/target.svg" alt="" decoding="async"> 920 </li> 921 <li class="marquee__chip"> 922 <img src="/img/stores/goodwill.svg" alt="" decoding="async"> 923 </li> 924 <li class="marquee__chip"> 925 <img src="/img/stores/roomstogo.jpg" alt="" decoding="async"> 926 </li> 927 <li class="marquee__chip"> 928 <img src="/img/stores/ikea.svg" alt="" decoding="async"> 929 </li> 930 <li class="marquee__chip"> 931 <img src="/img/stores/kroger.svg" alt="" decoding="async"> 932 </li> 933 <li class="marquee__chip"> 934 <img src="/img/stores/samsclub.svg" alt="" decoding="async"> 935 </li> 936 </ul> 937 </div> 938 </div> 939 </section> 940 <section class="section"> 941 <div class="container-wide"> 942 <div class="relative overflow-hidden rounded-3xl 943 bg-gradient-to-br from-slate-900 via-slate-900 to-brand-900 944 ring-1 ring-slate-800 945 px-6 py-14 sm:px-12 sm:py-20 text-center"> 946 <div aria-hidden="true" class="absolute inset-0 pointer-events-none"> 947 <div class="absolute -top-32 left-1/2 -translate-x-1/2 h-[420px] w-[840p
947x] max-w-full rounded-full 948 opacity-30 blur-3xl 949 bg-[radial-gradient(circle_at_center,theme(colors.brand.400)_0%,transparent_60%)]"></div> 950 </div> 951 952 <h2 class="reveal relative font-display text-3xl sm:text-4xl lg:text-5xl font-semibold tracking-tight text-white"> 953 Move it today. 954 </h2> 955 <p class="reveal relative mt-4 mx-auto max-w-xl text-slate-300 text-lg leading-relaxed"> 956 Free to download. No subscription. Your first pickup posts in under a minute. 957 </p> 958 <div class="reveal relative mt-9 flex flex-wrap items-center justify-center gap-4"> 959 <a href="https://apps.apple.com/us/app/truck-it-app/id1474750322" target="_blank" rel="noopener" aria-label="Download Truck It on the App Store" class="hover:opacity-90 transition"> 960 <img src="/img/App-Store-Download.png" alt="Download on the App Store" width="180" height="54" class="h-14 w-auto"> 961 </a> 962 <a href="https://play.google.com/store/apps/details?id=com.dttruckit.user" target="_blank" rel="noopener" aria-label="Get Truck It on Google Play" class="hover:opacity-90 transition"> 963 <img src="/img/Google-Play-Download.png" alt="Get it on Google Play" width="180" height="54" class="h-14 w-auto"> 964 </a> 965 </div> 966 </div> 967 </div> 968</section> 969 </main> 970 971 <div id="site-footer"> 972 <footer class="border-t border-slate-200 dark:border-slate-800 bg-white dark:bg-slate-950"> 973 <div class="container-wide py-14"> 974 <div class="grid gap-10 lg:grid-cols-4"> 975 <div class="lg:col-span-2 max-w-md"> 976 <a href="/" class="flex items-center gap-2.5 text-slate-900 dark:text-white hover:no-underline" aria-label="Truck It home"> 977 <img src="/img/Logo-Truck-It-.png" alt="" width="40" height="40" class="h-10 w-auto"> 978 <span class="font-display font-semibold text-lg tracking-tight">Truck It</span> 979 </a> 980 <p class="mt-4 text-slate-600 dark:text-slate-300 leading-relaxed"> 981 A friend with a truck, on demand. Connect with local drivers to move what you need, same-day, transparent, real-time. 982 </p> 983 <div class="mt-6 flex items-center gap-3"> 984 <a href="https://apps.apple.com/us/app/truck-it-app/id1474750322" target="_blank" rel="noopener" aria-label="Download Truck It on the App Store"> 985 <img src="/img/App-Store-Download.png" alt="Download on the App Store" width="160" height="48" class="h-12 w-auto"> 986 </a> 987 <a href="https://play.google.com/store/apps/details?id=com.dttruckit.user" target="_blank" rel="noopener" aria-label="Get Truck It on Google Play"> 988 <img src="/img/Google-Play-Download.png" alt="Get it on Google Play" width="160" height="48" class="h-12 w-auto"> 989 </a> 990 </div> 991 </div> 992 993 <div> 994 <h3 class="text-sm font-semibold tracking-wide text-slate-900 dark:text-white uppercase">Platform</h3> 995 <ul class="mt-4 space-y-3 text-sm"> 996 <li><a class="text-slate-600 hover:text-slate-900 dark:text-slate-300 dark:hover:text-white no-underline hover:no-underline" href="/customers">Request a pickup</a></li> 997 <li><a class="text-slate-600 hover:text-slate-900 dark:text-slate-300 dark:hover:text-white no-underline hover:no-underline" href="/drivers">Drive and earn</a></li> 998 <li><a class="text-slate-600 hover:text-slate-900 dark:text-slate-300 dark:hover:text-white no-underline hover:no-underline" href="/partners">Partner with us</a></li> 999 <li><a class="text-slate-600 hover:text-slate-900 dark:text-slate-300 dark:hover:text-white no-underline hover:no-underline" href="/tutorials">Help and tutorials</a></li> 1000 </ul> 1001 </div> 1002 <div> 1003 <h3 class="text-sm font-semibold tracking-wide text-slate-900 dark:text-white uppercase">Company</h3> 1004 <ul class="mt-4 space-y-3 text-sm"> 1005 <li><a class="text-slate-600 hover:text-slate-900 dark:text-slate-300 dark:hover:text-white no-underline hover:no-underline" href="/blog">Moving guides</a></li> 1006 <li><a class="text-slate-600 hover:text-slate-900 dark:text-slate-300 dark:hover:text-white no-underline hover:no-underline" href="/contact">Support</a></li> 1007 <li><a class="text-slate-600 hover:text-slate-900 dark:text-slate-300 dark:hover:text-white no-underline hover:no-underline" href="/privacy-policy">Privacy policy</a></li> 1008 <li><a class="text-slate-600 hover:text-slate-900 dark:text-slate-300 dark:hover:text-white no-underline hover:no-underline" href="/terms-conditions">Terms & conditions</a></li> 1009 </ul> 1010 </div> 1011 </div> 1012 1013 <div class="mt-12 pt-8 border-t border-slate-200 dark:border-slate-800 flex flex-col-reverse sm:flex-row sm:items-center sm:justify-between gap-x-6 gap-y-3 text-xs text-slate-600 dar
1013k:text-slate-300"> 1014 <p>© 2026 Truck It App LLC. All rights reserved.</p> 1015 <div class="flex flex-wrap items-center gap-x-5 gap-y-2"> 1016 <a href="https://www.truckit-app.com/login" class="text-slate-600 hover:text-slate-700 dark:text-slate-300 dark:hover:text-white no-underline hover:no-underline">Log in</a> 1017 <p class="flex items-center gap-2"> 1018 <span class="inline-block h-1.5 w-1.5 rounded-full bg-emerald-500 animate-subtle-pulse" aria-hidden="true"></span> 1019 Built in the US, drivers nationwide. 1020 </p> 1021 </div> 1022 </div> 1023 </div> 1024</footer> 1025 </div> 1026 1027 1028 <div id="troy-launcher" data-turbo-permanent> 1029 <div x-data="troyChat()" 1030 x-init=" 1031 window.addEventListener('troy:open', () => open()); 1032 $watch('isOpen', v => { if (v) $nextTick(() => $refs.input?.focus()) }); 1033 " 1034 class="fixed right-3 sm:right-6 z-50" 1035 style="bottom: max(1.25rem, env(safe-area-inset-bottom));"> 1036 1037 <button type="button" 1038 x-show="!isOpen" 1039 x-transition.opacity 1040 @click="open()" 1041 class="troy-launcher-pill inline-flex items-center gap-2.5 pl-2 pr-4 py-1.5 1042 text-slate-900 dark:text-white transition-transform hover:scale-[1.02]" 1043 aria-label="Open Troy"> 1044 <span class="inline-flex h-8 w-8 items-center justify-center rounded-full bg-brand-600 text-white text-sm font-display font-semibold shadow-inner">T</span> 1045 <span class="text-sm font-medium pr-0.5">Ask Troy</span> 1046 </button> 1047 1048 1049 <div x-show="isOpen" 1050 x-transition:enter="transition ease-out duration-200" 1051 x-transition:enter-start="opacity-0 translate-y-2 scale-95" 1052 x-transition:enter-end="opacity-100 translate-y-0 scale-100" 1053 x-transition:leave="transition ease-in duration-150" 1054 x-transition:leave-start="opacity-100 translate-y-0 scale-100" 1055 x-transition:leave-end="opacity-0 translate-y-2 scale-95" 1056 class="origin-bottom-right w-[min(380px,calc(100vw-2rem))] h-[min(560px,80vh)] 1057 troy-launcher-panel flex flex-col overflow-hidden" 1058 style="display: none;"> 1059 1060 <div class="px-4 py-3 border-b border-white/45 dark:border-white/10 flex items-center justify-between gap-3"> 1061 <div class="flex items-center gap-2.5"> 1062 <span class="inline-flex h-8 w-8 items-center justify-center rounded-full bg-brand-600 text-white text-sm font-display font-semibold">T</span> 1063 <div class="leading-tight"> 1064 <p class="text-sm font-medium text-slate-900 dark:text-white">Troy</p> 1065 <p class="text-[11px] text-slate-600 dark:text-slate-300 flex items-center gap-1.5"> 1066 <span class="inline-block h-1.5 w-1.5 rounded-full bg-emerald-500 animate-subtle-pulse"></span> 1067 Online · AI concierge 1068 </p> 1069 </div> 1070 </div> 1071 <div class="flex items-center gap-1"> 1072 <button type="button" @click="reset()" title="Start over" 1073 class="p-1.5 rounded-full text-slate-500 hover:text-slate-800 hover:bg-white/60 dark:text-slate-400 dark:hover:text-slate-100 dark:hover:bg-white/10"> 1074 <svg class="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M3 12a9 9 0 1 0 3-6.7L3 8M3 3v5h5"/></svg> 1075 </button> 1076 <button type="button" @click="close()" title="Close" 1077 class="p-1.5 rounded-full text-slate-500 hover:text-slate-800 hover:bg-white/60 dark:text-slate-400 dark:hover:text-slate-100 dark:hover:bg-white/10"> 1078 <svg class="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12"/></svg> 1079 </button> 1080 </div> 1081 </div> 1082 1083 1084 <div x-ref="scroll" class="flex-1 overflow-y-auto px-4 py-4 space-y-3 text-sm"> 1085 <template x-for="(m, i) in messages" :key="i"> 1086 <div :class="m.role === 'user' ? 'ml-auto max-w-[78%] bg-brand-600 text-white rounded-2xl rounded-tr-sm shadow-lg shadow-brand-900/10' : 'max-w-[84%] bg-white/70 dark:bg-white/10 text-slate-900 dark:text-slate-100 rounded-2xl rounded-tl-sm r
1086ing-1 ring-white/50 dark:ring-white/10'" 1087 class="w-fit min-w-0 px-3.5 py-2.5 leading-relaxed break-words"> 1088 <div x-show="m.pending && !m.content" class="text-slate-500 dark:text-slate-400 inline-flex items-center gap-1.5 py-0.5" aria-label="Troy is typing"> 1089 <span class="inline-block h-2 w-2 rounded-full bg-slate-400 animate-bounce" style="animation-delay: 0ms"></span> 1090 <span class="inline-block h-2 w-2 rounded-full bg-slate-400 animate-bounce" style="animation-delay: 120ms"></span> 1091 <span class="inline-block h-2 w-2 rounded-full bg-slate-400 animate-bounce" style="animation-delay: 240ms"></span> 1092 </div> 1093 <div x-show="m.content" 1094 class="troy-markdown" 1095 :class="m.role === 'user' ? 'troy-markdown-user' : 'troy-markdown-assistant'" 1096 x-html="renderMessage(m)"></div> 1097 </div> 1098 </template> 1099 </div> 1100 1101 1102 <form @submit.prevent="send()" class="px-3 py-3 border-t border-white/45 dark:border-white/10 flex items-end gap-2"> 1103 <textarea x-ref="input" x-model="draft" 1104 @keydown.enter.prevent="if (!$event.shiftKey) send()" 1105 rows="1" placeholder="Ask Troy anythingâ¦" 1106 class="flex-1 resize-none rounded-xl border-white/60 bg-white/75 dark:border-white/10 dark:bg-white/10 dark:text-white shadow-sm focus:border-brand-500 focus:ring-brand-500 text-sm"></textarea> 1107 <button type="submit" :disabled="!draft.trim() || isStreaming" 1108 class="inline-flex items-center justify-center h-10 w-10 rounded-xl bg-brand-600 text-white disabled:opacity-40 disabled:cursor-not-allowed hover:bg-brand-700 transition"> 1109 <svg class="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M3.4 20.6 21 12 3.4 3.4l3 8.6-3 8.6z"/></svg> 1110 </button> 1111 </form> 1112 <p class="px-4 pb-3 text-[10px] text-slate-400 dark:text-slate-500"> 1113 Troy is in early access. Answers may be incomplete, for anything urgent, <a href="/contact" class="underline underline-offset-2">contact a human</a>. 1114 </p> 1115 </div> 1116</div> 1117 1118 </div> 1119 1120 1121 <meta name="csrf-token" content="BHeKMlF6hGV0O5ueWkGykx45RGuoDdx1iTLUVieC"> 1122 1123
1123<script> 1124 /** 1125 * Tiny Alpine component for Troy. State lives entirely in the 1126 * launcher, no global store. SSE stream is parsed client-side 1127 * and appended to the assistant's growing message. 1128 */ 1129 function troyChat() { 1130 return { 1131 isOpen: false, 1132 isStreaming: false, 1133 draft: '', 1134 conversationId: '', 1135 messages: [ 1136 { role: 'assistant', content: "Hey, I'm Troy. Ask me anything about moving stuff with Truck It, pricing, driver earnings, the apps, whatever." }, 1137 ], 1138 _csrf: document.querySelector('meta[name="csrf-token"]')?.content || '', 1139 init() { 1140 this.conversationId = this._newConversationId(); 1141 }, 1142 open() { this.isOpen = true; }, 1143 close() { this.isOpen = false; }, 1144 reset() { 1145 this.messages = [{ role: 'assistant', content: "Started over. What's up?" }]; 1146 this.draft = ''; 1147 this.conversationId = this._newConversationId(); 1148 }, 1149 renderMessage(message) { 1150 return this._markdown(message.content || ''); 1151 }, 1152 async send() { 1153 const text = this.draft.trim(); 1154 if (! text || this.isStreaming) return; 1155 this.messages.push({ role: 'user', content: text }); 1156 this.draft = ''; 1157 this.isStreaming = true; 1158 this._scroll(); 1159 1160 // Use fetch + ReadableStream to consume SSE without the 1161 // EventSource auto-reconnect quirks (which would re-fire 1162 // the prompt on every disconnect, expensive + wrong). 1163 let assistantIdx = this.messages.push({ role: 'assistant', content: '', pending: true }) - 1; 1164 try { 1165 const r = await fetch('/troy/chat', { 1166 method: 'POST', 1167 credentials: 'same-origin', 1168 headers: { 1169 'Content-Type': 'application/json', 1170 'X-CSRF-TOKEN': this._csrf, 1171 'Accept': 'text/event-stream', 1172 }, 1173 body: JSON.stringify({ 1174 conversation_id: this.conversationId, 1175 history: this.messages.slice(0, -1).map(m => ({ role: m.role, content: m.content })), 1176 }), 1177 }); 1178 if (! r.ok || ! r.body) throw new Error('bad response'); 1179 1180 const reader = r.body.getReader(); 1181 const dec = new TextDecoder(); 1182 let buf = ''; 1183 // eslint-disable-next-line no-constant-condition 1184 while (true) { 1185 const { value, done } = await reader.read(); 1186 if (done) break; 1187 buf += dec.decode(value, { stream: true }); 1188 // SSE event boundary is \n\n 1189 let idx; 1190 while ((idx = buf.indexOf('\n\n')) !== -1) { 1191 const event = buf.slice(0, idx); 1192 buf = buf.slice(idx + 2); 1193 for (const line of event.split('\n')) { 1194 if (! line.startsWith('data:')) continue; 1195 const data = line.slice(5).trim(); 1196 if (data === '[DONE]') continue; 1197 try { 1198 const j = JSON.parse(data); 1199 if (typeof j.delta === 'string') { 1200 this.messages[assistantIdx].content += j.delta; 1201 this._scroll(); 1202 } 1203 } catch (_) { /* ignore parse errors */ } 1204 } 1205 } 1206 } 1207 } catch (e) { 1208 this.messages[assistantIdx].content ||= "I couldn't reach my brain just now. Try again in a moment, or hit the contact page if it persists."; 1209 } finally { 1210 this.messages[assistantIdx].pending = false;
1211 this.isStreaming = false; 1212 this._scroll(); 1213 } 1214 }, 1215 _markdown(raw) { 1216 const stash = []; 1217 const hold = html => { 1218 stash.push(html); 1219 return '\u0000' + (stash.length - 1) + '\u0000'; 1220 }; 1221 const restore = html => html.replace(/\u0000(\d+)\u0000/g, (_, i) => stash[Number(i)] || ''); 1222 const esc = s => String(s) 1223 .replace(/&/g, '&') 1224 .replace(/</g, '<') 1225 .replace(/>/g, '>') 1226 .replace(/"/g, '"') 1227 .replace(/'/g, '''); 1228 const visibleUrl = url => { 1229 let href = String(url || '').trim().replace(/&/g, '&'); 1230 if (! href) return ''; 1231 if (href.startsWith('/')) href = 'https://www.truckit-app.com' + href; 1232 else if (/^http:\/\//i.test(href)) href = href.replace(/^http:\/\//i, 'https://'); 1233 else if (! /^https:\/\//i.test(href)) href = 'https://' + href.replace(/^www\./i, 'www.'); 1234 href = href.replace(/^https:\/\/truckit-app\.com/i, 'https://www.truckit-app.com'); 1235 try { 1236 const parsed = new URL(href); 1237 if (parsed.protocol !== 'https:') return ''; 1238 return parsed.href; 1239 } catch (_) { 1240 return ''; 1241 } 1242 }; 1243 const anchor = (label, url, labelEscaped = false) => { 1244 const href = visibleUrl(url); 1245 if (! href) return labelEscaped ? String(label) : esc(label); 1246 const rawLabel = String(label || '').trim(); 1247 const safeHref = esc(href); 1248 if (! rawLabel || /^https:\/\//i.test(rawLabel)) { 1249 return `<a href="${safeHref}" target="_blank" rel="noopener noreferrer">${safeHref}</a>`; 1250 } 1251 const safeLabel = labelEscaped ? rawLabel : esc(rawLabel); 1252 return `<a href="${safeHref}" target="_blank" rel="noopener noreferrer">${safeLabel} <span class="troy-link-url">(${safeHref})</span></a>`; 1253 }; 1254 1255 let text = esc(raw).replace(/\r\n/g, '\n').replace(/\r/g, '\n'); 1256 text = text.replace(/`([^`\n]+)`/g, (_, code) => hold(`<code>${code}</code>`)); 1257 text = text.replace(/\[([^\]\n]+)\]\(([^)\s]+)\)/g, (_, label, url) => hold(anchor(label, url, true))); 1258 text = text.replace(/(^|[\s(])([A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,})\b/gi, (_, lead, email) => { 1259 const safeEmail = esc(email); 1260 return `${lead}${hold(`<a href="mailto:${safeEmail}">${safeEmail}</a>`)}`; 1261 }); 1262 text = text.replace(/(^|[\s(])((?:https?:\/\/|www\.|truckit-app\.com|apps\.apple\.com|play\.google\.com)[^\s<]*)/gi, (match, lead, url) => { 1263 let clean = url; 1264 let tail = ''; 1265 while (/[),.!?;:]$/.test(clean)) { 1266 tail = clean.slice(-1) + tail; 1267 clean = clean.slice(0, -1); 1268 } 1269 const href = visibleUrl(clean); 1270 return href ? lead + hold(anchor(href, href)) + tail : match; 1271 }); 1272 text = text.replace(/\*\*([^*\n]+)\*\*/g, '<strong>$1</strong>'); 1273 text = text.replace(/(^|[^\*])\*([^*\n]+)\*/g, '$1<em>$2</em>'); 1274 1275 const lines = text.split('\n'); 1276 const out = []; 1277 let list = null; 1278 const closeList = () => { 1279 if (list) out.push(`</${list}>`); 1280 list = null; 1281 }; 1282 for (const line of lines) { 1283 const trimmed = line.trim(); 1284 if (! trimmed) { 1285 closeList(); 1286 continue; 1287 } 1288 let m = trimmed.match(/^###\s+(.+)/); 1289 if (m) { closeList(); out.push(`<h4>${m[1]}</h4>`); continue; } 1290 m = trimmed.match(/^##\s+(.+)/); 1291 if (m) { closeList(); out.push(`<h4>${m[1]}</h4>`); continue; } 1292 m = trimmed.match(/^[-*]\s+(.+)/); 1293 if (m) { 1294 if (list !== 'ul') { closeList(); out.push('<ul>'); list = 'ul'; } 1295 out.push(`<li>${m[1]}</li>`); 1296 continue; 1297 } 1298 m = trimmed.match(/^\d+\.\s+(.+)/); 1299 if (m) { 1300 if (list !== 'ol') { closeList(); out.push('<ol>'); list = 'ol'; } 1301 out.push(`<li>${m[1]}</li>`); 1302 continue; 1303 } 1304 closeList(); 1305 out.push(`<p>${trimmed}</p>`); 1306 } 1307 closeList(); 1308 return restore(out.join('')); 1309 }, 1310 _scroll() { 1311 this.$nextTick(() => { 1312 if (this.$refs.scroll) this.$refs.scroll.
1312scrollTop = this.$refs.scroll.scrollHeight; 1313 }); 1314 }, 1315 _newConversationId() { 1316 if (window.crypto?.randomUUID) return window.crypto.randomUUID(); 1317 return 'troy-' + Date.now().toString(36) + '-' + Math.random().toString(36).slice(2); 1318 }, 1319 }; 1320 } 1321 window.troyChat = troyChat; 1322 </script>
1322 1323</body> 1324</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.