# 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 vertex 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:

1. **Raw palette values** are defined in `:root` (light) and overridden in `.dark` (dark): `--bg`,
   `--surface`, `--surface-alt`, `--fg`, `--heading`, `--muted`, `--border`, `--accent`,
   `--accent-hover`, `--accent-fg`, `--accent-soft`, `--grid-line` and `--grid-line-major`. The accent
   moves from teal (`#0e7490`) in light to cyan (`#22d3ee`) in dark. **To recolour the site, edit these
   raw values.**
2. **Theme tokens** in the `@theme` block 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`, `border-border`, and so on.

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 card elevation (`--shadow-card`, `--shadow-card-hover`).

## 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`  | Space Grotesk   | Headings           |
| `--font-sans`     | IBM Plex Sans   | Body text          |
| `--font-mono`     | JetBrains Mono  | Kickers and labels |

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.

## 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, which is shared with the product SPA so a visitor's theme
carries across. 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 vertex mark

The logo, the favicon and the `mark()` function in `scripts/generate-og.mjs` all draw the same vertex
mark. If you rebrand the logo, change all three together so the favicon and generated Open Graph images
stay consistent with the site.

## Checklist

- [ ] Recolour by editing the raw `--*` variables in `:root` and `.dark`; keep using the semantic
  utilities (`bg-surface`, `text-accent`) in markup so dark mode keeps working.
- [ ] Swap a font by installing its `@fontsource-variable` package, importing it in `global.css` and
  repointing the `--font-*` token.
- [ ] Update the logo, favicon and the `mark()` in `scripts/generate-og.mjs` together.
