@promptctl/rich-js 0.18.0 → 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -7
- package/dist/core/anchor.d.ts +45 -0
- package/dist/core/anchor.js +39 -0
- package/dist/core/ansi.d.ts +65 -0
- package/dist/core/ansi.js +231 -0
- package/dist/core/box.d.ts +145 -0
- package/dist/core/box.js +372 -0
- package/dist/core/cells.d.ts +192 -0
- package/dist/core/cells.js +334 -0
- package/dist/core/clock.d.ts +48 -0
- package/dist/core/clock.js +42 -0
- package/dist/core/color.d.ts +326 -0
- package/dist/core/color.js +1225 -0
- package/dist/core/console.d.ts +196 -0
- package/dist/core/console.js +596 -0
- package/dist/core/easing.d.ts +86 -0
- package/dist/core/easing.js +171 -0
- package/dist/core/emoji.d.ts +24 -0
- package/dist/core/emoji.js +391 -0
- package/dist/core/env.d.ts +16 -0
- package/dist/core/env.js +16 -0
- package/dist/core/export-html.d.ts +59 -0
- package/dist/core/export-html.js +197 -0
- package/dist/core/export-lines.d.ts +130 -0
- package/dist/core/export-lines.js +159 -0
- package/dist/core/export-svg.d.ts +49 -0
- package/dist/core/export-svg.js +213 -0
- package/dist/core/fnv1a.d.ts +10 -0
- package/dist/core/fnv1a.js +17 -0
- package/dist/core/highlighter.d.ts +33 -0
- package/dist/core/highlighter.js +190 -0
- package/dist/core/json.d.ts +27 -0
- package/dist/core/json.js +53 -0
- package/dist/core/markup.d.ts +140 -0
- package/dist/core/markup.js +654 -0
- package/dist/core/measure.d.ts +27 -0
- package/dist/core/measure.js +67 -0
- package/dist/core/memo.d.ts +19 -0
- package/dist/core/memo.js +34 -0
- package/dist/core/oklch.d.ts +161 -0
- package/dist/core/oklch.js +312 -0
- package/dist/core/osc8.d.ts +68 -0
- package/dist/core/osc8.js +78 -0
- package/dist/core/paint.d.ts +107 -0
- package/dist/core/paint.js +150 -0
- package/dist/core/place.d.ts +30 -0
- package/dist/core/place.js +49 -0
- package/dist/core/pretty.d.ts +247 -0
- package/dist/core/pretty.js +906 -0
- package/dist/core/protocol.d.ts +305 -0
- package/dist/core/protocol.js +183 -0
- package/dist/core/render.d.ts +87 -0
- package/dist/core/render.js +105 -0
- package/dist/core/segment.d.ts +162 -0
- package/dist/core/segment.js +488 -0
- package/dist/core/spinnerData.d.ts +12 -0
- package/dist/core/spinnerData.js +117 -0
- package/dist/core/strip.d.ts +152 -0
- package/dist/core/strip.js +326 -0
- package/dist/core/style.d.ts +189 -0
- package/dist/core/style.js +758 -0
- package/dist/core/subscription.d.ts +12 -0
- package/dist/core/subscription.js +12 -0
- package/dist/core/text.d.ts +283 -0
- package/dist/core/text.js +1097 -0
- package/dist/core/wrap.d.ts +46 -0
- package/dist/core/wrap.js +140 -0
- package/dist/host/app.d.ts +133 -0
- package/dist/host/app.js +285 -0
- package/dist/host/host-environment.d.ts +26 -0
- package/dist/host/host-environment.js +44 -0
- package/dist/host/index.d.ts +6 -0
- package/dist/host/index.js +3 -0
- package/dist/host/terminal-host.d.ts +180 -0
- package/dist/host/terminal-host.js +186 -0
- package/dist/index.d.ts +98 -0
- package/dist/index.js +114 -0
- package/dist/node/prompt.d.ts +34 -0
- package/dist/node/prompt.js +51 -0
- package/dist/node/save.d.ts +18 -0
- package/dist/node/save.js +24 -0
- package/dist/node/terminal-host.d.ts +114 -0
- package/dist/node/terminal-host.js +227 -0
- package/dist/node/traceback.d.ts +38 -0
- package/dist/node/traceback.js +98 -0
- package/dist/renderables/align.d.ts +16 -0
- package/dist/renderables/align.js +26 -0
- package/dist/renderables/columns.d.ts +77 -0
- package/dist/renderables/columns.js +191 -0
- package/dist/renderables/constrain.d.ts +15 -0
- package/dist/renderables/constrain.js +31 -0
- package/dist/renderables/effect.d.ts +98 -0
- package/dist/renderables/effect.js +160 -0
- package/dist/renderables/embed.d.ts +107 -0
- package/dist/renderables/embed.js +160 -0
- package/dist/renderables/flexStrip.d.ts +41 -0
- package/dist/renderables/flexStrip.js +200 -0
- package/dist/renderables/group.d.ts +14 -0
- package/dist/renderables/group.js +22 -0
- package/dist/renderables/layout.d.ts +75 -0
- package/dist/renderables/layout.js +223 -0
- package/dist/renderables/live.d.ts +74 -0
- package/dist/renderables/live.js +188 -0
- package/dist/renderables/markdown.d.ts +38 -0
- package/dist/renderables/markdown.js +587 -0
- package/dist/renderables/padding.d.ts +59 -0
- package/dist/renderables/padding.js +147 -0
- package/dist/renderables/panel.d.ts +114 -0
- package/dist/renderables/panel.js +303 -0
- package/dist/renderables/progress.d.ts +178 -0
- package/dist/renderables/progress.js +362 -0
- package/dist/renderables/progressBar.d.ts +31 -0
- package/dist/renderables/progressBar.js +64 -0
- package/dist/renderables/prompt.d.ts +71 -0
- package/dist/renderables/prompt.js +165 -0
- package/dist/renderables/ratio.d.ts +123 -0
- package/dist/renderables/ratio.js +213 -0
- package/dist/renderables/rule.d.ts +26 -0
- package/dist/renderables/rule.js +86 -0
- package/dist/renderables/spinner.d.ts +57 -0
- package/dist/renderables/spinner.js +103 -0
- package/dist/renderables/status.d.ts +29 -0
- package/dist/renderables/status.js +46 -0
- package/dist/renderables/syntax.d.ts +65 -0
- package/dist/renderables/syntax.js +166 -0
- package/dist/renderables/table.d.ts +232 -0
- package/dist/renderables/table.js +973 -0
- package/dist/renderables/traceback.d.ts +32 -0
- package/dist/renderables/traceback.js +279 -0
- package/dist/renderables/tree.d.ts +76 -0
- package/dist/renderables/tree.js +177 -0
- package/dist/renderables/viewport.d.ts +114 -0
- package/dist/renderables/viewport.js +196 -0
- package/dist/template-bindings/color-funcs.d.ts +109 -0
- package/dist/template-bindings/color-funcs.js +243 -0
- package/dist/template-bindings/helpers.d.ts +26 -0
- package/dist/template-bindings/helpers.js +33 -0
- package/dist/template-bindings/index.d.ts +119 -0
- package/dist/template-bindings/index.js +162 -0
- package/dist/template-bindings/palette-funcs.d.ts +96 -0
- package/dist/template-bindings/palette-funcs.js +145 -0
- package/dist/template-bindings/style-funcs.d.ts +28 -0
- package/dist/template-bindings/style-funcs.js +157 -0
- package/dist/themes/buildPalette.d.ts +57 -0
- package/dist/themes/buildPalette.js +100 -0
- package/dist/themes/colorMath.d.ts +94 -0
- package/dist/themes/colorMath.js +280 -0
- package/dist/themes/colorRef.d.ts +36 -0
- package/dist/themes/colorRef.js +78 -0
- package/dist/themes/data/ansi-tables.d.ts +14 -0
- package/dist/themes/data/ansi-tables.js +49 -0
- package/dist/themes/data/atom-one-dark.d.ts +3 -0
- package/dist/themes/data/atom-one-dark.js +177 -0
- package/dist/themes/data/atom-one-light.d.ts +3 -0
- package/dist/themes/data/atom-one-light.js +177 -0
- package/dist/themes/data/catppuccin-frappe.d.ts +3 -0
- package/dist/themes/data/catppuccin-frappe.js +177 -0
- package/dist/themes/data/catppuccin-latte.d.ts +3 -0
- package/dist/themes/data/catppuccin-latte.js +177 -0
- package/dist/themes/data/catppuccin-macchiato.d.ts +3 -0
- package/dist/themes/data/catppuccin-macchiato.js +177 -0
- package/dist/themes/data/catppuccin-mocha.d.ts +3 -0
- package/dist/themes/data/catppuccin-mocha.js +177 -0
- package/dist/themes/data/cyberpunk.d.ts +17 -0
- package/dist/themes/data/cyberpunk.js +193 -0
- package/dist/themes/data/default.d.ts +3 -0
- package/dist/themes/data/default.js +160 -0
- package/dist/themes/data/dracula.d.ts +3 -0
- package/dist/themes/data/dracula.js +177 -0
- package/dist/themes/data/flexoki.d.ts +3 -0
- package/dist/themes/data/flexoki.js +177 -0
- package/dist/themes/data/gruvbox.d.ts +3 -0
- package/dist/themes/data/gruvbox.js +177 -0
- package/dist/themes/data/index.d.ts +35 -0
- package/dist/themes/data/index.js +64 -0
- package/dist/themes/data/monokai.d.ts +3 -0
- package/dist/themes/data/monokai.js +177 -0
- package/dist/themes/data/nord.d.ts +3 -0
- package/dist/themes/data/nord.js +177 -0
- package/dist/themes/data/rose-pine-dawn.d.ts +3 -0
- package/dist/themes/data/rose-pine-dawn.js +177 -0
- package/dist/themes/data/rose-pine-moon.d.ts +3 -0
- package/dist/themes/data/rose-pine-moon.js +177 -0
- package/dist/themes/data/rose-pine.d.ts +3 -0
- package/dist/themes/data/rose-pine.js +177 -0
- package/dist/themes/data/solarized-dark.d.ts +3 -0
- package/dist/themes/data/solarized-dark.js +177 -0
- package/dist/themes/data/solarized-light.d.ts +3 -0
- package/dist/themes/data/solarized-light.js +177 -0
- package/dist/themes/data/svg-export.d.ts +3 -0
- package/dist/themes/data/svg-export.js +177 -0
- package/dist/themes/data/textual-ansi.d.ts +3 -0
- package/dist/themes/data/textual-ansi.js +160 -0
- package/dist/themes/data/textual-dark.d.ts +3 -0
- package/dist/themes/data/textual-dark.js +160 -0
- package/dist/themes/data/textual-light.d.ts +3 -0
- package/dist/themes/data/textual-light.js +160 -0
- package/dist/themes/data/tokyo-night.d.ts +3 -0
- package/dist/themes/data/tokyo-night.js +177 -0
- package/dist/themes/data/types.d.ts +31 -0
- package/dist/themes/data/types.js +10 -0
- package/dist/themes/palette.d.ts +45 -0
- package/dist/themes/palette.js +71 -0
- package/dist/themes/ramp.d.ts +70 -0
- package/dist/themes/ramp.js +103 -0
- package/dist/themes/registry.d.ts +44 -0
- package/dist/themes/registry.js +105 -0
- package/dist/themes/terminalThemes.d.ts +49 -0
- package/dist/themes/terminalThemes.js +63 -0
- package/dist/themes/transpose.d.ts +87 -0
- package/dist/themes/transpose.js +138 -0
- package/dist/widgets/button.d.ts +45 -0
- package/dist/widgets/button.js +177 -0
- package/dist/widgets/checkbox.d.ts +38 -0
- package/dist/widgets/checkbox.js +135 -0
- package/dist/widgets/dropdown.d.ts +64 -0
- package/dist/widgets/dropdown.js +416 -0
- package/dist/widgets/event-router.d.ts +71 -0
- package/dist/widgets/event-router.js +629 -0
- package/dist/widgets/focus-manager.d.ts +45 -0
- package/dist/widgets/focus-manager.js +191 -0
- package/dist/widgets/hit.d.ts +64 -0
- package/dist/widgets/hit.js +113 -0
- package/dist/widgets/index.d.ts +20 -0
- package/dist/widgets/index.js +14 -0
- package/dist/widgets/ink.d.ts +22 -0
- package/dist/widgets/ink.js +31 -0
- package/dist/widgets/slider.d.ts +54 -0
- package/dist/widgets/slider.js +247 -0
- package/dist/widgets/static-item.d.ts +34 -0
- package/dist/widgets/static-item.js +54 -0
- package/dist/widgets/text-input.d.ts +283 -0
- package/dist/widgets/text-input.js +1174 -0
- package/dist/widgets/themed-widget.d.ts +20 -0
- package/dist/widgets/themed-widget.js +89 -0
- package/dist/widgets/toggle.d.ts +41 -0
- package/dist/widgets/toggle.js +157 -0
- package/dist/widgets/types.d.ts +87 -0
- package/dist/widgets/types.js +30 -0
- package/dist/widgets/widget-app.d.ts +65 -0
- package/dist/widgets/widget-app.js +206 -0
- package/dist/widgets/widget-base.d.ts +42 -0
- package/dist/widgets/widget-base.js +172 -0
- package/package.json +16 -2
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
import { ColorDepth, ColorRgba, ColorSpec, blendRgb, contrastRatio, downgradeTable, relativeLuminance, resolveTerminal, SURFACE_BLACK, } from "../core/color.js";
|
|
2
|
+
import { Oklch } from "../core/oklch.js";
|
|
3
|
+
const LEVEL_STEP = 0.1;
|
|
4
|
+
function rgbToHsl(c) {
|
|
5
|
+
const r = c.red / 255;
|
|
6
|
+
const g = c.green / 255;
|
|
7
|
+
const b = c.blue / 255;
|
|
8
|
+
const max = Math.max(r, g, b);
|
|
9
|
+
const min = Math.min(r, g, b);
|
|
10
|
+
const l = (max + min) / 2;
|
|
11
|
+
const d = max - min;
|
|
12
|
+
if (d === 0)
|
|
13
|
+
return { h: 0, s: 0, l };
|
|
14
|
+
const s = d / (l > 0.5 ? 2 - max - min : max + min);
|
|
15
|
+
let h;
|
|
16
|
+
if (max === r)
|
|
17
|
+
h = ((g - b) / d) % 6;
|
|
18
|
+
else if (max === g)
|
|
19
|
+
h = (b - r) / d + 2;
|
|
20
|
+
else
|
|
21
|
+
h = (r - g) / d + 4;
|
|
22
|
+
h = (h * 60 + 360) % 360;
|
|
23
|
+
return { h, s, l };
|
|
24
|
+
}
|
|
25
|
+
function clampChannel(v) {
|
|
26
|
+
// Float HSL math + Math.round can land at -1 or 256 at the boundaries; clamp
|
|
27
|
+
// so an invalid ColorRgba never escapes this function.
|
|
28
|
+
const r = Math.round(v);
|
|
29
|
+
return r < 0 ? 0 : r > 255 ? 255 : r;
|
|
30
|
+
}
|
|
31
|
+
function hslToRgb(hsl) {
|
|
32
|
+
const { h, s, l } = hsl;
|
|
33
|
+
if (s === 0) {
|
|
34
|
+
const v = clampChannel(l * 255);
|
|
35
|
+
return new ColorRgba(v, v, v);
|
|
36
|
+
}
|
|
37
|
+
const c = (1 - Math.abs(2 * l - 1)) * s;
|
|
38
|
+
const hp = h / 60;
|
|
39
|
+
const x = c * (1 - Math.abs((hp % 2) - 1));
|
|
40
|
+
let r = 0, g = 0, b = 0;
|
|
41
|
+
if (hp < 1)
|
|
42
|
+
[r, g, b] = [c, x, 0];
|
|
43
|
+
else if (hp < 2)
|
|
44
|
+
[r, g, b] = [x, c, 0];
|
|
45
|
+
else if (hp < 3)
|
|
46
|
+
[r, g, b] = [0, c, x];
|
|
47
|
+
else if (hp < 4)
|
|
48
|
+
[r, g, b] = [0, x, c];
|
|
49
|
+
else if (hp < 5)
|
|
50
|
+
[r, g, b] = [x, 0, c];
|
|
51
|
+
else
|
|
52
|
+
[r, g, b] = [c, 0, x];
|
|
53
|
+
const m = l - c / 2;
|
|
54
|
+
return new ColorRgba(clampChannel((r + m) * 255), clampChannel((g + m) * 255), clampChannel((b + m) * 255));
|
|
55
|
+
}
|
|
56
|
+
function clamp01(v) {
|
|
57
|
+
return v < 0 ? 0 : v > 1 ? 1 : v;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Darken a color by N levels, where each level reduces HSL lightness by 10%.
|
|
61
|
+
* Negative levels lighten. Level 0 returns an equivalent triplet (after the
|
|
62
|
+
* RGB↔HSL roundtrip; values may differ by ±1 due to rounding).
|
|
63
|
+
*/
|
|
64
|
+
export function darken(color, levels) {
|
|
65
|
+
const hsl = rgbToHsl(color);
|
|
66
|
+
hsl.l = clamp01(hsl.l - LEVEL_STEP * levels);
|
|
67
|
+
return hslToRgb(hsl);
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Lighten a color by N levels. Equivalent to `darken(color, -levels)`.
|
|
71
|
+
*/
|
|
72
|
+
export function lighten(color, levels) {
|
|
73
|
+
return darken(color, -levels);
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Composite `fg` over `bg` with the given alpha (0..1). At alpha=0 returns bg;
|
|
77
|
+
* at alpha=1 returns fg.
|
|
78
|
+
*/
|
|
79
|
+
export function alphaBlend(fg, bg, alpha) {
|
|
80
|
+
return blendRgb(bg, fg, clamp01(alpha));
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Pick a contrasting foreground (black or white) for a background, using the
|
|
84
|
+
* WCAG relative-luminance threshold of 0.179 (the perceptually correct cutoff
|
|
85
|
+
* where black and white are equally readable). A translucent `bg` is judged
|
|
86
|
+
* as drawn: composited over `substrate` (see `drawnBackground`).
|
|
87
|
+
*/
|
|
88
|
+
export function contrastFor(bg, substrate = SURFACE_BLACK) {
|
|
89
|
+
const lum = relativeLuminance(drawnBackground(bg, substrate));
|
|
90
|
+
return lum > 0.179
|
|
91
|
+
? new ColorRgba(0, 0, 0)
|
|
92
|
+
: new ColorRgba(255, 255, 255);
|
|
93
|
+
}
|
|
94
|
+
// [LAW:one-way-deps] The WCAG measures live in core/color.ts, beside the
|
|
95
|
+
// ColorTable whose `matchReadable` needs them to pick a drawn text colour, and
|
|
96
|
+
// below the theme math here. Re-exported so this module stays the colour-math
|
|
97
|
+
// surface.
|
|
98
|
+
export { relativeLuminance, contrastRatio };
|
|
99
|
+
// Iterations for the lightness bisection below. 20 resolves L to ~1e-6 — far
|
|
100
|
+
// finer than 8-bit quantization or the eye.
|
|
101
|
+
const CONTRAST_ITERS = 20;
|
|
102
|
+
/**
|
|
103
|
+
* Return a foreground guaranteed to clear `minRatio` against `bg`, keeping the
|
|
104
|
+
* color *recognizably itself*. If the themed `fg` already passes it is returned
|
|
105
|
+
* untouched. Otherwise its OKLCH lightness is slid toward the pole that raises
|
|
106
|
+
* contrast — holding hue, and chroma where it stays in gamut (near the poles
|
|
107
|
+
* gamut clamping may reduce chroma, but hue is preserved) — until the ratio is
|
|
108
|
+
* met, so a blue on a dark-blue background becomes a lighter blue, not white.
|
|
109
|
+
* Only when no lightness of that hue can meet the ratio (a mid-toned
|
|
110
|
+
* background where even pure black-or-white tops out below the target) does it
|
|
111
|
+
* fall back to `contrastFor`'s black/white — the true maximum-contrast pick.
|
|
112
|
+
*
|
|
113
|
+
* A translucent `bg` is measured as it is drawn — composited over
|
|
114
|
+
* `substrate`, the SGR writer's black by default — and a translucent `fg` is
|
|
115
|
+
* then flattened over that drawn background, the order the writer composites
|
|
116
|
+
* in, so the ratio is measured on what the eye actually sees and the returned
|
|
117
|
+
* color is opaque.
|
|
118
|
+
*
|
|
119
|
+
* `drawnAt` is the depth the terminal will draw the pair at. At 256 colours
|
|
120
|
+
* the terminal rounds text and background independently, and two roundings
|
|
121
|
+
* can meet in the middle, so the ratio is measured on the drawn pair: a
|
|
122
|
+
* colour that loses the floor there is replaced by the nearest cube/grey entry
|
|
123
|
+
* that clears it (whose own rounding is itself). At ANSI the terminal draws
|
|
124
|
+
* each index in its own theme's colour, so the ratio is measured on
|
|
125
|
+
* `terminal`'s sixteen: a theme whose black is light and white dark (Rosé Pine
|
|
126
|
+
* Dawn) turns the nominal table's sides over. A replacement is the colour the
|
|
127
|
+
* writer emits as the index nearest `fg` that clears the floor as `terminal`
|
|
128
|
+
* draws it. Truecolor draws the colour chosen.
|
|
129
|
+
*
|
|
130
|
+
* [LAW:single-enforcer] The one place "is this text readable, and if not fix
|
|
131
|
+
* it" is decided. Callers route every fg/bg pair through here and the
|
|
132
|
+
* unreadable state never reaches output. [LAW:dataflow-not-control-flow] the
|
|
133
|
+
* function always runs; the measured ratio (data) decides how far the
|
|
134
|
+
* lightness moves — there is no caller-side "should I check contrast" branch.
|
|
135
|
+
*/
|
|
136
|
+
export function ensureContrast(fg, bg, minRatio = 4.5, // WCAG AA for normal text
|
|
137
|
+
drawnAt = ColorDepth.TRUECOLOR, substrate = SURFACE_BLACK, terminal) {
|
|
138
|
+
const ground = drawnBackground(bg, substrate);
|
|
139
|
+
const chosen = ensureContrastToward(fg, ground, minRatio, contrastFor(ground));
|
|
140
|
+
// [LAW:dataflow-not-control-flow] The depth names the table the terminal
|
|
141
|
+
// draws from; every table is measured the same way.
|
|
142
|
+
const table = drawnTable(drawnAt, terminal);
|
|
143
|
+
if (table === undefined)
|
|
144
|
+
return chosen;
|
|
145
|
+
const shownBg = shownAs(table, ground);
|
|
146
|
+
if (contrastRatio(shownAs(table, chosen), shownBg) >= minRatio)
|
|
147
|
+
return chosen;
|
|
148
|
+
return table.written.get(table.shown.matchReadable(fg.compositeOver(ground), shownBg, minRatio));
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* `chosen` (composited opaque over `substrate`), or — when the depth the
|
|
152
|
+
* terminal draws at rounds it to a colour `accept` refuses — the colour the
|
|
153
|
+
* writer emits as the nearest entry `accept` takes. `accept` sees the
|
|
154
|
+
* candidate as drawn, and `drawn`, the same rounding for any other colour it
|
|
155
|
+
* measures against, so the caller states a floor once and it holds on the
|
|
156
|
+
* colours the terminal shows — at ANSI, `terminal`'s own sixteen, as
|
|
157
|
+
* `ensureContrast` measures there. Truecolor
|
|
158
|
+
* draws from no table, so a colour refused there has no replacement;
|
|
159
|
+
* `undefined` means nothing the depth draws is accepted.
|
|
160
|
+
*
|
|
161
|
+
* `ensureContrast` is this with a contrast ratio as the floor; this is for a
|
|
162
|
+
* floor that is not text on its background (an open state standing off every
|
|
163
|
+
* closed cell, two planes standing off each other).
|
|
164
|
+
*/
|
|
165
|
+
export function ensureDrawn(chosen, drawnAt, accept, substrate = SURFACE_BLACK, terminal) {
|
|
166
|
+
// The floor was measured on `chosen` composited over `substrate`, so that
|
|
167
|
+
// opaque colour is what is returned — never a translucent one a different
|
|
168
|
+
// ground would composite into a colour `accept` never saw.
|
|
169
|
+
const opaque = drawnBackground(chosen, substrate);
|
|
170
|
+
const table = drawnTable(drawnAt, terminal);
|
|
171
|
+
const drawn = (c) => shownAs(table, drawnBackground(c, substrate));
|
|
172
|
+
if (accept(drawn(opaque), drawn))
|
|
173
|
+
return opaque;
|
|
174
|
+
// [LAW:dataflow-not-control-flow] Truecolor draws from no table, so it has
|
|
175
|
+
// no candidates: a refusal there is `undefined` like any exhausted search.
|
|
176
|
+
const index = table?.shown.matchWhere(opaque, (entry) => accept(entry, drawn));
|
|
177
|
+
return index === undefined ? undefined : table.written.get(index);
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* The colour a ground is shown as at `drawnAt`: composited over `substrate`
|
|
181
|
+
* (the SGR writer's black by default), rounded to the index the writer emits
|
|
182
|
+
* at that depth, and shown as the terminal shows that index — at ANSI, in
|
|
183
|
+
* `terminal`'s own colour. The one account `ensureDrawn` and `ensureContrast`
|
|
184
|
+
* measure by, for a caller that measures a floor of its own.
|
|
185
|
+
*/
|
|
186
|
+
export function drawnColour(colour, drawnAt, substrate = SURFACE_BLACK, terminal) {
|
|
187
|
+
return shownAs(drawnTable(drawnAt, terminal), drawnBackground(colour, substrate));
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* An opaque colour as the terminal shows it: downgraded to the index the
|
|
191
|
+
* writer emits and drawn as the terminal draws that index.
|
|
192
|
+
* [LAW:one-source-of-truth] That rounding is `ColorSpec.downgrade`'s, the one
|
|
193
|
+
* `Style.drawnColors` writes; the tables here only list the candidates.
|
|
194
|
+
*/
|
|
195
|
+
function shownAs(table, opaque) {
|
|
196
|
+
return table === undefined ? opaque : ColorSpec.fromRgba(opaque).downgrade(table.depth).getTruecolor(table.terminal);
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* A background as it is drawn: composited over the surface beneath it. That
|
|
200
|
+
* surface is a fact about where the pair is drawn, so it arrives as a value:
|
|
201
|
+
* the SGR writer (`Style.toSgrCodes`) and the exports that picture its output
|
|
202
|
+
* composite over `SURFACE_BLACK`, the default here; a caller that composites
|
|
203
|
+
* its colours onto a different surface itself names that one.
|
|
204
|
+
* [LAW:no-silent-failure] A surface has nothing under it, so a translucent one
|
|
205
|
+
* has no drawn colour to offer; `compositeOver` would read its raw RGB as if
|
|
206
|
+
* it were opaque, so it is refused here rather than measured wrong.
|
|
207
|
+
* [LAW:one-source-of-truth] Text is chosen against the colour the surface will
|
|
208
|
+
* show — measuring the raw RGBA reads a colour that is drawn nowhere, and text
|
|
209
|
+
* that "clears" it can land below the floor. Opaque colours composite to
|
|
210
|
+
* themselves.
|
|
211
|
+
*/
|
|
212
|
+
function drawnBackground(bg, substrate) {
|
|
213
|
+
if (substrate.alpha !== 1) {
|
|
214
|
+
throw new RangeError(`a contrast substrate is the opaque surface under a translucent background; got ${substrate.hex}`);
|
|
215
|
+
}
|
|
216
|
+
return bg.compositeOver(substrate);
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* The table the terminal draws from at `drawnAt`. The 256-colour cube and
|
|
220
|
+
* grey ramp are fixed by xterm, so the colour written is the colour shown.
|
|
221
|
+
* ANSI 0–15 are the terminal theme's own: the writer still picks the index by
|
|
222
|
+
* the nominal table — the Windows console's at WINDOWS — and the terminal
|
|
223
|
+
* shows `terminal`'s colour there.
|
|
224
|
+
* Truecolor draws the chosen colour itself, as do the depths no table stands
|
|
225
|
+
* behind.
|
|
226
|
+
*/
|
|
227
|
+
function drawnTable(drawnAt, terminal) {
|
|
228
|
+
const drawnBy = resolveTerminal(terminal, drawnAt);
|
|
229
|
+
switch (drawnAt) {
|
|
230
|
+
case ColorDepth.EIGHT_BIT:
|
|
231
|
+
return { depth: drawnAt, terminal: drawnBy, written: downgradeTable(drawnAt), shown: downgradeTable(drawnAt) };
|
|
232
|
+
case ColorDepth.STANDARD:
|
|
233
|
+
case ColorDepth.WINDOWS:
|
|
234
|
+
return { depth: drawnAt, terminal: drawnBy, written: downgradeTable(drawnAt), shown: drawnBy.ansiColors };
|
|
235
|
+
case ColorDepth.TRUECOLOR:
|
|
236
|
+
case ColorDepth.DEFAULT:
|
|
237
|
+
return undefined;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* `fg` held to `minRatio` on `bg` in truecolor, moving in lightness toward
|
|
242
|
+
* `toward` (black or white). `ensureContrast` moves toward the pole `bg`
|
|
243
|
+
* itself contrasts with; a colour that already has a side (a palette's
|
|
244
|
+
* `text-*` is its text, tinted) passes that side, since on a ground near the
|
|
245
|
+
* 0.179 cutoff both poles clear and only one also reads on everything else
|
|
246
|
+
* the colour is drawn on. Where `toward` cannot clear `minRatio` on `bg`,
|
|
247
|
+
* the floor wins over the side: the answer is `contrastFor(bg)`.
|
|
248
|
+
*/
|
|
249
|
+
export function ensureContrastToward(fg, bg, minRatio, toward) {
|
|
250
|
+
// Flatten translucency so the guarantee holds for the displayed color, not
|
|
251
|
+
// the raw bytes (e.g. a hand-written "#FFFFFF60" over a light surface).
|
|
252
|
+
const opaqueFg = fg.compositeOver(bg);
|
|
253
|
+
if (contrastRatio(opaqueFg, bg) >= minRatio)
|
|
254
|
+
return opaqueFg;
|
|
255
|
+
const lab = Oklch.fromRgba(opaqueFg);
|
|
256
|
+
// `toward` is black or white, the pole the lightness moves to.
|
|
257
|
+
const poleL = relativeLuminance(toward) > 0.179 ? 1 : 0;
|
|
258
|
+
// If even the pole of this hue can't reach the ratio, the hue physically
|
|
259
|
+
// can't — return the true maximum-contrast pick (pure black/white from
|
|
260
|
+
// contrastFor). The gamut-clamped OKLCH pole is only *near* b/w, so
|
|
261
|
+
// contrastFor is at least as strong and is the honest maximum.
|
|
262
|
+
const pole = new Oklch(poleL, lab.c, lab.h, lab.alpha).toRgba();
|
|
263
|
+
if (contrastRatio(pole, bg) < minRatio)
|
|
264
|
+
return contrastFor(bg);
|
|
265
|
+
// Bisect for the lightness nearest the original that still clears the ratio:
|
|
266
|
+
// the smallest perceptual change that achieves accessibility. Contrast is
|
|
267
|
+
// monotone in L over [lab.l, poleL] (everything below the crossing fails),
|
|
268
|
+
// so the search is well-posed.
|
|
269
|
+
let fail = lab.l;
|
|
270
|
+
let pass = poleL;
|
|
271
|
+
for (let i = 0; i < CONTRAST_ITERS; i++) {
|
|
272
|
+
const mid = (fail + pass) / 2;
|
|
273
|
+
const candidate = new Oklch(mid, lab.c, lab.h, lab.alpha).toRgba();
|
|
274
|
+
if (contrastRatio(candidate, bg) >= minRatio)
|
|
275
|
+
pass = mid;
|
|
276
|
+
else
|
|
277
|
+
fail = mid;
|
|
278
|
+
}
|
|
279
|
+
return new Oklch(pass, lab.c, lab.h, lab.alpha).toRgba();
|
|
280
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { type ColorRgba } from "../core/color.js";
|
|
2
|
+
import type { Palette } from "./palette.js";
|
|
3
|
+
/**
|
|
4
|
+
* A **color reference** is the one string form an author uses to name a
|
|
5
|
+
* concrete color: a palette variable name (`"primary"`, `"surface-active"`,
|
|
6
|
+
* `"text-primary"`) or a literal `#RRGGBB` / `#RRGGBBAA`.
|
|
7
|
+
*
|
|
8
|
+
* [LAW:parse-dont-validate] `resolveColorRef` is the single checkpoint that
|
|
9
|
+
* turns an untrusted reference string into a `ColorRgba`. Everything
|
|
10
|
+
* downstream — color math, `Style` construction, serialization — takes
|
|
11
|
+
* `ColorRgba` and therefore cannot ask again whether the name existed. There
|
|
12
|
+
* is no `isValidColorRef` companion, deliberately: a validator would hand back
|
|
13
|
+
* the same `string` it was given and every consumer would re-check.
|
|
14
|
+
*
|
|
15
|
+
* [LAW:no-silent-failure] A miss throws. An unknown palette name is a broken
|
|
16
|
+
* config, and the author needs to see which name and what was available — not
|
|
17
|
+
* a silently substituted default that makes the bar merely look wrong.
|
|
18
|
+
*/
|
|
19
|
+
export declare class ColorRefError extends Error {
|
|
20
|
+
readonly ref: string;
|
|
21
|
+
constructor(ref: string, detail: string, options?: ErrorOptions);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Resolve a color reference against `palette`.
|
|
25
|
+
*
|
|
26
|
+
* Accepting hex alongside names is what makes this **idempotent**:
|
|
27
|
+
* `resolveColorRef(p, resolveColorRef(p, r).hex)` equals
|
|
28
|
+
* `resolveColorRef(p, r)` for every `r` this function accepts. Callers
|
|
29
|
+
* therefore never branch on "is this a palette name or already a color" —
|
|
30
|
+
* they call it unconditionally on whatever the author wrote, whether that is
|
|
31
|
+
* `"surface-active"` or the output of a chain of color math.
|
|
32
|
+
* [LAW:dataflow-not-control-flow]
|
|
33
|
+
*
|
|
34
|
+
* @throws {ColorRefError} on malformed hex or an unknown palette name.
|
|
35
|
+
*/
|
|
36
|
+
export declare function resolveColorRef(palette: Palette, ref: string): ColorRgba;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { ColorParseError, parseHexColor } from "../core/color.js";
|
|
2
|
+
/**
|
|
3
|
+
* A **color reference** is the one string form an author uses to name a
|
|
4
|
+
* concrete color: a palette variable name (`"primary"`, `"surface-active"`,
|
|
5
|
+
* `"text-primary"`) or a literal `#RRGGBB` / `#RRGGBBAA`.
|
|
6
|
+
*
|
|
7
|
+
* [LAW:parse-dont-validate] `resolveColorRef` is the single checkpoint that
|
|
8
|
+
* turns an untrusted reference string into a `ColorRgba`. Everything
|
|
9
|
+
* downstream — color math, `Style` construction, serialization — takes
|
|
10
|
+
* `ColorRgba` and therefore cannot ask again whether the name existed. There
|
|
11
|
+
* is no `isValidColorRef` companion, deliberately: a validator would hand back
|
|
12
|
+
* the same `string` it was given and every consumer would re-check.
|
|
13
|
+
*
|
|
14
|
+
* [LAW:no-silent-failure] A miss throws. An unknown palette name is a broken
|
|
15
|
+
* config, and the author needs to see which name and what was available — not
|
|
16
|
+
* a silently substituted default that makes the bar merely look wrong.
|
|
17
|
+
*/
|
|
18
|
+
export class ColorRefError extends Error {
|
|
19
|
+
ref;
|
|
20
|
+
constructor(ref, detail, options) {
|
|
21
|
+
super(`color reference ${JSON.stringify(ref)} did not resolve — ${detail}`, options);
|
|
22
|
+
this.ref = ref;
|
|
23
|
+
this.name = "ColorRefError";
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
// A reference *shaped* like hex is resolved as hex; anything else is a palette
|
|
27
|
+
// name. This is a lexical distinction with no overlap — palette variable names
|
|
28
|
+
// never begin with `#` — so it is a parse, not a mode. A `#`-leading string
|
|
29
|
+
// that is malformed hex fails loudly here rather than falling through to a
|
|
30
|
+
// palette lookup that would report a confusing "unknown name" instead of
|
|
31
|
+
// "malformed hex".
|
|
32
|
+
const HEX_LEAD = "#";
|
|
33
|
+
// Cap the "did you mean" list. Palettes carry ~150 variables; dumping all of
|
|
34
|
+
// them buries the message. Nearby names are what a mistyped reference needs.
|
|
35
|
+
const SUGGESTION_LIMIT = 8;
|
|
36
|
+
/**
|
|
37
|
+
* Resolve a color reference against `palette`.
|
|
38
|
+
*
|
|
39
|
+
* Accepting hex alongside names is what makes this **idempotent**:
|
|
40
|
+
* `resolveColorRef(p, resolveColorRef(p, r).hex)` equals
|
|
41
|
+
* `resolveColorRef(p, r)` for every `r` this function accepts. Callers
|
|
42
|
+
* therefore never branch on "is this a palette name or already a color" —
|
|
43
|
+
* they call it unconditionally on whatever the author wrote, whether that is
|
|
44
|
+
* `"surface-active"` or the output of a chain of color math.
|
|
45
|
+
* [LAW:dataflow-not-control-flow]
|
|
46
|
+
*
|
|
47
|
+
* @throws {ColorRefError} on malformed hex or an unknown palette name.
|
|
48
|
+
*/
|
|
49
|
+
export function resolveColorRef(palette, ref) {
|
|
50
|
+
const trimmed = ref.trim();
|
|
51
|
+
if (trimmed.startsWith(HEX_LEAD)) {
|
|
52
|
+
try {
|
|
53
|
+
return parseHexColor(trimmed);
|
|
54
|
+
}
|
|
55
|
+
catch (cause) {
|
|
56
|
+
if (!(cause instanceof ColorParseError))
|
|
57
|
+
throw cause;
|
|
58
|
+
throw new ColorRefError(ref, cause.message, { cause });
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
const hit = palette.get(trimmed);
|
|
62
|
+
if (hit === undefined) {
|
|
63
|
+
throw new ColorRefError(ref, `no such variable in palette ${JSON.stringify(palette.name)}` +
|
|
64
|
+
suggest(palette, trimmed));
|
|
65
|
+
}
|
|
66
|
+
return hit;
|
|
67
|
+
}
|
|
68
|
+
// Names sharing a prefix or suffix with the miss — enough to catch the two
|
|
69
|
+
// mistakes that actually happen (a wrong qualifier, `surface-active` vs
|
|
70
|
+
// `surface-lighten`; a wrong root, `text-primary` vs `primary-text`) without
|
|
71
|
+
// printing the whole palette.
|
|
72
|
+
function suggest(palette, miss) {
|
|
73
|
+
const parts = miss.split("-");
|
|
74
|
+
const near = [...palette.vars.keys()]
|
|
75
|
+
.filter((name) => parts.some((part) => part !== "" && name.includes(part)))
|
|
76
|
+
.slice(0, SUGGESTION_LIMIT);
|
|
77
|
+
return near.length === 0 ? "" : `; did you mean: ${near.join(", ")}`;
|
|
78
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type AnsiColorsData } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* The VGA colours a terminal draws with no theme of its own: Rich's
|
|
4
|
+
* `DEFAULT_TERMINAL_THEME`, and what `textual-ansi` spells its palette in.
|
|
5
|
+
*/
|
|
6
|
+
export declare const VGA_ANSI: AnsiColorsData;
|
|
7
|
+
/**
|
|
8
|
+
* The ANSI tables Textual draws named colours in for a theme that has no
|
|
9
|
+
* terminal scheme of its own: `MONOKAI` under a dark theme and `ALABASTER`
|
|
10
|
+
* under a light one (`ansi_theme_dark` / `ansi_theme_light` in Textual's
|
|
11
|
+
* `app.py`, values from its `_ansi_theme.py`).
|
|
12
|
+
*/
|
|
13
|
+
export declare const TEXTUAL_DARK_ANSI: AnsiColorsData;
|
|
14
|
+
export declare const TEXTUAL_LIGHT_ANSI: AnsiColorsData;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { STANDARD_TABLE } from "../../core/color.js";
|
|
2
|
+
import { ANSI_SLOTS } from "./types.js";
|
|
3
|
+
/**
|
|
4
|
+
* The VGA colours a terminal draws with no theme of its own: Rich's
|
|
5
|
+
* `DEFAULT_TERMINAL_THEME`, and what `textual-ansi` spells its palette in.
|
|
6
|
+
*/
|
|
7
|
+
export const VGA_ANSI = Object.fromEntries(ANSI_SLOTS.map((slot, n) => [slot, STANDARD_TABLE.get(n).hex]));
|
|
8
|
+
/**
|
|
9
|
+
* The ANSI tables Textual draws named colours in for a theme that has no
|
|
10
|
+
* terminal scheme of its own: `MONOKAI` under a dark theme and `ALABASTER`
|
|
11
|
+
* under a light one (`ansi_theme_dark` / `ansi_theme_light` in Textual's
|
|
12
|
+
* `app.py`, values from its `_ansi_theme.py`).
|
|
13
|
+
*/
|
|
14
|
+
export const TEXTUAL_DARK_ANSI = {
|
|
15
|
+
black: "#1A1A1A",
|
|
16
|
+
red: "#F4005F",
|
|
17
|
+
green: "#98E024",
|
|
18
|
+
yellow: "#FD971F",
|
|
19
|
+
blue: "#9D65FF",
|
|
20
|
+
magenta: "#F4005F",
|
|
21
|
+
cyan: "#58D1EB",
|
|
22
|
+
white: "#C4C5B5",
|
|
23
|
+
brightBlack: "#625E4C",
|
|
24
|
+
brightRed: "#F4005F",
|
|
25
|
+
brightGreen: "#98E024",
|
|
26
|
+
brightYellow: "#E0D561",
|
|
27
|
+
brightBlue: "#9D65FF",
|
|
28
|
+
brightMagenta: "#F4005F",
|
|
29
|
+
brightCyan: "#58D1EB",
|
|
30
|
+
brightWhite: "#F6F6EF",
|
|
31
|
+
};
|
|
32
|
+
export const TEXTUAL_LIGHT_ANSI = {
|
|
33
|
+
black: "#000000",
|
|
34
|
+
red: "#AA3731",
|
|
35
|
+
green: "#448C27",
|
|
36
|
+
yellow: "#CB9000",
|
|
37
|
+
blue: "#325CC0",
|
|
38
|
+
magenta: "#7A3E9D",
|
|
39
|
+
cyan: "#0083B2",
|
|
40
|
+
white: "#F7F7F7",
|
|
41
|
+
brightBlack: "#777777",
|
|
42
|
+
brightRed: "#F05050",
|
|
43
|
+
brightGreen: "#60CB00",
|
|
44
|
+
brightYellow: "#FFBC5D",
|
|
45
|
+
brightBlue: "#007ACC",
|
|
46
|
+
brightMagenta: "#E64CE6",
|
|
47
|
+
brightCyan: "#00AACB",
|
|
48
|
+
brightWhite: "#F7F7F7",
|
|
49
|
+
};
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
const theme = {
|
|
2
|
+
name: "atom-one-dark",
|
|
3
|
+
dark: true,
|
|
4
|
+
// iTerm2-Color-Schemes "One Half Dark", a terminal port of Atom One
|
|
5
|
+
ansi: {
|
|
6
|
+
black: "#282C34",
|
|
7
|
+
red: "#E06C75",
|
|
8
|
+
green: "#98C379",
|
|
9
|
+
yellow: "#E5C07B",
|
|
10
|
+
blue: "#61AFEF",
|
|
11
|
+
magenta: "#C678DD",
|
|
12
|
+
cyan: "#56B6C2",
|
|
13
|
+
white: "#DCDFE4",
|
|
14
|
+
brightBlack: "#5D677A",
|
|
15
|
+
brightRed: "#E06C75",
|
|
16
|
+
brightGreen: "#98C379",
|
|
17
|
+
brightYellow: "#E5C07B",
|
|
18
|
+
brightBlue: "#61AFEF",
|
|
19
|
+
brightMagenta: "#C678DD",
|
|
20
|
+
brightCyan: "#56B6C2",
|
|
21
|
+
brightWhite: "#DCDFE4",
|
|
22
|
+
},
|
|
23
|
+
vars: {
|
|
24
|
+
"accent": "#A378C2",
|
|
25
|
+
"accent-darken-1": "#8E65AD",
|
|
26
|
+
"accent-darken-2": "#7A5299",
|
|
27
|
+
"accent-darken-3": "#674085",
|
|
28
|
+
"accent-lighten-1": "#B78BD6",
|
|
29
|
+
"accent-lighten-2": "#CC9FEC",
|
|
30
|
+
"accent-lighten-3": "#E2B3FF",
|
|
31
|
+
"accent-muted": "#4C425E",
|
|
32
|
+
"background": "#282C34",
|
|
33
|
+
"background-darken-1": "#181C23",
|
|
34
|
+
"background-darken-2": "#050A14",
|
|
35
|
+
"background-darken-3": "#000000",
|
|
36
|
+
"background-lighten-1": "#383C44",
|
|
37
|
+
"background-lighten-2": "#494D56",
|
|
38
|
+
"background-lighten-3": "#5B5F68",
|
|
39
|
+
"block-cursor-background": "#61AFEF",
|
|
40
|
+
"block-cursor-blurred-background": "#61AFEF4C",
|
|
41
|
+
"block-cursor-blurred-foreground": "#ABB2BF",
|
|
42
|
+
"block-cursor-foreground": "#FFFFFFDD",
|
|
43
|
+
"block-hover-background": "#FFFFFF19",
|
|
44
|
+
"boost": "#FFFFFF0A",
|
|
45
|
+
"boost-darken-1": "#E9E9E90A",
|
|
46
|
+
"boost-darken-2": "#D4D4D40A",
|
|
47
|
+
"boost-darken-3": "#BFBFBF0A",
|
|
48
|
+
"boost-lighten-1": "#FFFFFF0A",
|
|
49
|
+
"boost-lighten-2": "#FFFFFF0A",
|
|
50
|
+
"boost-lighten-3": "#FFFFFF0A",
|
|
51
|
+
"border": "#61AFEF",
|
|
52
|
+
"border-blurred": "#353B47",
|
|
53
|
+
"button-color-foreground": "#FFFFFFDD",
|
|
54
|
+
"button-foreground": "#ABB2BF",
|
|
55
|
+
"error": "#EF6262",
|
|
56
|
+
"error-darken-1": "#D84D50",
|
|
57
|
+
"error-darken-2": "#C1373E",
|
|
58
|
+
"error-darken-3": "#AA1F2E",
|
|
59
|
+
"error-lighten-1": "#FF7674",
|
|
60
|
+
"error-lighten-2": "#FF8B87",
|
|
61
|
+
"error-lighten-3": "#FFA09B",
|
|
62
|
+
"error-muted": "#643C41",
|
|
63
|
+
"footer-background": "#4F5666",
|
|
64
|
+
"footer-description-background": "#00000000",
|
|
65
|
+
"footer-description-foreground": "#ABB2BF",
|
|
66
|
+
"footer-foreground": "#ABB2BF",
|
|
67
|
+
"footer-item-background": "#00000000",
|
|
68
|
+
"footer-key-background": "#00000000",
|
|
69
|
+
"footer-key-foreground": "#A378C2",
|
|
70
|
+
"foreground": "#ABB2BF",
|
|
71
|
+
"foreground-darken-1": "#979DAA",
|
|
72
|
+
"foreground-darken-2": "#838A96",
|
|
73
|
+
"foreground-darken-3": "#707783",
|
|
74
|
+
"foreground-disabled": "#ABB2BF60",
|
|
75
|
+
"foreground-lighten-1": "#BFC6D3",
|
|
76
|
+
"foreground-lighten-2": "#D4DBE8",
|
|
77
|
+
"foreground-lighten-3": "#E9F0FE",
|
|
78
|
+
"foreground-muted": "#ABB2BF99",
|
|
79
|
+
"input-cursor-background": "#ABB2BF",
|
|
80
|
+
"input-cursor-foreground": "#282C34",
|
|
81
|
+
"input-selection-background": "#77C3FF66",
|
|
82
|
+
"link-background": "#00000000",
|
|
83
|
+
"link-background-hover": "#61AFEF",
|
|
84
|
+
"link-color": "#FFFFFFDD",
|
|
85
|
+
"link-color-hover": "#FFFFFFDD",
|
|
86
|
+
"markdown-h1-background": "#00000000",
|
|
87
|
+
"markdown-h1-color": "#61AFEF",
|
|
88
|
+
"markdown-h2-background": "#00000000",
|
|
89
|
+
"markdown-h2-color": "#61AFEF",
|
|
90
|
+
"markdown-h3-background": "#00000000",
|
|
91
|
+
"markdown-h3-color": "#61AFEF",
|
|
92
|
+
"markdown-h4-background": "#00000000",
|
|
93
|
+
"markdown-h4-color": "#ABB2BF",
|
|
94
|
+
"markdown-h5-background": "#00000000",
|
|
95
|
+
"markdown-h5-color": "#ABB2BF",
|
|
96
|
+
"markdown-h6-background": "#00000000",
|
|
97
|
+
"markdown-h6-color": "#ABB2BF99",
|
|
98
|
+
"panel": "#4F5666",
|
|
99
|
+
"panel-darken-1": "#3D4453",
|
|
100
|
+
"panel-darken-2": "#2C3342",
|
|
101
|
+
"panel-darken-3": "#1C2331",
|
|
102
|
+
"panel-lighten-1": "#616878",
|
|
103
|
+
"panel-lighten-2": "#737A8B",
|
|
104
|
+
"panel-lighten-3": "#868E9F",
|
|
105
|
+
"primary": "#61AFEF",
|
|
106
|
+
"primary-background": "#4F5B6A",
|
|
107
|
+
"primary-background-darken-1": "#3F4D5D",
|
|
108
|
+
"primary-background-darken-2": "#303F50",
|
|
109
|
+
"primary-background-darken-3": "#303F50",
|
|
110
|
+
"primary-background-lighten-1": "#5E6A77",
|
|
111
|
+
"primary-background-lighten-2": "#6E7884",
|
|
112
|
+
"primary-background-lighten-3": "#7D8791",
|
|
113
|
+
"primary-darken-1": "#489BD9",
|
|
114
|
+
"primary-darken-2": "#2C87C4",
|
|
115
|
+
"primary-darken-3": "#0074AF",
|
|
116
|
+
"primary-lighten-1": "#77C3FF",
|
|
117
|
+
"primary-lighten-2": "#8ED8FF",
|
|
118
|
+
"primary-lighten-3": "#A4EDFF",
|
|
119
|
+
"primary-muted": "#39536C",
|
|
120
|
+
"scrollbar": "#355674",
|
|
121
|
+
"scrollbar-active": "#61AFEF",
|
|
122
|
+
"scrollbar-background": "#181C23",
|
|
123
|
+
"scrollbar-background-active": "#181C23",
|
|
124
|
+
"scrollbar-background-hover": "#181C23",
|
|
125
|
+
"scrollbar-corner-color": "#181C23",
|
|
126
|
+
"scrollbar-hover": "#3C6589",
|
|
127
|
+
"secondary": "#C678DD",
|
|
128
|
+
"secondary-background": "#5B5567",
|
|
129
|
+
"secondary-background-darken-1": "#4D465A",
|
|
130
|
+
"secondary-background-darken-2": "#3F374D",
|
|
131
|
+
"secondary-background-darken-3": "#3F374D",
|
|
132
|
+
"secondary-background-lighten-1": "#6A6475",
|
|
133
|
+
"secondary-background-lighten-2": "#787382",
|
|
134
|
+
"secondary-background-lighten-3": "#87828F",
|
|
135
|
+
"secondary-darken-1": "#B064C7",
|
|
136
|
+
"secondary-darken-2": "#9B50B3",
|
|
137
|
+
"secondary-darken-3": "#873D9E",
|
|
138
|
+
"secondary-lighten-1": "#DB8CF2",
|
|
139
|
+
"secondary-lighten-2": "#F1A0FF",
|
|
140
|
+
"secondary-lighten-3": "#FFB5FF",
|
|
141
|
+
"secondary-muted": "#574266",
|
|
142
|
+
"success": "#62F062",
|
|
143
|
+
"success-darken-1": "#48DA4D",
|
|
144
|
+
"success-darken-2": "#29C438",
|
|
145
|
+
"success-darken-3": "#00AF22",
|
|
146
|
+
"success-lighten-1": "#7AFF76",
|
|
147
|
+
"success-lighten-2": "#91FF8A",
|
|
148
|
+
"success-lighten-3": "#A8FF9F",
|
|
149
|
+
"success-muted": "#396641",
|
|
150
|
+
"surface": "#3B414D",
|
|
151
|
+
"surface-active": "#484E5B",
|
|
152
|
+
"surface-darken-1": "#2A303B",
|
|
153
|
+
"surface-darken-2": "#1A202B",
|
|
154
|
+
"surface-darken-3": "#09101B",
|
|
155
|
+
"surface-lighten-1": "#4C525E",
|
|
156
|
+
"surface-lighten-2": "#5E6471",
|
|
157
|
+
"surface-lighten-3": "#707684",
|
|
158
|
+
"text": "#FFFFFFDD",
|
|
159
|
+
"text-accent": "#C2A5D6",
|
|
160
|
+
"text-disabled": "#FFFFFF60",
|
|
161
|
+
"text-error": "#F59797",
|
|
162
|
+
"text-muted": "#FFFFFF99",
|
|
163
|
+
"text-primary": "#96CAF4",
|
|
164
|
+
"text-secondary": "#D9A5E8",
|
|
165
|
+
"text-success": "#97F597",
|
|
166
|
+
"text-warning": "#E9CC92",
|
|
167
|
+
"warning": "#DDB25B",
|
|
168
|
+
"warning-darken-1": "#C79D47",
|
|
169
|
+
"warning-darken-2": "#B28A34",
|
|
170
|
+
"warning-darken-3": "#9C7721",
|
|
171
|
+
"warning-lighten-1": "#F4C66E",
|
|
172
|
+
"warning-lighten-2": "#FFDB82",
|
|
173
|
+
"warning-lighten-3": "#FFF096",
|
|
174
|
+
"warning-muted": "#5E543F",
|
|
175
|
+
},
|
|
176
|
+
};
|
|
177
|
+
export default theme;
|