<!-- Layout: container -->
<main class="container">
<!-- Component: card -->
<article>
<h2>Sign in</h2>
<!-- Components: form controls -->
<form>
<label>
Email
<input
type="email"
name="email"
autocomplete="email"
required
>
</label>
<label>
Password
<input
type="password"
name="password"
autocomplete="current-password"
required
>
</label>
<label>
<input type="checkbox" checked>
Remember me
</label>
<button>Sign in</button>
</form>
</article>
</main>
Production-ready UI
from semantic HTML.
Cirth turns native HTML elements into accessible, themeable interfaces. Load one stylesheet, customize it with runtime design tokens, and ship an interface that needs no JavaScript runtime and no build step.
Start with the HTML you already know.
Standard elements carry the styling and the behaviour. Change the markup and you change the interface — there is no component API in between, and nothing in these three samples is wired to a script.
cirth.min.css
Article + table
<article>
<header><h3>Team</h3></header>
<table>
<thead>
<tr><th scope="col">Name</th><th scope="col">Role</th></tr>
</thead>
<tbody>
<tr><th scope="row">Ada Lovelace</th><td>Engineer</td></tr>
<tr><th scope="row">Grace Hopper</th><td>Designer</td></tr>
</tbody>
</table>
<footer><button type="button">Invite</button></footer>
</article>
Team
| Name | Role |
|---|---|
| Ada Lovelace | Engineer |
| Grace Hopper | Designer |
Nine elements, no classes. <th scope> on both axes is what gives a screen reader real row and column navigation — an ARIA re-implementation of a table cannot be reached this way.
Disclosure group
<article>
<header><h3>Delivery</h3></header>
<details name="delivery" open>
<summary>Standard delivery</summary>
<p>Three to five working days, tracked. Free.</p>
</details>
<details name="delivery">
<summary>Express delivery</summary>
<p>Next working day if ordered before 14:00.</p>
</details>
</article>
Delivery
Standard delivery
Three to five working days, tracked. Free.
Express delivery
Next working day if ordered before 14:00.
Open one and the other closes: name makes the group exclusive and the browser runs it. The questions under Before you install are this same element, once per question.
Form + validation
<article>
<header><h3>Notifications</h3></header>
<label>
Email
<input type="email" name="email" placeholder="you@example.com" required>
</label>
<label>
<input type="checkbox" name="notes" role="switch" checked>
Send release notes
</label>
<button type="button">Save</button>
</article>
Notifications
Type an address that is not one, then leave the field. required and type="email" are the whole validation layer — and :user-invalid holds the error styling back until the reader has caused it, so nothing is painted red on arrival.
Your theme. Same HTML.
Every colour, radius and font is a --cirth-* custom property. The markup on the right never changes and no class is added to it — the declarations on the left do, one at a time, and the finished interface follows them.
<cirth-theme-preview> · its own Cirth, in a shadow root
.cirth {
--cirth-primary: light-dark(
oklch(52.7% 0.107 44deg),
oklch(65.7% 0.134 44deg)
);
--cirth-border-radius: var(--cirth-radius-sm);
--cirth-canvas: light-dark(
oklch(97.3% 0.006 44deg),
oklch(20.15% 0.0225 280deg)
);
}--cirth-primary--cirth-border-radius--cirth-canvas
Account settings
Real values, from the files that declare them: the default theme in cirth.scoped.css, and the plain and playroom presets compiled from src/presets/. In your own page the same declarations go on :root — every token, and how to override it.
Every claim has a check path.
Not everything below is the same kind of statement. Some are guarantees — properties the project intends to keep. Some are capabilities: things Cirth lets you do, which say nothing about what you build with them. One is a current fact, measured on this build and free to move. Each cell says which it is, and how to check it.
- Guarantee
- 0 B JS runtime No runtime shipped by Cirth. Your application can still use JavaScript for anything it needs. Inspect
- Guarantee
- WCAG 2.2 AA baseline Automated checks over Cirth's own components and defaults — a floor to build on, not a verdict on your interface. Method
- Capability
- Flexible distribution Classless and scoped builds, with print sheets and token presets as optional outputs beside them. Compare
- Current fact
- Small CSS footprint13.9 KB gzipped in this build — every bundle is measured on every build. Current size
Before you install
Do I need to write any JavaScript?
Cirth itself does not require or ship any. The package is compiled CSS, and the interactive patterns it styles — accordion, dropdown, modal, popover — are native <details>, <dialog> and [popover] elements driven by the browser. Your application can still use JavaScript wherever its own behavior needs it: data, state, routing, anything it builds in the DOM. Cirth styles what is there, whoever put it there.
Is a build step required?
No. One <link rel="stylesheet"> — or one import where you already bundle — and standard elements are styled. It also drops into a Vite, PostCSS or bundler pipeline unchanged when you have one; neither way is the blessed one. The SCSS in the repository is how the published CSS is produced, not a Sass API you are expected to compile.
How big is the default stylesheet?
13.9 KB gzipped in the build this site was made from. That is a measurement, not a promise: a script gzips every bundle on every build and fails past the current budget, so the number stays honest — and it is free to move when covering more HTML, or a better accessibility default, is worth the bytes.
Which browsers are supported?
Chrome, Chrome for Android and Edge 123+; Firefox and Firefox for Android 130+; iOS Safari and Safari 18.2+; Opera 109+; Samsung Internet 27+. That is the Browserslist target in package.json — what Lightning CSS compiles the output against, and what check-browserslist.js holds to one engine floor across every family, so a Chromium fork left behind cannot quietly lower it. No version of Internet Explorer is supported.
How is this different from Pico CSS?
Cirth began as a fork of Pico CSS and remains indebted to it, but it is an independent framework now rather than a promise of compatibility. What has moved since the fork: the published package is CSS only, in classless and scoped forms — four builds today, default, classless, scoped and scoped classless — with print sheets and token presets as separate outputs beside them; the twenty inherited accent themes are one theme (copper) plus plain and playroom as token-override presets; .grid is now an intrinsically wrapping grid and the single-row equal-column layout is .row; the CSS-only [data-tooltip] is gone, replaced by the native popover, because a message drawn with content: attr() cannot be reached by assistive technology; and a WCAG 2.2 AA baseline is verified in the source with axe over every page, theme and mode. See the full comparison.
Is Cirth affiliated with the Tolkien estate?
No. The project is not affiliated with, endorsed by, or associated with the Tolkien estate, the Tolkien Society, Amazon's Middle-earth adaptations, or any other rights holder. The name points at the Cirth runic alphabet — an angular script cut for carving, where every letter is reduced to the strokes the material allows — because that reduction is the constraint this framework is built around. It is a reference, not a claim of license or partnership. The mark, the wordmark and the rest of the project's identity are Cirth's own work and are unrelated to Tolkien's; Brand sets out where they come from and how they may be used.
What license is Cirth under?
The code is under the Apache License 2.0, which is also what @cirthcss/cirth declares on npm. You can use it in commercial and closed-source work, modify it, and redistribute it, including as part of a larger product, provided you keep the license and copyright notices and state what you changed; it also grants a patent license, and it comes with no warranty. Cirth is a fork of Pico CSS, which was MIT — NOTICE.md records that history. The name and the logo are not covered by the code license: they are brand assets with their own terms, set out on the Brand page.