UX-DSL
XS0px

Typography

Type scale, font families, and text styles.
A comprehensive, theme-aware typography system that scales from mobile to desktop automatically.
Interactive Demo: Typography

Theme Config (Live Typography)
h1: {
"fontSize": "xs(space(7)) md(space(8)) lg(space(9)) xl(space(10))",
"fontFamily": "Inter"// inherited
"fontWeight": "700"
"lineHeight": "xs(1.2) md(1.3)"
"letterSpacing": "-0.02em"
"textTransform": "none"// inherited
"textDecoration": "none"// inherited
"fontStyle": "normal"// inherited
"marginBlockStart": "auto"// inherited
"marginBlockEnd": "0.2em"
}
CSS Usage
.any-class{@ds-typo(h1);}

Theme Configuration: The settings below define your JSON theme. Once configured in uxdsl.theme.json, the mixin above applies these responsive rules automatically.

Typography Showcase
h1

UXDSL: The Design System Language

h2

The Evolution of Styling

h3

Atomic vs Semantic

h4

The rise of design tokens

h5
Runtime adaptability
h6
Future of CSS generation
p

UXDSL bridges the gap between design tokens and CSS generation, allowing for a truly semantic and adaptable design system that scales with your application.

body

UXDSL provides a type-safe, token-aware styling experience that integrates seamlessly with modern frameworks.

spanInline token usage
caption

Figure 1: Token dependency graph

smallv1.0.0-beta
codeconst answer = 42;
pre
const theme = { colors: { primary: 'blue' } };

The Power of Semantic Typography

UXDSL decouples visual style from HTML tags. While you can write standard HTML, the real power comes from the @ds-typo mixin. This allows you to apply the visual properties of a "Heading 1" to any element, while maintaining semantic correctness.

Because these mixins are backed by CSS variables, changing the theme instantly updates every instance of that typography style across your entire application—spacing, weight, size, and line-height included.

Usage Example

/* Apply H1 visuals to a div */
.hero-title {
@ds-typo (h1);
color: palette(primary-dark);
}

/* Apply Body visuals to a span */
.description {
@ds-typo (body);
opacity: 0.8;
}

Available Variants

GroupTokensBest for
Headingsh1h6Titles, hierarchy, section structure
Readingbody, pLong-form content and UI copy
Utilityspan, small, captionLabels, meta, secondary text
Codecode, preInline code and blocks

What Prevents “Knockout” Today

“Knockout” here means: a typography system that is role-driven, fluid, density-aware, auditable, and easy to evolve without regressions.

GapWhy it mattersWhat to build
Missing role abstractionTokens tied to tags can’t express intent like “label”, “kicker”, “eyebrow”, “metric”.Add a role layer (e.g. typo_roles) and map roles → details, then apply via @ds-typo(role).
No fluid / optical scalingBreakpoint steps can feel jumpy; headings may look oversized/undersized between breakpoints.Support fluid values (e.g. clamp-based) or a computed scale per viewport, plus optional optical adjustments.
Typography not density-awareDense UI needs different sizes/line-heights than roomy layouts, even with the same theme.Allow density to select a typography preset (or apply density multipliers to size/line).
Demo lacks introspection toolsHard to debug “what resolved where” and why a token looks the way it does.Add an inspector: resolved values per breakpoint + inherited-from + final CSS vars.
Defaults could be strongerMost users copy defaults; weak defaults lead to inconsistent apps.Ship stronger built-in scales + role presets + accessibility-first recommendations.

Customizing Typography

You can override the default type scale by adding a typography_details section to your uxdsl.theme.json file. This allows you to fine-tune sizes, weights, and line-heights for every semantic tag.

The fontSize and lineHeight properties support UXDSL's responsive syntax, allowing you to define scaling from mobile to desktop in a single line.

// uxdsl.theme.json
	{
	  "typography_details": {
	    "h1": {
	      "fontSize": "xs(space(7)) md(space(8)) lg(space(9)) xl(space(10))",
	      "fontWeight": "800",
	      "lineHeight": "1.1",
	      "letterSpacing": "-0.03em"
	    },
	    "p": {
	      "fontSize": "xs(space(5))",
	      "lineHeight": "1.6"
	    }
	  }
	}

Breakpoint Resolution & Responsive Rules

UXDSL supports responsive values using the xs() sm() md() lg() xl() syntax. When a value is missing at a breakpoint, it inherits from the nearest lower breakpoint that defines it.

Nearest-lower-breakpoint inheritance

{
	  "typography_details": {
	    "h1": { "fontSize": "xs(space(7)) md(space(8))" }
	  }
	}
Resolved result (example):
BreakpointValue
XS2rem
SM2rem (inherits from XS)
MD2.5rem
LG2.5rem (inherits from MD)
XL2.5rem (inherits from MD)

Resolution rules (summary)

RuleWhat it means
Inherit downMissing breakpoint values inherit from the nearest lower breakpoint that is defined.
Prefer explicitIf a breakpoint is present (e.g. lg(...)), it wins for that breakpoint and above until overridden.
Same syntax everywhereAny string-based typography field can use xs()/md()/… syntax.

Which typography properties can be responsive?

In practice, UXDSL's responsive syntax is most commonly used for fontSize and lineHeight, but the theme schema accepts responsive strings for any string-based typography field.


Type Scale Overview

The demo above is theme-aware and breakpoint-aware: edit typography_details, switch themes, and the rendered samples update immediately. For a quick sanity check, you can also inspect the generated CSS variables (e.g. --h1-size, --body-line) in DevTools.

Example resolved scale

TokenXSSMMDLGXL
H12rem2rem2.5rem3.125rem3.875rem
H21.5rem2rem2rem2.5rem3.125rem
Body1rem1rem1rem1rem1rem
Caption0.75rem0.75rem0.75rem0.75rem0.75rem

Typography API Reference

Typography is configured under typography_details in the theme JSON. Each tag/role supports a set of optional fields.

PropertyTypeResponsive syntaxTypical
fontSizestringxs(space(5)) md(space(6))
lineHeightstringxs(1.6) md(1.7)
fontWeightstring"400", "600", "700"
fontFamilystring"Inter", var(--font-ui)
letterSpacingstring"-0.02em"
textTransformstringnone, uppercase, lowercase, capitalize
textDecorationstringnone, underline, line-through, overline
fontStylestringnormal, italic, oblique
marginBlockStartstringdensity(2) or 0.5rem
marginBlockEndstringdensity(2) or 0.5rem
Tip: keep the core set small and consistent; use component-level tweaks (spacing, transform) when a new global token isn't justified.

Accessibility & Legibility

UXDSL makes it easy to keep typography readable across breakpoints by centralizing size and line-height in theme tokens.

Recommended minimum sizes

Text roleXSMD–LG
Body1rem1.0625–1.125rem
Small0.875rem0.875–0.9375rem
Caption0.75rem0.75–0.8125rem

Line-height guidance

Role familyGuidance
Body / paragraphs1.4–1.7
Headings (H1–H3)1.1–1.3
Small / caption1.3–1.6

Contrast

For normal text, aim for WCAG AA contrast of at least 4.5:1. For large text (e.g. headings ≥ 1.5rem regular weight), 3:1 is often acceptable. This repo includes a palette contrast audit you can run to catch regressions.

npm run theme:audit

Typography Recipes

PatternTokenNotes
Card titleh5Compact hierarchy for dense UI
Form labelcaptionOften paired with transform + spacing
Hero headingh1Usually needs responsive line-height
MetadatasmallGood with reduced emphasis

Card title

.card-title {
@ds-typo(h5);
margin-block-end: density(2);
}

Form label

.form-label {
@ds-typo(caption);
text-transform: uppercase;
letter-spacing: 0.02em;
}

Marketing hero heading

.hero-heading {
@ds-typo(h1);
line-height: xs(1.15) md(1.2) xl(1.25);
margin-block-end: density(5);
}

Metadata / timestamps

.metadata {
@ds-typo(small);
opacity: 0.7;
}

What UXDSL Outputs (Compiled CSS)

UXDSL compiles typography to plain CSS variables and simple selectors. This keeps runtime overhead low and makes the system easy to inspect.

Source

.hero-title {
@ds-typo(h1);
}

Compiled shape (example)

:where(h1).ds-typo {
font-size: var(--h1-size);
font-weight: var(--h1-weight, 700);
font-family: var(--h1-font-family, var(--font-ui));
line-height: var(--h1-line);
letter-spacing: var(--h1-spacing);
text-transform: var(--h1-transform, none);
text-decoration: var(--h1-decoration, none);
font-style: var(--h1-style, normal);
margin-block-start: var(--h1-margin-block-start, auto);
margin-block-end: var(--h1-margin-block-end, auto);
}

	@media (min-width: 768px) {
	  :root {
	    --h1-size: var(--space-8);
	  }
	}

Preset Type Scale Examples

These presets demonstrate how the responsive syntax can express common patterns. Use them as a starting point and tune for your product.

Material-inspired

{
	  "typography_details": {
	    "h1": { "fontSize": "xs(space(7)) md(space(8)) lg(space(9)) xl(space(10))", "fontWeight": "700", "lineHeight": "xs(1.15) md(1.2)" },
	    "h2": { "fontSize": "xs(space(6)) sm(space(7)) lg(space(8)) xl(space(9))", "fontWeight": "700", "lineHeight": "xs(1.2) md(1.25)" },
	    "h3": { "fontSize": "xs(space(6)) md(space(7)) xl(space(8))", "fontWeight": "600", "lineHeight": "xs(1.25) md(1.3)" },
	    "body": { "fontSize": "xs(space(5))", "lineHeight": "xs(1.6) md(1.7)" }
	  }
	}

Fluent-style compact UI

{
	  "typography_details": {
	    "h1": { "fontSize": "xs(space(6)) md(space(7)) xl(space(8))", "fontWeight": "600", "lineHeight": "xs(1.15) md(1.2)" },
	    "body": { "fontSize": "xs(space(5))", "lineHeight": "xs(1.55) md(1.6)" },
	    "caption": { "fontSize": "xs(space(4))", "lineHeight": "1.4" }
	  }
	}