Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
1aa9180
feat: rework to oklch and add themes
ryanatkn Jul 7, 2026
4b59e87
feat: themes and oklch
ryanatkn Jul 7, 2026
48985f6
update
ryanatkn Jul 7, 2026
3f2c8f4
add theme editor
ryanatkn Jul 8, 2026
af6553d
Merge branch 'main' into oklch
ryanatkn Jul 10, 2026
990448e
wip
ryanatkn Jul 10, 2026
6bdc86d
wip
ryanatkn Jul 10, 2026
2e6e47f
rework API
ryanatkn Jul 11, 2026
3a987f4
wip
ryanatkn Jul 11, 2026
b01bb39
wip
ryanatkn Jul 11, 2026
fef5d35
wip
ryanatkn Jul 11, 2026
b0b02e8
wip
ryanatkn Jul 12, 2026
05b9602
Merge branch 'main' into oklch
ryanatkn Jul 16, 2026
ea7aa72
wip
ryanatkn Jul 16, 2026
1b876c6
wip
ryanatkn Jul 16, 2026
a3cc9e2
add hue shift and remove an unwanted terminal theme
ryanatkn Jul 16, 2026
9263f07
wip
ryanatkn Jul 16, 2026
a5c6037
wip
ryanatkn Jul 22, 2026
187375d
wip
ryanatkn Jul 24, 2026
000210c
wip
ryanatkn Jul 24, 2026
e948f47
wip
ryanatkn Jul 24, 2026
475db25
refactor
ryanatkn Jul 24, 2026
2258867
wip
ryanatkn Jul 24, 2026
bfe364d
wip
ryanatkn Jul 24, 2026
8404f16
wip
ryanatkn Jul 24, 2026
354ac4f
wip
ryanatkn Jul 24, 2026
e690ed4
wip
ryanatkn Jul 24, 2026
659b73a
wip
ryanatkn Jul 24, 2026
9236e19
rework
ryanatkn Jul 29, 2026
566a670
more rework
ryanatkn Jul 29, 2026
2f842ea
changesets
ryanatkn Jul 29, 2026
239325b
wip
ryanatkn Jul 29, 2026
e948bcc
more
ryanatkn Jul 29, 2026
c1c19a2
cleanup
ryanatkn Jul 29, 2026
de608ef
merge
ryanatkn Jul 29, 2026
bb8757a
wip
ryanatkn Jul 29, 2026
ef61627
refactor
ryanatkn Jul 30, 2026
9cfde83
wip
ryanatkn Jul 30, 2026
0832f1e
wip
ryanatkn Jul 30, 2026
1fe23d8
Merge branch 'main' into oklch
ryanatkn Aug 18, 2026
7bc092f
rework the themes
ryanatkn Aug 18, 2026
b37262a
refactoring and simplification
ryanatkn Aug 18, 2026
9ae8501
rename to smolder
ryanatkn Aug 18, 2026
2feaf7c
merge main
ryanatkn Sep 1, 2026
cf9f4bf
wip
ryanatkn Sep 1, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions .changeset/base-styles.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
---
'@fuzdev/fuz_css': minor
---

feat: rework base styles - interaction states, micro-surface variables, body font, button border style, section rhythm

Breaking:

- `body` reads `--font_family` (default `var(--font_family_sans)`) instead
of `--font_family_sans`; set `--font_family` for a serif body.
- Buttons read `--button_border_style` (default `var(--border_style)`) and
`--button_border_style_active` while pressed. A contextual
`--border_style` on an ancestor no longer reaches buttons - set the
button knobs there too.
- Selected buttons use `--text_00` for inverse text (was
`--text_05`/`--text_10`); `.palette_X` buttons fill with `palette_X_50`
(was stop 40), the selected border matching the fill.
- Hovering an input, textarea, or select colors the border with
`--outline_color` instead of `--border_color_20`; disabled inputs no
longer react to hover.
- `section` bottom margin is a `--flow_margin` multiple (same default),
scaled by size composites; `.unstyled` opts out.

New:

- Focus outlines use `outline-offset: var(--outline_offset)` (default
`1px`).
- Themable micro-surfaces: `--scrollbar_thumb_color` (`var(--shade_40)`),
`--scrollbar_track_color` (transparent), `--caret_color`
(`var(--accent_50)`), `--backdrop_color` (`var(--darken_60)`).
- `@media (prefers-contrast: more)` maps onto the curve knobs in the
`fuz.preferences` layer; theme overrides beat it.
- `check_theme` gains `GATE_SELECTED_TEXT`; the knob catalog's border
styles gain `inset`/`outset`.
14 changes: 14 additions & 0 deletions .changeset/generators.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
'@fuzdev/fuz_css': minor
---

feat: dev-server prescan, and `base_css` without `variables` is an error

- The Vite plugin pre-scans sources at dev-server startup so the first page
load has complete utility CSS. New `prescan` option: `true` (default,
`src` under the Vite root), `false`, or an array of directories.
- `base_css` enabled with `variables: null` is now the error diagnostic
`theme_variables_disabled`. Set `base_css: null` too for utility-only
mode, or keep `variables` and set `additional_variables: 'all'` to bundle
the full theme.
- `CssResolutionResult` loses `referenced_variables`.
52 changes: 52 additions & 0 deletions .changeset/oklch-color-system.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
---
'@fuzdev/fuz_css': minor
---

feat: derived OKLCH color system with semantic intents and cascade layers

Breaking:

- `--color_X_NN` → `--palette_X_NN` (10 letters × 13 stops);
`ColorVariant`/`color_variants` → `PaletteVariant`/`palette_variants`.
- Class renames: `border_color_X_NN` → `border_X_NN`,
`outline_color_X_NN` → `outline_X_NN`, `shadow_color_X_NN` →
`shadow_X_NN`, `.color_a`-`.color_j` → `.palette_a`-`.palette_j`.
`.color_X_NN`, `bg_X_NN`, `border_color_NN`, and `shadow_color_*` keep
their names.
- Classes removed: `.fg_NN`/`.bg_NN` (use
`background-color:var(--fg_10)`; `bg_` is now the opaque prefix),
`.hue_a`-`.hue_j` and `--hue`, and every `_light`/`_dark` variable and
class.
- `--hue_a`…`--hue_j` are OKLCH angles (blue `250`, was `210`); replace
`hsl(var(--hue_x) …)` with `oklch(<l> <c> var(--hue_x))` or a stop.
- `--tint_hue`/`--tint_saturation` → `--hue_neutral` + `--neutral_chroma`.
- `color-mix()` interpolates `in oklab` (was `in hsl`).
- Shipped CSS is layered `fuz.base` < `fuz.preferences` < `fuz.theme` <
`fuz.utilities`; unlayered consumer styles beat all of it. Custom
`base_css` is re-layered into `fuz.base`.
- `variables.ts` exports only `default_variables`; read a variable with
`default_variables.find((v) => v.name === 'space_md')`. `icon_sizes` →
`ICON_SIZES` (`ICON_SIZES.xs === 18`, was `'18px'`); `Z_INDEX_MAX`
removed (inline `2147483647`).

New:

- Curve knobs: `--chroma_scale`, `--palette_lightness_00/_100/_curve` (and
`shade_`/`text_`), `--palette_chroma_min/_max`, `--chroma_curve`, with
pinnable derived stops `--palette_lightness_NN`, `--palette_chroma_NN`,
`--chroma_shape_NN`.
- Intent knobs `--hue_accent`/`_positive`/`_negative`/`_caution`/`_info`,
each with a 13-stop scale (`--accent_00`…`--accent_100`), token classes
(`.positive_50`, `.bg_caution_10`), `--selection_color`, and
`intent_variants`/`IntentVariant`. Links, focus, selection,
`accent-color`, and disabled-active feedback use them; focus follows
`--outline_color` with the accent as fallback.
- Per-slot chroma multipliers `--palette_X_chroma_scale` and
`--<intent>_chroma_scale` (default `1`; brown `f` ships at `0.55`).
- `--border_color_lightness`/`--border_color_chroma` derive the
`border_color_*` alpha ramp through the neutral intent.
- Value tables in `variable_data.ts`: `FONT_SIZES`, `SPACE_SIZES`,
`BORDER_RADII`, `DISTANCES`, `LINE_HEIGHTS`, `DURATIONS`
(+ `duration_variants`), `SHADOW_GEOMETRY`, `SHADOW_ALPHAS`,
`OVERLAY_ALPHAS`.
- Design-time modules `ramps.ts`, `oklch.ts`, `wcag.ts`.
43 changes: 43 additions & 0 deletions .changeset/theme-authoring.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
---
'@fuzdev/fuz_css': minor
---

feat: themes as knob-sets - schema, registry and modifiers, scheme stance, knob catalog, checks, pure renderer, build-time `theme` option

Breaking:

- `Theme` moves to `variable.ts` as a strict zod schema:
`import type {Theme} from '@fuzdev/fuz_css/variable.ts'` (was
`theme.ts`). Unknown properties are errors; `parse_theme(value)` returns
a theme-or-`null`.
- `RenderThemeStyleOptions.empty_default_theme` removed - pass the defaults:
`render_theme_style({name: 'base', variables: default_variables})`.
- `render_theme_style` loses `specificity` and gains
`layer?: string | null` (default `'fuz.theme'`); `generate_theme_css`
loses its specificity parameter; the `theme_specificity` generator option
is removed.
- `default_themes` is just base. Low/high contrast are `contrast_modifiers`,
composed over a theme with `compose_themes(base, ...overlays)`.

New:

- `Theme.scheme?: 'dual' | 'light' | 'dark'` (`ThemeScheme`). Author a
single-scheme theme single-slot and pass it through
`resolve_theme_stance` (`theme_stance.ts`), which fills `scheme_mirror`;
the renderer pins `color-scheme`.
- Exemplar themes under `themes/`: smolder, parchment, concrete, nineties,
phosphor (dark-only), neon (dark-only).
- Scale knobs `--shadow_alpha_scale`, `--radius_scale`, `--scale_factor`,
`--font_weight`, `--heading_font_weight` (hook; setting it flattens the
ladder), `--heading_font_family`, `--background_image`.
- `knobs.ts`: the typed knob catalog (`theme_knobs`, `theme_knob_by_name`,
`theme_knob_axes`); `palette_glosses` in `variable_data.ts`.
- `theme_check.ts`: `validate_theme(unknown)`, `check_theme` (gamut,
monotonicity, contrast gates; `GATE_*` thresholds), `compile_theme`
(per-theme chroma caps), `create_theme_resolver`,
`known_theme_variable_names`.
- Generators take `theme`, baked into the output and tree-shaken:
`vite_plugin_fuz_css({theme: phosphor_theme})`. Composes with fuz_ui's
`ThemeRoot`, the runtime theme winning. `apply_theme_variables` is
exported from `variable_graph.ts`.
- `theme.ts` no longer imports `variables.ts` (~1.3KB minified, was ~38KB).
Loading
Loading