Theming

CSS variables, colour palettes, typography tokens, and dark mode — everything that shapes the visual identity.

Design Tokens Overview

All visual properties in Zostel UI are controlled by CSS custom properties defined inside the Tailwind v4 @theme block in globals.css. Because they are standard CSS variables, you can override any token at runtime, scope overrides to a selector, or swap entire palettes for dark mode.

Tailwind v4 automatically generates utility classes for every token — so --color-zostel-orange becomes bg-zostel-orange, text-zostel-orange, border-zostel-orange, etc.

Brand Colours

The four core brand colours anchor the entire system:

Zostel Orange
#F1563F
Zostel Grey
#43474B
Zostel White
#FFFFFF
Zostel Beige
#F0EDDE
/* Brand colours */
--color-zostel-orange: #F1563F;
--color-zostel-grey:   #43474B;
--color-zostel-white:  #FFFFFF;
--color-zostel-beige:  #F0EDDE;

Secondary Colour Palettes

Five nature-inspired palettes — each with three shades — provide accent colours for illustrations, data visualisation, and decorative elements.

Sunny Days
#FFAA00
#FF5500
#FFF000
Waters
#99DDFF
#33CCCC
#0066CC
Fields
#CCFF00
#00AA77
#99DD00
Flowers
#FF0066
#FFCC77
#FF1199
Valleys
#9955CC
#6688CC
#FF99CC

Semantic Colour Variables

A shadcn/ui-compatible semantic layer maps abstract names to concrete brand values. Components reference these tokens so they automatically adapt to light and dark mode.

Variable Light Dark
--color-background #F0EDDE #43474B
--color-foreground #43474B #F0EDDE
--color-primary #F1563F #F1563F
--color-card #FFFFFF #3a3a39
--color-muted #e8e4d3 #4a4a49
--color-accent #fde8e2 #4a2a1e
--color-border #d8d5c6 #5a5a59
--color-destructive #FF3311 #FF3311

Font Families

Three typefaces define the Zostel brand voice. Each is registered as a Tailwind font-family token:

Futura
Primary typeface — used for headings, UI text, and the wordmark.
--font-futura: 'Futura', 'Verdana', sans-serif;
--font-sans: 'Futura', 'Verdana', sans-serif;
Gotham Narrow
Secondary typeface — used for body copy and navigational elements.
--font-gotham: 'Gotham Narrow', 'Verdana', sans-serif;
Mrs Eaves
Accent serif — used sparingly for editorial flourishes and pull quotes.
--font-mrs-eaves: 'Mrs Eaves', 'Georgia', serif;

Use the utility classes font-futura, font-gotham, and font-mrs-eaves in your markup.

Dark Mode

Dark mode is activated by adding the .dark class to the <html> or <body> element. The semantic variables are swapped via a .dark CSS selector in globals.css:

/* Dark theme overrides */
.dark {
  --color-background:         #43474B;
  --color-foreground:         #F0EDDE;
  --color-card:               #3a3a39;
  --color-card-foreground:    #F0EDDE;
  --color-muted:              #4a4a49;
  --color-muted-foreground:   #a0a09f;
  --color-accent:             #4a2a1e;
  --color-accent-foreground:  #F0EDDE;
  --color-border:             #5a5a59;
  --color-input:              #5a5a59;
}

Toggle it programmatically with the useTheme hook:

import { useTheme } from 'zostel-ui';

function ThemeToggle() {
  const { theme, toggleTheme } = useTheme();

  return (
    <button onClick={toggleTheme}>
      {theme === 'dark' ? 'Light mode' : 'Dark mode'}
    </button>
  );
}

Tip: The primary and ring colours intentionally stay the same in both modes — Zostel Orange is the brand anchor regardless of theme.

Other Tokens

Border Radius

--radius-sm: 0.25rem
--radius-md: 0.375rem
--radius-lg: 0.5rem
--radius-xl: 0.75rem

Animation Durations

--duration-fast: 150ms
--duration-normal: 300ms
--duration-slow: 500ms
--duration-slower: 1000ms

Customising Tokens

To override any token, add your own @theme block after importing globals.css, or set CSS variables on a wrapping element for scoped overrides:

/* Global override in your app CSS */
@theme {
  --color-primary: #e63946;  /* swap brand colour */
  --radius-lg: 0.75rem;     /* rounder corners */
}

/* Scoped override */
.promo-section {
  --color-background: #1a1a2e;
  --color-foreground: #eaeaea;
}

Built-in Gradient Classes

Four ready-made gradient utility classes combine brand and secondary colours:

.gradient-sunset
Sunny → Orange → Flower
.gradient-ocean
Water-1 → Water-2 → Water-3
.gradient-forest
Field-1 → Field-2 → Field-3
.gradient-brand
Zostel Orange → Flower-1