@ra9/tan-compose-kit / themes

Theming and CSS‑framework interop.

Three layers of override: global semantic tokens, per‑component tokens, per‑instance CSS. Drop‑in presets for dark mode, Bootstrap, and Tailwind. The kit's components live in Shadow DOM, so they never fight your existing CSS.

Quick switch

Click a preset to re‑skin the live demo below. The same buttons, inputs, badges, and stat cards — different palette and radius. Each preset is one CSS module load.

Light (default) Dark Bootstrap Tailwind Material shadcn
Primary Secondary Danger Ghost
neutral info success warning danger

Install & import a theme

A theme is one CSS module that sets --tc-* custom properties on :root. Install the kit, then import exactly one preset — the kit reads those tokens through Shadow DOM, so every component re‑skins at once.

// 1. the components import "@ra9/tan-compose-kit"; // 2. one theme preset — its :root tokens drive every component import "@ra9/tan-compose-kit/themes/dark";

The base tokens preset is the light default that every other preset extends, so you only ever import one. Imports are idempotent — loading a theme twice is a no‑op.

Pull the pre‑built bundles straight from jsDelivr — the theme first, then the kit. Swap the tag to pin a version. <script type="module" src="https://cdn.jsdelivr.net/gh/RA9/tan-compose@kit-v1.11.0/kit/dist/themes/shadcn.min.js"></script> <script type="module" src="https://cdn.jsdelivr.net/gh/RA9/tan-compose@kit-v1.11.0/kit/dist/kit.min.js"></script>

Three layers of override

Every kit component participates in a layered cascade. Override at whichever level fits.

1. Global semantic tokens

Set on :root. Cascade through Shadow DOM into every component. This is the layer the four presets configure.

:root { --tc-color-accent: #a16939; --tc-color-accent-hover: #8a572d; --tc-color-ink: #14171f; --tc-color-surface: #ffffff; --tc-color-rule: #ece5d3; --tc-color-success: #207a5b; --tc-color-warning: #a87326; --tc-color-danger: #b3261e; --tc-radius-md: 8px; --tc-font-sans: 'Inter', system-ui, sans-serif; }

2. Per-component tokens

Each component exposes finer-grained hooks like --tc-btn-primary-bg, --tc-input-border, --tc-table-row-hover. They default to the global semantic tokens but can be overridden per‑component:

tc-button { --tc-btn-primary-bg: linear-gradient(135deg, #6366f1, #8b5cf6); }

3. Per-instance overrides

Pass the variable as inline style. Affects only that one element.

<tc-button style="--tc-btn-primary-bg: tomato">Special</tc-button>

Bundled presets

Pick one. They're all idempotent — importing twice is a no‑op.

PresetImportWhat it changes
tokens (default) @ra9/tan-compose-kit/themes/tokens Light theme, warm-tan accent. The base every other preset extends.
dark @ra9/tan-compose-kit/themes/dark Dark surface + ink, accent brightened for contrast.
bootstrap @ra9/tan-compose-kit/themes/bootstrap Bootstrap 5 primary blue, semantic palette, default radius.
tailwind @ra9/tan-compose-kit/themes/tailwind Tailwind slate/indigo palette, default radius scale.
material @ra9/tan-compose-kit/themes/material Material Design 3 indigo, Roboto, elevation-style shadows.
shadcn @ra9/tan-compose-kit/themes/shadcn shadcn/ui zinc neutrals, tighter radii, Inter typography.

Switch themes at runtime

Because a preset is just :root tokens, switching is a matter of swapping which token block is live. Inject the preset's CSS into a <style> you can replace — exactly what the demo at the top of this page does:

const THEMES = { light: "", // base tokens — nothing to add dark: `:root { --tc-color-bg:#0f1218; --tc-color-surface:#1a1d29; --tc-color-ink:#f5f0e6; --tc-color-accent:#d49a68; }`, }; function applyTheme(name) { document.querySelector("style[data-theme]")?.remove(); const css = THEMES[name]; if (!css) return; // "light" → base only const s = document.createElement("style"); s.dataset.theme = name; s.textContent = css; document.head.appendChild(s); }

Persist the choice in localStorage and re‑apply on load so it survives a refresh. Nothing re‑renders — every component picks up the new tokens through the cascade instantly.

Dark mode from system preference

To follow the OS setting with zero JavaScript, wrap the dark tokens in a media query and load it after the base tokens:

@media (prefers-color-scheme: dark) { :root { --tc-color-bg: #0f1218; --tc-color-surface: #1a1d29; --tc-color-ink: #f5f0e6; --tc-color-rule: #2a2f3d; --tc-color-accent: #d49a68; } }

Combine the two: default to the system preference, but let an explicit toggle win by writing tokens to a higher‑specificity selector like :root[data-theme="dark"].

Using alongside Bootstrap or Tailwind

Your global Bootstrap or Tailwind classes never reach inside a kit component; the kit's CSS never reaches outside. They coexist by construction. The presets just align the kit's look so a user can't tell which buttons came from where.

Bootstrap

import "bootstrap/dist/css/bootstrap.min.css"; import "@ra9/tan-compose-kit"; import "@ra9/tan-compose-kit/themes/bootstrap"; // kit components now match Bootstrap's primary blue + radius <div class="container"> <tc-input label="Email" name="email"></tc-input> <tc-button variant="primary">Save</tc-button> </div>

Tailwind

import "@ra9/tan-compose-kit"; import "@ra9/tan-compose-kit/themes/tailwind"; // utility classes don't enter the kit's Shadow DOM, // but the kit's tokens align with Tailwind's slate/indigo <div class="grid grid-cols-3 gap-4"> <tc-stat label="MRR" value="42"></tc-stat> <tc-stat label="Churn" value="0.4%"></tc-stat> <tc-stat label="LTV" value="240"></tc-stat> </div>

Other frameworks

Bulma, Bootstrap 4, plain CSS — same shape. Override the handful of --tc-color-* tokens to match the framework's brand color and you're done.

Writing your own preset

Just CSS. Set the tokens you want to change; the rest cascade from the base.

:root { --tc-color-accent: #ff6b00; --tc-color-accent-hover: #cc5500; --tc-color-accent-soft: #ffe5d0; --tc-color-ink: #2a2a2e; --tc-radius-md: 12px; --tc-font-sans: 'Söhne', system-ui, sans-serif; }

Load that file after the kit's base tokens and every component updates.

The full token list

See Docs for the complete catalogue, but the most-used:

  • --tc-color-accent / -hover / -soft — primary brand color and its derivatives
  • --tc-color-ink / -soft / -muted — three steps of text emphasis
  • --tc-color-surface / -alt — background surfaces
  • --tc-color-rule / -strong — borders and dividers
  • --tc-color-{info,success,warning,danger} + matching -bg and -fg
  • --tc-radius-{sm,md,lg,pill}
  • --tc-shadow-{sm,md,lg}
  • --tc-space-{1..8} — spacing scale used by layout primitives
  • --tc-focus-ring — single source of truth for focus outlines
  • --tc-font-{sans,mono}