Getting started
One stylesheet, one script, and you are done. There is nothing to install, nothing to compile, and no configuration file — drop the kit into a page and start using the classes.
Install
The fastest way in is the CDN. jsDelivr serves the kit straight from GitHub, so these two lines are a complete install:
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/1978io/78UIKit@v0.4.0/css/kit.css">
<script defer src="https://cdn.jsdelivr.net/gh/1978io/78UIKit@v0.4.0/js/_78.js"></script>
Pinning to a release like v0.4.0 means your site cannot change under you.
You can also use @main for the latest (it moves on every push), or download the repo
and serve the files yourself. jsDelivr serves minified builds too — swap in
kit.min.css and _78.min.js.
The complete <head>
In a real page you want one more thing: a tiny inline script that sets the theme before the first paint, so a returning visitor never sees a flash of the wrong theme. It has to run before any stylesheet, so it goes first.
<head>
<!-- 1. pre-paint theme — FIRST, before any stylesheet -->
<script>
(function(){var p=localStorage.getItem('_78-theme')||'system';
var t=p==='system'?(matchMedia('(prefers-color-scheme: light)').matches?'light':'dark'):p;
var r=document.documentElement;r.dataset.theme=t;r.dataset.themePref=p;})();
</script>
<!-- 2. the kit -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/1978io/78UIKit@v0.4.0/css/kit.css">
<script defer src="https://cdn.jsdelivr.net/gh/1978io/78UIKit@v0.4.0/js/_78.js"></script>
<!-- 3. your own theme overrides, AFTER the kit -->
<style>:root[data-theme="dark"]{--accent:#7c5cff}</style>
</head>
--accent-hover, --accent-lo, --accent-glow,
--ring — are their own tokens, so a full theme sets those alongside
--accent, or lets the
theme generator write the complete set for you.
Library adapters
If you use Tabulator, FullCalendar or Chart.js, the kit has opt-in adapters that make them follow
your theme. They are deliberately not part of kit.css, so you include only
the ones you need — always after the library itself. They live on the same CDN under
/css/adapters/ and /js/adapters/.
Your first components
Everything is a class. There is no JavaScript to initialize and no component to register — write the markup and it works. Here are the two you will reach for first, rendered by the same kit that renders this page.
Buttons
<button class="_78-btn _78-btn-primary">Primary</button>
<button class="_78-btn">Default</button>
<button class="_78-btn _78-btn-ghost">Ghost</button>
<button class="_78-btn _78-btn-danger">Danger</button>
Add _78-btn-sm for a smaller control or _78-btn-full to fill its
container. For an icon on its own, use _78-icon-btn.
Cards
A card is a surface with a border and padding. Put anything inside it.
<div class="_78-card">
<div class="_78-card-title">Card title</div>
<p>A card is a surface with a border and padding.</p>
</div>
For dashboards there is also _78-stat-card, a KPI card with a number, a delta and a
sparkline, laid out by _78-kpi-grid.
The theme toggle
Give any element the class _78-theme-toggle and the kit wires it up on load. There is
nothing to call: clicking it cycles Dark → Light → System and remembers
the choice. The toggle in this page's topbar is exactly this markup.
The button carries three icons, one per preference, each tagged with data-pref. The
kit's CSS shows whichever matches the current setting, so the icon always reflects what you picked.
<button class="_78-icon-btn _78-theme-toggle" type="button">
<svg class="_78-theme-icon" data-pref="dark">…</svg>
<svg class="_78-theme-icon" data-pref="light">…</svg>
<svg class="_78-theme-icon" data-pref="system">…</svg>
</button>
If you would rather drive it yourself, the whole API is four calls:
_78.theme.pref // 'dark' | 'light' | 'system'
_78.theme.current // the resolved 'dark' | 'light'
_78.theme.set('light') // or 'dark' | 'system'
_78.theme.cycle() // dark → light → system → dark
_78.theme.mount(el) // wire your own element as a toggle
_78.theme.KEY // '_78-theme' — the localStorage key
_78.theme.PREPAINT // the snippet above, as a string
_78.theme.mount(el) is for a toggle you build after page load, or one you would rather
not give the _78-theme-toggle class. Elements carrying that class are mounted for you,
so you only need this for the dynamic case.
var btn = document.createElement('button');
btn.textContent = 'Theme';
_78.theme.mount(btn); // now it cycles, like any ._78-theme-toggle
document.addEventListener('_78:themechange', function (e) {
// e.detail = { theme: 'dark' | 'light', pref: 'dark' | 'light' | 'system' }
});
Writing a lot of these classes by hand? Editor
setup gets you _78- autocomplete and go-to-definition in VS Code.
Working with an AI assistant
/llms.txt and
/llms-full.txt. Point Claude Code,
Cursor or any assistant with web access at it and it writes real kit markup instead of guessing
at class names — Using with AI has
the URLs and some prompts to copy.