Theme Configuration: The settings below define your JSON theme. Once configured in uxdsl.theme.json, the mixin above applies these responsive rules automatically.
UXDSL bridges the gap between design tokens and CSS generation, allowing for a truly semantic and adaptable design system that scales with your application.
UXDSL provides a type-safe, token-aware styling experience that integrates seamlessly with modern frameworks.
Figure 1: Token dependency graph
const answer = 42;const theme = { colors: { primary: 'blue' } };Typography is a configured text style with responsive behavior. A component chooses a style such as h1; the theme defines its size, weight, line height and other properties across breakpoints. Like Density, it keeps shared responsive decisions in the system.
Spacing defines values. Density defines responsive spacing. Typography defines responsive text styles. Typography can use Spacing tokens without forcing the same progression as Density. Native CSS remains available for intentional exceptions.
This illustrative theme defines the complete progression. Omitted built-in breakpoint names retain the library defaults; custom names can also be configured.
{
"breakpoints": { "xs": 0, "md": 768, "xl": 1280 },
"spacing": { "7": "1.75rem", "8": "2rem", "10": "2.5rem" },
"fonts": { "families": { "ui": "Inter, sans-serif" } },
"typography_details": {
"default": {
"fontFamily": "var(--uxdsl__font__ui)",
"fontWeight": "400",
"lineHeight": "1.5"
},
"h1": {
"fontSize": "xs(space(7)) md(space(8)) xl(space(10))",
"fontWeight": "700",
"lineHeight": "xs(1.2) md(1.3)"
}
}
}typography_details.default supplies missing fields to each configured style. A style’s own field replaces that default field as a whole; it does not merge individual breakpoint expressions. A responsive field needs a base value. The most recent applicable rule remains active until another breakpoint overrides it.
| Viewport | Font size | Line height |
|---|---|---|
| Below 768px | space(7) → 1.75rem | 1.2 |
| 768px to below 1280px | space(8) → 2rem | 1.3 |
| 1280px and above | space(10) → 2.5rem | 1.3, inherited from md |
.page-title {
@ds-typo(h1);
}/* Equivalent size behavior, shown in isolation */
.page-title { font-size: 1.75rem; }
@media (min-width: 768px) {
.page-title { font-size: 2rem; }
}
@media (min-width: 1280px) {
.page-title { font-size: 2.5rem; }
}The mixin consumes CSS variables such as --uxdsl__typography__h1-size and --uxdsl__typography__h1-line. The compiler generates their responsive definitions from the JSON. Pure CSS can centralize the same behavior with variables and media queries; UXDSL provides the reusable configuration and compilation layer.
Keep HTML semantics independent of visual styling: use the appropriate heading level for the document, even when its visual style comes from another Typography role. Custom configured names, such as label, can also be consumed with @ds-typo(label).
PostCSS accepts the JSON as its theme option. SSR and browser applications use generateThemeCss(theme) from postcss-uxdsl/ds-runtime. Both call the same Typography generator. For live changes, regenerate and replace the managed theme stylesheet rather than appending overrides:
import { generateThemeCss } from 'postcss-uxdsl/ds-runtime'
// themeStyle is the application's existing managed <style> element.
// Generate first so an invalid update cannot clear the active stylesheet.
const css = generateThemeCss(nextTheme)
themeStyle.textContent = cssThe playground edits the JSON and applies this same generator. Its breakpoint buttons inspect a simulated viewport width using the shared resolver; they do not resize the browser. Default mode follows the actual viewport.
Configured fields are fontFamily, fontSize, lineHeight, fontWeight, letterSpacing, textTransform, textDecoration, fontStyle, marginBlockStart and marginBlockEnd. Each accepts a nonempty string containing a CSS value or a configured responsive progression.
The shared compiler checks role names, fields, base values and breakpoint widths. It preserves nested CSS expressions and Spacing references. It does not yet validate every CSS value, token dependency or accessibility requirement. Legacy flat typography variables remain supported; use typography_details for structured responsive styles.
AI implementation guide
Responsibility: maintain shared text roles and their responsive behavior. Typography defines reusable visual text styles; components select the appropriate role without hardcoding the resolved values. HTML preserves document semantics.
Typography is the preferred shared abstraction for text styling. Preserve intent, not just the current computed value. Keep the configured role and its responsive behavior intact, just as you would preserve a Density token or a semantic Palette reference.
typography_details, its default fields, referenced fonts, spacing, and breakpoints before choosing or modifying a style. Treat these references as dependencies; inspect them without assuming they need to change.@ds-typo(role). Do not invent undefined roles or tokens.Decision rule: Choose the configured Typography role in the component. Define and evolve its visual and responsive behavior in the theme. Use local CSS only for intentional exceptions.
.page-title {
@ds-typo(h1);
}The component selects the h1 typography role. The theme controls its font family, weight, line height, spacing references and responsive size progression.
Avoid copying the currently resolved values when the component is intended to remain connected to the shared Typography role:
.page-title {
font-size: 2rem;
line-height: 1.2;
}These local values no longer follow changes to the shared role. They are appropriate only when that independence is an intentional exception.
Make page titles follow the application’s responsive typography.
h1.@ds-typo(h1) to the title selector while preserving appropriate HTML semantics.