Skip to content
djust/docs
Appearance
Mode
djust.org →
Browse documentation

4 min read

CSS Variables

Every theme pack emits a runtime <style> block of CSS custom properties into your document. Tailwind utilities, your own CSS, and djust's shipped components all resolve through those variables — so swapping packs at runtime recolors the entire site without a rebuild.

The naming follows shadcn/ui conventions, with djust extensions for states (success, warning, info), media (link, code, selection), and structural surfaces (surface_1 / _2 / _3).

The HSL triplet convention

Every color token is emitted as an HSL triplet with no hsl(...) wrapper:

--background: 40 30% 7%;        /* not hsl(40 30% 7%) */
--primary: 28 85% 55%;

You wrap with hsl(...) at the consumption site. The win: opacity composes naturally:

background: hsl(var(--primary));
border: 1px solid hsl(var(--primary) / 0.5);    /* 50% opacity */
box-shadow: 0 0 0 4px hsl(var(--ring) / 0.2);

The full token list

Base surfaces

TokenWhat it paints
--backgroundThe page background.
--foregroundBody text on --background.
--cardSlightly lifted surface (cards, panels, modals).
--card-foregroundText inside a card.
--popoverPopover / dropdown / tooltip background.
--popover-foregroundText inside a popover.

Action

TokenWhat it paints
--primaryThe dominant action color (CTA buttons, focused inputs, link).
--primary-foregroundText on a --primary background.
--secondarySubdued action (cancel buttons, alternate fills).
--secondary-foregroundText on --secondary.
--accentHighlights (active nav, selected row). Often equals --primary.
--accent-foregroundText on --accent.
--mutedMuted background (disabled fills, subtle dividers).
--muted-foregroundSubdued text — captions, secondary labels.
--destructiveRed for delete confirms, error states.
--destructive-foregroundText on --destructive.

Status (djust extensions)

TokenWhat it paints
--successGreen for confirmations, success toasts.
--success-foregroundText on --success.
--warningAmber/orange for warnings.
--warning-foregroundText on --warning.
--infoBlue for informational callouts.
--info-foregroundText on --info.

Media (djust extensions)

TokenWhat it paints
--linkInline link color.
--link-hoverLink color on hover.
--code<code> background tint.
--code-foreground<code> text color.
--selection::selection background.
--selection-foreground::selection text.
--brandDistinctive identity color, often more saturated than --primary (Dracula Pink, Nord Frost, Catppuccin Rosewater). Set to match --primary if your pack has no separate brand color.
--brand-foregroundText on --brand.

UI elements

TokenWhat it paints
--borderDefault border color (cards, inputs, dividers).
--inputInput field border (often equals --border).
--ringFocus ring (often equals --primary).

Surfaces (djust extensions for landing-page layering)

For complex dark layouts that need three distinct elevation levels:

TokenWhat it paints
--surface-1Darkest — ultra-dark base background.
--surface-2Mid — panels, navbars.
--surface-3Elevated — cards, modals.

A simple light-mode pack can leave these all equal to --background and --card. Dark editorial / dashboard packs typically use them to build depth without shadows.

Geometry

TokenWhat it paints
--radiusBorder-radius multiplier in rem (e.g. --radius: 0.5rem). Components like buttons and cards multiply this.

Light vs. dark

Every shipped pack defines a LIGHT and a DARK set of these tokens. The active mode determines which set goes into :root. The mode-switcher flips :root (or a .dark class, depending on pack config) and the whole site recolors immediately — no JS needed for the recoloring itself, only for storing the user's choice.

Where to find the canonical list

Source of truth is the ThemeTokens dataclass. Every shipped pack populates the same field set — you can copy the closest pack and tweak.

See also

  • Settings — how to choose which pack emits these tokens at request time.
  • Tailwind — declaring brand aliases that resolve through these tokens.
  • extra_css_vars — for project-specific variables outside this token set.

Spotted a typo or want to improve this page? Edit on GitHub →