---
name: theme-crafting
description: Author complete custom daisyUI 5 themes for PageWeave — full variable sets, OKLCH color logic, dark-mode safety.
---

# Theme Crafting

Custom daisyUI themes with OKLCH, built for PageWeave

Craft custom themes for PageWeave sites. PageWeave runs Tailwind CSS v4 + daisyUI 5; the theme is pinned via `data-theme` and set with `update_theme(website, config: { css })`.

## Required variables (never skip)

A custom theme must define at minimum:

- `--color-primary` / `--color-primary-content`
- `--color-base-100` / `--color-base-content`
- `--color-neutral` / `--color-neutral-content`

Complete themes also define base-200/base-300, secondary/accent + contents, info/success/warning/error + contents, radius tokens (`--radius-box/field/selector`), `--size-selector`, `--size-field`, `--border`, `--depth`, `--noise`.

## Dark themes MUST include color-scheme

```css
color-scheme: dark;
```

Without it, browser UI (scrollbars, form controls) and PageWeave's watermark render light on a dark site.

## Write bare variables

Pass the variables WITHOUT a `[data-theme]` selector — PageWeave wraps them automatically.

## OKLCH workflow

Work in OKLCH for perceptual uniformity:

1. **Ground first**: pick base-100 lightness — 0.94–0.98 for light, 0.15–0.2 for dark.
2. **One hue family for structure**: keep base-100/200/300 in the same hue, shifting only lightness by 0.04–0.06 steps.
3. **Ink from the same world**: base-content shares the ground's hue at high contrast (≥ 7:1 for body text).
4. **One accent**: primary at chroma 0.12–0.2. Its `-content` must clear 4.5:1 against it.
5. **Semantic colors are functional**: success/warning/error appear in badges and alerts only — never decoration.
6. **Test the pairs**: every `*-content` against its parent, plus primary-on-base-100 for links/buttons.

## Radius & texture as register

- `0rem` everywhere → brutalist/industrial/luxury
- `0.25rem` → editorial restraint
- `1rem+` / pill fields → playful/organic
- `--noise: 1` adds subtle grain (paper feels); `--depth: 1` adds component emboss (retro/toy feels)

## Apply fonts separately

Themes don't load fonts. Add Google Fonts to html_head and assign via CSS:

```html
<link href="https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,300..700&family=Instrument+Sans:wght@400..700&display=swap" rel="stylesheet">
```

```css
h1,h2,h3 { font-family:"Fraunces",serif }
body { font-family:"Instrument Sans",sans-serif }
```

## Verify before shipping

- Screenshot a page using buttons, badges, inputs, tables, and an alert — all five exercise the semantic colors.
- Check the `.md` view too: code blocks inherit theme colors.
- Toggle OS reduced-motion: nothing should break.