defuss-shadcn / introduction

A UI component system
that scales with local AI.

Themeable components built on semantic HTML, modern CSS, and vanilla JavaScript. No framework. No build step for consumers — dist/ is committed and ready to use as-is. The simplest possible foundation for AI-driven prototyping.

This documentation dogfoods the system: on the published site every component stylesheet, script, and theme you see styled here is loaded straight from the jsDelivr CDN — the same URLs as the CDN quick start. Every demo that renders correctly is proof that the CDN install works in general.

Statistics

68 components — 27 with JavaScript, 41 CSS-only — 67.9 KiB minified + compressed. Measured from the shipped files. Full details in: dist/stats.json - updated on every build.

Components

68

ATM · MOL · ORG · BLK · TPL

With JavaScript

27

interactive, State API–driven

CSS-only

41

zero behavior, pure markup

Minified + Compressed

67.9 KiB

the *.min.css / *.min.js twins

Themeable

Full shadcn semantic token model. Swap a tweakcn theme and every component updates instantly.

Component Skills

Every component includes a structured skill — markup, variants, ARIA, and wiring conventions — grounded in web standards. Point an agent at dist/SKILL.md: the generated index of every skill (type/why/when/where + supported states).

Observable state

Interactive components expose a State API (el.api.setState('open')), so agents and tests can drive every documented state by name.

Accessible

Built on native HTML elements and WAI-ARIA patterns. Keyboard navigation, focus management, and screen reader support by default — and every theme preset's nav text is contrast-gated (WCAG AA) by verify.

Framework Free

Runs in any browser, zero dependencies, no build pipeline required — and 41 of 68 components need no JavaScript at all. The shipped footprint (counts per type, JS/CSS-only split, byte sizes raw/minified/gzipped) is published as dist/stats.json.

Built on five layers.

Tokens. Component skill. CSS. HTML. JavaScript (if needed). That's the whole system.

1 — semantic tokens
/* default-semantic-tokens.css — the design system */
:root {
  --background:         oklch(1 0 0);
  --foreground:         oklch(0.145 0.005 285);
  --primary:            oklch(0.205 0.005 285);
  --primary-foreground: oklch(0.985 0.002 247);
  --border:             oklch(0.88 0.004 247);
  --radius:             0.625rem;
  /* ...all color pairs, shadows, spacing */
}
.dark { /* same keys, dark values */ }
2 — component-skill.md file
# Pattern: Button

## Native basis
`<button>` element. Also works on `<a>` for link-style buttons.

## Native Web APIs
- `<button>` — native clickable element with built-in keyboard and form support
- `:focus-visible` — keyboard-only focus ring
- `commandfor` / `command` — declarative button→dialog/popover triggers without JS
  # ...prefers-reduced-motion, prefers-contrast, forced-colors

## Structure
<button class="btn" data-variant="default">Click me</button>

## Variants
| data-variant  | Surface              | Text                     | Hover           |
|---------------|----------------------|--------------------------|-----------------|
| default       | --primary            | --primary-foreground     | opacity: 0.88   |
| secondary     | --secondary          | --secondary-foreground   | opacity: 0.8    |
| outline       | --background + border | --foreground             | --accent bg     |
| ghost         | transparent          | --foreground             | --accent bg     |
| destructive   | --destructive        | --destructive-foreground | opacity: 0.88   |
| link          | transparent          | --primary                | underline       |
  # ...sizes, accessibility, notes
3 — component CSS
/* button.css — styled with tokens */
@layer components {
  .btn {
    display: inline-flex;
    align-items: center;
    border-radius: var(--radius-md);
    font-weight: 500;
  }
  .btn[data-variant="default"] {
    background: var(--primary);
    color: var(--primary-foreground);
  }
  /* ...secondary, destructive, outline, ghost, link */
}
4 — semantic HTML
<button class="btn" data-variant="default"
        data-dialog-trigger="confirm">
  Open Dialog
</button>

<dialog id="confirm" class="dialog">
  <div class="dialog-content">...</div>
</dialog>
5 — vanilla JavaScript (if needed)
// dialog.js — wire interactivity
function init() {
  document.querySelectorAll('[data-dialog-trigger]:not([data-init])').forEach((trigger) => {
    trigger.dataset.init = '';
    const dialog = document.getElementById(trigger.dataset.dialogTrigger);
    if (!dialog) return;
    trigger.addEventListener('click', () => dialog.showModal());
  });
  /* ...close-on-backdrop, [data-dialog-close] buttons, focus restore */
}

init();
new MutationObserver(init).observe(document, { childList: true, subtree: true });