@bismawy/pi-arnative 0.4.0 → 0.5.2
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/CHANGELOG.md +41 -0
- package/README.md +8 -0
- package/extensions/arnative.ts +14 -3
- package/extensions/footer.ts +25 -26
- package/extensions/section-headers.ts +39 -11
- package/extensions/tools.ts +12 -10
- package/extensions/ui-render-tweaks.ts +53 -4
- package/extensions/usage.ts +21 -16
- package/lib/ansi.ts +83 -6
- package/package.json +1 -1
- package/themes/arnative-cyberpunk.json +35 -33
- package/themes/arnative-dracula.json +27 -25
- package/themes/arnative-emerald.json +8 -6
- package/themes/arnative-gruvbox.json +27 -25
- package/themes/arnative-matrix.json +24 -22
- package/themes/arnative-nord.json +24 -22
- package/themes/arnative-sun.json +9 -7
- package/themes/arnative-synthwave.json +35 -33
- package/themes/arnative-violet.json +9 -7
- package/themes/arnative-zinc.json +8 -6
- package/themes/arnative.json +9 -7
- package/themes/gen-themes.mjs +145 -54
package/themes/gen-themes.mjs
CHANGED
|
@@ -17,8 +17,9 @@ import { parseOklch, oklchToRgb } from "../lib/color.ts";
|
|
|
17
17
|
import { assert } from "../lib/check.ts";
|
|
18
18
|
|
|
19
19
|
const HERE = dirname(fileURLToPath(import.meta.url));
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
// Pi 1.2.0 moved the published schema to pi.dev; older releases validated this
|
|
21
|
+
// reference only as a string, so the new URL is safe on both.
|
|
22
|
+
const SCHEMA = "https://pi.dev/schemas/theme.schema.json";
|
|
22
23
|
|
|
23
24
|
// --- color helpers ---------------------------------------------------------
|
|
24
25
|
|
|
@@ -31,6 +32,23 @@ function oklch(L, C, H) {
|
|
|
31
32
|
return `oklch(${+(L * 100).toFixed(1)}% ${round3(chroma)} ${Math.round(hue(H))})`;
|
|
32
33
|
}
|
|
33
34
|
|
|
35
|
+
/**
|
|
36
|
+
* Soft tier of a color: clone at L 0.82 with a fifth of the GAMUT-CLAMPED chroma, hue
|
|
37
|
+
* kept. `lib/ansi.ts` softens the resolved token with this same recipe at runtime, so a
|
|
38
|
+
* `*Soft` var declared here and the extension's derived value agree. Grey-collapse is
|
|
39
|
+
* avoided because the hue is carried, not dropped.
|
|
40
|
+
*
|
|
41
|
+
* The chroma keeps five decimals (not the usual three): the soft tier multiplies it by
|
|
42
|
+
* 0.18, so a coarser round-trip shifts the last hex digit and the `declare == derive`
|
|
43
|
+
* guard in ui-render-tweaks.ts fails.
|
|
44
|
+
*/
|
|
45
|
+
function soften(value) {
|
|
46
|
+
const o = parseOklch(value);
|
|
47
|
+
assert(o !== null, `cannot soften a non-oklch color: ${value}`);
|
|
48
|
+
const { chroma } = oklchToRgb(0.82, o.C * 0.18, o.H);
|
|
49
|
+
return `oklch(82% ${+chroma.toFixed(5)} ${Math.round(hue(o.H))})`;
|
|
50
|
+
}
|
|
51
|
+
|
|
34
52
|
// --- shared ramps ----------------------------------------------------------
|
|
35
53
|
|
|
36
54
|
const NEUTRAL = { fg: 0.88, fgMuted: 0.72, fgDim: 0.61, fgFaint: 0.49 };
|
|
@@ -38,16 +56,26 @@ const THINKING = { off: 0.4, minimal: 0.47, low: 0.55, medium: 0.63, high: 0.71,
|
|
|
38
56
|
const SEMANTIC = { success: 145, error: 25, warning: 85 };
|
|
39
57
|
const SYNTAX_OFFSET = { keyword: 0, func: 45, variable: -45, string: 120, number: 180, type: 90 };
|
|
40
58
|
|
|
41
|
-
/** Default hue for a role used outside `syntax*` (heading/link/label). */
|
|
42
|
-
const ACCENT_OFFSET = {
|
|
59
|
+
/** Default hue for a role used outside `syntax*` (heading/link/label/code/bullet/border). */
|
|
60
|
+
const ACCENT_OFFSET = {
|
|
61
|
+
heading: 0,
|
|
62
|
+
link: 0,
|
|
63
|
+
label: 60,
|
|
64
|
+
code: 0,
|
|
65
|
+
bullet: 0,
|
|
66
|
+
border: 0,
|
|
67
|
+
selected: 0,
|
|
68
|
+
searchMatch: 0,
|
|
69
|
+
};
|
|
43
70
|
|
|
44
71
|
// --- theme parameters ------------------------------------------------------
|
|
45
72
|
|
|
46
73
|
/**
|
|
47
|
-
* `accent` is the seed color (OKLCH, hue + reference lightness/chroma)
|
|
48
|
-
*
|
|
49
|
-
* `
|
|
50
|
-
*
|
|
74
|
+
* `accent` is the seed/focus color (OKLCH, hue + reference lightness/chroma);
|
|
75
|
+
* `primary` and `secondary` define the theme's core signature and dual-tone balance;
|
|
76
|
+
* `chroma` is the normalized accent chroma.
|
|
77
|
+
* `hues` overrides the derived hue per role (keyword/func/… /heading/link/label/code/…)
|
|
78
|
+
* to keep rich multi-colored palettes (cyberpunk, synthwave, dracula, etc.) authentic.
|
|
51
79
|
*/
|
|
52
80
|
const THEMES = {
|
|
53
81
|
arnative: {
|
|
@@ -56,6 +84,8 @@ const THEMES = {
|
|
|
56
84
|
canvasL: 0.27,
|
|
57
85
|
neutralHue: 232,
|
|
58
86
|
neutralChroma: 0.012,
|
|
87
|
+
primary: "oklch(82% 0.14 218)",
|
|
88
|
+
secondary: "oklch(78% 0.11 282)",
|
|
59
89
|
hues: { heading: 75, label: 282 },
|
|
60
90
|
},
|
|
61
91
|
"arnative-sun": {
|
|
@@ -64,6 +94,8 @@ const THEMES = {
|
|
|
64
94
|
canvasL: 0.27,
|
|
65
95
|
neutralHue: 70,
|
|
66
96
|
neutralChroma: 0.012,
|
|
97
|
+
primary: "oklch(84% 0.15 70)",
|
|
98
|
+
secondary: "oklch(78% 0.12 35)",
|
|
67
99
|
hues: { heading: 60, label: 330 },
|
|
68
100
|
},
|
|
69
101
|
"arnative-zinc": {
|
|
@@ -72,6 +104,8 @@ const THEMES = {
|
|
|
72
104
|
canvasL: 0.26,
|
|
73
105
|
neutralHue: 285,
|
|
74
106
|
neutralChroma: 0.005,
|
|
107
|
+
primary: "oklch(86% 0.015 285)",
|
|
108
|
+
secondary: "oklch(72% 0.025 240)",
|
|
75
109
|
hues: { heading: 285, label: 285 },
|
|
76
110
|
},
|
|
77
111
|
"arnative-violet": {
|
|
@@ -80,6 +114,8 @@ const THEMES = {
|
|
|
80
114
|
canvasL: 0.27,
|
|
81
115
|
neutralHue: 295,
|
|
82
116
|
neutralChroma: 0.012,
|
|
117
|
+
primary: "oklch(82% 0.15 294)",
|
|
118
|
+
secondary: "oklch(78% 0.11 215)",
|
|
83
119
|
hues: { heading: 295, label: 330 },
|
|
84
120
|
},
|
|
85
121
|
"arnative-emerald": {
|
|
@@ -88,80 +124,119 @@ const THEMES = {
|
|
|
88
124
|
canvasL: 0.27,
|
|
89
125
|
neutralHue: 165,
|
|
90
126
|
neutralChroma: 0.012,
|
|
127
|
+
primary: "oklch(84% 0.13 165)",
|
|
128
|
+
secondary: "oklch(78% 0.10 195)",
|
|
91
129
|
hues: { heading: 165, label: 200 },
|
|
92
130
|
},
|
|
93
131
|
"arnative-matrix": {
|
|
94
132
|
accent: "oklch(86.9% 0.2776 144.466116)",
|
|
95
133
|
chroma: 0.22,
|
|
96
|
-
canvasL: 0.
|
|
134
|
+
canvasL: 0.24,
|
|
97
135
|
neutralHue: 145,
|
|
98
136
|
neutralChroma: 0.02,
|
|
137
|
+
primary: "oklch(88% 0.24 145)",
|
|
138
|
+
secondary: "oklch(76% 0.16 165)",
|
|
139
|
+
surfaceMsg: "oklch(24% 0.035 145)",
|
|
99
140
|
hues: {
|
|
100
141
|
heading: 145, link: 145, label: 145,
|
|
101
142
|
keyword: 145, func: 145, variable: 145, string: 145, number: 145, type: 145,
|
|
102
143
|
},
|
|
103
144
|
},
|
|
104
145
|
"arnative-cyberpunk": {
|
|
105
|
-
accent: "oklch(
|
|
146
|
+
accent: "oklch(76% 0.22 355)",
|
|
106
147
|
chroma: 0.2,
|
|
107
|
-
canvasL: 0.
|
|
148
|
+
canvasL: 0.24,
|
|
108
149
|
neutralHue: 275,
|
|
109
150
|
neutralChroma: 0.02,
|
|
151
|
+
primary: "oklch(88% 0.18 95)",
|
|
152
|
+
secondary: "oklch(82% 0.16 200)",
|
|
153
|
+
surfaceMsg: "oklch(24% 0.035 200)",
|
|
154
|
+
borderAccent: "secondary",
|
|
155
|
+
headingColor: "primary",
|
|
156
|
+
codeColor: "secondary",
|
|
157
|
+
bulletColor: "primary",
|
|
158
|
+
keywordColor: "secondary",
|
|
110
159
|
hues: {
|
|
111
|
-
heading:
|
|
112
|
-
keyword:
|
|
160
|
+
heading: 95, link: 200, label: 200, code: 200, bullet: 95, border: 200, selected: 200, searchMatch: 95,
|
|
161
|
+
keyword: 200, func: 95, variable: 355, string: 140, number: 45, type: 200,
|
|
113
162
|
},
|
|
114
163
|
},
|
|
115
164
|
"arnative-synthwave": {
|
|
116
|
-
accent: "oklch(
|
|
165
|
+
accent: "oklch(80% 0.18 50)",
|
|
117
166
|
chroma: 0.17,
|
|
118
|
-
canvasL: 0.
|
|
167
|
+
canvasL: 0.24,
|
|
119
168
|
neutralHue: 300,
|
|
120
169
|
neutralChroma: 0.015,
|
|
170
|
+
primary: "oklch(78% 0.19 339)",
|
|
171
|
+
secondary: "oklch(82% 0.16 185)",
|
|
172
|
+
surfaceMsg: "oklch(24% 0.03 300)",
|
|
173
|
+
borderAccent: "secondary",
|
|
174
|
+
codeColor: "secondary",
|
|
175
|
+
bulletColor: "primary",
|
|
121
176
|
hues: {
|
|
122
|
-
heading:
|
|
123
|
-
keyword:
|
|
177
|
+
heading: 50, link: 185, label: 185, code: 185, bullet: 339, border: 185, selected: 185, searchMatch: 50,
|
|
178
|
+
keyword: 185, func: 50, variable: 339, string: 45, number: 339, type: 290,
|
|
124
179
|
},
|
|
125
180
|
},
|
|
126
181
|
"arnative-gruvbox": {
|
|
127
|
-
accent: "oklch(
|
|
182
|
+
accent: "oklch(76% 0.15 45)",
|
|
128
183
|
chroma: 0.14,
|
|
129
184
|
canvasL: 0.24,
|
|
130
185
|
neutralHue: 70,
|
|
131
186
|
neutralChroma: 0.015,
|
|
187
|
+
primary: "oklch(84% 0.14 83)",
|
|
188
|
+
secondary: "oklch(78% 0.10 175)",
|
|
189
|
+
borderAccent: "secondary",
|
|
190
|
+
headingColor: "primary",
|
|
191
|
+
codeColor: "secondary",
|
|
192
|
+
bulletColor: "accent",
|
|
132
193
|
hues: {
|
|
133
|
-
heading:
|
|
134
|
-
keyword:
|
|
194
|
+
heading: 83, link: 175, label: 175, code: 175, bullet: 45, border: 83, selected: 83, searchMatch: 83,
|
|
195
|
+
keyword: 45, func: 83, variable: 175, string: 145, number: 45, type: 83,
|
|
135
196
|
},
|
|
136
197
|
},
|
|
137
198
|
"arnative-nord": {
|
|
138
|
-
accent: "oklch(
|
|
199
|
+
accent: "oklch(74% 0.09 310)",
|
|
139
200
|
chroma: 0.07,
|
|
140
201
|
canvasL: 0.3,
|
|
141
202
|
neutralHue: 240,
|
|
142
203
|
neutralChroma: 0.01,
|
|
204
|
+
primary: "oklch(78% 0.08 217)",
|
|
205
|
+
secondary: "oklch(82% 0.09 195)",
|
|
206
|
+
borderAccent: "secondary",
|
|
207
|
+
codeColor: "secondary",
|
|
208
|
+
bulletColor: "primary",
|
|
143
209
|
hues: {
|
|
144
|
-
heading:
|
|
145
|
-
keyword:
|
|
210
|
+
heading: 75, link: 195, label: 195, code: 195, bullet: 217, border: 217, selected: 217, searchMatch: 75,
|
|
211
|
+
keyword: 217, func: 195, variable: 217, string: 145, number: 310, type: 195,
|
|
146
212
|
},
|
|
147
213
|
},
|
|
148
214
|
"arnative-dracula": {
|
|
149
|
-
accent: "oklch(
|
|
215
|
+
accent: "oklch(76% 0.18 330)",
|
|
150
216
|
chroma: 0.14,
|
|
151
217
|
canvasL: 0.29,
|
|
152
218
|
neutralHue: 285,
|
|
153
219
|
neutralChroma: 0.012,
|
|
220
|
+
primary: "oklch(78% 0.15 295)",
|
|
221
|
+
secondary: "oklch(82% 0.13 190)",
|
|
222
|
+
borderAccent: "secondary",
|
|
223
|
+
codeColor: "secondary",
|
|
224
|
+
bulletColor: "accent",
|
|
154
225
|
hues: {
|
|
155
|
-
heading:
|
|
156
|
-
keyword: 330, func:
|
|
226
|
+
heading: 85, link: 190, label: 190, code: 190, bullet: 330, border: 295, selected: 295, searchMatch: 85,
|
|
227
|
+
keyword: 330, func: 140, variable: 190, string: 85, number: 295, type: 190,
|
|
157
228
|
},
|
|
158
229
|
},
|
|
159
230
|
};
|
|
160
231
|
|
|
161
232
|
// --- role order (matches the pi theme schema) ------------------------------
|
|
162
|
-
|
|
233
|
+
//
|
|
234
|
+
// Only tokens pi's schema declares may appear as keys here: since 1.2.0 the
|
|
235
|
+
// `colors` object is validated with `additionalProperties: false`, and an extra
|
|
236
|
+
// key rejects the whole theme at startup. Arnative's own colors (`accentSoft`,
|
|
237
|
+
// `primary`, `secondary`, …) live in `vars` and are referenced from these roles.
|
|
163
238
|
const ROLE_ORDER = [
|
|
164
|
-
"accent", "
|
|
239
|
+
"accent", "border", "borderAccent", "borderMuted", "success", "error", "warning",
|
|
165
240
|
"muted", "dim", "text", "thinkingText",
|
|
166
241
|
"selectedBg", "scrollbarTrack", "scrollbarThumb", "searchMatchBg", "searchMatchText",
|
|
167
242
|
"userMessageBg", "userMessageText", "customMessageBg", "customMessageText", "customMessageLabel",
|
|
@@ -189,26 +264,42 @@ function derive(spec) {
|
|
|
189
264
|
const roleHue = (role) => hue(H[role]);
|
|
190
265
|
const sem = (role) => hue(SEMANTIC[role]);
|
|
191
266
|
|
|
267
|
+
const primarySeed = spec.primary ? parseOklch(spec.primary) : null;
|
|
268
|
+
const secondarySeed = spec.secondary ? parseOklch(spec.secondary) : null;
|
|
269
|
+
const primaryVal = primarySeed ? oklch(primarySeed.L, primarySeed.C, primarySeed.H) : oklch(0.82, c, h);
|
|
270
|
+
const secondaryVal = secondarySeed ? oklch(secondarySeed.L, secondarySeed.C, secondarySeed.H) : oklch(0.78, Math.min(c * 0.8, 0.12), roleHue("label"));
|
|
271
|
+
|
|
272
|
+
// Soft counterpart of the border-accent tier — the footer's label, clock and status
|
|
273
|
+
// colour. Softened from the SAME value the `borderAccent` token resolves to, because
|
|
274
|
+
// that token is what extensions read back at runtime (`softSecondaryOf` in
|
|
275
|
+
// lib/ansi.ts). One source keeps the declared value and the runtime one identical.
|
|
276
|
+
const accentBorderVal = oklch(0.82, c * 0.6, h);
|
|
277
|
+
const accentVal = oklch(0.78, c, h);
|
|
278
|
+
const borderAccentRole = spec.borderAccent ?? "accentBorder";
|
|
279
|
+
const borderAccentVal = { accentBorder: accentBorderVal, secondary: secondaryVal }[borderAccentRole] ?? borderAccentRole;
|
|
280
|
+
|
|
192
281
|
const vars = {
|
|
193
282
|
fg: oklch(NEUTRAL.fg, nc, nh),
|
|
194
283
|
fgMuted: oklch(NEUTRAL.fgMuted, nc, nh),
|
|
195
284
|
fgDim: oklch(NEUTRAL.fgDim, nc, nh),
|
|
196
285
|
fgFaint: oklch(NEUTRAL.fgFaint, nc, nh),
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
286
|
+
primary: primaryVal,
|
|
287
|
+
secondary: secondaryVal,
|
|
288
|
+
secondarySoft: soften(borderAccentVal),
|
|
289
|
+
accent: accentVal,
|
|
290
|
+
accentSoft: soften(accentVal),
|
|
291
|
+
accentBorder: accentBorderVal,
|
|
200
292
|
success: oklch(0.78, Math.min(c, 0.15), sem("success")),
|
|
201
293
|
error: oklch(0.76, Math.min(c, 0.15), sem("error")),
|
|
202
294
|
warning: oklch(0.86, Math.min(c, 0.14), sem("warning")),
|
|
203
|
-
surfaceMsg: oklch(base, nc * 0.5, nh),
|
|
295
|
+
surfaceMsg: spec.surfaceMsg ?? oklch(base, nc * 0.5, nh),
|
|
204
296
|
};
|
|
205
297
|
|
|
206
|
-
const accentLiteral = oklch(0.8, c * 0.7, h);
|
|
298
|
+
const accentLiteral = oklch(0.8, Math.min(c * 0.7, 0.14), h);
|
|
207
299
|
const roles = {
|
|
208
300
|
accent: "accent",
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
borderAccent: "accentBorder",
|
|
301
|
+
border: oklch(0.55, Math.min(c * 0.35, 0.08), roleHue("border")),
|
|
302
|
+
borderAccent: spec.borderAccent ?? "accentBorder",
|
|
212
303
|
borderMuted: "fgFaint",
|
|
213
304
|
success: "success",
|
|
214
305
|
error: "error",
|
|
@@ -218,45 +309,45 @@ function derive(spec) {
|
|
|
218
309
|
text: "fg",
|
|
219
310
|
thinkingText: "fgMuted",
|
|
220
311
|
|
|
221
|
-
selectedBg: oklch(base + 0.07, c * 0.25,
|
|
312
|
+
selectedBg: oklch(base + 0.07, Math.min(c * 0.25, 0.06), roleHue("selected")),
|
|
222
313
|
scrollbarTrack: "fgFaint",
|
|
223
314
|
scrollbarThumb: "accentSoft",
|
|
224
|
-
searchMatchBg: oklch(base + 0.14, c * 0.45,
|
|
315
|
+
searchMatchBg: oklch(base + 0.14, Math.min(c * 0.45, 0.10), roleHue("searchMatch")),
|
|
225
316
|
searchMatchText: "fg",
|
|
226
317
|
userMessageBg: "surfaceMsg",
|
|
227
318
|
userMessageText: "fg",
|
|
228
|
-
customMessageBg: oklch(base + 0.01, c * 0.4, roleHue("label")),
|
|
319
|
+
customMessageBg: oklch(base + 0.01, Math.min(c * 0.4, 0.05), roleHue("label")),
|
|
229
320
|
customMessageText: "fg",
|
|
230
|
-
customMessageLabel: oklch(0.78, c * 0.7, roleHue("label")),
|
|
321
|
+
customMessageLabel: spec.labelColor ?? oklch(0.78, Math.min(c * 0.7, 0.14), roleHue("label")),
|
|
231
322
|
|
|
232
|
-
toolPendingBg: oklch(base - 0.02, c * 0.3, h),
|
|
233
|
-
toolSuccessBg: oklch(base - 0.03, c * 0.4, sem("success")),
|
|
234
|
-
toolErrorBg: oklch(base - 0.03, c * 0.4, sem("error")),
|
|
323
|
+
toolPendingBg: oklch(base - 0.02, Math.min(c * 0.3, 0.05), h),
|
|
324
|
+
toolSuccessBg: oklch(base - 0.03, Math.min(c * 0.4, 0.06), sem("success")),
|
|
325
|
+
toolErrorBg: oklch(base - 0.03, Math.min(c * 0.4, 0.06), sem("error")),
|
|
235
326
|
toolTitle: "fg",
|
|
236
327
|
toolOutput: "fgMuted",
|
|
237
328
|
|
|
238
|
-
mdHeading: oklch(0.88, c * 0.6, roleHue("heading")),
|
|
239
|
-
mdLink: oklch(0.8, c * 0.7, roleHue("link")),
|
|
329
|
+
mdHeading: spec.headingColor ?? oklch(0.88, Math.min(c * 0.6, 0.14), roleHue("heading")),
|
|
330
|
+
mdLink: spec.linkColor ?? oklch(0.8, Math.min(c * 0.7, 0.14), roleHue("link")),
|
|
240
331
|
mdLinkUrl: "fgDim",
|
|
241
|
-
mdCode: accentLiteral,
|
|
332
|
+
mdCode: spec.codeColor ?? accentLiteral,
|
|
242
333
|
mdCodeBlock: "success",
|
|
243
334
|
mdCodeBlockBorder: "fgMuted",
|
|
244
335
|
mdQuote: "fgMuted",
|
|
245
336
|
mdQuoteBorder: "fgMuted",
|
|
246
337
|
mdHr: "fgFaint",
|
|
247
|
-
mdListBullet: accentLiteral,
|
|
338
|
+
mdListBullet: spec.bulletColor ?? accentLiteral,
|
|
248
339
|
|
|
249
340
|
toolDiffAdded: "success",
|
|
250
341
|
toolDiffRemoved: "error",
|
|
251
342
|
toolDiffContext: "fgMuted",
|
|
252
343
|
|
|
253
344
|
syntaxComment: "fgDim",
|
|
254
|
-
syntaxKeyword: accentLiteral,
|
|
255
|
-
syntaxFunction: oklch(0.86, c * 0.8, roleHue("func")),
|
|
256
|
-
syntaxVariable: oklch(0.84, c * 0.55, roleHue("variable")),
|
|
257
|
-
syntaxString: oklch(0.82, c * 0.7, roleHue("string")),
|
|
258
|
-
syntaxNumber: oklch(0.8, c * 0.7, roleHue("number")),
|
|
259
|
-
syntaxType: oklch(0.8, c * 0.8, roleHue("type")),
|
|
345
|
+
syntaxKeyword: spec.keywordColor ?? accentLiteral,
|
|
346
|
+
syntaxFunction: oklch(0.86, Math.min(c * 0.8, 0.16), roleHue("func")),
|
|
347
|
+
syntaxVariable: oklch(0.84, Math.min(c * 0.55, 0.14), roleHue("variable")),
|
|
348
|
+
syntaxString: oklch(0.82, Math.min(c * 0.7, 0.16), roleHue("string")),
|
|
349
|
+
syntaxNumber: oklch(0.8, Math.min(c * 0.7, 0.15), roleHue("number")),
|
|
350
|
+
syntaxType: oklch(0.8, Math.min(c * 0.8, 0.16), roleHue("type")),
|
|
260
351
|
syntaxOperator: "fg",
|
|
261
352
|
syntaxPunctuation: "fgMuted",
|
|
262
353
|
|
|
@@ -274,7 +365,7 @@ function derive(spec) {
|
|
|
274
365
|
const exp = {
|
|
275
366
|
pageBg: oklch(base - 0.06, nc, nh),
|
|
276
367
|
cardBg: oklch(base - 0.03, nc, nh),
|
|
277
|
-
infoBg: oklch(base + 0.05, c * 0.25, h),
|
|
368
|
+
infoBg: oklch(base + 0.05, Math.min(c * 0.25, 0.06), h),
|
|
278
369
|
};
|
|
279
370
|
|
|
280
371
|
// Roles must match ROLE_ORDER exactly and each value must be a var name or a literal.
|