Skip to content

Colors & themes

Color tokens for surfaces, text, borders, accents and feedback, defined for both themes.

Color names express visual presence across both themes. Subtle surfaces recede; prominent surfaces and rules stand out. Each family has a default level under its bare name, such as --text; body text uses it, and headings and links use prominent text. Text adds --text-muted, one level beyond subtle. Each family exposes only the levels it needs and lists them in this order: default, prominent, subtle, muted.

01Surfaces

Use the default background for the page and content surfaces. Subtle and prominent variants create levels of separation within that palette.

TokenRoleDefinition
--backgroundDefault background for the page and content surfaces.lightoklch(100% 0 0)darkoklch(13% 0.004 260)
--background-prominentFilled controls and contained surfaces: fields, buttons and messages.lightoklch(98% 0 0)darkoklch(23% 0.004 260)
--background-subtleHover feedback, current and selected items, and subtle separation such as code blocks.lightoklch(99% 0 0)darkoklch(18% 0.004 260)

02Text

Choose contrast by the text role. Body and interface text use the default text; headings and links use prominent text. Supporting information and metadata have distinct levels.

TokenRoleDefinition
--textDefault body and interface text.lightoklch(40% 0.005 260)darkoklch(80% 0.004 260)
--text-prominentProminent text for headings, links and active elements.lightoklch(18% 0.004 260)darkoklch(95% 0.002 260)
--text-subtleSupporting descriptions, secondary links and subdued controls.lightoklch(47% 0.005 260)darkoklch(71% 0.005 260)
--text-mutedContent metadata, muted labels, markers and peripheral notes.lightoklch(54% 0.005 260)darkoklch(62% 0.005 260)

The browser suite checks the neutral text levels against all three neutral surfaces in both themes. Custom surfaces, transparency and overlays need their own contrast verification.

03Borders

Color and opacity control the presence of rules; structural classes and components own their geometry.

TokenRoleDefinition
--borderDefault borders for frames, dividers and structural markers.lightoklch(93% 0 0 / var(--border-opacity))darkoklch(34% 0.004 260 / var(--border-opacity))
--border-prominentBorders and dividers that stand out.lightoklch(89% 0 0 / var(--border-opacity))darkoklch(43% 0.004 260 / var(--border-opacity))
--border-subtleSubtle rules, such as code block edges.lightoklch(95.5% 0 0 / var(--border-opacity))darkoklch(26% 0.004 260 / var(--border-opacity))
--border-opacityShared alpha for all border levels.0.4

Use --border-subtle for rules that should recede behind structural borders.

All three border levels use --border-opacity. It does not change text, surfaces or accent crosses.

The border levels are deliberately faint and do not identify controls. The chat composer, whose boundary identifies it, uses --text-muted instead, which keeps the 3:1 contrast required for a control boundary in both themes. Checkbox and radio use --border-prominent and rely on their fill and label. Select and text fields rely on their --background-prominent fill and label instead of a visible border.

04Accent

Use the accent for interaction states and decorative markers. One pink serves both themes, so the dark theme does not redefine it; its translucent variant and the keyboard focus color derive from it at the root. An app that overrides --accent on a nested scope also sets --accent-subtle and --focus there.

TokenRoleDefinition
--accentAccent color for links, active states, focus and section crosses.oklch(66.198% 0.24435 1.678)
--accent-subtleTranslucent accent background for hover feedback.color-mix(in oklch, var(--accent) 10%, transparent)

05Feedback

Functional colors identify errors, success, warnings and information without changing the gallery accent. Always pair the color with meaningful text; a color alone does not communicate a state.

TokenRoleDefinition
--feedback-errorValidation errors and failed actions.lightoklch(54% 0.37 19.6)darkoklch(66% 0.244 12)
--feedback-successCompleted actions.lightoklch(65.5% 0.37 147.4)darkoklch(78% 0.162 157.3)
--feedback-warningConditions requiring attention before continuing.lightoklch(72% 0.247 68.6)darkoklch(82% 0.37 80)
--feedback-infoInformational status, not a decorative highlight.lightoklch(63.5% 0.293 230)darkoklch(76% 0.135 230)

The light values favor saturation over contrast and stay below 4.5:1 on light surfaces; the dark values are checked at 4.5:1 against all three neutral surfaces. They are not interchangeable background fills; colored surfaces and transparent overlays require separate contrast checks. Use native aria-invalid, associated explanations and an app-owned status or alert region as appropriate.

06Themes

Light is the :root default. Applying data-theme="dark" to <html> selects the dark palette; omitted values retain their inherited definitions. ThemeToggle persists the choice under dg-theme, and Page restores it before first paint.

<html lang="en" data-theme="dark">
  <!-- Application document -->
</html>
distributed·gallery