Skip to main content

LUZ Design system for humans, ready for AI.

Tokens, CSS and a little vanilla JavaScript, built on what the browser already does: start a project with LUZ, the Light, Usable and Zero-dependency design system, or migrate it page by page. Every component works before JavaScript loads, and every change starts with a failing test.

The light where you are

With JavaScript on, the light of your hour is drawn here.

Base

Your brand, as tokens

Colors, scales and the three modes as CSS custom properties. No components: your markup, your classes. In a project that already exists, start here: they touch nothing.

  • Colors. 53 primitives and 63 semantic tokens, in light, dark and high contrast.
  • Scales. Space, type, radii and shadows, from three knobs.
  • Weight. 3.0 KB gzipped, with everything before it.
npm
npm install @luz-ds/tokens
CDN
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@luz-ds/tokens@0.3.0/dist/luz-tokens.min.css">
.cta {
  background: var(--luz-brand-fill);
  color: var(--luz-text-on-fill);
}

.cta:hover {
  background: var(--luz-brand-fill-hover);
}

a {
  color: var(--luz-brand-primary);
}

Base + Core

Components with core

Components and layout on top of the tokens, in one cascade layer your own CSS always beats. To start a project, or to migrate one in parts with luz.conditional.css.

  • Components. 29 of them, from buttons and forms to tabs and a media player.
  • Layout. 10 objects for rows, grids, stacks and containers.
  • Weight. 26.5 KB gzipped, with everything before it.
npm
npm install @luz-ds/tokens @luz-ds/core
CDN
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@luz-ds/tokens@0.3.0/dist/luz-tokens.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@luz-ds/core@0.3.0/dist/luz.min.css">
<script type="module" src="https://cdn.jsdelivr.net/npm/@luz-ds/core@0.3.0/dist/luz.min.js"></script>
<div class="luz-field">
  <label class="luz-field__label" for="f-name">Project name</label>
  <input class="luz-input" id="f-name" type="text" aria-describedby="f-name-help">
  <div class="luz-field__helper" id="f-name-help">Shown on the dashboard.</div>
</div>
<div class="luz-field">
  <label class="luz-field__label" for="f-slug">Slug</label>
  <input class="luz-input luz-input--error" id="f-slug" type="text"
         aria-invalid="true" aria-describedby="f-slug-error">
  <div class="luz-field__error" id="f-slug-error">Use letters, numbers and dashes only.</div>
</div>

Base + Core + Catalog

A whole site with the catalog

What a site needs as a whole: search it, ask about cookies, switch its language.

  • Search. A dialog on Ctrl K that, without JavaScript, is a link to the index.
  • Language and notices. A language switch, submenus and a cookie notice that covers nothing.
  • Weight. 58.6 KB gzipped, with everything before it.
npm
npm install @luz-ds/tokens @luz-ds/core @luz-ds/catalog
CDN
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@luz-ds/tokens@0.3.0/dist/luz-tokens.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@luz-ds/core@0.3.0/dist/luz.min.css">
<!-- One link per catalog component the page uses: here the search -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@luz-ds/catalog@0.3.0/dist/components/search.min.css">
<script type="module" src="https://cdn.jsdelivr.net/npm/@luz-ds/core@0.3.0/dist/luz.min.js"></script>
<script type="module" src="https://cdn.jsdelivr.net/npm/@luz-ds/catalog@0.3.0/dist/catalog.min.js"></script>
<luz-search>
  <a class="luz-search__fallback" href="docs/a-z/" data-luz-search-fallback>A–Z</a>
  <button class="luz-search__trigger" type="button" data-luz-search-open hidden>Search</button>
  <dialog class="luz-modal luz-search" id="luz-search"
          data-luz-search-src="/search-index.json">
    <search class="luz-search__body">
      <input class="luz-input" id="luz-search-q" type="text">
      <p class="luz-search__status" role="status"></p>
      <div class="luz-search__results" data-luz-search-results>…</div>
    </search>
  </dialog>
</luz-search>

Base + Core + Catalog + your prompt

Your whole site from a prompt

Pick the one for your kind of site and paste it into the AI you use. It asks what you need, then builds your site, or moves the one you have, onto LUZ.

  • It asks first. Rounds of numbered questions, the answer it recommends first, and nothing is written until you say go.
  • Your stack, your brand. Plain HTML, Astro, React, Vue or Angular, with your own colors or the default ones.
  • Checked as it goes. Each step ends with LUZ’s own check and a short note of what it could not verify.

Another kind of site, or not sure yet? The general prompt asks first.

Start from scratch

Why LUZ

Three words, one promise.

A CSS-first, zero-build design system for the web. Your CSS always wins, JavaScript is only an enhancement, and every page works before it loads.

Light

Little code, no build step.

  • tokens 3.0 KB
  • core 23.5 KB
  • catalog 32.1 KB
The three base packages: 58.6 KB. The gzipped weight each package publishes, measured in dist when this page is built.

Plain CSS and small ES modules, from a CDN or from npm. No preprocessor, no compiler and no build step: what you read in the files is exactly what the browser runs. Tokens and core stay as small as we can keep them, and their size ceiling never goes up. Catalog is light because it comes in pieces: each component is its own file, and a page loads only the ones it uses.

Usable

Accessibility is where it starts, not an add-on.

  • Color contrast 100%
  • Right-to-left tested 97%
  • No JavaScript needed 72%
  • Own focus style 41%
  • Forced colors rules 41%
  • No known issues 45%
  • Tests without JS 29%
29 components, 362 test files. Counted when this page is built; what is short of 100% is in the statement.

It aims at WCAG 2.2 AA, the level of EN 301 549 version 4.1.1, the EU standard for accessible digital products. It starts from what the browser does well, adds visible focus, contrast and reduced motion, and checks them with axe on every change. It does not meet every criterion yet: the statement lists what is checked, what is untested and what fails.

Zero-dependency

Your code, not a tree of someone else’s.

  • CSS frameworks 0
  • CSS preprocessors 0
  • JavaScript frameworks 0
  • Code highlighters 0
  • Icon libraries 0
  • Utility libraries 0
  • Search and motion 0
Runtime dependencies: 0. Counted in every package’s package.json when this page is built.

LUZ’s packages ship with no dependencies: only CSS and ES modules over what the browser already offers. Nothing to install to try it, no framework to keep up with, and nothing that breaks when another library ships a new major version.

A good fit

  • Content sites, documentation and public services that must meet WCAG 2.1 or 2.2 AA: LUZ helps, and the result is yours to test.
  • Server-rendered pages and static sites, in any back-end language.
  • Teams that want to read and own their CSS.

Not a good fit

  • You need ready-made React or Vue components.
  • You need a data grid, charts or a date-range picker: LUZ has none.
  • You need a stable API today: LUZ is in beta, and names can still change.

Semantic HTML, styled

Your HTML comes styled

Write the element you mean and LUZ styles it, with no class. Start a project with LUZ, or migrate it page by page: your CSS always wins.

  • No class. 68 tags come styled as they are, forms and tables included.
  • One class. The role and the whole component: a link that looks like a button, a danger button, a card.
  • In your project. luz.conditional.css styles only what is inside [data-luz]; the rest of your page stays as it is.

21 of 29 components are CSS only; the rest improve with a script and work without it.

See all HTML tags
<details open>
  <summary>Do I need classes?</summary>
  <p>No. The HTML comes styled.</p>
</details>
Do I need classes?

No. The HTML comes styled.

Without LUZ

Do I need classes?

No. The HTML comes styled.

The same HTML, with LUZ

Do I need classes?
Light
Do I need classes?
Dark
Do I need classes?
High contrast
<label for="email">Email</label>
<input id="email" type="email"
  value="ana@example.com">
<button>Save changes</button>

Without LUZ

The same HTML, with LUZ

Light
Dark
High contrast
<a class="luz-btn luz-btn--primary"
  href="/docs/">Read the docs</a>
<button class="luz-btn luz-btn--danger"
  type="button">Delete project</button>
Read the docs

Without the class

Read the docs

With the class

Light
Dark
High contrast

Color modes

Three modes for everyone. The whole day, if you want it.

Every semantic color is defined for light, dark and high contrast, and one attribute, data-theme, switches them: on the whole page, or on one box, like these. That much comes with core. The rest of the day is up to you.

Core · included

Time-of-day color mode · Catalog, optional

Six moments, not one switch

Declare the moments of your day in HTML, from dawn to night, and let the reader pick one, or drag through the day. Auto stays the system's, and high contrast is never repainted.

  • Measured, not guessed. Every moment is checked for contrast over its base mode, like the three modes are.
  • Opt-in, zero bytes. It lives in catalog: one stylesheet and one lazy chunk. Leave it out and your page carries none of it.
Read the luz-theme-time docs

Questions

Frequently asked questions

Short answers to what people ask about LUZ: what it is and how to use it.

About LUZ

What is LUZ?

LUZ is a design system for the web in three parts: tokens, core and the catalog, with prompts so an AI can build the site with you. It lets the browser do the work, checks instead of promising, and an AI can write it without making anything up.

What does each part of LUZ do?

Tokens hold the look, core styles your HTML and gives you components, and the catalog adds what a whole site needs. Tokens are the colors, scales, type and three color modes as CSS custom properties, and they work alone. Core is the reset, the style of every HTML element, the layout objects (o-container, o-stack, o-grid), the components (.luz-btn, .luz-card, .luz-tabs) and a little optional JavaScript. The catalog is pieces for the whole site, like search and the cookie banner.

What makes LUZ different from the systems most people use?

LUZ starts from the browser instead of from a framework: native HTML, no build step, any stack, and it works without JavaScript. Accessibility is checked, not promised: axe tests, every contrast computed in each mode, forced colors and reduced motion. It needs less markup, because HTML comes out complete without classes, and it is customized without a fight, with layers, :where() and tokens, never !important. It is ready for AI in a way you can verify: the prompts are generated from the packages, so they never carry an invented class.

Where does LUZ fall short?

LUZ falls short in community, in complex widgets (a date picker, a combobox, a data table), in components for React or Vue, and in maturity: it is still 0.x.

Using it

What is the best way to use LUZ?

The best way is six steps, with nothing to compile:

  1. Load luz-tokens.css, luz.css and luz.js from the CDN or npm.
  2. Write semantic HTML.
  3. Add a class only for what HTML cannot say, and lay out with core's objects.
  4. Put your brand in with tokens: copy _template.css and change the values.
  5. From the catalog, link only what you use.
  6. JavaScript is optional: everything works without it.

The fast lane: paste the prompt for your kind of site into an AI and review the result with luz-check.

Do I need JavaScript to use LUZ?

No. Most LUZ components are CSS only, and the ones with a script work without it too. The page of each component says what you get without JavaScript.

Can I change the default styles later?

Yes, without fighting them. Tokens are the intended way to change the whole look, and your own CSS wins: LUZ is in cascade layers, so unlayered CSS beats it with no !important. What you do not override stays: change only the color of an h1 and it keeps LUZ's size.

What is LUZ for?

LUZ is for websites written in HTML, new or already built: a landing page, a blog, documentation, a company site. It fits any generator or CMS that produces HTML, Markdown included (Hugo, Astro, Eleventy), projects with no build step, and sites that must be accessible and work without JavaScript. An existing site can move to it piece by piece.

What is LUZ not for?

LUZ is not for utility classes in the style of Tailwind, nor for React or Vue apps that expect their framework's components: LUZ gives HTML and classes. It gives no ready-made page structure (header, hero, footer) either: you write it, or the AI does.

Not here? More questions, on HTML and classes and on existing projects