Landing site
Theming and dark mode
Recolour the site through the design tokens in global.css, swap fonts, and understand the class-based dark mode and the shared slice mark.
Colours and design tokens
All colours and design tokens live in src/styles/global.css. The colour system has two layers, and
the distinction matters:
- Raw palette values are defined in
:root(light) and overridden in.dark(dark):--bg,--surface,--surface-alt,--fg,--heading,--muted,--border, the--accent*and--signal*families and the--ink*family. To recolour the site, edit these raw values. - Theme tokens in the
@themeblock map onto the raw values (for example--color-accent: var(--accent)). Tailwind turns these into the semantic utilities you use in markup:bg-surface,text-muted,text-accent,bg-signal,bg-ink, and so on.
The orange comes in two strengths on purpose:
| Family | What it is for |
|---|---|
accent |
Text-safe orange for links, icons and small labels (#c2410c light, #ff8a5c dark) |
signal |
Bright orange for fills: primary buttons, the CTA band, the logo’s slice. Pair it with signal-fg text; it is too light for body text |
ink |
The near-black band behind the architecture section, terminals, the featured price card and the footer, with its own ink-fg, ink-muted, ink-heading and ink-border |
Always reach for the semantic utilities in markup and never hard-code a colour. Because the utilities
resolve through the raw variables, and the raw variables flip under .dark, dark mode keeps working
for free.
The same file also defines the typography tokens (--font-display, --font-sans, --font-mono),
section spacing (--spacing-section) and elevation (--shadow-card, --shadow-card-hover, and
--shadow-shot for the raised hero screenshot).
Fonts
The three fonts are self-hosted through @fontsource-variable/* packages, so the site makes no
external font requests. They are imported at the top of src/styles/global.css and wired to the
typography tokens:
| Token | Font | Used for |
|---|---|---|
--font-display |
Bricolage Grotesque | Headings |
--font-sans |
Geist | Body text and labels |
--font-mono |
Geist Mono | Code, file paths and terminal output |
To swap a font: install the matching @fontsource-variable/<name> package, add an @import for it in
global.css, and repoint the relevant --font-* token at the new family. The Open Graph generator
uses TTF copies of the same fonts in scripts/fonts/, so replace those too and update the file list
and family names at the top of scripts/generate-og.mjs.
Dark mode
Dark mode is class-based: the .dark class on <html> swaps the raw palette. The choice is persisted
under the slicekit.theme localStorage key. The SPA uses the same key name, but storage belongs to
an origin, so separate landing and app domains keep independent preferences. Blocked storage falls back to the
system preference; the toggle continues to work in memory. An inline no-flash script in src/layouts/Layout.astro applies the stored theme before
the first paint, so there is no flash of the wrong theme. Shiki code blocks switch to their dark
variables under .dark as well.
The slice mark
The logo (Logo.astro), the favicon (public/favicon.svg), public/logo.svg and the mark()
function in scripts/generate-og.mjs all draw the same mark: three stacked layers cut by one vertical
slice in signal orange. The PNG icons (favicon.ico, apple-touch-icon.png, icon-192.png,
icon-512.png, logo.png) are rendered from those SVGs. If you rebrand the logo, change all of them
together so the favicon and generated Open Graph images stay consistent with the site.
Checklist
- Recolour by editing the raw
--*variables in:rootand.dark; keep using the semantic utilities (bg-surface,text-accent) in markup so dark mode keeps working. - Swap a font by installing its
@fontsource-variablepackage, importing it inglobal.cssand repointing the--font-*token. - Update the logo, favicon, the PNG icons and the
mark()inscripts/generate-og.mjstogether.