# 78 UI Kit > A theme-forward, no-build UI kit — plain HTML / CSS / JS you drop in. One stylesheet, one script, and > every color resolves at runtime from CSS custom properties, so re-theming is an override block rather > than a rebuild. Built for dashboards: KPI cards, tables, no-library data-viz primitives, and theme > adapters that recolor Tabulator, FullCalendar and Chart.js along with everything else — including on a > live theme switch. MIT. Two things shape every decision in the kit: - **Theme-forward.** A theme is *only* color. Color tokens live in `:root[data-theme="dark"]` / `["light"]`; non-color tokens (radius, type, spacing, layout sizes) live in a plain `:root`. Nothing hardcodes a color, so overriding the tokens re-themes the whole kit. - **Built for dashboards.** Stat/KPI cards, a table style, sparkline / progress / bar / donut / gauge / trend primitives, an app shell, and adapters so third-party tables and charts follow the theme too. No framework. No build step. No dependencies. Version 0.x — the public API may still change before 1.0. ## Install ```html
``` `@v0.4.0` pins a release; `@main` tracks the latest. `kit.min.css` / `_78.min.js` are also served. Or download the repo and serve the files yourself. Library adapters are opt-in and live under `/css/adapters/` and `/js/adapters/` — they are never part of `kit.css`. ## Naming - **CSS classes** are prefixed `_78-` — `._78-btn`, `._78-stat-card`, `._78-nav-item`. - **Modifiers** are suffixes on the block class — `._78-btn-primary`, `._78-table-compact` — and shared state classes are their own prefixed class alongside it: `._78-active`, `._78-selected`, `._78-up`, `._78-down`, `._78-invert`, `._78-high` / `._78-mid` / `._78-low`, `._78-danger`. - **JS** is one global, `_78`, with no dependencies: `_78.theme`, `_78.tone`, `_78.util`, `_78.shell`, `_78.modal`, `_78.notify`, `_78.tabs`, `_78.seg`, `_78.viz`, `_78.toc`, `_78.adapters.chartjs`, `_78.gen`. - **Events** are namespaced `_78:` and fire on `document` (except `_78:tabchange`, which bubbles from the tab list, `_78:segchange`, which bubbles from the segmented control, and `_78:tocchange`, from the contents rail): `_78:themechange`, `_78:railchange`, `_78:drawerchange`, `_78:tabchange`, `_78:segchange`, `_78:tocchange`, `_78:genchange`. ## Tokens Token *names* are the contract; the shipped values are a neutral default palette meant to be overridden. - **Core color:** `--bg` `--bg2` `--bg3` `--border` `--text` `--dim` `--accent` - **Accent derived:** `--accent-hover` `--accent-text` `--accent-lo` `--accent-lo-hover` `--accent-glow` - **Semantic:** `--success` `--warn` `--danger` `--info`, each with a `-lo` tint - **Categories:** `--cat-1` … `--cat-6`, each with a `-lo` tint — label colors that are not states - **Charts:** `--series-2` — the second chart series, a gray that recedes behind `--accent` - **Surface details:** `--row-hover` `--row-border` `--row-selected` `--ring` `--overlay` `--shadow` `--shadow-lg` - **Non-color (shared `:root`):** `--radius-sm` `--radius` `--radius-lg` `--radius-pill` · `--font` `--font-mono` · `--fs-xs`…`--fs-xl` `--lh` · `--space-1`…`--space-6` · `--control-h` `--control-h-sm` `--icon-btn-size` `--ring-w` · `--sidebar-w` `--rail-w` `--header-h` `--content-max` · `--transition` `--transition-slow` The `--space-*` tokens are also the escape hatch above the utility scale: there is no margin utility over 16px and there are no padding utilities, by design — use the token directly instead. ## Tones One vocabulary for every component that takes a tone, and it is the token names: `accent` `success` `warn` `danger` `info` `dim`. Aliases, permanent and identical: `green` = success, `red` = danger, `amber` / `yellow` = warn. Write the canonical name. - Badge `._78-badge-{tone}` · tag `._78-tag-{tone}` · text `._78-text-{tone}` or `._78-{tone}` (also on `._78-stat-card__num`) · alert `._78-alert-{tone}` · data-viz `._78-tone-{tone}` / `data-tone` · modal `tone:` · toast `type:` (`danger` = the toast's `error`). All six on each. - `_78.tone('red')` → `'danger'`; `_78.tone.names` lists the six. - **Categories** (labels that are not states, like a source or a team): `cat-1` … `cat-6` on badge, tag, text and viz tone — `._78-badge-cat-3`. Hues sit clear of success / warn / danger; use them in order. ## Components - **App shell** — `._78-topbar` + `._78-sidebar` that collapses to an icon rail and becomes a mobile drawer, plus `._78-app-main`; driven by `_78.shell`. Flat nav items only, no nested menus. The open drawer keeps keyboard focus inside it and makes the page behind `inert`. - **Buttons** — `._78-btn` (`-primary` / `-ghost` / `-danger` / `-sm` / `-full`), `._78-icon-btn`, `._78-btn-group`. - **Cards** — `._78-card` and the KPI `._78-stat-card` (label / number / delta / sparkline), laid out by `._78-kpi-grid` / `._78-card-grid`. Stacked cards space themselves; in a grid they line up at the top. `._78-card-stack` spaces a list of cards with a gap, even when each one is wrapped. `._78-stat-card__actions` puts a small control (a seg, an icon button) beside the label; `._78-stat-card__lines` / `__line` / `__key` / `__value` are key : value lines with the keys in one column. - **Contents rail** — `._78-toc` in a `._78-toc-layout`, filled by `_78.toc`: an "On this page" rail built from the page's headings, sticky, with an IntersectionObserver scroll-spy (`aria-current`), a `._78-details` dropdown under 880px, nothing under two headings. `data-toc-*` options, `_78:tocchange`. - **Grid** — `._78-grid` (auto-fit, `--min` track size, no breakpoints) with `._78-col-span-2` (two columns when there's room, else the whole row) and `._78-col-full`. `._78-kpi-grid` / `._78-card-grid` are presets of it. - **Meta line** — `._78-meta`, the small dim line of facts under a headline; the kit draws the `·` between child elements. `._78-meta-label` lead-in, `-xs`, and a line clamp (`-clamp` / `-clamp-2`). - **Forms** — `._78-field` with `._78-input` / `._78-select` / `._78-textarea` / `._78-check` and one consistent focus ring. `._78-form-inline` puts a field and its button on one row (a form in a card foot). - **Toggle switch** — `._78-switch` (+ `-sm`, `._78-switch-row`), a real `` restyled as a track and thumb, so keyboard, `:disabled` and label association are native. Stacked `._78-switch-row`s space themselves. - **Segmented control** — `._78-seg` / `._78-seg-btn` (+ `-sm` / `-full` / `-accent`), one-of-N, mounted by `_78.seg` as a `radiogroup` with roving tabindex; fires `_78:segchange`. - **Disclosure** — `._78-details` (+ `-plain` / `-fill` / `-sm`), a styled `