Foundations
Styling
A guide to the Constructive color system and CSS variables. Tokens ship with @constructive-io/ui and the shadcn registry theme — the same values power every primitive on this site.
Overview
The theme builds on shadcn/ui’s CSS variable approach: semantic names on :root and .dark, wired into Tailwind via @theme inline so utilities like bg-primary and text-muted-foreground always track the active mode.
OKLCH semantic colors
Surfaces, brand, feedback, charts, and sidebar tokens in light and dark.
Radius scale
A single --radius (0.5rem) with derived xs → 2xl steps for consistent corners.
Shadows & card elevation
Tailwind shadow steps plus package utilities shadow-card and shadow-card-lg.
Typography stacks
Sans, mono, and serif CSS variables mapped to font-sans / font-mono utilities.
Z-index layers
Named stacking levels for floating UI, modals, toasts, and the portal root.
Swatches below resolve against the live document theme — use the theme toggle in the top bar to compare light and dark. Source of truth is packages/ui/src/theme.ts; generated CSS is imported as @constructive-io/ui/globals.css.
Installation
Pull in the full token set with one import (npm) or by adding the registry theme (shadcn).
Install the package, then import the generated globals in your app stylesheet.
pnpm add @constructive-io/ui@import '@constructive-io/ui/globals.css';New to the dual install paths? See Setup for the full install guide. Your npm/registry choice is remembered across pages.
Colors
Semantic tokens pair a surface with a foreground. Prefer names like bg-primary over raw hex so components stay mode-aware.
- Aa Bb Cc 123
background / foreground - Aa Bb Cc 123
primary / primary-foreground - Aa Bb Cc 123
secondary / secondary-foreground - Aa Bb Cc 123
muted / muted-foreground - Aa Bb Cc 123
accent / accent-foreground - Aa Bb Cc 123
destructive / destructive-foreground - Aa Bb Cc 123
card / card-foreground - Aa Bb Cc 123
popover / popover-foreground
Surfaces
Page canvas, raised panels, and floating layers.
--backgroundbg-backgroundApp canvas / body background
…
--foregroundbg-foregroundDefault body text
…
--cardbg-cardCard and panel surfaces
…
--card-foregroundbg-card-foregroundText on card surfaces
…
--popoverbg-popoverPopover, menu, and select surfaces
…
--popover-foregroundbg-popover-foregroundText on popover surfaces
…
Brand & interactive
Primary actions, secondary fills, and quiet emphasis.
--primarybg-primaryBrand accent and primary actions
…
--primary-foregroundbg-primary-foregroundText/icons on primary
…
--secondarybg-secondarySecondary buttons and fills
…
--secondary-foregroundbg-secondary-foregroundText on secondary
…
--mutedbg-mutedSubtle backgrounds and wells
…
--muted-foregroundbg-muted-foregroundSecondary and helper text
…
--accentbg-accentHover, selected, and soft highlight
…
--accent-foregroundbg-accent-foregroundText on accent
…
Feedback
Semantic status colors for errors, success, and warnings.
--destructivebg-destructiveDestructive actions and error states
…
--destructive-foregroundbg-destructive-foregroundText on destructive
…
--infobg-infoInformational status
…
--info-foregroundbg-info-foregroundText for info emphasis
…
--successbg-successSuccess and positive status
…
--success-foregroundbg-success-foregroundText for success emphasis
…
--warningbg-warningWarning and caution status
…
--warning-foregroundbg-warning-foregroundText for warning emphasis
…
Borders, inputs & focus
Structural lines, field chrome, and focus rings.
--borderbg-borderDefault borders (often used at 60% opacity)
…
--inputbg-inputInput borders and field edges
…
--ringbg-ringFocus ring color
…
Charts
Series colors for data visualization.
--chart-1bg-chart-1Chart series 1
…
--chart-2bg-chart-2Chart series 2
…
--chart-3bg-chart-3Chart series 3
…
--chart-4bg-chart-4Chart series 4
…
--chart-5bg-chart-5Chart series 5
…
Sidebar
Navigation shell tokens used by layout chrome.
--sidebarbg-sidebarSidebar background
…
--sidebar-foregroundbg-sidebar-foregroundSidebar text
…
--sidebar-primarybg-sidebar-primarySidebar brand / active accent
…
--sidebar-primary-foregroundbg-sidebar-primary-foregroundText on sidebar primary
…
--sidebar-accentbg-sidebar-accentSidebar hover / active fill
…
--sidebar-accent-foregroundbg-sidebar-accent-foregroundText on sidebar accent
…
--sidebar-borderbg-sidebar-borderSidebar borders
…
--sidebar-ringbg-sidebar-ringSidebar focus ring
…
Radius
One base radius drives the scale. Default --radius is 0.5rem; derived steps keep buttons, inputs, and cards optically aligned.
--radius-xsrounded-xscalc(var(--radius) - 6px)
--radius-smrounded-smcalc(var(--radius) - 4px)
--radius-mdrounded-mdvar(--radius) · 0.5rem
--radius-lgrounded-lgcalc(var(--radius) + 2px)
--radius-xlrounded-xlcalc(var(--radius) + 6px)
--radius-2xlrounded-2xlcalc(var(--radius) + 10px)
Shadows
Standard shadow utilities plus card elevation helpers that use --shadow-border and --shadow-border-hover for a subtle edge + lift.
shadow-2xsshadow-xsshadow-smshadowshadow-mdshadow-lgshadow-xlshadow-2xl
Card elevation utilities (package-specific, not Tailwind defaults):
.shadow-cardDefault elevated card edge (uses --shadow-border)
.shadow-card-lgHover / emphasized card edge (uses --shadow-border-hover)
Typography
Font stacks are CSS variables mapped into Tailwind. This docs site loads Geist; the package defaults fall back to Open Sans and system mono.
--font-sansfont-sansThe quick brown fox jumps over the lazy dog
Body UI font (Open Sans / Geist Sans when loaded)
--font-monofont-monoconst token = "primary"
Code and tabular data
--font-seriffont-serifEditorial serif for long-form accents
Optional serif stack (Georgia)
Z-index layers
Named layers keep portaled overlays (dialogs, menus, toasts) above page content without ad-hoc magic numbers.
| Token | Value | Use |
|---|---|---|
--z-layer-floating | 1000 | Floating UI above page content |
--z-layer-modal-backdrop | 2000 | Modal / dialog backdrops |
--z-layer-modal-content | 2001 | Modal / dialog content |
--z-layer-floating-elevated | 3000 | Elevated floating layers |
--z-layer-toast | 4000 | Toasts and transient notices |
--z-layer-portal-root | 9999 | Portal root stacking context |
The package also sets isolation on the app root and position: relative on body so Base UI portals and backdrops stack predictably — including on iOS Safari after scroll.
Dark mode
Tokens redefine under .dark. Pair the class strategy with next-themes (or your own toggle) so documentElement carries class dark.
/* from package globals */
@custom-variant dark (&:is(.dark *));Light values live on :root; dark values on .dark. Primary brand blue stays consistent across modes; neutrals and surfaces shift for contrast.
Customization
Override semantic variables after the package import. Keep names intact so components continue to resolve the right tokens.
/* Override after the package import */
@import '@constructive-io/ui/globals.css';
:root {
--primary: oklch(0.55 0.18 250);
--radius: 0.625rem;
}
.dark {
--primary: oklch(0.72 0.14 250);
}- Prefer redefining
--primary,--radius, and surface tokens over editing component source. - Always set matching
*-foregroundpairs when you change a surface or brand color. - For registry installs, overrides still belong in your app CSS after generated theme CSS.