Skip to content

Combat UI

Progressive components that compose with native HTML.

A small set of token-driven CSS primitives and accessible custom elements. Light DOM stays yours; behavior and ARIA stay ours.

Get started Browse components

Why Combat UI

The majority of the system is just HTML and CSS. Layout primitives are class-based, making them portable across frameworks and tech stacks. Web Components are only used when additional behavior, accessibility features, or ARIA interactions are required. Everything is driven by a small set of CSS custom properties, so changing a single variable propagates consistently throughout the entire system.

Native HTML, slotted

Anchors, buttons, and copy stay in light DOM. SEO, analytics, and your existing CSS keep working.

Token-driven theming

Colors, type, spacing, density, and component tokens cascade through plain CSS variables

Progressive enhancement

Pages render before JavaScript loads. Components hydrate behavior on top of HTML that's already meaningful.

Install

Add the package, import the bundle, and the cui-* elements register on the global custom element registry. We currently have no npm package, but you can clone the repo and import the local bundle for now. A package is coming soon.

Use everything (drop-in)

Import the auto entry. Every cui-* element registers itself and the global utility stylesheet is included.

Use only what you need (tree-shakeable)

Import elements from their subpaths. Each one self-registers, so your bundler ships only the components you actually use.

Programmatic API & types

The package root is side-effect-free: it exports the element classes, helpers (toast, defineCombatUi, getTheme / setTheme) and TypeScript types, but on its own it does not register elements or inject any CSS. Call defineCombatUi() to register the whole set at once.

Global stylesheet

The utility-class layer (design tokens, layout, and the light-DOM cui-* classes) ships as a separate stylesheet. The auto entry includes it; otherwise import it once:

Maps

cui-map uses Leaflet as an optional peer dependency, loaded on demand the first time a map appears. Install it alongside Combat UI when you use maps (add leaflet.markercluster too for marker clustering):

With a bundler

Without a bundler

<script type="importmap"> { "imports": { "leaflet": "https://esm.sh/leaflet@1.9.4", "leaflet.markercluster": "https://esm.sh/leaflet.markercluster@1.5.3?external=leaflet" } } </script> <script type="module"> import "combat-ui/auto"; </script>

Use a component

Import the bundle, then drop an element into your HTML. The element registers itself and the global utility stylesheet is included, no setup, no build step.

Status

Stable primitives, growing component set.

Layout, theming, and foundation classes are stable. The component set is intentionally small and grows when a pattern earns its keep.

Open foundations See the demo