> ## Documentation Index
> Fetch the complete documentation index at: https://opencals.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# NOIR Drive — luxury car rental template

> Free, open-source luxury car rental website template. Next.js 15, multi-day booking by the day, delivery or garage collection, per-day extras, chauffeur packages, Stripe checkout and passwordless accounts, built on the Opencals Storefront API.

A complete luxury car-rental website you can clone and deploy today. NOIR Drive
is the first template built around **multi-day bookings**: each car is booked
**by the day**, from a pick-up date to a return date, and blocked for the whole
span. Start here if you rent cars, boats, equipment or villas by the day. It runs
on the same [Storefront API](https://opencals.com/docs/api-reference/introduction.md) and typed
[TypeScript SDK](https://opencals.com/docs/guides/storefront-sdk.md) as [Haar](https://opencals.com/docs/open-source/haar.md),
[Frisor](https://opencals.com/docs/open-source/frisor.md), [Clear Care](https://opencals.com/docs/open-source/clarity.md) and
[VOLT](https://opencals.com/docs/open-source/volt.md).

It's set in Dubai (AED, `Asia/Dubai`) with an all-black fleet of twelve cars.
Two booking surfaces sit over one store: a **multi-day rental flow** for the
fleet, and a classic **chauffeur flow** with real drivers.

> **[Live demo](https://template-noir.vercel.app)**
>
> template-noir.vercel.app

> **[Source code](https://github.com/letsopencals/template-noir)**
>
> letsopencals/template-noir (MIT)

> **[Deploy to Vercel](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fletsopencals%2Ftemplate-noir\&env=OPENCALS_API_KEY,AUTH_SECRET\&envDescription=API%20key%20from%20your%20Opencals%20dashboard%20and%20a%20random%20secret%20for%20auth\&project-name=noir-drive\&repository-name=template-noir)**
>
> One-click deploy

![NOIR Drive luxury car rental website template shown on a laptop in front of a black fleet in Dubai](https://raw.githubusercontent.com/letsopencals/template-noir/main/docs/cover.png)

NOIR Drive — the storefront on desktop, set in Dubai

![NOIR Drive template homepage hero reading Drive the night over a showroom of black cars](https://raw.githubusercontent.com/letsopencals/template-noir/main/docs/homepage-hero.png)

Homepage hero — cinematic, all-black, with Book a car up front

## Multi-day booking

Customers pick a car, choose pick-up and return dates on a range calendar that
reads the car's live availability, then choose *Deliver to my address* or
*Collect at the garage* and a handover window. Per-day extras (excess waiver,
additional driver) are priced × days, and fixed extras (child seat, prepaid
fuel) once. Driving licence and ID uploads and a deposit-and-terms checkbox are
regular checkout questions. The total is always **days × daily rate + extras**,
the same maths the engine charges.

![NOIR Drive template booking flow with a two-month range calendar, handover windows, delivery or garage choice and a rental summary](https://raw.githubusercontent.com/letsopencals/template-noir/main/docs/book-a-car.png)

Book a car — range calendar on live availability, handover windows and a running total

## The rental model

This is the part worth copying even if you never ship NOIR Drive itself. It
uses existing Opencals features only.

| Piece | How it's modelled |
| - | - |
| A car | One staffless product in its own product pool (so a booking blocks it at both locations), `duration: 86400`, `allowCustomDuration: true`, `maxDuration`, `maxAttendees: 1` |
| Availability across midnight | A continuous 24/7 schedule. Bookings longer than 24 hours are validated against continuous availability |
| Date picker | `getCurrentAvailabilitiesMerged` **without** `duration`; the client checks that pick-up → return fits inside one range |
| The slot | Pick-up date 00:00 → return date 00:00 in the store timezone, sent in UTC |
| Handover window, flight number, collection address | Appointment [custom attributes](https://opencals.com/docs/changelog/custom-attributes.md) |
| Delivery or collection | A `PHYSICAL` garage location and a `DELIVERY` location; the customer's address is captured at checkout |
| Per-day extras | Add-ons with `durationMultiplied` |
| Security deposit | Shown per car and accepted with a required checkbox question; taken at handover, never charged online |

Dubai pick-up 10 Nov → return 13 Nov becomes
`{ fromDate: '2026-11-09', fromTime: '20:00:00', toDate: '2026-11-12', toTime: '20:00:00' }`:
three days, three units, three × the daily rate.

Give each car its own product rather than a variant: variants don't block each
other, so the same car could be booked twice.

## What's inside

![NOIR Drive template car page for a Rolls-Royce Cullinan priced per day](https://raw.githubusercontent.com/letsopencals/template-noir/main/docs/car-page.png)

Car page — specs and the daily rate, with a jump to the availability calendar

![NOIR Drive template rates table listing daily rate, deposit and kilometres per day for each car](https://raw.githubusercontent.com/letsopencals/template-noir/main/docs/rates.png)

Rates — one price per day, with deposit and km allowance for every car

![NOIR Drive template chauffeur page offering airport transfers, hourly and full-day packages](https://raw.githubusercontent.com/letsopencals/template-noir/main/docs/chauffeur.png)

Chauffeur — packages booked through the classic staff flow

| Feature | Notes |
| - | - |
| Fleet and car pages | Category filters from collections, "available for your dates", a two-month availability calendar with booked days struck through |
| Rates | A full rates table (daily rate, deposit, km per day) |
| Multi-day booking | Range calendar, delivery or garage, handover windows, per-day and fixed extras, checkout questions |
| Chauffeur | Packages booked through the classic staff flow, with a preferred-car request |
| Cart & Stripe checkout | Cart + Checkout + Payment endpoints |
| Rental-aware accounts | Pick-up → return dates in the store timezone, day count, handover details; customers can change dates (same length) or cancel within policy |
| Passwordless accounts | 6-digit email login (password fallback), one-time email links via `/link/[token]` |
| Motion | Lenis smooth scrolling, text and image reveals, parallax, count-up specs; every effect has a reduced-motion fallback |
| SEO | Per-page metadata, Open Graph, `AutoRental` and `Product` structured data, `robots.txt`, `sitemap.xml` |
| Stack | Next.js 15, TypeScript, Tailwind v4, Framer Motion, `@opencals/storefront-sdk` v0.3.14 |

## Get started

**1. Clone and install**

```bash theme={"theme":{"light":"github-light","dark":"github-dark-default"}}
git clone https://github.com/letsopencals/template-noir.git
cd template-noir
npm install
```

**2. Add your API key**

Create a store in the [Opencals dashboard](https://opencals.com) and choose
the **NOIR Drive** dataset preset (category Car rental). It seeds the
fleet on a 24/7 schedule, the garage and delivery locations, extras,
checkout questions, chauffeurs and packages. Then grab a private storefront key
(`spk_`, see [API keys](https://opencals.com/docs/authentication.md#api-keys)) and set `OPENCALS_API_KEY` and
`AUTH_SECRET` in `.env`.

**3. Run it**

```bash theme={"theme":{"light":"github-light","dark":"github-dark-default"}}
npm run dev
```

Your cars, rates and availability render immediately.

**4. Deploy**

Push to your own repo and
[deploy to Vercel](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fletsopencals%2Ftemplate-noir\&env=OPENCALS_API_KEY,AUTH_SECRET\&envDescription=API%20key%20from%20your%20Opencals%20dashboard%20and%20a%20random%20secret%20for%20auth\&project-name=noir-drive\&repository-name=template-noir),
or host anywhere Next.js runs.

> [!NOTE]
>
> Set **Storefront Base URL** in your dashboard (Settings → API) to your
> deployed domain. Every customer link (view, reschedule, cancel, leave
> feedback) is built as `{storefrontBaseUrl}/link/{token}`, so if it still
> points at localhost those emailed links go nowhere.

## Make it yours

MIT-licensed: rebrand it, restructure it, or use it for client work. All
business copy lives in `lib/site-config.ts`: name, currency and timezone,
per-car specs and deposits, handover windows, delivery zones, FAQs and contact
details. Every colour and font is a Tailwind v4 `@theme` token in
`app/globals.css`:

```css theme={"theme":{"light":"github-light","dark":"github-dark-default"}}
@theme {
  --color-bg: #050505;          /* page black */
  --color-ink: #F4F1EA;         /* warm ivory text */
  --color-primary: #C8A96B;     /* champagne accent */
}
```

Building a different rental site with an AI agent? The
[build-booking-site skill](https://opencals.com/docs/ai-agents/build-booking-site-skill.md) has a
`rentals-multi-day` reference with the full pattern.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.