Theming
Everything is CSS variables, so a theme is a handful of values. The Studio sets them for you.
Cities
Each city is a palette and a signature band. Danfo Yellow (#FFC400) and Micra Gold (#E8A317) so far. Lagos · Danfo is the default; switch any area with data-theme, or install @cruiseui/cruise-theme-ibadan to make Ibadan the default.
<section data-theme="ibadan">…</section>Main colour
Set --primary to your brand colour. Text on it uses --on-primary, so check the contrast: the Studio checks it and offers a readable version of your colour when it's too low.
.cruise { --primary: #2BB673; --on-primary: #111111; }Dark mode
Add nepa-mode to <html> (or any element, for one dark section). Shadows switch to the main colour. Always label the toggle "Dark mode" with aria-label="Toggle dark mode".
document.documentElement.classList.toggle("nepa-mode");Corners
Square (0px) is the default. For Soft or Round, add data-corners next to the cruise class, on <body> for the whole app or on any area. Every component follows, hard shadows included; checkboxes and the switch knob stay small-cornered, and radios stay round.
Now showing: <body className="cruise" data-corners="round">
app/layout.tsx
<body className="cruise" data-corners="round">Or set the radius yourself, e.g. in globals.css:
globals.css
.cruise { --radius: 12px; }Options: Square 0px · Soft 6px · Round 12px. Plain HTML works the same way: <html data-corners="soft"> with the hosted theme.css.
Focus style
Text fields (inputs, textareas, selects, the combobox, Naira and phone inputs, OTP boxes) show focus by lifting into their hard shadow. For an outline or a coloured border instead, add data-focus next to the cruise class. Buttons, links, checkboxes, radios, switches and tabs keep their keyboard focus ring in every mode. Click or Tab into the fields:
Lift (default)no attribute
Ringdata-focus="ring"
Borderdata-focus="border"
app/layout.tsx
<body className="cruise" data-focus="ring">Options: none (lift), "ring", "border". Under reduced motion the lift keeps its shadow but doesn't move. Every option stays at 3:1 contrast or more, in light and dark mode and on yellow.
Borders and shadows
Borders: Light 2px · Bold 3px · Heavy 4px (--border-w). Shadows: Low 3px · Mid 4px · High 6px (--shadow-x, --shadow-y).
.cruise { --border-w: 2px; --shadow-x: 3px; --shadow-y: 3px; }Lit and dark areas: .on-primary and .on-deep
Any element with a --primary background gets .on-primary: inside it, text, borders and shadows stay dark in both modes. Dark sections (a footer on --deep) get .on-deep. The components add these for you; add them yourself on your own coloured sections.
<section class="on-primary">…</section>
<footer class="on-deep">…</footer>Pidgin copy
Plain English is the default everywhere. In the Studio you can switch the AI prompt to Pidgin mode; it then uses the spec's copy bank for buttons and messages. Component labels are always yours to set.
CSS variables
| Variable | Default | Dark mode | Used for |
|---|---|---|---|
--primary | #FFC400 | — | The city's main colour: buttons, highlights, header strips. |
--on-primary | #111111 | — | Text and icons on --primary. Stays dark in both modes. |
--ink | #111111 | #FFF6E0 | Text, borders and shadows. |
--ink-muted | #5C574A | #B5AE99 | Secondary text only (hints, captions). |
--paper | #FFF6E0 | #14140F | Page background. |
--surface | #FFFFFF | #1F1F1A | Cards, inputs, menus. |
--muted | #E8DCC2 | #2A2A22 | Quiet fills: disabled controls, zebra rows, chips. |
--tint | color-mix(in srgb, var(--primary) 18%, var(--surface)) | color-mix(in srgb, var(--primary) 18%, var(--surface)) | A light wash of --primary for panels. |
--danger | #E63B2E | — | Errors and destructive actions. |
--success | #008751 | — | Done, paid, healthy. |
--info | #2B59C3 | — | Links and info; the keyboard focus ring on .brutal. |
--deep | #1F2A5C | — | Dark sections (footer) with .on-deep. |
--border-w | 3px | — | Border width (Light / Bold / Heavy). |
--radius | 0px | — | Corners (Square / Soft / Round). |
--shadow-x | 4px | — | Hard shadow offset, sideways. |
--shadow-y | 4px | — | Hard shadow offset, down. |
--font-display | 'Baloo 2', system-ui, sans-serif | — | Headings and buttons: Baloo 2. |
--font-body | 'Bricolage Grotesque', system-ui, sans-serif | — | Body text: Bricolage Grotesque. |