@pierre/theme 0.0.18
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/.github/workflows/publish.yml +40 -0
- package/.github/workflows/test.yml +66 -0
- package/.vscode/extensions.json +5 -0
- package/.vscode/launch.json +24 -0
- package/.vscode/tasks.json +24 -0
- package/.vscodeignore +9 -0
- package/DISPLAY-P3.md +120 -0
- package/LICENSE.md +21 -0
- package/README.md +67 -0
- package/color-comparison.html +234 -0
- package/icon.png +0 -0
- package/package.json +61 -0
- package/src/build.ts +23 -0
- package/src/color-p3.ts +229 -0
- package/src/demo-p3.ts +44 -0
- package/src/package-vsix.ts +22 -0
- package/src/palette.ts +379 -0
- package/src/test.ts +272 -0
- package/src/theme.ts +615 -0
- package/tsconfig.json +21 -0
package/src/build.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// src/build.ts
|
|
2
|
+
import { writeFileSync, mkdirSync } from "node:fs";
|
|
3
|
+
import { light as rolesLight, dark as rolesDark } from "./palette";
|
|
4
|
+
import { makeTheme } from "./theme";
|
|
5
|
+
import { convertRolesToP3 } from "./color-p3";
|
|
6
|
+
|
|
7
|
+
mkdirSync("themes", { recursive: true });
|
|
8
|
+
|
|
9
|
+
// Convert palettes to Display P3 color space
|
|
10
|
+
const rolesLightP3 = convertRolesToP3(rolesLight);
|
|
11
|
+
const rolesDarkP3 = convertRolesToP3(rolesDark);
|
|
12
|
+
|
|
13
|
+
const out = [
|
|
14
|
+
{ file: "themes/pierre-light.json", theme: makeTheme("Pierre Light", "light", rolesLight) },
|
|
15
|
+
{ file: "themes/pierre-dark.json", theme: makeTheme("Pierre Dark", "dark", rolesDark) },
|
|
16
|
+
{ file: "themes/pierre-light-vibrant.json", theme: makeTheme("Pierre Light Vibrant", "light", rolesLightP3) },
|
|
17
|
+
{ file: "themes/pierre-dark-vibrant.json", theme: makeTheme("Pierre Dark Vibrant", "dark", rolesDarkP3) }
|
|
18
|
+
];
|
|
19
|
+
|
|
20
|
+
for (const {file, theme} of out) {
|
|
21
|
+
writeFileSync(file, JSON.stringify(theme, null, 2), "utf8");
|
|
22
|
+
console.log("Wrote", file);
|
|
23
|
+
}
|
package/src/color-p3.ts
ADDED
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
// src/color-p3.ts
|
|
2
|
+
// Convert sRGB hex colors to CSS Display P3 color space format
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Convert hex color to RGB values (0-1 range)
|
|
6
|
+
*/
|
|
7
|
+
function hexToRgb01(hex: string): [number, number, number] {
|
|
8
|
+
const cleaned = hex.replace('#', '');
|
|
9
|
+
const expanded = cleaned.length === 3
|
|
10
|
+
? cleaned.split('').map(x => x + x).join('')
|
|
11
|
+
: cleaned;
|
|
12
|
+
|
|
13
|
+
const num = parseInt(expanded, 16);
|
|
14
|
+
const r = ((num >> 16) & 255) / 255;
|
|
15
|
+
const g = ((num >> 8) & 255) / 255;
|
|
16
|
+
const b = (num & 255) / 255;
|
|
17
|
+
|
|
18
|
+
return [r, g, b];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Apply sRGB gamma correction (linearize)
|
|
23
|
+
*/
|
|
24
|
+
function srgbToLinear(c: number): number {
|
|
25
|
+
if (c <= 0.04045) {
|
|
26
|
+
return c / 12.92;
|
|
27
|
+
}
|
|
28
|
+
return Math.pow((c + 0.055) / 1.055, 2.4);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Remove sRGB gamma correction (to display)
|
|
33
|
+
*/
|
|
34
|
+
function linearToSrgb(c: number): number {
|
|
35
|
+
if (c <= 0.0031308) {
|
|
36
|
+
return c * 12.92;
|
|
37
|
+
}
|
|
38
|
+
return 1.055 * Math.pow(c, 1 / 2.4) - 0.055;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Apply Display P3 gamma correction (same as sRGB)
|
|
43
|
+
*/
|
|
44
|
+
const linearToP3 = linearToSrgb;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Convert linear sRGB to linear Display P3
|
|
48
|
+
* Using the standard conversion matrix from sRGB to P3
|
|
49
|
+
*/
|
|
50
|
+
function linearSrgbToLinearP3(r: number, g: number, b: number): [number, number, number] {
|
|
51
|
+
// Conversion matrix from linear sRGB to linear Display P3
|
|
52
|
+
// This matrix converts from sRGB primaries to P3 primaries via XYZ
|
|
53
|
+
const rOut = 0.82246197 * r + 0.17753803 * g + 0.00000000 * b;
|
|
54
|
+
const gOut = 0.03319420 * r + 0.96680580 * g + 0.00000000 * b;
|
|
55
|
+
const bOut = 0.01708263 * r + 0.07239744 * g + 0.91051993 * b;
|
|
56
|
+
|
|
57
|
+
return [rOut, gOut, bOut];
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Format a number for CSS color function (round to reasonable precision)
|
|
62
|
+
*/
|
|
63
|
+
function formatColorValue(value: number): string {
|
|
64
|
+
// Clamp to 0-1 range
|
|
65
|
+
const clamped = Math.max(0, Math.min(1, value));
|
|
66
|
+
// Round to 6 decimal places for precision without being excessive
|
|
67
|
+
return clamped.toFixed(6);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Convert RGB to HSL color space
|
|
72
|
+
*/
|
|
73
|
+
function rgbToHsl(r: number, g: number, b: number): [number, number, number] {
|
|
74
|
+
const max = Math.max(r, g, b);
|
|
75
|
+
const min = Math.min(r, g, b);
|
|
76
|
+
const delta = max - min;
|
|
77
|
+
|
|
78
|
+
let h = 0;
|
|
79
|
+
let s = 0;
|
|
80
|
+
const l = (max + min) / 2;
|
|
81
|
+
|
|
82
|
+
if (delta !== 0) {
|
|
83
|
+
s = l > 0.5 ? delta / (2 - max - min) : delta / (max + min);
|
|
84
|
+
|
|
85
|
+
switch (max) {
|
|
86
|
+
case r:
|
|
87
|
+
h = ((g - b) / delta + (g < b ? 6 : 0)) / 6;
|
|
88
|
+
break;
|
|
89
|
+
case g:
|
|
90
|
+
h = ((b - r) / delta + 2) / 6;
|
|
91
|
+
break;
|
|
92
|
+
case b:
|
|
93
|
+
h = ((r - g) / delta + 4) / 6;
|
|
94
|
+
break;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return [h, s, l];
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Convert HSL to RGB color space
|
|
103
|
+
*/
|
|
104
|
+
function hslToRgb(h: number, s: number, l: number): [number, number, number] {
|
|
105
|
+
let r, g, b;
|
|
106
|
+
|
|
107
|
+
if (s === 0) {
|
|
108
|
+
r = g = b = l;
|
|
109
|
+
} else {
|
|
110
|
+
const hue2rgb = (p: number, q: number, t: number) => {
|
|
111
|
+
if (t < 0) t += 1;
|
|
112
|
+
if (t > 1) t -= 1;
|
|
113
|
+
if (t < 1/6) return p + (q - p) * 6 * t;
|
|
114
|
+
if (t < 1/2) return q;
|
|
115
|
+
if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;
|
|
116
|
+
return p;
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
|
|
120
|
+
const p = 2 * l - q;
|
|
121
|
+
|
|
122
|
+
r = hue2rgb(p, q, h + 1/3);
|
|
123
|
+
g = hue2rgb(p, q, h);
|
|
124
|
+
b = hue2rgb(p, q, h - 1/3);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return [r, g, b];
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Enhance colors to take advantage of P3's wider gamut
|
|
132
|
+
* Increases saturation and vibrancy for colors that can benefit from P3
|
|
133
|
+
*/
|
|
134
|
+
function enhanceForP3Gamut(r: number, g: number, b: number): [number, number, number] {
|
|
135
|
+
// Convert to HSL for easier saturation manipulation
|
|
136
|
+
const [h, s, l] = rgbToHsl(r, g, b);
|
|
137
|
+
|
|
138
|
+
// Only enhance colors that have some saturation and aren't too light or dark
|
|
139
|
+
// (grays and near-blacks/whites don't benefit from P3 enhancement)
|
|
140
|
+
if (s < 0.1 || l < 0.1 || l > 0.9) {
|
|
141
|
+
return [r, g, b];
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Calculate enhancement factor based on original saturation
|
|
145
|
+
// More saturated colors get more enhancement (they can handle it)
|
|
146
|
+
const saturationBoost = 0.15 + (s * 0.15); // 15-30% boost depending on saturation
|
|
147
|
+
|
|
148
|
+
// Boost saturation, but not beyond 1.0
|
|
149
|
+
let newS = s + (s * saturationBoost);
|
|
150
|
+
newS = Math.min(1.0, newS);
|
|
151
|
+
|
|
152
|
+
// For highly saturated colors, also slightly increase luminance to make them "pop"
|
|
153
|
+
// but only if they're not already too light
|
|
154
|
+
let newL = l;
|
|
155
|
+
if (s > 0.5 && l < 0.7) {
|
|
156
|
+
newL = l + (l * 0.05); // Slight 5% luminance boost for vibrant colors
|
|
157
|
+
newL = Math.min(0.9, newL);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Convert back to RGB
|
|
161
|
+
return hslToRgb(h, newS, newL);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Convert sRGB hex color to CSS Display P3 color format with enhancement
|
|
166
|
+
* Returns: "color(display-p3 r g b)" or "color(display-p3 r g b / alpha)"
|
|
167
|
+
*/
|
|
168
|
+
export function srgbHexToP3Color(srgbHex: string, enhance: boolean = true): string {
|
|
169
|
+
// Handle alpha channel if present
|
|
170
|
+
const hasAlpha = srgbHex.length === 9 || (srgbHex.startsWith('#') && srgbHex.length === 9);
|
|
171
|
+
let alpha = '';
|
|
172
|
+
let colorHex = srgbHex;
|
|
173
|
+
|
|
174
|
+
if (hasAlpha) {
|
|
175
|
+
const alphaHex = srgbHex.slice(-2);
|
|
176
|
+
const alphaValue = parseInt(alphaHex, 16) / 255;
|
|
177
|
+
alpha = ` / ${formatColorValue(alphaValue)}`;
|
|
178
|
+
colorHex = srgbHex.slice(0, -2);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// Convert to linear sRGB
|
|
182
|
+
const [sR, sG, sB] = hexToRgb01(colorHex);
|
|
183
|
+
const linearSR = srgbToLinear(sR);
|
|
184
|
+
const linearSG = srgbToLinear(sG);
|
|
185
|
+
const linearSB = srgbToLinear(sB);
|
|
186
|
+
|
|
187
|
+
// Convert to linear P3
|
|
188
|
+
const [linearPR, linearPG, linearPB] = linearSrgbToLinearP3(linearSR, linearSG, linearSB);
|
|
189
|
+
|
|
190
|
+
// Apply P3 gamma to get display values
|
|
191
|
+
let pR = linearToP3(linearPR);
|
|
192
|
+
let pG = linearToP3(linearPG);
|
|
193
|
+
let pB = linearToP3(linearPB);
|
|
194
|
+
|
|
195
|
+
// Enhance colors to take advantage of P3's wider gamut
|
|
196
|
+
if (enhance) {
|
|
197
|
+
[pR, pG, pB] = enhanceForP3Gamut(pR, pG, pB);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// Format as CSS color(display-p3 ...) function
|
|
201
|
+
return `color(display-p3 ${formatColorValue(pR)} ${formatColorValue(pG)} ${formatColorValue(pB)}${alpha})`;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Convert all colors in a Roles object to Display P3
|
|
206
|
+
*/
|
|
207
|
+
export function convertRolesToP3<T>(obj: T): T {
|
|
208
|
+
if (typeof obj === 'string') {
|
|
209
|
+
// If it's a hex color string, convert it
|
|
210
|
+
if ((obj as string).match(/^#[0-9a-fA-F]{6}([0-9a-fA-F]{2})?$/)) {
|
|
211
|
+
return srgbHexToP3Color(obj as string) as any;
|
|
212
|
+
}
|
|
213
|
+
return obj;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
if (Array.isArray(obj)) {
|
|
217
|
+
return obj.map(item => convertRolesToP3(item)) as any;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
if (obj !== null && typeof obj === 'object') {
|
|
221
|
+
const result: any = {};
|
|
222
|
+
for (const [key, value] of Object.entries(obj as any)) {
|
|
223
|
+
result[key] = convertRolesToP3(value);
|
|
224
|
+
}
|
|
225
|
+
return result;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
return obj;
|
|
229
|
+
}
|
package/src/demo-p3.ts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// src/demo-p3.ts
|
|
2
|
+
// Demonstration of Display P3 color conversion with enhancement
|
|
3
|
+
|
|
4
|
+
import { srgbHexToP3Color } from "./color-p3";
|
|
5
|
+
|
|
6
|
+
console.log("Display P3 Color Conversion Demo");
|
|
7
|
+
console.log("=".repeat(70));
|
|
8
|
+
console.log("");
|
|
9
|
+
|
|
10
|
+
const testColors = [
|
|
11
|
+
{ name: "Blue", srgb: "#008cff" },
|
|
12
|
+
{ name: "Green", srgb: "#0dbe4e" },
|
|
13
|
+
{ name: "Red", srgb: "#ff2e3f" },
|
|
14
|
+
{ name: "Purple", srgb: "#c635e4" },
|
|
15
|
+
{ name: "Pink", srgb: "#fc2b73" },
|
|
16
|
+
{ name: "Orange", srgb: "#fe8c2c" },
|
|
17
|
+
{ name: "Cyan", srgb: "#08c0ef" },
|
|
18
|
+
{ name: "Teal", srgb: "#00c5d2" }
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
console.log("Color conversions from sRGB to Enhanced Display P3:");
|
|
22
|
+
console.log("(Enhanced to take advantage of P3's wider gamut)");
|
|
23
|
+
console.log("");
|
|
24
|
+
|
|
25
|
+
for (const { name, srgb } of testColors) {
|
|
26
|
+
const p3Basic = srgbHexToP3Color(srgb, false);
|
|
27
|
+
const p3Enhanced = srgbHexToP3Color(srgb, true);
|
|
28
|
+
console.log(`${name.padEnd(10)} ${srgb}`);
|
|
29
|
+
console.log(`${''.padEnd(10)} Basic: ${p3Basic}`);
|
|
30
|
+
console.log(`${''.padEnd(10)} Enhanced: ${p3Enhanced}`);
|
|
31
|
+
console.log("");
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
console.log("=".repeat(70));
|
|
35
|
+
console.log("");
|
|
36
|
+
console.log("Enhancement Details:");
|
|
37
|
+
console.log("- Saturation boost: 15-30% depending on original saturation");
|
|
38
|
+
console.log("- Luminance boost: 5% for highly saturated colors");
|
|
39
|
+
console.log("- Grays and near-blacks/whites are left unchanged");
|
|
40
|
+
console.log("");
|
|
41
|
+
console.log("These enhanced colors take full advantage of Display P3's");
|
|
42
|
+
console.log("wider color gamut (~25% more colors than sRGB).");
|
|
43
|
+
console.log("");
|
|
44
|
+
console.log("Browser support: Safari 10+, Chrome 111+, Firefox 113+, Edge 111+");
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync } from "fs";
|
|
2
|
+
import { execSync } from "child_process";
|
|
3
|
+
import { join } from "path";
|
|
4
|
+
|
|
5
|
+
const pkgPath = join(__dirname, "..", "package.json");
|
|
6
|
+
const original = readFileSync(pkgPath, "utf-8");
|
|
7
|
+
const pkg = JSON.parse(original);
|
|
8
|
+
|
|
9
|
+
// Store original name and swap to unscoped version for VSIX
|
|
10
|
+
const originalName = pkg.name;
|
|
11
|
+
pkg.name = "pierre-theme";
|
|
12
|
+
|
|
13
|
+
console.log(`Temporarily renaming package: ${originalName} → ${pkg.name}\n`);
|
|
14
|
+
|
|
15
|
+
try {
|
|
16
|
+
writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + "\n");
|
|
17
|
+
execSync("vsce package", { stdio: "inherit", cwd: join(__dirname, "..") });
|
|
18
|
+
} finally {
|
|
19
|
+
// Always restore original package.json
|
|
20
|
+
writeFileSync(pkgPath, original);
|
|
21
|
+
console.log(`\nRestored package name: ${originalName}`);
|
|
22
|
+
}
|
package/src/palette.ts
ADDED
|
@@ -0,0 +1,379 @@
|
|
|
1
|
+
// src/palette.ts
|
|
2
|
+
|
|
3
|
+
const gray = {
|
|
4
|
+
"020":"#fbfbfb",
|
|
5
|
+
"040":"#f9f9f9",
|
|
6
|
+
"060":"#f8f8f8",
|
|
7
|
+
"080":"#f2f2f3",
|
|
8
|
+
"100":"#eeeeef",
|
|
9
|
+
"200":"#dbdbdd",
|
|
10
|
+
"300":"#c6c6c8",
|
|
11
|
+
"400":"#adadb1",
|
|
12
|
+
"500":"#8E8E95",
|
|
13
|
+
"600":"#84848A",
|
|
14
|
+
"700":"#79797F",
|
|
15
|
+
"800":"#6C6C71",
|
|
16
|
+
"900":"#4A4A4E",
|
|
17
|
+
"920":"#424245",
|
|
18
|
+
"940":"#39393c",
|
|
19
|
+
"960":"#2e2e30",
|
|
20
|
+
"980":"#1F1F21",
|
|
21
|
+
"1000":"#141415",
|
|
22
|
+
"1020":"#0B0B0C",
|
|
23
|
+
"1040":"#070707"
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const red = {
|
|
27
|
+
"050":"#ffedea",
|
|
28
|
+
"100":"#ffdbd6",
|
|
29
|
+
"200":"#ffb7ae",
|
|
30
|
+
"300":"#ff9187",
|
|
31
|
+
"400":"#ff6762",
|
|
32
|
+
"500":"#ff2e3f",
|
|
33
|
+
"600":"#d52c36",
|
|
34
|
+
"700":"#ad292e",
|
|
35
|
+
"800":"#862425",
|
|
36
|
+
"900":"#611e1d",
|
|
37
|
+
"950":"#3e1715"
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const orange = {
|
|
41
|
+
"050":"#fff3ea",
|
|
42
|
+
"100":"#ffe8d5",
|
|
43
|
+
"200":"#ffd1ab",
|
|
44
|
+
"300":"#ffba82",
|
|
45
|
+
"400":"#ffa359",
|
|
46
|
+
"500":"#fe8c2c",
|
|
47
|
+
"600":"#d47628",
|
|
48
|
+
"700":"#ac6023",
|
|
49
|
+
"800":"#854c1e",
|
|
50
|
+
"900":"#603819",
|
|
51
|
+
"950":"#3d2513"
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const yellow = {
|
|
55
|
+
"050": "#fff9ea",
|
|
56
|
+
"100": "#fff4d5",
|
|
57
|
+
"200": "#ffe9ab",
|
|
58
|
+
"300": "#ffde80",
|
|
59
|
+
"400": "#ffd452",
|
|
60
|
+
"500": "#ffca00",
|
|
61
|
+
"600": "#d5a910",
|
|
62
|
+
"700": "#ac8816",
|
|
63
|
+
"800": "#856a17",
|
|
64
|
+
"900": "#604c16",
|
|
65
|
+
"950": "#3d3112"
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
const green = {
|
|
69
|
+
"050": "#edf9ed",
|
|
70
|
+
"100": "#daf3db",
|
|
71
|
+
"200": "#b4e7b7",
|
|
72
|
+
"300": "#8cda94",
|
|
73
|
+
"400": "#5ecc71",
|
|
74
|
+
"500": "#0dbe4e",
|
|
75
|
+
"600": "#199f43",
|
|
76
|
+
"700": "#1d8138",
|
|
77
|
+
"800": "#1d642e",
|
|
78
|
+
"900": "#1b4923",
|
|
79
|
+
"950": "#162f19"
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
const mint = {
|
|
83
|
+
"050": "#edfaf7",
|
|
84
|
+
"100": "#dbf5ef",
|
|
85
|
+
"200": "#b7ebdf",
|
|
86
|
+
"300": "#8fe0d0",
|
|
87
|
+
"400": "#61d5c0",
|
|
88
|
+
"500": "#00cab1",
|
|
89
|
+
"600": "#16a994",
|
|
90
|
+
"700": "#1d8978",
|
|
91
|
+
"800": "#1e6a5e",
|
|
92
|
+
"900": "#1c4d44",
|
|
93
|
+
"950": "#16312c"
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
const teal = {
|
|
97
|
+
"050": "#eef9fa",
|
|
98
|
+
"100": "#ddf4f6",
|
|
99
|
+
"200": "#b9e8ed",
|
|
100
|
+
"300": "#92dde4",
|
|
101
|
+
"400": "#64d1db",
|
|
102
|
+
"500": "#00c5d2",
|
|
103
|
+
"600": "#17a5af",
|
|
104
|
+
"700": "#1e858e",
|
|
105
|
+
"800": "#1f686e",
|
|
106
|
+
"900": "#1d4b4f",
|
|
107
|
+
"950": "#173033"
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
const cyan = {
|
|
111
|
+
"050": "#eff9fe",
|
|
112
|
+
"100": "#def2fc",
|
|
113
|
+
"200": "#bce6f9",
|
|
114
|
+
"300": "#96d9f6",
|
|
115
|
+
"400": "#68cdf2",
|
|
116
|
+
"500": "#08c0ef",
|
|
117
|
+
"600": "#1ca1c7",
|
|
118
|
+
"700": "#2182a1",
|
|
119
|
+
"800": "#22657c",
|
|
120
|
+
"900": "#1e4959",
|
|
121
|
+
"950": "#182f38"
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
const blue = {
|
|
125
|
+
"050": "#eff5ff",
|
|
126
|
+
"100": "#dfebff",
|
|
127
|
+
"200": "#bdd7ff",
|
|
128
|
+
"300": "#97c4ff",
|
|
129
|
+
"400": "#69b1ff",
|
|
130
|
+
"500": "#009fff",
|
|
131
|
+
"600": "#1a85d4",
|
|
132
|
+
"700": "#216cab",
|
|
133
|
+
"800": "#215584",
|
|
134
|
+
"900": "#1f3e5e",
|
|
135
|
+
"950": "#19283c"
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
const indigo = {
|
|
139
|
+
"050": "#f5ecff",
|
|
140
|
+
"100": "#ead9ff",
|
|
141
|
+
"200": "#d3b4fe",
|
|
142
|
+
"300": "#ba8ffd",
|
|
143
|
+
"400": "#9d6afb",
|
|
144
|
+
"500": "#7b43f8",
|
|
145
|
+
"600": "#693acf",
|
|
146
|
+
"700": "#5731a7",
|
|
147
|
+
"800": "#462981",
|
|
148
|
+
"900": "#35205c",
|
|
149
|
+
"950": "#24173a"
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
const purple = {
|
|
153
|
+
"050": "#fbedfd",
|
|
154
|
+
"100": "#f7dbfb",
|
|
155
|
+
"200": "#eeb6f6",
|
|
156
|
+
"300": "#e290f0",
|
|
157
|
+
"400": "#d568ea",
|
|
158
|
+
"500": "#c635e4",
|
|
159
|
+
"600": "#a631be",
|
|
160
|
+
"700": "#872b9a",
|
|
161
|
+
"800": "#692677",
|
|
162
|
+
"900": "#4d1f56",
|
|
163
|
+
"950": "#321736"
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
const pink = {
|
|
167
|
+
"050": "#ffedf0",
|
|
168
|
+
"100": "#ffdbe1",
|
|
169
|
+
"200": "#ffb7c4",
|
|
170
|
+
"300": "#ff91a8",
|
|
171
|
+
"400": "#ff678d",
|
|
172
|
+
"500": "#fc2b73",
|
|
173
|
+
"600": "#d32a61",
|
|
174
|
+
"700": "#aa2850",
|
|
175
|
+
"800": "#84243f",
|
|
176
|
+
"900": "#5f1e2f",
|
|
177
|
+
"950": "#3d1720"
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
const brown = {
|
|
181
|
+
"050": "#f8f2ee",
|
|
182
|
+
"100": "#f1e4dd",
|
|
183
|
+
"200": "#e3cabb",
|
|
184
|
+
"300": "#d3b19b",
|
|
185
|
+
"400": "#c3987b",
|
|
186
|
+
"500": "#b27f5c",
|
|
187
|
+
"600": "#956b4f",
|
|
188
|
+
"700": "#7a5841",
|
|
189
|
+
"800": "#5f4534",
|
|
190
|
+
"900": "#453327",
|
|
191
|
+
"950": "#2d221b"
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
export type Roles = {
|
|
195
|
+
bg: {
|
|
196
|
+
editor: string; // main editor background (brightest in light, darkest in dark)
|
|
197
|
+
window: string; // sidebar, activity bar, status bar, title bar, inactive tabs
|
|
198
|
+
inset: string; // inputs, dropdowns
|
|
199
|
+
elevated: string; // panels, hover backgrounds
|
|
200
|
+
};
|
|
201
|
+
fg: { base: string; fg1: string; fg2: string; fg3: string; fg4: string };
|
|
202
|
+
border: {
|
|
203
|
+
window: string; // borders for sidebar, activity bar, status bar, title bar
|
|
204
|
+
editor: string; // general editor borders
|
|
205
|
+
indentGuide: string; // indent guide lines
|
|
206
|
+
indentGuideActive: string; // active indent guide line
|
|
207
|
+
inset: string; // borders for inputs, dropdowns
|
|
208
|
+
elevated: string; // borders for panels
|
|
209
|
+
};
|
|
210
|
+
accent: { primary: string; link: string; subtle: string; contrastOnAccent: string };
|
|
211
|
+
states: { merge: string, success: string; danger: string; warn: string; info: string };
|
|
212
|
+
syntax: {
|
|
213
|
+
comment: string; string: string; number: string; keyword: string;
|
|
214
|
+
regexp: string; func: string; type: string; variable: string;
|
|
215
|
+
// Extended token types
|
|
216
|
+
operator: string; punctuation: string; constant: string;
|
|
217
|
+
parameter: string; namespace: string; decorator: string;
|
|
218
|
+
escape: string; invalid: string; tag: string; attribute: string;
|
|
219
|
+
};
|
|
220
|
+
ansi: {
|
|
221
|
+
black: string; red: string; green: string; yellow: string;
|
|
222
|
+
blue: string; magenta: string; cyan: string; white: string;
|
|
223
|
+
brightBlack: string; brightRed: string; brightGreen: string; brightYellow: string;
|
|
224
|
+
brightBlue: string; brightMagenta: string; brightCyan: string; brightWhite: string;
|
|
225
|
+
};
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
export const light: Roles = {
|
|
229
|
+
bg: {
|
|
230
|
+
editor: "#ffffff",
|
|
231
|
+
window: gray["060"],
|
|
232
|
+
inset: gray["080"],
|
|
233
|
+
elevated: gray["040"]
|
|
234
|
+
},
|
|
235
|
+
fg: {
|
|
236
|
+
base: gray["1040"],
|
|
237
|
+
fg1: gray["900"],
|
|
238
|
+
fg2: gray["800"],
|
|
239
|
+
fg3: gray["600"],
|
|
240
|
+
fg4: gray["500"]
|
|
241
|
+
},
|
|
242
|
+
border: {
|
|
243
|
+
window: gray["100"],
|
|
244
|
+
editor: gray["200"],
|
|
245
|
+
indentGuide: gray["100"],
|
|
246
|
+
indentGuideActive: gray["200"],
|
|
247
|
+
inset: gray["200"],
|
|
248
|
+
elevated: gray["100"]
|
|
249
|
+
},
|
|
250
|
+
accent: {
|
|
251
|
+
primary: blue["500"],
|
|
252
|
+
link: blue["500"],
|
|
253
|
+
subtle: blue["100"],
|
|
254
|
+
contrastOnAccent: "#ffffff"
|
|
255
|
+
},
|
|
256
|
+
states: {
|
|
257
|
+
merge: indigo["500"],
|
|
258
|
+
success: mint["500"],
|
|
259
|
+
danger: red["500"],
|
|
260
|
+
warn: yellow["500"],
|
|
261
|
+
info: cyan["500"]
|
|
262
|
+
},
|
|
263
|
+
syntax: {
|
|
264
|
+
comment: gray["600"],
|
|
265
|
+
string: green["600"],
|
|
266
|
+
number: cyan["600"],
|
|
267
|
+
keyword: pink["500"],
|
|
268
|
+
regexp: teal["600"],
|
|
269
|
+
func: indigo["500"],
|
|
270
|
+
type: purple["500"],
|
|
271
|
+
variable: orange["600"],
|
|
272
|
+
// Extended token types
|
|
273
|
+
operator: cyan["500"],
|
|
274
|
+
punctuation: gray["700"],
|
|
275
|
+
constant: yellow["600"],
|
|
276
|
+
parameter: gray["700"],
|
|
277
|
+
namespace: yellow["600"],
|
|
278
|
+
decorator: blue["500"],
|
|
279
|
+
escape: cyan["600"],
|
|
280
|
+
invalid: "#ffffff",
|
|
281
|
+
tag: red["600"],
|
|
282
|
+
attribute: mint["600"]
|
|
283
|
+
},
|
|
284
|
+
ansi: {
|
|
285
|
+
black: gray["980"],
|
|
286
|
+
red: red["500"],
|
|
287
|
+
green: green["500"],
|
|
288
|
+
yellow: yellow["500"],
|
|
289
|
+
blue: blue["500"],
|
|
290
|
+
magenta: purple["500"],
|
|
291
|
+
cyan: cyan["500"],
|
|
292
|
+
white: gray["300"],
|
|
293
|
+
// make bright colors match the non-bright counterparts
|
|
294
|
+
brightBlack: gray["980"],
|
|
295
|
+
brightRed: red["500"],
|
|
296
|
+
brightGreen: green["500"],
|
|
297
|
+
brightYellow: yellow["500"],
|
|
298
|
+
brightBlue: blue["500"],
|
|
299
|
+
brightMagenta: purple["500"],
|
|
300
|
+
brightCyan: cyan["500"],
|
|
301
|
+
brightWhite: gray["300"]
|
|
302
|
+
}
|
|
303
|
+
};
|
|
304
|
+
|
|
305
|
+
export const dark: Roles = {
|
|
306
|
+
bg: {
|
|
307
|
+
editor: gray["1040"],
|
|
308
|
+
window: gray["1000"],
|
|
309
|
+
inset: gray["980"],
|
|
310
|
+
elevated: gray["1020"]
|
|
311
|
+
},
|
|
312
|
+
fg: {
|
|
313
|
+
base: gray["020"],
|
|
314
|
+
fg1: gray["200"],
|
|
315
|
+
fg2: gray["400"],
|
|
316
|
+
fg3: gray["600"],
|
|
317
|
+
fg4: gray["700"]
|
|
318
|
+
},
|
|
319
|
+
border: {
|
|
320
|
+
window: gray["1040"],
|
|
321
|
+
editor: gray["920"],
|
|
322
|
+
indentGuide: gray["940"],
|
|
323
|
+
indentGuideActive: gray["960"],
|
|
324
|
+
inset: gray["920"],
|
|
325
|
+
elevated: gray["960"]
|
|
326
|
+
},
|
|
327
|
+
accent: {
|
|
328
|
+
primary: blue["500"],
|
|
329
|
+
link: blue["500"],
|
|
330
|
+
subtle: blue["950"],
|
|
331
|
+
contrastOnAccent: gray["1040"]
|
|
332
|
+
},
|
|
333
|
+
states: {
|
|
334
|
+
merge: indigo["500"],
|
|
335
|
+
success: mint["500"],
|
|
336
|
+
danger: red["500"],
|
|
337
|
+
warn: yellow["500"],
|
|
338
|
+
info: cyan["500"]
|
|
339
|
+
},
|
|
340
|
+
syntax: {
|
|
341
|
+
comment: gray["600"],
|
|
342
|
+
string: green["400"],
|
|
343
|
+
number: cyan["400"],
|
|
344
|
+
keyword: pink["400"],
|
|
345
|
+
regexp: teal["400"],
|
|
346
|
+
func: indigo["400"],
|
|
347
|
+
type: purple["400"],
|
|
348
|
+
variable: orange["400"],
|
|
349
|
+
// Extended token types
|
|
350
|
+
operator: cyan["500"],
|
|
351
|
+
punctuation: gray["700"],
|
|
352
|
+
constant: yellow["400"],
|
|
353
|
+
parameter: gray["400"],
|
|
354
|
+
namespace: yellow["500"],
|
|
355
|
+
decorator: blue["400"],
|
|
356
|
+
escape: cyan["400"],
|
|
357
|
+
invalid: "#ffffff",
|
|
358
|
+
tag: red["400"],
|
|
359
|
+
attribute: mint["400"]
|
|
360
|
+
},
|
|
361
|
+
ansi: {
|
|
362
|
+
black: gray["1000"],
|
|
363
|
+
red: red["500"],
|
|
364
|
+
green: green["500"],
|
|
365
|
+
yellow: yellow["500"],
|
|
366
|
+
blue: blue["500"],
|
|
367
|
+
magenta: purple["500"],
|
|
368
|
+
cyan: cyan["500"],
|
|
369
|
+
white: gray["300"],
|
|
370
|
+
brightBlack: gray["1000"],
|
|
371
|
+
brightRed: red["500"],
|
|
372
|
+
brightGreen: green["500"],
|
|
373
|
+
brightYellow: yellow["500"],
|
|
374
|
+
brightBlue: blue["500"],
|
|
375
|
+
brightMagenta: purple["500"],
|
|
376
|
+
brightCyan: cyan["500"],
|
|
377
|
+
brightWhite: gray["300"]
|
|
378
|
+
}
|
|
379
|
+
};
|