Theming
Colour, type, spacing and radius tokens — and where to change them.
Reading the theme
Features read through KiteColors and KiteText, never
the design library. Both are extension types — zero runtime cost, and the only
thing that changes if the library does.
final c = KiteColors.of(context);
final t = KiteText.of(context);
Container(
padding: const EdgeInsets.all(KiteSpace.xl),
decoration: BoxDecoration(
color: c.card,
border: Border.all(color: c.border),
borderRadius: KiteRadius.allLg,
),
child: Text('Revenue', style: t.muted),
);
Colour
| Token | Use |
|---|---|
background | Page ground |
card / cardForeground | Raised surfaces |
border | Hairlines, dividers, outlines |
primary / primaryForeground | Accent fills and text on them |
muted / mutedForeground | Recessed fills and secondary text |
accent | Hover and selected rows |
destructive | Delete, errors |
ring | Focus outline |
Semantic tone is separate from the brand accent. Status uses
KiteTone — success, warning,
danger, info, neutral — so "paid"
reads as paid whatever accent is active. Never encode state in the accent
colour.
Type
h1–h4, p, lead,
large, small, muted. Geist for text,
Geist Mono for figures.
Text(
value,
style: t.h3.copyWith(
fontFeatures: const [FontFeature.tabularFigures()],
),
)
Use tabular figures anywhere digits line up in a column — tables, stat tiles, pagination. Proportional digits make a column of numbers ragged.
Spacing and radius
KiteSpace.xs 4 KiteRadius.sm 6
KiteSpace.sm 8 KiteRadius.md 8
KiteSpace.md 12 KiteRadius.lg 12
KiteSpace.lg 16
KiteSpace.xl 24 // section padding
KiteSpace.xxl 32
Every gap comes from here, so density is retuned in one file rather than hunted through widgets.
Breakpoints
KiteBreak.isMobile(context) // < 640
KiteBreak.isTablet(context) // 640–1024
KiteBreak.isDesktop(context) // ≥ 1024
Used for genuinely different layouts, not squeezed ones — the shell swaps a sidebar for a bottom bar and drawer, and the inbox swaps a split view for a full-screen push.
Dark mode and accents
Three accents × light/dark, switchable at runtime from Settings. Add one by
extending KiteAccent in lib/core/theme/app_theme.dart:
enum KiteAccent {
slate('Slate'),
blue('Blue'),
violet('Violet'),
rose('Rose'); // add here
ShadColorScheme scheme(Brightness b) => switch ((this, b)) {
(KiteAccent.rose, Brightness.light) => const ShadRoseColorScheme.light(),
(KiteAccent.rose, Brightness.dark) => const ShadRoseColorScheme.dark(),
…
};
}
Twelve palettes ship with the design library: slate, blue, green, gray, neutral, orange, red, rose, stone, violet, yellow, zinc.
Swapping the design library
lib/kite_ui/_shadcn.dart is the single import surface. To move to
forui or plain Material, change that file and reimplement the
wrappers around it. Nothing in features/ changes — that is the
whole point of the
one rule.