CSS framework and design system for semantic HTML
fuz_css (@fuzdev/fuz_css) styles HTML elements by default and integrates
custom properties, themes, and utility classes into a complete system.
Early alpha with breaking changes ahead.
For coding conventions, see Skill(fuz-stack). For UI
components (themes, color scheme controls), see fuz_ui.
gro check # typecheck, test, lint, format check (run before committing)
gro typecheck # typecheck only (faster iteration)
gro test # run tests (SKIP_EXAMPLE_TESTS=1 to skip slow integration tests)
gro gen # regenerate theme.css and other .gen files
gro build # build the package for productionIMPORTANT for AI agents: Do NOT run gro dev - the developer will manage the
dev server.
- Svelte 5 - component framework (for docs site only)
- SvelteKit - application framework (for docs site only)
- @sveltejs/acorn-typescript, acorn-jsx, zimmerframe - AST parsing and walking
- zod - schema validation
- @webref/css - CSS property validation
- fuz_util (@fuzdev/fuz_util) - utility functions
fuz_css is a CSS framework and design system:
- Semantic HTML styling without classes
- Design tokens as CSS custom properties
- Smart utility class generation (includes only used)
- UI components (use fuz_ui)
- JavaScript runtime - all output is pure CSS
- Animation utilities (planned)
- Full Tailwind compatibility
- Semantic styles - The reset stylesheet styles HTML elements (buttons,
inputs, links, headings, forms, tables) without adding classes. Uses
low-specificity
:where()selectors so your styles easily override the defaults. Addclass="unstyled"to any element to opt out of opinionated styling (colors, borders, decorative properties) while keeping normalizations (font inheritance, border-collapse). - Style variables - Design tokens as CSS custom properties that enable customization and runtime theming. Each variable provides values for light and/or dark color-schemes.
- Base styles - Reset stylesheet with semantic defaults
- Theme variables - Style variables as CSS custom properties
- Utility classes - Generated per-project, only includes used classes
In bundled mode (virtual:fuz.css or ./fuz.css), all three layers are
combined and only used content is included. In utility-only mode, import
style.css and theme.css from the package separately (full content).
- TypeScript objects in variables.ts define all design tokens
- Each variable can have
lightand/ordarkvalues - Light/dark are color-schemes within a theme, not separate themes
render_theme_style()generates CSS with specificity multiplier
Two generators available, both using AST-based extraction and per-file caching:
- Gro generator - gen_fuz_css.ts for SvelteKit projects using Gro
- Vite plugin - vite_plugin_fuz_css.ts
for Svelte/React/Preact/Solid via
virtual:fuz.css
Both output only CSS for classes actually used. Supports Svelte 5.16+ class
syntax, JSX className, clsx/cn calls, and // @fuz-classes comment hints.
Comment hints for static extraction: The AST extractor cannot detect dynamic class names or elements. Use comment hints to explicitly include them:
// @fuz-classes box row p_md- Classes to include// @fuz-elements button input- Elements to include base styles for// @fuz-variables shade_40 text_50- CSS variables to include in theme
Both produce errors if the specified item can't be resolved, helping catch typos early. Implicitly detected classes that can't be resolved are silently skipped (they may belong to other CSS frameworks).
CSS variable detection: Variables are detected via simple regex scan of
var(--name patterns in source files. Only theme variables are included;
unknown variables are silently ignored. This catches usage in component props
like size="var(--icon_size_xs)" that AST-based extraction would miss.
See GenFuzCssOptions and VitePluginFuzCssOptions types for configuration.
- Token classes - Map to style variables:
p_md,color_a_50,gap_lg - Composite classes - Multi-property shortcuts:
box,column,row,ellipsis,pixelated,circular,selectable,clickable,pane,panel,sm(tighter sizing),md(default sizing / cascade reset),icon_button,plain,menuitem,chevron,chip - Literal classes - CSS
property:valuesyntax:display:flex,opacity:50%
All class types support modifiers: responsive (md:), state (hover:),
color-scheme (dark:), pseudo-element (before:).
Literal classes use property:value syntax that maps 1:1 to CSS:
display:flex→display: flex;hover:opacity:80%→:hover { opacity: 80%; }md:dark:hover:opacity:80%→ nested media/ancestor/state wrappers
Modifier ordering is [media:][ancestor:][state...:][pseudo-element:]property:value.
Space encoding uses ~ for multi-value properties (margin:0~auto). Arbitrary
breakpoints via min-width(800px): and max-width(600px):. Built-in max-width
variants (max-sm:, max-md:, etc.) and media feature queries (print:,
motion-safe:, contrast-more:, etc.) are also available.
See variables.ts for definitions, variable_data.ts for size/color variants.
Colors:
- 10 hues with semantic roles:
a(primary/blue),b(success/green),c(error/red),d(secondary/purple),e(tertiary/yellow),f(muted/brown),g(decorative/pink),h(caution/orange),i(info/cyan),j(flourish/teal) - 13 intensity stops:
color_a_00(lightest) throughcolor_a_100(darkest), with_50as the base (steps: 00, 05, 10, 20, 30, 40, 50, 60, 70, 80, 90, 95, 100) bg_*/fg_*- color-scheme-aware (swap in dark mode, use alpha for stacking)darken_*/lighten_*- color-scheme-agnostic (don't swap)text_*- opaque text colors (text_00–text_100, alpha avoided for performance).text_min/text_maxfor untinted extremes (pure black/white).shade_*- shade scale (shade_00–shade_100), plusshade_min/shade_max
Size variants: Core pattern is xs → sm → md → lg → xl, with
extended ranges varying by family:
- Spaces:
xs5...xs→sm→md→lg→xl...xl15(23 steps) - Font sizes:
xs→sm→md→lg→xl...xl9(13 steps) - Icon sizes:
xs→sm→md→lg→xl...xl3(7 steps) - Border radii:
xs3...xs→sm→md→lg→xl(7 steps) - Distances, shadows, line heights:
xs→sm→md→lg→xl(5 steps)
Generated CSS includes only the theme variables, base styles, and utility classes your code uses:
SvelteKit (Gro):
// src/routes/fuz.gen.css.ts
import {gen_fuz_css} from '@fuzdev/fuz_css/gen_fuz_css.js';
export const gen = gen_fuz_css();Then import the generated file in your layout: import './fuz.css';
Vite (Svelte/React/Preact/Solid):
// vite.config.ts
import {vite_plugin_fuz_css} from '@fuzdev/fuz_css/vite_plugin_fuz_css.js';
export default defineConfig({plugins: [vite_plugin_fuz_css()]});
// main.ts
import 'virtual:fuz.css';The Vite plugin supports HMR - changes to source files automatically trigger CSS regeneration during development.
For projects managing their own theme/base styles, set base_css: null and
variables: null in generator options, then import package CSS separately
(@fuzdev/fuz_css/style.css and theme.css include everything).
Use GenFuzCssOptions or VitePluginFuzCssOptions to customize:
base_css- Custom base styles or callback to modify defaultsvariables- Custom theme variables or callback to modify defaultsadditional_classes- Classes to always include (for dynamic names)additional_elements- Elements to always include, or'all'for all base stylesadditional_variables- Variables to always include, or'all'for all theme varsexclude_classes- Classes to exclude from outputexclude_elements- Elements to exclude from base CSSexclude_variables- Variables to exclude from theme
src/routes/docs/ has pages for: introduction, api, examples, semantic, themes, variables, classes, colors, buttons, chips, elements, forms, typography, borders, shading, shadows, layout. See tomes.ts for structure.
Library - src/lib/
Variables & themes:
- variables.ts - All style variable definitions
- variable.ts -
StyleVariabletype and validation - variable_data.ts - Size, color, border variants
- theme.ts - Theme rendering,
ColorSchemetype - themes.ts - Theme definitions (base, low/high contrast)
- theme.gen.css.ts - Gro generator that produces
theme.css
CSS extraction:
- css_class_extractor.ts - AST-based class extraction from Svelte/TS/JSX files
- file_filter.ts -
FileFiltertype for filtering extractable files - diagnostics.ts -
SourceLocation,ExtractionDiagnostic,CssGenerationErrortypes
CSS generation:
- gen_fuz_css.ts - Gro generator with per-file caching
- vite_plugin_fuz_css.ts - Vite plugin with
HMR via
virtual:fuz.css - css_plugin_options.ts - Shared options types for Gro/Vite generators
- css_cache.ts - Cache infrastructure with content hash validation, atomic writes, CI skip
- css_bundled_resolution.ts - Core bundled CSS resolution algorithm
- variable_graph.ts - Variable dependency graph for transitive resolution
- css_variable_utils.ts - CSS variable extraction utilities
- class_variable_index.ts - Class to variable mapping for dependency resolution
- style_rule_parser.ts - CSS rule parsing for base style tree-shaking
- css_class_generation.ts -
CssClassDefinitiontypes,generate_classes_css() - css_class_definitions.ts - Token and composite class registry
- css_classes.ts - CssClasses collection for tracking classes per-file
- css_class_generators.ts - Token class template generators
- css_class_composites.ts - Composite class definitions
- css_class_resolution.ts - Class resolution and cycle detection
- css_class_interpreters.ts - Modified class and literal interpreters
- css_ruleset_parser.ts - CSS ruleset parsing
- css_literal.ts - CSS-literal parser and validator
- modifiers.ts - Modifier definitions (breakpoints, states, pseudo-elements)
- deps.ts -
CacheDepsinterface for dependency injection - deps_defaults.ts - Default filesystem implementations
- example_class_utilities.ts - Example classes for Vite plugin integration tests
Stylesheets (for utility-only mode or direct import):
- style.css - CSS reset and element defaults (all rules)
- theme.css - Generated base theme variables (all variables)
Examples - examples/
Vite plugin examples for Svelte, React, Preact, and Solid. Each demonstrates token, composite, and literal classes with modifiers.
Important: All 4 example App files must be kept in sync. When updating one, update all others with equivalent changes.
Tests - src/test/
Tests use dot-separated aspect splitting. Major test suites:
css_class_extractor.{test,elements,expressions,jsx,locations,tracked_vars,typescript,utilities}.test.tscss_bundled_resolution.{test,diagnostics,variables}.test.tscss_ruleset_parser.{test,generation,modifiers,parse,selectors}.test.tscss_class_resolution.{test,literals}.test.tsstyle_rule_parser.{test,custom}.test.ts
Plus standalone tests: css_cache, css_classes, css_literal, variable,
variables, variable_graph, modifiers, diagnostics, file_filter,
themes, css_class_generators, css_plugin_options, css_variable_utils,
fuz_comments, generate_bundled_css, generate_classes_css, and more.
Integration: vite_plugin_examples.test.ts (skip with
SKIP_EXAMPLE_TESTS=1).
- Static extraction only - Runtime dynamic classes (
document.createElement,innerHTML) won't be detected. Useadditional_classesoption as workaround. - No animation utilities - Animation class generation not yet supported
- HSL color system - OKLCH migration planned for better perceptual uniformity
- Button composites incomplete - Some button variant classes are work in progress
- CSS Cascade Layers -
@layersupport under consideration but not yet implemented
- TypeScript strict mode
- Svelte 5 with runes API (for docs site)
- Prettier with tabs, 100 char width
- Node >= 22.15
- Tests in
src/test/(not co-located)
fuz_ui- UI components built on fuz_cssfuz_util- utility functions (no CSS dependency)fuz_template- starter template using fuz_cssfuz_blog- blog template using fuz_cssfuz_mastodon- Mastodon components using fuz_css