From f6c55b5359ae42a4c94a385c08502f37d3642249 Mon Sep 17 00:00:00 2001 From: Manuel de Brito Fontes Date: Sun, 8 Nov 2026 21:25:21 -0300 Subject: [PATCH] palette: a terminal is black in either theme, with its own ANSI colours [terminal] holds a terminal's background, foreground, cursor and selection and the sixteen ANSI colours. `task palette` holds the foreground (7:1) and each colour (4.5:1; white at 7) on the background, the foreground on ANSI black and on the selection, and the cursor both ways. dist/ writes them as --terminal-* in dashboard.css, --spin-terminal-* in tokens.css, and under "terminal" in tokens.json. Co-Authored-By: Claude Opus 5.5 --- README.md | 2 +- cmd/palette/checks.go | 44 ++++++++++++++++++++++++++++++++++++++++++ cmd/palette/main.go | 39 ++++++++++++++++++++++++++++++++++++- cmd/palette/outputs.go | 23 +++++++++++++++++++++- dist/dashboard.css | 20 +++++++++++++++++++ dist/perception.js | 2 +- dist/tokens.css | 20 +++++++++++++++++++ dist/tokens.json | 22 +++++++++++++++++++++ palette.toml | 28 +++++++++++++++++++++++++++ 9 files changed, 196 insertions(+), 4 deletions(-) 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