diff --git a/README.md b/README.md
index cbfa4a0..bdf7055 100644
--- a/README.md
+++ b/README.md
@@ -13,7 +13,7 @@ through protanopia, deuteranopia or tritanopia, with every pair the palette is h
| Source | What it makes |
|---|---|
-| `palette.toml` | `dist/`: `tokens.css` (every role as `--spin-*`), `starlight.css` (the website's `--sl-color-*`), `dashboard.css` (shadcn's HSL variables, light on `:root`, dark on `.dark`, and the dashboard's radius, scrim, dense type scale, heading tracking and motion), `tokens.json`, and `perception.js` and `simulate.svg` for the preview |
+| `palette.toml` | `dist/`: `tokens.css` (every role as `--spin-*`), `starlight.css` (the website's `--sl-color-*`), `dashboard.css` (shadcn's HSL variables, light on `:root`, dark on `.dark`, and the dashboard's radius, scrim, dense type scale, heading tracking, motion and a terminal's black surface and sixteen ANSI colours as `--terminal-*`), `tokens.json`, and `perception.js` and `simulate.svg` for the preview |
| spin's `dashboard/e2e/catalog.spec.ts` | `screens/`: every route, tab, dialog and menu of the app in both themes at 1440 and 390 px, and what each draws that this palette does not have - a colour, a face, a size, a radius, contrast, overflow, a target too small (`task screens SCREENS=
`). The catalog and the audit are committed; the images, hundreds a release, are an archive on a release of this repository that `screens.json` names and Pages unpacks. [See them](https://spin-stack.github.io/brand/screens.html) |
| `assets/mark.png` | `logos/`: the stack of disks, cut from the mark as it was drawn (1024 px on a clear ground): the tile on the brand's navy (512, 256; the touch icon at 180, the favicon at 64 and 32) for a dark ground, clear (512, 256) for a light one, and clear with its shadow drawn for the dark page (`mark-dark-*`, 512, 256), where the light one's grey shadow read as a pale ring. Each is the drawing reduced; a size it would have to enlarge fails |
diff --git a/cmd/palette/checks.go b/cmd/palette/checks.go
index aa3757f..683f940 100644
--- a/cmd/palette/checks.go
+++ b/cmd/palette/checks.go
@@ -148,6 +148,11 @@ func holds(p palette) ([]result, error) {
apart("meaning", pair[0]+" | "+pair[1], c[pair[0]], c[pair[1]], meaningTritan)
}
}
+ term, err := terminalHolds(p)
+ if err != nil {
+ return nil, err
+ }
+ out = append(out, term...)
for _, r := range out {
if math.IsNaN(r.contrast) {
return nil, fmt.Errorf("%s %s: not a number", r.mode, r.what)
@@ -156,6 +161,40 @@ func holds(p palette) ([]result, error) {
return out, nil
}
+// terminalHolds is the terminal's pairs, the same in either theme: its text on its background,
+// each ANSI colour on it, and the foreground on what a program or a person paints under a cell -
+// ANSI black and the selection. The cursor is a block the character under it reads on.
+func terminalHolds(p palette) ([]result, error) {
+ c, err := p.Terminal.colors()
+ if err != nil {
+ return nil, fmt.Errorf("terminal: %w", err)
+ }
+ var out []result
+ hold := func(what string, fg, bg rgb, floor float64) {
+ r := result{mode: "term", kind: "text", what: what, contrast: contrast(fg, bg), floor: floor}
+ r.ok = r.contrast >= floor
+ out = append(out, r)
+ }
+ bg := c["background"]
+ hold("foreground on background", c["foreground"], bg, bodyText)
+ for _, k := range ansi {
+ switch k {
+ case "black":
+ hold("foreground on black", c["foreground"], c[k], bodyText)
+ case "white", "bright_white":
+ hold(k+" on background", c[k], bg, bodyText)
+ default:
+ hold(k+" on background", c[k], bg, text)
+ }
+ }
+ hold("foreground on selection", c["foreground"], c["selection"], bodyText)
+ hold("background on cursor", bg, c["cursor"], text)
+ r := result{mode: "term", kind: "non-text", what: "cursor on background", contrast: contrast(c["cursor"], bg), floor: nonText}
+ r.ok = r.contrast >= nonText
+ out = append(out, r)
+ return out, nil
+}
+
// colors reads a mode's roles by name.
func colors(m mode) (map[string]rgb, error) {
named := map[string]string{
@@ -164,6 +203,11 @@ func colors(m mode) (map[string]rgb, error) {
"accent": m.Accent, "accent_text": m.AccentText, "on_accent": m.OnAccent, "label": m.Label,
"success": m.Success, "warning": m.Warning, "error": m.Error, "destructive": m.Destructive,
}
+ return parseNamed(named)
+}
+
+// parseNamed parses every color by its name, failing on one that is missing.
+func parseNamed(named map[string]string) (map[string]rgb, error) {
out := map[string]rgb{}
for name, hex := range named {
if hex == "" {
diff --git a/cmd/palette/main.go b/cmd/palette/main.go
index fac72b6..871f895 100644
--- a/cmd/palette/main.go
+++ b/cmd/palette/main.go
@@ -29,11 +29,48 @@ type mode struct {
Destructive string
}
+type terminal struct {
+ Background, Foreground, Cursor, Selection string
+ Black, Red, Green, Yellow, Blue, Magenta, Cyan, White string
+ BrightBlack string `toml:"bright_black"`
+ BrightRed string `toml:"bright_red"`
+ BrightGreen string `toml:"bright_green"`
+ BrightYellow string `toml:"bright_yellow"`
+ BrightBlue string `toml:"bright_blue"`
+ BrightMagenta string `toml:"bright_magenta"`
+ BrightCyan string `toml:"bright_cyan"`
+ BrightWhite string `toml:"bright_white"`
+}
+
+// ansi is the sixteen colours by palette.toml's names, in the order a program numbers them.
+var ansi = []string{
+ "black", "red", "green", "yellow", "blue", "magenta", "cyan", "white",
+ "bright_black", "bright_red", "bright_green", "bright_yellow", "bright_blue", "bright_magenta", "bright_cyan", "bright_white",
+}
+
+// terminalRoles is the terminal's roles before the sixteen colours, in the order they are written.
+var terminalRoles = []string{"background", "foreground", "cursor", "selection"}
+
+// colors reads the terminal's roles and colours by palette.toml's names.
+func (t terminal) colors() (map[string]rgb, error) {
+ named := map[string]string{
+ "background": t.Background, "foreground": t.Foreground, "cursor": t.Cursor, "selection": t.Selection,
+ "black": t.Black, "red": t.Red, "green": t.Green, "yellow": t.Yellow,
+ "blue": t.Blue, "magenta": t.Magenta, "cyan": t.Cyan, "white": t.White,
+ "bright_black": t.BrightBlack, "bright_red": t.BrightRed, "bright_green": t.BrightGreen,
+ "bright_yellow": t.BrightYellow, "bright_blue": t.BrightBlue, "bright_magenta": t.BrightMagenta,
+ "bright_cyan": t.BrightCyan, "bright_white": t.BrightWhite,
+ }
+ return parseNamed(named)
+}
+
type palette struct {
Brand map[string]string
Dark mode
Light mode
- Tint struct{ Hover, Selected, Scrim, Fill, Badge float64 }
+ // A terminal's roles and its sixteen ANSI colours, the same in either theme.
+ Terminal terminal
+ Tint struct{ Hover, Selected, Scrim, Fill, Badge float64 }
// What lifts a menu or a dialog off what is under it, per theme: a CSS box-shadow.
Elevation struct{ Dark, Light string }
Type struct {
diff --git a/cmd/palette/outputs.go b/cmd/palette/outputs.go
index 2af35e3..83c2836 100644
--- a/cmd/palette/outputs.go
+++ b/cmd/palette/outputs.go
@@ -18,10 +18,14 @@ func outputs(p palette, results []result) (map[string][]byte, error) {
if err != nil {
return nil, err
}
+ term, err := p.Terminal.colors()
+ if err != nil {
+ return nil, err
+ }
files := map[string][]byte{}
j, err := json.MarshalIndent(map[string]any{
- "brand": p.Brand, "dark": hexes(dark), "light": hexes(light),
+ "brand": p.Brand, "dark": hexes(dark), "light": hexes(light), "terminal": hexes(term),
"tint": p.Tint, "type": p.Type, "layout": p.Layout, "controls": p.Controls, "elevation": p.Elevation, "motion": p.Motion,
}, "", " ")
if err != nil {
@@ -95,6 +99,7 @@ func tokensCSS(p palette, dark, light map[string]rgb) string {
for _, k := range names {
fmt.Fprintf(&b, "\t--spin-brand-%s: %s;\n", k, strings.ToUpper(p.Brand[k]))
}
+ b.WriteString(terminalVars(p, "spin-terminal"))
fmt.Fprintf(&b, "\t--spin-wordmark: %q;\n", p.Type.Wordmark)
fmt.Fprintf(&b, "\t--spin-font-sans: '%s', %s;\n", p.Type.Sans, p.Type.FallbackSans)
fmt.Fprintf(&b, "\t--spin-font-mono: '%s', %s;\n", p.Type.Mono, p.Type.FallbackMono)
@@ -264,6 +269,8 @@ func dashboardCSS(p palette, dark, light map[string]rgb) string {
dim := dark["page"]
b255 := func(v float64) int { return int(math.Round(v * 255)) }
fmt.Fprintf(&b, "\t--scrim: rgb(%d %d %d / %g);\n", b255(dim.r), b255(dim.g), b255(dim.b), p.Tint.Scrim)
+ // A terminal, black in either theme: hex, since xterm reads them off the page for its canvas.
+ b.WriteString(terminalVars(p, "terminal"))
// The word the sidebar writes beside the mark: the app's catalog audit holds its text to this.
fmt.Fprintf(&b, "\t--spin-wordmark: %q;\n", p.Type.Wordmark)
fmt.Fprintf(&b, "\t--spin-font-sans: '%s', %s;\n\t--spin-font-mono: '%s', %s;\n", p.Type.Sans, p.Type.FallbackSans, p.Type.Mono, p.Type.FallbackMono)
@@ -282,6 +289,20 @@ func dashboardCSS(p palette, dark, light map[string]rgb) string {
return b.String()
}
+// terminalVars is the terminal's roles, then its sixteen colours in a program's order, as
+// ---: hex.
+func terminalVars(p palette, prefix string) string {
+ c, err := p.Terminal.colors()
+ if err != nil {
+ panic("palette.toml's terminal: " + err.Error())
+ }
+ var b strings.Builder
+ for _, k := range append(append([]string{}, terminalRoles...), ansi...) {
+ fmt.Fprintf(&b, "\t--%s-%s: %s;\n", prefix, strings.ReplaceAll(k, "_", "-"), c[k].hex())
+ }
+ return b.String()
+}
+
// hsl writes a color as shadcn's variables hold it: "H S% L%", for hsl(var(--x)).
func hsl(c rgb) string {
mx, mn := math.Max(c.r, math.Max(c.g, c.b)), math.Min(c.r, math.Min(c.g, c.b))
diff --git a/dist/dashboard.css b/dist/dashboard.css
index 7df640d..85b5ecc 100644
--- a/dist/dashboard.css
+++ b/dist/dashboard.css
@@ -82,6 +82,26 @@
--spin-control-gap: 6px;
--spin-width-page: 1600px;
--scrim: rgb(14 20 33 / 0.64);
+ --terminal-background: #0A0C10;
+ --terminal-foreground: #E6EBF2;
+ --terminal-cursor: #27BFE8;
+ --terminal-selection: #2C3A55;
+ --terminal-black: #262C38;
+ --terminal-red: #F0707A;
+ --terminal-green: #4CC38A;
+ --terminal-yellow: #E3B04B;
+ --terminal-blue: #6A9FF0;
+ --terminal-magenta: #D58AE6;
+ --terminal-cyan: #27BFE8;
+ --terminal-white: #C9D1DE;
+ --terminal-bright-black: #7D889C;
+ --terminal-bright-red: #FF9CA4;
+ --terminal-bright-green: #7EE0AE;
+ --terminal-bright-yellow: #F5CF7A;
+ --terminal-bright-blue: #9CC0FF;
+ --terminal-bright-magenta: #EBB2F7;
+ --terminal-bright-cyan: #5FE3D6;
+ --terminal-bright-white: #FFFFFF;
--spin-wordmark: "Spinbox";
--spin-font-sans: 'IBM Plex Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;
--spin-font-mono: 'IBM Plex Mono', ui-monospace, 'SF Mono', Menlo, monospace;
diff --git a/dist/perception.js b/dist/perception.js
index 6f3bcb7..8f1621f 100644
--- a/dist/perception.js
+++ b/dist/perception.js
@@ -1,2 +1,2 @@
// Written by `task palette`: every pair palette.toml is held to, and how it held.
-export const perception = [{"Mode":"dark","Kind":"text","What":"text on page","Contrast":15.37,"Floor":7,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"muted on page","Contrast":7.41,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"accent_text on page","Contrast":9.6,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"success on page","Contrast":8.31,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"warning on page","Contrast":9.27,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"error on page","Contrast":7.1,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"text on surface","Contrast":13.9,"Floor":7,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"muted on surface","Contrast":6.7,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"accent_text on surface","Contrast":8.68,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"success on surface","Contrast":7.52,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"warning on surface","Contrast":8.39,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"error on surface","Contrast":6.42,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"text on raised","Contrast":12.09,"Floor":7,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"muted on raised","Contrast":5.83,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"accent_text on raised","Contrast":7.55,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"success on raised","Contrast":6.54,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"warning on raised","Contrast":7.3,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"error on raised","Contrast":5.59,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"text on overlay","Contrast":10.17,"Floor":7,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"muted on overlay","Contrast":4.9,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"accent_text on overlay","Contrast":6.35,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"success on overlay","Contrast":5.5,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"warning on overlay","Contrast":6.14,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"error on overlay","Contrast":4.7,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"success on its badge over page","Contrast":6.83,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"warning on its badge over page","Contrast":7.54,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"error on its badge over page","Contrast":5.99,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"accent_text on its badge over page","Contrast":7.69,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"success on its badge over surface","Contrast":6.06,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"warning on its badge over surface","Contrast":6.69,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"error on its badge over surface","Contrast":5.34,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"accent_text on its badge over surface","Contrast":6.8,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"success on its badge over raised","Contrast":5.24,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"warning on its badge over raised","Contrast":5.79,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"error on its badge over raised","Contrast":4.64,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"accent_text on its badge over raised","Contrast":5.87,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"label on page","Contrast":8.27,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"accent_text on the selected tint over page","Contrast":7.07,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"text on the selected tint over page","Contrast":11.32,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"label on surface","Contrast":7.48,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"accent_text on the selected tint over surface","Contrast":6.36,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"text on the selected tint over surface","Contrast":10.19,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"on_accent on accent","Contrast":4.53,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"white on destructive","Contrast":5.22,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"on_accent on accent under the pointer","Contrast":5.58,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"on_accent on accent pressed","Contrast":6.94,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"white on destructive under the pointer","Contrast":6.37,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"white on destructive pressed","Contrast":7.83,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"text on a secondary button","Contrast":12.09,"Floor":7,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"text on a secondary button under the pointer","Contrast":10.17,"Floor":7,"Worst":0,"OK":true},{"Mode":"dark","Kind":"non-text","What":"border_strong on page","Contrast":4.15,"Floor":3,"Worst":0,"OK":true},{"Mode":"dark","Kind":"non-text","What":"accent (the focus ring) on page","Contrast":4.07,"Floor":3,"Worst":0,"OK":true},{"Mode":"dark","Kind":"non-text","What":"border_strong on raised","Contrast":3.27,"Floor":3,"Worst":0,"OK":true},{"Mode":"dark","Kind":"non-text","What":"accent (the focus ring) on raised","Contrast":3.2,"Floor":3,"Worst":0,"OK":true},{"Mode":"dark","Kind":"edge","What":"page | surface","Distance":{"deutan":3.6,"deutan+ips":3.3,"dim":3.1,"drawn":3.6,"ips":3.3,"protan":3.6,"protan+ips":3.4,"tritan":4.2},"Floor":3,"Worst":2,"OK":true},{"Mode":"dark","Kind":"edge","What":"surface | raised","Distance":{"deutan":4.1,"deutan+ips":4,"dim":3.9,"drawn":4.2,"ips":4.1,"protan":4.2,"protan+ips":4.1,"tritan":4},"Floor":3,"Worst":2,"OK":true},{"Mode":"dark","Kind":"edge","What":"page | raised","Distance":{"deutan":7.7,"deutan+ips":7.3,"dim":7,"drawn":7.8,"ips":7.4,"protan":7.9,"protan+ips":7.5,"tritan":8.1},"Floor":3,"Worst":2,"OK":true},{"Mode":"dark","Kind":"line","What":"border on page","Distance":{"deutan":14.5,"deutan+ips":13.6,"dim":12.9,"drawn":14.6,"ips":13.8,"protan":15,"protan+ips":14.1,"tritan":15},"Floor":6,"Worst":4,"OK":true},{"Mode":"dark","Kind":"line","What":"border on raised","Distance":{"deutan":7.3,"deutan+ips":6.9,"dim":6.6,"drawn":7.4,"ips":7,"protan":7.5,"protan+ips":7.1,"tritan":7.4},"Floor":6,"Worst":4,"OK":true},{"Mode":"dark","Kind":"state","What":"selected tint over page | page","Distance":{"deutan":9.7,"deutan+ips":9.3,"dim":9.6,"drawn":10.9,"ips":10.3,"protan":10,"protan+ips":9.5,"tritan":12.6},"Floor":10,"Worst":6,"OK":true},{"Mode":"dark","Kind":"hover","What":"hover tint over page | page","Distance":{"deutan":3.9,"deutan+ips":3.7,"dim":3.7,"drawn":4.4,"ips":4.1,"protan":3.8,"protan+ips":3.6,"tritan":7},"Floor":3,"Worst":2,"OK":true},{"Mode":"dark","Kind":"state","What":"selected tint over surface | surface","Distance":{"deutan":8.4,"deutan+ips":8.3,"dim":9.2,"drawn":10.2,"ips":9.7,"protan":8.9,"protan+ips":8.6,"tritan":10.8},"Floor":10,"Worst":6,"OK":true},{"Mode":"dark","Kind":"hover","What":"hover tint over surface | surface","Distance":{"deutan":3.2,"deutan+ips":3.2,"dim":3.6,"drawn":4.2,"ips":3.9,"protan":3.3,"protan+ips":3.2,"tritan":5.4},"Floor":3,"Worst":2,"OK":true},{"Mode":"dark","Kind":"hover","What":"accent under the pointer | accent","Distance":{"deutan":5.4,"deutan+ips":5.4,"dim":5.6,"drawn":5.7,"ips":5.7,"protan":6.2,"protan+ips":6.1,"tritan":6.1},"Floor":3,"Worst":2,"OK":true},{"Mode":"dark","Kind":"hover","What":"destructive under the pointer | destructive","Distance":{"deutan":5.8,"deutan+ips":5.8,"dim":5.2,"drawn":5.3,"ips":5.2,"protan":3.9,"protan+ips":3.9,"tritan":5.3},"Floor":3,"Worst":2,"OK":true},{"Mode":"dark","Kind":"hover","What":"secondary under the pointer | secondary","Distance":{"deutan":4,"deutan+ips":3.8,"dim":3.7,"drawn":4,"ips":3.9,"protan":4.1,"protan+ips":4,"tritan":4},"Floor":3,"Worst":2,"OK":true},{"Mode":"dark","Kind":"edge","What":"secondary button | page","Distance":{"deutan":7.7,"deutan+ips":7.3,"dim":7,"drawn":7.8,"ips":7.4,"protan":7.9,"protan+ips":7.5,"tritan":8.1},"Floor":3,"Worst":2,"OK":true},{"Mode":"dark","Kind":"meaning","What":"success | error","Distance":{"deutan":14.6,"deutan+ips":14.5,"dim":69,"drawn":69.9,"ips":69.6,"protan":32.4,"protan+ips":32.2,"tritan":64.2},"Floor":20,"Worst":10,"OK":true},{"Mode":"dark","Kind":"meaning","What":"success | warning","Distance":{"deutan":16.7,"deutan+ips":16.6,"dim":35.1,"drawn":35.5,"ips":35.4,"protan":11.5,"protan+ips":11.4,"tritan":51.9},"Floor":20,"Worst":10,"OK":true},{"Mode":"dark","Kind":"meaning","What":"warning | error","Distance":{"deutan":28.9,"deutan+ips":28.8,"dim":47.7,"drawn":48.5,"ips":48.2,"protan":41.5,"protan+ips":41.2,"tritan":11.5},"Floor":20,"Worst":10,"OK":true},{"Mode":"dark","Kind":"meaning","What":"accent | success","Distance":{"deutan":40.6,"deutan+ips":40.3,"dim":41.6,"drawn":42.3,"ips":42,"protan":42.5,"protan+ips":42.2,"tritan":18},"Floor":20,"Worst":10,"OK":true},{"Mode":"dark","Kind":"meaning","What":"accent | error","Distance":{"deutan":27,"deutan+ips":26.7,"dim":46.4,"drawn":47.3,"ips":47,"protan":10.8,"protan+ips":10.7,"tritan":62.5},"Floor":20,"Worst":10,"OK":true},{"Mode":"light","Kind":"text","What":"text on page","Contrast":17.74,"Floor":7,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"muted on page","Contrast":6.63,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"accent_text on page","Contrast":7.46,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"success on page","Contrast":6.81,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"warning on page","Contrast":6.71,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"error on page","Contrast":7.67,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"text on surface","Contrast":16.09,"Floor":7,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"muted on surface","Contrast":6.01,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"accent_text on surface","Contrast":6.76,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"success on surface","Contrast":6.18,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"warning on surface","Contrast":6.09,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"error on surface","Contrast":6.95,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"text on raised","Contrast":14.27,"Floor":7,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"muted on raised","Contrast":5.33,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"accent_text on raised","Contrast":6,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"success on raised","Contrast":5.48,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"warning on raised","Contrast":5.4,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"error on raised","Contrast":6.17,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"text on overlay","Contrast":17.74,"Floor":7,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"muted on overlay","Contrast":6.63,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"accent_text on overlay","Contrast":7.46,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"success on overlay","Contrast":6.81,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"warning on overlay","Contrast":6.71,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"error on overlay","Contrast":7.67,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"success on its badge over page","Contrast":5.68,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"warning on its badge over page","Contrast":5.61,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"error on its badge over page","Contrast":6.25,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"accent_text on its badge over page","Contrast":6.17,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"success on its badge over surface","Contrast":5.18,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"warning on its badge over surface","Contrast":5.12,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"error on its badge over surface","Contrast":5.7,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"accent_text on its badge over surface","Contrast":5.63,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"success on its badge over raised","Contrast":4.63,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"warning on its badge over raised","Contrast":4.57,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"error on its badge over raised","Contrast":5.08,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"accent_text on its badge over raised","Contrast":5.03,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"label on page","Contrast":7.6,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"accent_text on the selected tint over page","Contrast":5.02,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"text on the selected tint over page","Contrast":11.94,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"label on surface","Contrast":6.9,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"accent_text on the selected tint over surface","Contrast":4.63,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"text on the selected tint over surface","Contrast":11.01,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"on_accent on accent","Contrast":5.5,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"white on destructive","Contrast":5.62,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"on_accent on accent under the pointer","Contrast":6.68,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"on_accent on accent pressed","Contrast":8.14,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"white on destructive under the pointer","Contrast":6.83,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"white on destructive pressed","Contrast":8.33,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"text on a secondary button","Contrast":16.09,"Floor":7,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"text on a secondary button under the pointer","Contrast":14.27,"Floor":7,"Worst":0,"OK":true},{"Mode":"light","Kind":"non-text","What":"border_strong on page","Contrast":3.86,"Floor":3,"Worst":0,"OK":true},{"Mode":"light","Kind":"non-text","What":"accent (the focus ring) on page","Contrast":5.5,"Floor":3,"Worst":0,"OK":true},{"Mode":"light","Kind":"non-text","What":"border_strong on raised","Contrast":3.1,"Floor":3,"Worst":0,"OK":true},{"Mode":"light","Kind":"non-text","What":"accent (the focus ring) on raised","Contrast":4.43,"Floor":3,"Worst":0,"OK":true},{"Mode":"light","Kind":"edge","What":"page | surface","Distance":{"deutan":3.6,"deutan+ips":3.6,"dim":3.4,"drawn":3.4,"ips":3.4,"protan":3.3,"protan+ips":3.3,"tritan":3.5},"Floor":3,"Worst":2,"OK":true},{"Mode":"light","Kind":"edge","What":"surface | raised","Distance":{"deutan":3.5,"deutan+ips":3.5,"dim":3.4,"drawn":3.4,"ips":3.4,"protan":3.3,"protan+ips":3.3,"tritan":3.6},"Floor":3,"Worst":2,"OK":true},{"Mode":"light","Kind":"edge","What":"page | raised","Distance":{"deutan":7.1,"deutan+ips":7,"dim":6.8,"drawn":6.8,"ips":6.8,"protan":6.6,"protan+ips":6.6,"tritan":7.1},"Floor":3,"Worst":2,"OK":true},{"Mode":"light","Kind":"line","What":"border on page","Distance":{"deutan":13.1,"deutan+ips":13,"dim":12.7,"drawn":12.8,"ips":12.7,"protan":12.5,"protan+ips":12.4,"tritan":13},"Floor":6,"Worst":4,"OK":true},{"Mode":"light","Kind":"line","What":"border on raised","Distance":{"deutan":6.5,"deutan+ips":6.5,"dim":6.3,"drawn":6.4,"ips":6.4,"protan":6.3,"protan+ips":6.3,"tritan":6.4},"Floor":6,"Worst":4,"OK":true},{"Mode":"light","Kind":"state","What":"selected tint over page | page","Distance":{"deutan":13.2,"deutan+ips":13.1,"dim":13.8,"drawn":13.9,"ips":13.9,"protan":11.3,"protan+ips":11.3,"tritan":17},"Floor":10,"Worst":6,"OK":true},{"Mode":"light","Kind":"hover","What":"hover tint over page | page","Distance":{"deutan":5.1,"deutan+ips":5.1,"dim":5.6,"drawn":5.6,"ips":5.6,"protan":4.3,"protan+ips":4.3,"tritan":7.4},"Floor":3,"Worst":2,"OK":true},{"Mode":"light","Kind":"state","What":"selected tint over surface | surface","Distance":{"deutan":12.1,"deutan+ips":12.1,"dim":12.8,"drawn":12.9,"ips":12.9,"protan":10.4,"protan+ips":10.3,"tritan":15.6},"Floor":10,"Worst":6,"OK":true},{"Mode":"light","Kind":"hover","What":"hover tint over surface | surface","Distance":{"deutan":4.6,"deutan+ips":4.6,"dim":5.1,"drawn":5.2,"ips":5.1,"protan":3.9,"protan+ips":3.9,"tritan":6.6},"Floor":3,"Worst":2,"OK":true},{"Mode":"light","Kind":"hover","What":"accent under the pointer | accent","Distance":{"deutan":4.6,"deutan+ips":4.6,"dim":4.8,"drawn":4.9,"ips":4.8,"protan":5.3,"protan+ips":5.3,"tritan":5.3},"Floor":3,"Worst":2,"OK":true},{"Mode":"light","Kind":"hover","What":"destructive under the pointer | destructive","Distance":{"deutan":5.6,"deutan+ips":5.5,"dim":4.9,"drawn":5,"ips":5,"protan":3.7,"protan+ips":3.6,"tritan":5.2},"Floor":3,"Worst":2,"OK":true},{"Mode":"light","Kind":"hover","What":"secondary under the pointer | secondary","Distance":{"deutan":3.5,"deutan+ips":3.5,"dim":3.4,"drawn":3.4,"ips":3.4,"protan":3.3,"protan+ips":3.3,"tritan":3.6},"Floor":3,"Worst":2,"OK":true},{"Mode":"light","Kind":"edge","What":"secondary button | page","Distance":{"deutan":3.6,"deutan+ips":3.6,"dim":3.4,"drawn":3.4,"ips":3.4,"protan":3.3,"protan+ips":3.3,"tritan":3.5},"Floor":3,"Worst":2,"OK":true},{"Mode":"light","Kind":"meaning","What":"success | error","Distance":{"deutan":10.3,"deutan+ips":10,"dim":61.3,"drawn":64.1,"ips":62.9,"protan":29.7,"protan+ips":29,"tritan":56.5},"Floor":20,"Worst":10,"OK":true},{"Mode":"light","Kind":"meaning","What":"success | warning","Distance":{"deutan":16.1,"deutan+ips":15.6,"dim":35.2,"drawn":36.7,"ips":36.1,"protan":11.5,"protan+ips":10.8,"tritan":46.6},"Floor":20,"Worst":10,"OK":true},{"Mode":"light","Kind":"meaning","What":"warning | error","Distance":{"deutan":24.6,"deutan+ips":24,"dim":37.8,"drawn":41.1,"ips":39.7,"protan":38.6,"protan+ips":37.4,"tritan":9.3},"Floor":20,"Worst":10,"OK":true},{"Mode":"light","Kind":"meaning","What":"accent | success","Distance":{"deutan":32.2,"deutan+ips":31.7,"dim":33.3,"drawn":34.3,"ips":33.9,"protan":34.9,"protan+ips":34.5,"tritan":9.7},"Floor":20,"Worst":10,"OK":true},{"Mode":"light","Kind":"meaning","What":"accent | error","Distance":{"deutan":19.9,"deutan+ips":19.8,"dim":44.2,"drawn":45.6,"ips":45,"protan":16.6,"protan+ips":16.4,"tritan":61.3},"Floor":20,"Worst":10,"OK":true}];
+export const perception = [{"Mode":"dark","Kind":"text","What":"text on page","Contrast":15.37,"Floor":7,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"muted on page","Contrast":7.41,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"accent_text on page","Contrast":9.6,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"success on page","Contrast":8.31,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"warning on page","Contrast":9.27,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"error on page","Contrast":7.1,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"text on surface","Contrast":13.9,"Floor":7,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"muted on surface","Contrast":6.7,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"accent_text on surface","Contrast":8.68,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"success on surface","Contrast":7.52,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"warning on surface","Contrast":8.39,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"error on surface","Contrast":6.42,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"text on raised","Contrast":12.09,"Floor":7,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"muted on raised","Contrast":5.83,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"accent_text on raised","Contrast":7.55,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"success on raised","Contrast":6.54,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"warning on raised","Contrast":7.3,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"error on raised","Contrast":5.59,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"text on overlay","Contrast":10.17,"Floor":7,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"muted on overlay","Contrast":4.9,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"accent_text on overlay","Contrast":6.35,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"success on overlay","Contrast":5.5,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"warning on overlay","Contrast":6.14,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"error on overlay","Contrast":4.7,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"success on its badge over page","Contrast":6.83,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"warning on its badge over page","Contrast":7.54,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"error on its badge over page","Contrast":5.99,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"accent_text on its badge over page","Contrast":7.69,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"success on its badge over surface","Contrast":6.06,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"warning on its badge over surface","Contrast":6.69,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"error on its badge over surface","Contrast":5.34,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"accent_text on its badge over surface","Contrast":6.8,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"success on its badge over raised","Contrast":5.24,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"warning on its badge over raised","Contrast":5.79,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"error on its badge over raised","Contrast":4.64,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"accent_text on its badge over raised","Contrast":5.87,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"label on page","Contrast":8.27,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"accent_text on the selected tint over page","Contrast":7.07,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"text on the selected tint over page","Contrast":11.32,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"label on surface","Contrast":7.48,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"accent_text on the selected tint over surface","Contrast":6.36,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"text on the selected tint over surface","Contrast":10.19,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"on_accent on accent","Contrast":4.53,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"white on destructive","Contrast":5.22,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"on_accent on accent under the pointer","Contrast":5.58,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"on_accent on accent pressed","Contrast":6.94,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"white on destructive under the pointer","Contrast":6.37,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"white on destructive pressed","Contrast":7.83,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"text on a secondary button","Contrast":12.09,"Floor":7,"Worst":0,"OK":true},{"Mode":"dark","Kind":"text","What":"text on a secondary button under the pointer","Contrast":10.17,"Floor":7,"Worst":0,"OK":true},{"Mode":"dark","Kind":"non-text","What":"border_strong on page","Contrast":4.15,"Floor":3,"Worst":0,"OK":true},{"Mode":"dark","Kind":"non-text","What":"accent (the focus ring) on page","Contrast":4.07,"Floor":3,"Worst":0,"OK":true},{"Mode":"dark","Kind":"non-text","What":"border_strong on raised","Contrast":3.27,"Floor":3,"Worst":0,"OK":true},{"Mode":"dark","Kind":"non-text","What":"accent (the focus ring) on raised","Contrast":3.2,"Floor":3,"Worst":0,"OK":true},{"Mode":"dark","Kind":"edge","What":"page | surface","Distance":{"deutan":3.6,"deutan+ips":3.3,"dim":3.1,"drawn":3.6,"ips":3.3,"protan":3.6,"protan+ips":3.4,"tritan":4.2},"Floor":3,"Worst":2,"OK":true},{"Mode":"dark","Kind":"edge","What":"surface | raised","Distance":{"deutan":4.1,"deutan+ips":4,"dim":3.9,"drawn":4.2,"ips":4.1,"protan":4.2,"protan+ips":4.1,"tritan":4},"Floor":3,"Worst":2,"OK":true},{"Mode":"dark","Kind":"edge","What":"page | raised","Distance":{"deutan":7.7,"deutan+ips":7.3,"dim":7,"drawn":7.8,"ips":7.4,"protan":7.9,"protan+ips":7.5,"tritan":8.1},"Floor":3,"Worst":2,"OK":true},{"Mode":"dark","Kind":"line","What":"border on page","Distance":{"deutan":14.5,"deutan+ips":13.6,"dim":12.9,"drawn":14.6,"ips":13.8,"protan":15,"protan+ips":14.1,"tritan":15},"Floor":6,"Worst":4,"OK":true},{"Mode":"dark","Kind":"line","What":"border on raised","Distance":{"deutan":7.3,"deutan+ips":6.9,"dim":6.6,"drawn":7.4,"ips":7,"protan":7.5,"protan+ips":7.1,"tritan":7.4},"Floor":6,"Worst":4,"OK":true},{"Mode":"dark","Kind":"state","What":"selected tint over page | page","Distance":{"deutan":9.7,"deutan+ips":9.3,"dim":9.6,"drawn":10.9,"ips":10.3,"protan":10,"protan+ips":9.5,"tritan":12.6},"Floor":10,"Worst":6,"OK":true},{"Mode":"dark","Kind":"hover","What":"hover tint over page | page","Distance":{"deutan":3.9,"deutan+ips":3.7,"dim":3.7,"drawn":4.4,"ips":4.1,"protan":3.8,"protan+ips":3.6,"tritan":7},"Floor":3,"Worst":2,"OK":true},{"Mode":"dark","Kind":"state","What":"selected tint over surface | surface","Distance":{"deutan":8.4,"deutan+ips":8.3,"dim":9.2,"drawn":10.2,"ips":9.7,"protan":8.9,"protan+ips":8.6,"tritan":10.8},"Floor":10,"Worst":6,"OK":true},{"Mode":"dark","Kind":"hover","What":"hover tint over surface | surface","Distance":{"deutan":3.2,"deutan+ips":3.2,"dim":3.6,"drawn":4.2,"ips":3.9,"protan":3.3,"protan+ips":3.2,"tritan":5.4},"Floor":3,"Worst":2,"OK":true},{"Mode":"dark","Kind":"hover","What":"accent under the pointer | accent","Distance":{"deutan":5.4,"deutan+ips":5.4,"dim":5.6,"drawn":5.7,"ips":5.7,"protan":6.2,"protan+ips":6.1,"tritan":6.1},"Floor":3,"Worst":2,"OK":true},{"Mode":"dark","Kind":"hover","What":"destructive under the pointer | destructive","Distance":{"deutan":5.8,"deutan+ips":5.8,"dim":5.2,"drawn":5.3,"ips":5.2,"protan":3.9,"protan+ips":3.9,"tritan":5.3},"Floor":3,"Worst":2,"OK":true},{"Mode":"dark","Kind":"hover","What":"secondary under the pointer | secondary","Distance":{"deutan":4,"deutan+ips":3.8,"dim":3.7,"drawn":4,"ips":3.9,"protan":4.1,"protan+ips":4,"tritan":4},"Floor":3,"Worst":2,"OK":true},{"Mode":"dark","Kind":"edge","What":"secondary button | page","Distance":{"deutan":7.7,"deutan+ips":7.3,"dim":7,"drawn":7.8,"ips":7.4,"protan":7.9,"protan+ips":7.5,"tritan":8.1},"Floor":3,"Worst":2,"OK":true},{"Mode":"dark","Kind":"meaning","What":"success | error","Distance":{"deutan":14.6,"deutan+ips":14.5,"dim":69,"drawn":69.9,"ips":69.6,"protan":32.4,"protan+ips":32.2,"tritan":64.2},"Floor":20,"Worst":10,"OK":true},{"Mode":"dark","Kind":"meaning","What":"success | warning","Distance":{"deutan":16.7,"deutan+ips":16.6,"dim":35.1,"drawn":35.5,"ips":35.4,"protan":11.5,"protan+ips":11.4,"tritan":51.9},"Floor":20,"Worst":10,"OK":true},{"Mode":"dark","Kind":"meaning","What":"warning | error","Distance":{"deutan":28.9,"deutan+ips":28.8,"dim":47.7,"drawn":48.5,"ips":48.2,"protan":41.5,"protan+ips":41.2,"tritan":11.5},"Floor":20,"Worst":10,"OK":true},{"Mode":"dark","Kind":"meaning","What":"accent | success","Distance":{"deutan":40.6,"deutan+ips":40.3,"dim":41.6,"drawn":42.3,"ips":42,"protan":42.5,"protan+ips":42.2,"tritan":18},"Floor":20,"Worst":10,"OK":true},{"Mode":"dark","Kind":"meaning","What":"accent | error","Distance":{"deutan":27,"deutan+ips":26.7,"dim":46.4,"drawn":47.3,"ips":47,"protan":10.8,"protan+ips":10.7,"tritan":62.5},"Floor":20,"Worst":10,"OK":true},{"Mode":"light","Kind":"text","What":"text on page","Contrast":17.74,"Floor":7,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"muted on page","Contrast":6.63,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"accent_text on page","Contrast":7.46,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"success on page","Contrast":6.81,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"warning on page","Contrast":6.71,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"error on page","Contrast":7.67,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"text on surface","Contrast":16.09,"Floor":7,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"muted on surface","Contrast":6.01,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"accent_text on surface","Contrast":6.76,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"success on surface","Contrast":6.18,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"warning on surface","Contrast":6.09,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"error on surface","Contrast":6.95,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"text on raised","Contrast":14.27,"Floor":7,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"muted on raised","Contrast":5.33,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"accent_text on raised","Contrast":6,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"success on raised","Contrast":5.48,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"warning on raised","Contrast":5.4,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"error on raised","Contrast":6.17,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"text on overlay","Contrast":17.74,"Floor":7,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"muted on overlay","Contrast":6.63,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"accent_text on overlay","Contrast":7.46,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"success on overlay","Contrast":6.81,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"warning on overlay","Contrast":6.71,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"error on overlay","Contrast":7.67,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"success on its badge over page","Contrast":5.68,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"warning on its badge over page","Contrast":5.61,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"error on its badge over page","Contrast":6.25,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"accent_text on its badge over page","Contrast":6.17,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"success on its badge over surface","Contrast":5.18,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"warning on its badge over surface","Contrast":5.12,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"error on its badge over surface","Contrast":5.7,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"accent_text on its badge over surface","Contrast":5.63,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"success on its badge over raised","Contrast":4.63,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"warning on its badge over raised","Contrast":4.57,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"error on its badge over raised","Contrast":5.08,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"accent_text on its badge over raised","Contrast":5.03,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"label on page","Contrast":7.6,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"accent_text on the selected tint over page","Contrast":5.02,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"text on the selected tint over page","Contrast":11.94,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"label on surface","Contrast":6.9,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"accent_text on the selected tint over surface","Contrast":4.63,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"text on the selected tint over surface","Contrast":11.01,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"on_accent on accent","Contrast":5.5,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"white on destructive","Contrast":5.62,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"on_accent on accent under the pointer","Contrast":6.68,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"on_accent on accent pressed","Contrast":8.14,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"white on destructive under the pointer","Contrast":6.83,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"white on destructive pressed","Contrast":8.33,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"text on a secondary button","Contrast":16.09,"Floor":7,"Worst":0,"OK":true},{"Mode":"light","Kind":"text","What":"text on a secondary button under the pointer","Contrast":14.27,"Floor":7,"Worst":0,"OK":true},{"Mode":"light","Kind":"non-text","What":"border_strong on page","Contrast":3.86,"Floor":3,"Worst":0,"OK":true},{"Mode":"light","Kind":"non-text","What":"accent (the focus ring) on page","Contrast":5.5,"Floor":3,"Worst":0,"OK":true},{"Mode":"light","Kind":"non-text","What":"border_strong on raised","Contrast":3.1,"Floor":3,"Worst":0,"OK":true},{"Mode":"light","Kind":"non-text","What":"accent (the focus ring) on raised","Contrast":4.43,"Floor":3,"Worst":0,"OK":true},{"Mode":"light","Kind":"edge","What":"page | surface","Distance":{"deutan":3.6,"deutan+ips":3.6,"dim":3.4,"drawn":3.4,"ips":3.4,"protan":3.3,"protan+ips":3.3,"tritan":3.5},"Floor":3,"Worst":2,"OK":true},{"Mode":"light","Kind":"edge","What":"surface | raised","Distance":{"deutan":3.5,"deutan+ips":3.5,"dim":3.4,"drawn":3.4,"ips":3.4,"protan":3.3,"protan+ips":3.3,"tritan":3.6},"Floor":3,"Worst":2,"OK":true},{"Mode":"light","Kind":"edge","What":"page | raised","Distance":{"deutan":7.1,"deutan+ips":7,"dim":6.8,"drawn":6.8,"ips":6.8,"protan":6.6,"protan+ips":6.6,"tritan":7.1},"Floor":3,"Worst":2,"OK":true},{"Mode":"light","Kind":"line","What":"border on page","Distance":{"deutan":13.1,"deutan+ips":13,"dim":12.7,"drawn":12.8,"ips":12.7,"protan":12.5,"protan+ips":12.4,"tritan":13},"Floor":6,"Worst":4,"OK":true},{"Mode":"light","Kind":"line","What":"border on raised","Distance":{"deutan":6.5,"deutan+ips":6.5,"dim":6.3,"drawn":6.4,"ips":6.4,"protan":6.3,"protan+ips":6.3,"tritan":6.4},"Floor":6,"Worst":4,"OK":true},{"Mode":"light","Kind":"state","What":"selected tint over page | page","Distance":{"deutan":13.2,"deutan+ips":13.1,"dim":13.8,"drawn":13.9,"ips":13.9,"protan":11.3,"protan+ips":11.3,"tritan":17},"Floor":10,"Worst":6,"OK":true},{"Mode":"light","Kind":"hover","What":"hover tint over page | page","Distance":{"deutan":5.1,"deutan+ips":5.1,"dim":5.6,"drawn":5.6,"ips":5.6,"protan":4.3,"protan+ips":4.3,"tritan":7.4},"Floor":3,"Worst":2,"OK":true},{"Mode":"light","Kind":"state","What":"selected tint over surface | surface","Distance":{"deutan":12.1,"deutan+ips":12.1,"dim":12.8,"drawn":12.9,"ips":12.9,"protan":10.4,"protan+ips":10.3,"tritan":15.6},"Floor":10,"Worst":6,"OK":true},{"Mode":"light","Kind":"hover","What":"hover tint over surface | surface","Distance":{"deutan":4.6,"deutan+ips":4.6,"dim":5.1,"drawn":5.2,"ips":5.1,"protan":3.9,"protan+ips":3.9,"tritan":6.6},"Floor":3,"Worst":2,"OK":true},{"Mode":"light","Kind":"hover","What":"accent under the pointer | accent","Distance":{"deutan":4.6,"deutan+ips":4.6,"dim":4.8,"drawn":4.9,"ips":4.8,"protan":5.3,"protan+ips":5.3,"tritan":5.3},"Floor":3,"Worst":2,"OK":true},{"Mode":"light","Kind":"hover","What":"destructive under the pointer | destructive","Distance":{"deutan":5.6,"deutan+ips":5.5,"dim":4.9,"drawn":5,"ips":5,"protan":3.7,"protan+ips":3.6,"tritan":5.2},"Floor":3,"Worst":2,"OK":true},{"Mode":"light","Kind":"hover","What":"secondary under the pointer | secondary","Distance":{"deutan":3.5,"deutan+ips":3.5,"dim":3.4,"drawn":3.4,"ips":3.4,"protan":3.3,"protan+ips":3.3,"tritan":3.6},"Floor":3,"Worst":2,"OK":true},{"Mode":"light","Kind":"edge","What":"secondary button | page","Distance":{"deutan":3.6,"deutan+ips":3.6,"dim":3.4,"drawn":3.4,"ips":3.4,"protan":3.3,"protan+ips":3.3,"tritan":3.5},"Floor":3,"Worst":2,"OK":true},{"Mode":"light","Kind":"meaning","What":"success | error","Distance":{"deutan":10.3,"deutan+ips":10,"dim":61.3,"drawn":64.1,"ips":62.9,"protan":29.7,"protan+ips":29,"tritan":56.5},"Floor":20,"Worst":10,"OK":true},{"Mode":"light","Kind":"meaning","What":"success | warning","Distance":{"deutan":16.1,"deutan+ips":15.6,"dim":35.2,"drawn":36.7,"ips":36.1,"protan":11.5,"protan+ips":10.8,"tritan":46.6},"Floor":20,"Worst":10,"OK":true},{"Mode":"light","Kind":"meaning","What":"warning | error","Distance":{"deutan":24.6,"deutan+ips":24,"dim":37.8,"drawn":41.1,"ips":39.7,"protan":38.6,"protan+ips":37.4,"tritan":9.3},"Floor":20,"Worst":10,"OK":true},{"Mode":"light","Kind":"meaning","What":"accent | success","Distance":{"deutan":32.2,"deutan+ips":31.7,"dim":33.3,"drawn":34.3,"ips":33.9,"protan":34.9,"protan+ips":34.5,"tritan":9.7},"Floor":20,"Worst":10,"OK":true},{"Mode":"light","Kind":"meaning","What":"accent | error","Distance":{"deutan":19.9,"deutan+ips":19.8,"dim":44.2,"drawn":45.6,"ips":45,"protan":16.6,"protan+ips":16.4,"tritan":61.3},"Floor":20,"Worst":10,"OK":true},{"Mode":"term","Kind":"text","What":"foreground on background","Contrast":16.34,"Floor":7,"Worst":0,"OK":true},{"Mode":"term","Kind":"text","What":"foreground on black","Contrast":11.69,"Floor":7,"Worst":0,"OK":true},{"Mode":"term","Kind":"text","What":"red on background","Contrast":6.81,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"term","Kind":"text","What":"green on background","Contrast":8.84,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"term","Kind":"text","What":"yellow on background","Contrast":9.86,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"term","Kind":"text","What":"blue on background","Contrast":7.3,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"term","Kind":"text","What":"magenta on background","Contrast":8.02,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"term","Kind":"text","What":"cyan on background","Contrast":9.04,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"term","Kind":"text","What":"white on background","Contrast":12.73,"Floor":7,"Worst":0,"OK":true},{"Mode":"term","Kind":"text","What":"bright_black on background","Contrast":5.47,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"term","Kind":"text","What":"bright_red on background","Contrast":9.83,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"term","Kind":"text","What":"bright_green on background","Contrast":12.27,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"term","Kind":"text","What":"bright_yellow on background","Contrast":13.13,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"term","Kind":"text","What":"bright_blue on background","Contrast":10.62,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"term","Kind":"text","What":"bright_magenta on background","Contrast":11.41,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"term","Kind":"text","What":"bright_cyan on background","Contrast":12.53,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"term","Kind":"text","What":"bright_white on background","Contrast":19.57,"Floor":7,"Worst":0,"OK":true},{"Mode":"term","Kind":"text","What":"foreground on selection","Contrast":9.51,"Floor":7,"Worst":0,"OK":true},{"Mode":"term","Kind":"text","What":"background on cursor","Contrast":9.04,"Floor":4.5,"Worst":0,"OK":true},{"Mode":"term","Kind":"non-text","What":"cursor on background","Contrast":9.04,"Floor":3,"Worst":0,"OK":true}];
diff --git a/dist/tokens.css b/dist/tokens.css
index 27124b7..b7b9848 100644
--- a/dist/tokens.css
+++ b/dist/tokens.css
@@ -68,6 +68,26 @@
--spin-brand-frost: #EAF0F6;
--spin-brand-mint: #5FE3D6;
--spin-brand-navy: #111827;
+ --spin-terminal-background: #0A0C10;
+ --spin-terminal-foreground: #E6EBF2;
+ --spin-terminal-cursor: #27BFE8;
+ --spin-terminal-selection: #2C3A55;
+ --spin-terminal-black: #262C38;
+ --spin-terminal-red: #F0707A;
+ --spin-terminal-green: #4CC38A;
+ --spin-terminal-yellow: #E3B04B;
+ --spin-terminal-blue: #6A9FF0;
+ --spin-terminal-magenta: #D58AE6;
+ --spin-terminal-cyan: #27BFE8;
+ --spin-terminal-white: #C9D1DE;
+ --spin-terminal-bright-black: #7D889C;
+ --spin-terminal-bright-red: #FF9CA4;
+ --spin-terminal-bright-green: #7EE0AE;
+ --spin-terminal-bright-yellow: #F5CF7A;
+ --spin-terminal-bright-blue: #9CC0FF;
+ --spin-terminal-bright-magenta: #EBB2F7;
+ --spin-terminal-bright-cyan: #5FE3D6;
+ --spin-terminal-bright-white: #FFFFFF;
--spin-wordmark: "Spinbox";
--spin-font-sans: 'IBM Plex Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;
--spin-font-mono: 'IBM Plex Mono', ui-monospace, 'SF Mono', Menlo, monospace;
diff --git a/dist/tokens.json b/dist/tokens.json
index 36aad0c..203369d 100644
--- a/dist/tokens.json
+++ b/dist/tokens.json
@@ -74,6 +74,28 @@
"Draw": 700,
"Ease": "cubic-bezier(0.2, 0.7, 0.2, 1)"
},
+ "terminal": {
+ "background": "#0A0C10",
+ "black": "#262C38",
+ "blue": "#6A9FF0",
+ "bright_black": "#7D889C",
+ "bright_blue": "#9CC0FF",
+ "bright_cyan": "#5FE3D6",
+ "bright_green": "#7EE0AE",
+ "bright_magenta": "#EBB2F7",
+ "bright_red": "#FF9CA4",
+ "bright_white": "#FFFFFF",
+ "bright_yellow": "#F5CF7A",
+ "cursor": "#27BFE8",
+ "cyan": "#27BFE8",
+ "foreground": "#E6EBF2",
+ "green": "#4CC38A",
+ "magenta": "#D58AE6",
+ "red": "#F0707A",
+ "selection": "#2C3A55",
+ "white": "#C9D1DE",
+ "yellow": "#E3B04B"
+ },
"tint": {
"Hover": 0.1,
"Selected": 0.27,
diff --git a/palette.toml b/palette.toml
index 5f96872..6d6a2a8 100644
--- a/palette.toml
+++ b/palette.toml
@@ -60,6 +60,34 @@ warning = "#845000"
error = "#9A1F60" # magenta-leaning, as dark's: a deutan tells it from success by its blue
destructive = "#C0303F"
+# A terminal - the workspace's shell, an agent's console, a machine's boot log - is black in either
+# theme: a console on the page's white read as a document, not a shell (2026-11-08). Its own roles,
+# not the dark theme's: the dark page is navy, and a terminal on it would be a card, not a screen.
+# The dashboard frames it with the theme's border. The sixteen ANSI colours are what a program asks
+# for by number; each reads at 4.5:1 on the background (the foreground and white at 7), except
+# black, which a program paints as a cell's background and the foreground reads on.
+[terminal]
+background = "#0A0C10"
+foreground = "#E6EBF2"
+cursor = "#27BFE8" # the brand's cyan; the character under it is the background
+selection = "#2C3A55" # the foreground holds 7:1 on it
+black = "#262C38"
+red = "#F0707A"
+green = "#4CC38A"
+yellow = "#E3B04B"
+blue = "#6A9FF0"
+magenta = "#D58AE6"
+cyan = "#27BFE8"
+white = "#C9D1DE"
+bright_black = "#7D889C"
+bright_red = "#FF9CA4"
+bright_green = "#7EE0AE"
+bright_yellow = "#F5CF7A"
+bright_blue = "#9CC0FF"
+bright_magenta = "#EBB2F7"
+bright_cyan = "#5FE3D6"
+bright_white = "#FFFFFF"
+
# The accent over a surface, for what is selected or hovered on the site (the current page in the
# sidebar, a hovered link): an alpha, so one value serves every surface. The label on a tint is
# accent_text. The dashboard keeps the accent for its one primary action and the focus ring: its