Skip to content
UI Kit
Accent color

Build

Theming

A handful of tokens carry the whole look. Change the accent, the radius or the typeface once, and every component follows in light and dark.

On this page

Tokens#

Components never use fixed colors, only tokens. Every token has one value for light and one for dark, so every component works in both modes without an extra line. As Tailwind classes they look like this.

ClassPaired withWhat it does
bg-backgroundtext-foregroundThe page and its text.
bg-surface, bg-surface-2text-foregroundQuiet areas set off from the page, such as a band or a code panel.
bg-cardtext-card-foregroundCards and panels.
bg-mutedtext-muted-foregroundMuted areas and secondary text.
border-borderborder-border-strongHairlines, and the stronger edge on hover.
bg-primarytext-primary-foregroundThe accent, for the main button and active states.
text-success, text-destructivebg-warning, text-infoStates such as saved, error, warning and note.

Every value with swatches is on the Theming page. Shadows come through shadow-[var(--shadow-sm)] up to --shadow-lg, the light top edge through var(--highlight).

Accent#

The accent colors main buttons, active states, chart lines and small lights. Seven ready accents are there, data-accent picks one, on the html element for the whole page or on any other element for just that area.

  • Blueblue
  • Violetviolet
  • Cyancyan
  • Emeraldgreen
  • Sunsetorange
  • Roserose
  • Neutralneutral
<html class="dark" data-accent="violet">

<!-- Only this area in green -->
<section data-accent="green">…</section>

Dark mode as the default#

The kit starts dark. Without a class kit.css shows light mode, class="dark" on the html element switches to dark. Write the class straight into the markup and dark mode is there with the first paint.

<html lang="en" class="dark" data-accent="blue">

When visitors may switch, a small script in the head remembers the choice. A toggle only flips the class.

src/layouts/Layout.astro
<script is:inline>
  // In <head>, before the first paint. Dark stays unless someone chose light.
  const saved = localStorage.getItem('theme');
  document.documentElement.classList.toggle('dark', saved !== 'light');
</script>
function toggleTheme() {
  const dark = document.documentElement.classList.toggle('dark');
  localStorage.setItem('theme', dark ? 'dark' : 'light');
}

Your own brand color#

Your brand color becomes the accent, tuned for light and dark.

  1. Compute the color system

    aiw theme --colors brand=#1f6feb

    aiw theme computes an OKLCH scale in eleven steps, measures the WCAG contrast of every step and writes src/styles/theme.css with the accent for both modes, plus DTCG tokens in tokens/colors.tokens.json.

  2. Import it after kit.css

    /* src/styles/global.css */
    @import "tailwindcss";
    @import "@fontsource-variable/inter";
    @import "./kit.css";
    @import "./theme.css";
  3. Leave out data-accent

    With your own color the html element carries only class="dark". A ready accent would win over your color in dark mode.

By hand it is two tokens per mode. In the color lab you set them with sliders and copy the CSS.

src/styles/theme.css
:root {
  --primary: oklch(0.56 0.17 200);
  --primary-foreground: oklch(0.985 0 0);
}
.dark {
  --primary: oklch(0.69 0.14 200);
  --primary-foreground: oklch(0.18 0.03 200);
}

Radius#

One value drives every corner. --radius is the base, rounded-sm up to rounded-2xl follow from it. Smaller values look factual, larger ones soft.

:root {
  --radius: 0.5rem; /* default 0.75rem */
}

Typeface#

The kit works with one typeface for everything, code included, figures set tabular. The stack starts with SF Pro Display on Apple devices and takes Inter everywhere else, self-hosted by aiw add kit.

Bring your own typeface with aiw fonts add, self-hosted with fallback metrics against layout shift, and set it as --font-sans.

aiw fonts add Manrope
:root {
  --font-sans: "Manrope Variable", system-ui, sans-serif;
}

Often searched

Jump to

Copied to the clipboard