Color
The color roles every theme fills, how they're solved in OKLCH, and the contrast targets they meet.
Every theme fills the same roles. Components only ever read roles, so they never branch on a theme.
| Group | Roles |
|---|---|
| Surfaces | surface-lower, surface-low, surface-default, surface-raised, surface-overlay |
| Borders | border-quiet, border-normal, border-loud, border-accent |
| Text | text-strong, text-primary, text-secondary, text-disabled, link |
| Neutral fills | fill-neutral-resting, -hovered, -pressed, -selected, -disabled |
| Primary fills | fill-primary-resting, -hovered, -pressed, on-primary |
| Accent | accent, fill-accent-resting, -hovered, -pressed, fill-accent-quiet, on-accent, focus |
| Status | info, success, important, warning, danger, each with fill-*-quiet and border-* |
Each is a CSS variable named --gw-color-<role>.
Surface layers
The surfaces are layers, each a step lighter than the one below in both modes. Pick a surface by what a piece is, not by how it should look:
| Layer | Role | For |
|---|---|---|
| Wells | surface-lower |
What’s set into a surface: field inputs, meter and gauge tracks, segmented tracks |
| Low | surface-low |
Quiet bands within the page, such as a sidebar |
| Page | surface-default |
The page and the app bar |
| Raised | surface-raised |
Cards, expansions, notifications and badges |
| Overlay | surface-overlay |
What floats above the page: dialogs, sheets, popovers, menus, toasts and the command menu |
A small piece sitting on a surface, such as a key hint, takes a layer above it so it reads as lifted: surface-raised on a well or the page, and the overlay with 8% of text-primary mixed in on an overlay, where there’s no layer left.
Solved, not hand-set
A core theme has two inputs: a dark background and an accent. Everything else is solved in OKLCH, with derived colors mixed in OKLab:
- Surfaces keep the background’s hue and chroma, stepping lightness. Light mode carries the same tint at lower chroma.
- Text is solved along the surface hue until it reaches its contrast target.
- The accent keeps its hue and chroma and moves in lightness until it reaches 5:1.
- Status colors start from GitHub’s Markdown alert colors and are solved the same way.
Contrast targets
All measured on the raised surface, the lowest-contrast surface text sits on:
| Role | Target |
|---|---|
| Strong text | 11:1 |
| Body text | 9:1 |
| Muted text | 4.6:1 |
| Accent | 5:1 |
| Status colors | 4.8:1 |
| Text on the accent fill | 4.5:1 |
mise run check fails when a core theme misses one. The contrast report lists every ratio.
Status colors
GitHub’s Markdown alert set, so each has its own color, mapped onto the feedback roles and onto ANSI colors in terminals:
| Alert | Role | ANSI |
|---|---|---|
| Note | info |
Blue |
| Tip | success |
Green |
| Important | important |
Magenta |
| Warning | warning |
Yellow |
| Caution | danger |
Red |
Overview
Machine controls
Next boot is set to Arch Linux, with the VM test bed on standby.
Updated 4 minutes ago
| dotfiles | 14 | |
| system-bridge | 3 | |
| triage | 1 |
Overview
Machine controls
Next boot is set to Arch Linux, with the VM test bed on standby.
Updated 4 minutes ago
| dotfiles | 14 | |
| system-bridge | 3 | |
| triage | 1 |
Overview
Machine controls
Next boot is set to Arch Linux, with the VM test bed on standby.
Updated 4 minutes ago
| dotfiles | 14 | |
| system-bridge | 3 | |
| triage | 1 |