@diagrammo/dgmo 0.0.1

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.
@@ -0,0 +1,220 @@
1
+ import type { PaletteColors } from './types';
2
+ import { mute, tint, shade, contrastText } from './color-utils';
3
+
4
+ // ============================================================
5
+ // Mermaid Theme Variable Generator
6
+ // ============================================================
7
+
8
+ /**
9
+ * Generates ~121 Mermaid theme variables from palette tokens.
10
+ * Replaces the hardcoded lightThemeVars/darkThemeVars objects.
11
+ *
12
+ * Dark mode fills use `mute()` to derive desaturated variants
13
+ * that are readable with light text.
14
+ */
15
+ export function buildMermaidThemeVars(
16
+ colors: PaletteColors,
17
+ isDark: boolean
18
+ ): Record<string, string> {
19
+ const c = colors.colors;
20
+
21
+ // Ordered accent array for pie/cScale/fillType/actor slots
22
+ const accentOrder = [
23
+ c.blue,
24
+ c.red,
25
+ c.green,
26
+ c.yellow,
27
+ c.purple,
28
+ c.orange,
29
+ c.teal,
30
+ c.cyan,
31
+ colors.secondary,
32
+ ];
33
+
34
+ // Dark mode fills use muted variants for readability
35
+ const fills = isDark ? accentOrder.map(mute) : accentOrder;
36
+
37
+ return {
38
+ // ── Backgrounds ──
39
+ background: isDark ? colors.overlay : colors.border,
40
+ mainBkg: colors.surface,
41
+
42
+ // ── Primary/Secondary/Tertiary nodes ──
43
+ primaryColor: isDark ? colors.primary : colors.surface,
44
+ primaryTextColor: colors.text,
45
+ primaryBorderColor: isDark ? colors.secondary : colors.border,
46
+ secondaryColor: colors.secondary,
47
+ secondaryTextColor: contrastText(colors.secondary, colors.text, colors.bg),
48
+ secondaryBorderColor: colors.primary,
49
+ tertiaryColor: colors.accent,
50
+ tertiaryTextColor: contrastText(colors.accent, colors.text, colors.bg),
51
+ tertiaryBorderColor: colors.border,
52
+
53
+ // ── Lines & text ──
54
+ lineColor: colors.textMuted,
55
+ textColor: colors.text,
56
+
57
+ // ── Clusters ──
58
+ clusterBkg: colors.bg,
59
+ clusterBorder: isDark ? colors.border : colors.textMuted,
60
+ titleColor: colors.text,
61
+
62
+ // ── Labels ──
63
+ edgeLabelBackground: 'transparent',
64
+
65
+ // ── Notes (sequence diagrams) ──
66
+ noteBkgColor: colors.bg,
67
+ noteTextColor: colors.text,
68
+ noteBorderColor: isDark ? colors.border : colors.textMuted,
69
+
70
+ // ── Actors (sequence diagrams) ──
71
+ actorBkg: colors.surface,
72
+ actorTextColor: colors.text,
73
+ actorBorder: isDark ? colors.border : colors.textMuted,
74
+ actorLineColor: colors.textMuted,
75
+
76
+ // ── Signals (sequence diagrams) ──
77
+ signalColor: colors.textMuted,
78
+ signalTextColor: colors.text,
79
+
80
+ // ── Labels ──
81
+ labelColor: colors.text,
82
+ labelTextColor: colors.text,
83
+ labelBoxBkgColor: colors.surface,
84
+ labelBoxBorderColor: isDark ? colors.border : colors.textMuted,
85
+
86
+ // ── Loop boxes ──
87
+ loopTextColor: colors.text,
88
+
89
+ // ── Activation (sequence diagrams) ──
90
+ activationBkgColor: isDark ? colors.overlay : colors.border,
91
+ activationBorderColor: isDark ? colors.border : colors.textMuted,
92
+
93
+ // ── Sequence numbers ──
94
+ sequenceNumberColor: isDark ? colors.text : colors.bg,
95
+
96
+ // ── State diagrams ──
97
+ labelBackgroundColor: colors.surface,
98
+
99
+ // ── Pie chart (9 slices) ──
100
+ // Dark mode: use muted fills so light pieSectionTextColor stays readable
101
+ ...Object.fromEntries(
102
+ (isDark ? fills : accentOrder).map((col, i) => [`pie${i + 1}`, col])
103
+ ),
104
+ pieTitleTextColor: colors.text,
105
+ pieSectionTextColor: isDark ? colors.text : colors.bg,
106
+ pieLegendTextColor: colors.text,
107
+ pieStrokeColor: 'transparent',
108
+ pieOuterStrokeWidth: '0px',
109
+ pieOuterStrokeColor: 'transparent',
110
+
111
+ // ── cScale (9 tiers) — muted in dark mode ──
112
+ ...Object.fromEntries(fills.map((f, i) => [`cScale${i}`, f])),
113
+ ...Object.fromEntries(
114
+ fills.map((_, i) => [
115
+ `cScaleLabel${i}`,
116
+ isDark ? colors.text : i < 2 || i > 6 ? colors.bg : colors.text,
117
+ ])
118
+ ),
119
+
120
+ // ── fillType (8 slots) ──
121
+ ...Object.fromEntries(
122
+ [0, 1, 2, 3, 4, 5, 6, 7].map((i) => [
123
+ `fillType${i}`,
124
+ fills[i % fills.length],
125
+ ])
126
+ ),
127
+
128
+ // ── Journey actors (6 slots) ──
129
+ ...Object.fromEntries(
130
+ [c.red, c.green, c.yellow, c.purple, c.orange, c.teal].map((color, i) => [
131
+ `actor${i}`,
132
+ color,
133
+ ])
134
+ ),
135
+
136
+ // ── Flowchart ──
137
+ nodeBorder: isDark ? colors.border : colors.textMuted,
138
+ nodeTextColor: colors.text,
139
+
140
+ // ── Gantt ──
141
+ gridColor: isDark ? colors.textMuted : colors.border,
142
+ doneTaskBkgColor: c.green,
143
+ doneTaskBorderColor: isDark ? colors.border : colors.textMuted,
144
+ activeTaskBkgColor: colors.secondary,
145
+ activeTaskBorderColor: colors.primary,
146
+ critBkgColor: c.orange,
147
+ critBorderColor: c.red,
148
+ taskBkgColor: colors.surface,
149
+ taskBorderColor: isDark ? colors.border : colors.textMuted,
150
+ taskTextColor: contrastText(colors.surface, colors.text, colors.bg),
151
+ taskTextDarkColor: colors.bg,
152
+ taskTextLightColor: colors.text,
153
+ taskTextOutsideColor: colors.text,
154
+ doneTaskTextColor: contrastText(c.green, colors.text, colors.bg),
155
+ activeTaskTextColor: contrastText(colors.secondary, colors.text, colors.bg),
156
+ critTaskTextColor: contrastText(c.orange, colors.text, colors.bg),
157
+ sectionBkgColor: isDark
158
+ ? shade(colors.primary, colors.bg, 0.6)
159
+ : tint(colors.primary, 0.6),
160
+ altSectionBkgColor: colors.bg,
161
+ sectionBkgColor2: isDark
162
+ ? shade(colors.primary, colors.bg, 0.6)
163
+ : tint(colors.primary, 0.6),
164
+ todayLineColor: c.yellow,
165
+
166
+ // ── Quadrant ──
167
+ quadrant1Fill: isDark
168
+ ? shade(c.green, colors.bg, 0.75)
169
+ : tint(c.green, 0.75),
170
+ quadrant2Fill: isDark ? shade(c.blue, colors.bg, 0.75) : tint(c.blue, 0.75),
171
+ quadrant3Fill: isDark ? shade(c.red, colors.bg, 0.75) : tint(c.red, 0.75),
172
+ quadrant4Fill: isDark
173
+ ? shade(c.yellow, colors.bg, 0.75)
174
+ : tint(c.yellow, 0.75),
175
+ quadrant1TextFill: colors.text,
176
+ quadrant2TextFill: colors.text,
177
+ quadrant3TextFill: colors.text,
178
+ quadrant4TextFill: colors.text,
179
+ quadrantPointFill: isDark ? c.cyan : c.blue,
180
+ quadrantPointTextFill: colors.text,
181
+ quadrantXAxisTextFill: colors.text,
182
+ quadrantYAxisTextFill: colors.text,
183
+ quadrantTitleFill: colors.text,
184
+ quadrantInternalBorderStrokeFill: colors.border,
185
+ quadrantExternalBorderStrokeFill: colors.border,
186
+ };
187
+ }
188
+
189
+ // ============================================================
190
+ // Mermaid Theme CSS Generator
191
+ // ============================================================
192
+
193
+ /**
194
+ * Generates custom CSS overrides for Mermaid SVGs.
195
+ * Handles git graph label backgrounds and dark-mode text readability.
196
+ */
197
+ export function buildThemeCSS(palette: PaletteColors, isDark: boolean): string {
198
+ const base = `
199
+ .branchLabelBkg { fill: transparent !important; stroke: transparent !important; }
200
+ .commit-label-bkg { fill: transparent !important; stroke: transparent !important; }
201
+ .tag-label-bkg { fill: transparent !important; stroke: transparent !important; }
202
+
203
+ /* GitGraph: ensure commit and branch label text matches palette */
204
+ .commit-label { fill: ${palette.text} !important; }
205
+ .branch-label { fill: ${palette.text} !important; }
206
+ .tag-label { fill: ${palette.text} !important; }
207
+ `;
208
+
209
+ if (!isDark) return base;
210
+
211
+ return (
212
+ base +
213
+ `
214
+ /* Flowchart: ensure node and edge label text is readable */
215
+ .nodeLabel, .label { color: ${palette.text} !important; fill: ${palette.text} !important; }
216
+ .edgeLabel { color: ${palette.text} !important; fill: ${palette.text} !important; }
217
+ .edgeLabel .label { color: ${palette.text} !important; fill: ${palette.text} !important; }
218
+ `
219
+ );
220
+ }
@@ -0,0 +1,59 @@
1
+ import type { PaletteConfig } from './types';
2
+ import { registerPalette } from './registry';
3
+
4
+ // ============================================================
5
+ // Nord Palette Definition
6
+ // ============================================================
7
+
8
+ export const nordPalette: PaletteConfig = {
9
+ id: 'nord',
10
+ name: 'Nord',
11
+ light: {
12
+ bg: '#eceff4', // nord6
13
+ surface: '#e5e9f0', // nord5
14
+ overlay: '#d8dee9', // nord4 (muted/secondary backgrounds)
15
+ border: '#d8dee9', // nord4
16
+ text: '#2e3440', // nord0
17
+ textMuted: '#4c566a', // nord3
18
+ primary: '#5e81ac', // nord10
19
+ secondary: '#81a1c1', // nord9
20
+ accent: '#81a1c1', // nord9
21
+ destructive: '#bf616a', // nord11
22
+ colors: {
23
+ red: '#bf616a', // nord11
24
+ orange: '#d08770', // nord12
25
+ yellow: '#ebcb8b', // nord13
26
+ green: '#a3be8c', // nord14
27
+ blue: '#5e81ac', // nord10
28
+ purple: '#b48ead', // nord15
29
+ teal: '#8fbcbb', // nord7
30
+ cyan: '#88c0d0', // nord8
31
+ gray: '#4c566a', // nord3
32
+ },
33
+ },
34
+ dark: {
35
+ bg: '#2e3440', // nord0
36
+ surface: '#3b4252', // nord1
37
+ overlay: '#434c5e', // nord2
38
+ border: '#4c566a', // nord3
39
+ text: '#eceff4', // nord6
40
+ textMuted: '#d8dee9', // nord4
41
+ primary: '#88c0d0', // nord8 (different from light's nord10)
42
+ secondary: '#81a1c1', // nord9
43
+ accent: '#81a1c1', // nord9
44
+ destructive: '#bf616a', // nord11
45
+ colors: {
46
+ red: '#bf616a', // nord11
47
+ orange: '#d08770', // nord12
48
+ yellow: '#ebcb8b', // nord13
49
+ green: '#a3be8c', // nord14
50
+ blue: '#5e81ac', // nord10
51
+ purple: '#b48ead', // nord15
52
+ teal: '#8fbcbb', // nord7
53
+ cyan: '#88c0d0', // nord8
54
+ gray: '#4c566a', // nord3
55
+ },
56
+ },
57
+ };
58
+
59
+ registerPalette(nordPalette);
@@ -0,0 +1,62 @@
1
+ import type { PaletteConfig } from './types';
2
+ import { registerPalette } from './registry';
3
+
4
+ // ============================================================
5
+ // One Dark Palette Definition
6
+ // Based on Atom's One Dark theme
7
+ // ============================================================
8
+
9
+ export const oneDarkPalette: PaletteConfig = {
10
+ id: 'one-dark',
11
+ name: 'One Dark',
12
+ light: {
13
+ // One Light variant (Atom's light counterpart)
14
+ bg: '#fafafa',
15
+ surface: '#f0f0f0',
16
+ overlay: '#e5e5e5',
17
+ border: '#d0d0d0',
18
+ text: '#383a42',
19
+ textMuted: '#696c77',
20
+ primary: '#4078f2',
21
+ secondary: '#a626a4',
22
+ accent: '#0184bc',
23
+ destructive: '#e45649',
24
+ colors: {
25
+ red: '#e45649',
26
+ orange: '#c18401',
27
+ yellow: '#c18401',
28
+ green: '#50a14f',
29
+ blue: '#4078f2',
30
+ purple: '#a626a4',
31
+ teal: '#0184bc',
32
+ cyan: '#0997b3',
33
+ gray: '#696c77',
34
+ },
35
+ },
36
+ dark: {
37
+ // One Dark (Atom's dark theme)
38
+ bg: '#282c34',
39
+ surface: '#21252b',
40
+ overlay: '#2c313a',
41
+ border: '#3e4451',
42
+ text: '#abb2bf',
43
+ textMuted: '#5c6370',
44
+ primary: '#61afef',
45
+ secondary: '#c678dd',
46
+ accent: '#56b6c2',
47
+ destructive: '#e06c75',
48
+ colors: {
49
+ red: '#e06c75',
50
+ orange: '#d19a66',
51
+ yellow: '#e5c07b',
52
+ green: '#98c379',
53
+ blue: '#61afef',
54
+ purple: '#c678dd',
55
+ teal: '#56b6c2',
56
+ cyan: '#56b6c2',
57
+ gray: '#5c6370',
58
+ },
59
+ },
60
+ };
61
+
62
+ registerPalette(oneDarkPalette);
@@ -0,0 +1,92 @@
1
+ import type { PaletteConfig, PaletteColors } from './types';
2
+
3
+ // ============================================================
4
+ // Constants
5
+ // ============================================================
6
+
7
+ const PALETTE_REGISTRY = new Map<string, PaletteConfig>();
8
+ const DEFAULT_PALETTE_ID = 'nord';
9
+
10
+ // ============================================================
11
+ // Validation
12
+ // ============================================================
13
+
14
+ /** Validate that a hex string is well-formed (#RGB or #RRGGBB). */
15
+ export function isValidHex(value: string): boolean {
16
+ return /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/.test(value);
17
+ }
18
+
19
+ /** Named color keys that must be present in PaletteColors.colors. */
20
+ const COLOR_KEYS: (keyof PaletteColors['colors'])[] = [
21
+ 'red',
22
+ 'orange',
23
+ 'yellow',
24
+ 'green',
25
+ 'blue',
26
+ 'purple',
27
+ 'teal',
28
+ 'cyan',
29
+ 'gray',
30
+ ];
31
+
32
+ /** Semantic color keys that must be present at the top level of PaletteColors. */
33
+ const SEMANTIC_KEYS: (keyof Omit<PaletteColors, 'colors'>)[] = [
34
+ 'bg',
35
+ 'surface',
36
+ 'overlay',
37
+ 'border',
38
+ 'text',
39
+ 'textMuted',
40
+ 'primary',
41
+ 'secondary',
42
+ 'accent',
43
+ 'destructive',
44
+ ];
45
+
46
+ function validatePaletteColors(
47
+ colors: PaletteColors,
48
+ mode: string,
49
+ paletteId: string
50
+ ): void {
51
+ for (const key of SEMANTIC_KEYS) {
52
+ const value = colors[key];
53
+ if (typeof value !== 'string' || !isValidHex(value)) {
54
+ throw new Error(
55
+ `Palette "${paletteId}" ${mode}.${key}: invalid hex "${value}"`
56
+ );
57
+ }
58
+ }
59
+ for (const key of COLOR_KEYS) {
60
+ const value = colors.colors[key];
61
+ if (typeof value !== 'string' || !isValidHex(value)) {
62
+ throw new Error(
63
+ `Palette "${paletteId}" ${mode}.colors.${key}: invalid hex "${value}"`
64
+ );
65
+ }
66
+ }
67
+ }
68
+
69
+ // ============================================================
70
+ // Registry Functions
71
+ // ============================================================
72
+
73
+ /**
74
+ * Register a palette. Called at module initialization.
75
+ * Validates that all 19 color fields per mode are present and valid hex.
76
+ * Throws on malformed palettes to catch errors at startup, not at render time.
77
+ */
78
+ export function registerPalette(palette: PaletteConfig): void {
79
+ validatePaletteColors(palette.light, 'light', palette.id);
80
+ validatePaletteColors(palette.dark, 'dark', palette.id);
81
+ PALETTE_REGISTRY.set(palette.id, palette);
82
+ }
83
+
84
+ /** Get palette by id. Returns Nord if id is unrecognized (FR10). */
85
+ export function getPalette(id: string): PaletteConfig {
86
+ return PALETTE_REGISTRY.get(id) ?? PALETTE_REGISTRY.get(DEFAULT_PALETTE_ID)!;
87
+ }
88
+
89
+ /** List all registered palettes (for the selector UI). */
90
+ export function getAvailablePalettes(): PaletteConfig[] {
91
+ return Array.from(PALETTE_REGISTRY.values());
92
+ }
@@ -0,0 +1,76 @@
1
+ import type { PaletteConfig } from './types';
2
+ import { registerPalette } from './registry';
3
+
4
+ // ============================================================
5
+ // Rosé Pine Palette Definition
6
+ // ============================================================
7
+
8
+ // Official Rosé Pine colors: https://rosepinetheme.com/palette
9
+ //
10
+ // Dawn (light):
11
+ // Base #faf4ed | Surface #fffaf3 | Overlay #f2e9e1
12
+ // Muted #9893a5 | Subtle #797593 | Text #575279
13
+ // Highlight Med #dfdad9
14
+ //
15
+ // Moon (dark):
16
+ // Base #232136 | Surface #2a273f | Overlay #393552
17
+ // Muted #6e6a86 | Subtle #908caa | Text #e0def4
18
+ // Highlight Med #44415a
19
+ //
20
+ // Accents (Dawn / Moon):
21
+ // Love #b4637a / #eb6f92 | Gold #ea9d34 / #f6c177
22
+ // Rose #d7827e / #ea9a97 | Pine #286983 / #3e8fb0
23
+ // Foam #56949f / #9ccfd8 | Iris #907aa9 / #c4a7e7
24
+
25
+ export const rosePinePalette: PaletteConfig = {
26
+ id: 'rose-pine',
27
+ name: 'Rosé Pine',
28
+ light: {
29
+ bg: '#faf4ed', // Dawn Base
30
+ surface: '#fffaf3', // Dawn Surface
31
+ overlay: '#f2e9e1', // Dawn Overlay
32
+ border: '#dfdad9', // Dawn Highlight Med
33
+ text: '#575279', // Dawn Text
34
+ textMuted: '#9893a5', // Dawn Muted
35
+ primary: '#286983', // Dawn Pine
36
+ secondary: '#56949f', // Dawn Foam
37
+ accent: '#907aa9', // Dawn Iris
38
+ destructive: '#b4637a', // Dawn Love
39
+ colors: {
40
+ red: '#b4637a', // Love
41
+ orange: '#d7827e', // Rose
42
+ yellow: '#ea9d34', // Gold
43
+ green: '#286983', // Pine
44
+ blue: '#56949f', // Foam
45
+ purple: '#907aa9', // Iris
46
+ teal: '#286983', // Pine
47
+ cyan: '#56949f', // Foam
48
+ gray: '#9893a5', // Muted
49
+ },
50
+ },
51
+ dark: {
52
+ bg: '#232136', // Moon Base
53
+ surface: '#2a273f', // Moon Surface
54
+ overlay: '#393552', // Moon Overlay
55
+ border: '#44415a', // Moon Highlight Med
56
+ text: '#e0def4', // Moon Text
57
+ textMuted: '#908caa', // Moon Subtle
58
+ primary: '#3e8fb0', // Moon Pine
59
+ secondary: '#9ccfd8', // Moon Foam
60
+ accent: '#c4a7e7', // Moon Iris
61
+ destructive: '#eb6f92', // Moon Love
62
+ colors: {
63
+ red: '#eb6f92', // Love
64
+ orange: '#ea9a97', // Rose
65
+ yellow: '#f6c177', // Gold
66
+ green: '#3e8fb0', // Pine
67
+ blue: '#9ccfd8', // Foam
68
+ purple: '#c4a7e7', // Iris
69
+ teal: '#3e8fb0', // Pine
70
+ cyan: '#9ccfd8', // Foam
71
+ gray: '#6e6a86', // Muted
72
+ },
73
+ },
74
+ };
75
+
76
+ registerPalette(rosePinePalette);
@@ -0,0 +1,69 @@
1
+ import type { PaletteConfig } from './types';
2
+ import { registerPalette } from './registry';
3
+
4
+ // ============================================================
5
+ // Solarized Palette Definition
6
+ // ============================================================
7
+
8
+ // Official Solarized colors: https://ethanschoonover.com/solarized/
9
+ //
10
+ // Base tones:
11
+ // base03 #002b36 | base02 #073642 | base01 #586e75 | base00 #657b83
12
+ // base0 #839496 | base1 #93a1a1 | base2 #eee8d5 | base3 #fdf6e3
13
+ //
14
+ // Accent colors:
15
+ // yellow #b58900 | orange #cb4b16 | red #dc322f | magenta #d33682
16
+ // violet #6c71c4 | blue #268bd2 | cyan #2aa198 | green #859900
17
+
18
+ export const solarizedPalette: PaletteConfig = {
19
+ id: 'solarized',
20
+ name: 'Solarized',
21
+ light: {
22
+ bg: '#fdf6e3', // base3
23
+ surface: '#eee8d5', // base2
24
+ overlay: '#eee8d5', // base2 (muted/secondary backgrounds)
25
+ border: '#93a1a1', // base1
26
+ text: '#657b83', // base00
27
+ textMuted: '#93a1a1', // base1
28
+ primary: '#268bd2', // blue
29
+ secondary: '#2aa198', // cyan
30
+ accent: '#6c71c4', // violet
31
+ destructive: '#dc322f', // red
32
+ colors: {
33
+ red: '#dc322f',
34
+ orange: '#cb4b16',
35
+ yellow: '#b58900',
36
+ green: '#859900',
37
+ blue: '#268bd2',
38
+ purple: '#6c71c4',
39
+ teal: '#2aa198',
40
+ cyan: '#2aa198', // Solarized has no separate cyan — reuse teal
41
+ gray: '#586e75', // base01
42
+ },
43
+ },
44
+ dark: {
45
+ bg: '#002b36', // base03
46
+ surface: '#073642', // base02
47
+ overlay: '#073642', // base02 (muted/secondary backgrounds)
48
+ border: '#586e75', // base01
49
+ text: '#839496', // base0
50
+ textMuted: '#586e75', // base01
51
+ primary: '#268bd2', // blue
52
+ secondary: '#2aa198', // cyan
53
+ accent: '#6c71c4', // violet
54
+ destructive: '#dc322f', // red
55
+ colors: {
56
+ red: '#dc322f',
57
+ orange: '#cb4b16',
58
+ yellow: '#b58900',
59
+ green: '#859900',
60
+ blue: '#268bd2',
61
+ purple: '#6c71c4',
62
+ teal: '#2aa198',
63
+ cyan: '#2aa198',
64
+ gray: '#586e75', // base01
65
+ },
66
+ },
67
+ };
68
+
69
+ registerPalette(solarizedPalette);
@@ -0,0 +1,78 @@
1
+ import type { PaletteConfig } from './types';
2
+ import { registerPalette } from './registry';
3
+
4
+ // ============================================================
5
+ // Tokyo Night Palette Definition
6
+ // ============================================================
7
+
8
+ // Official Tokyo Night colors: https://github.com/folke/tokyonight.nvim
9
+ //
10
+ // Night (dark):
11
+ // bg #1a1b26 | bg_highlight #292e42 | terminal_black #414868
12
+ // fg_gutter #3b4261 | fg #c0caf5 | fg_dark #a9b1d6
13
+ // comment #565f89
14
+ //
15
+ // Day (light):
16
+ // bg #e1e2e7 | bg_float #d0d5e3 | bg_highlight #c4c8da
17
+ // fg_gutter #a8aecb | fg #3760bf | fg_dark #6172b0
18
+ // dark3 #8990b3
19
+ //
20
+ // Accents (Day / Night):
21
+ // Red #f52a65 / #f7768e | Orange #b15c00 / #ff9e64
22
+ // Yellow #8c6c3e / #e0af68 | Green #587539 / #9ece6a
23
+ // Blue #2e7de9 / #7aa2f7 | Purple #7847bd / #bb9af7
24
+ // Teal #118c74 / #1abc9c | Cyan #007197 / #7dcfff
25
+ // Magenta #9854f1 / #bb9af7
26
+
27
+ export const tokyoNightPalette: PaletteConfig = {
28
+ id: 'tokyo-night',
29
+ name: 'Tokyo Night',
30
+ light: {
31
+ bg: '#e1e2e7', // Day bg
32
+ surface: '#d0d5e3', // Day bg_float
33
+ overlay: '#c4c8da', // Day bg_highlight
34
+ border: '#a8aecb', // Day fg_gutter
35
+ text: '#3760bf', // Day fg
36
+ textMuted: '#6172b0', // Day fg_dark
37
+ primary: '#2e7de9', // Day blue
38
+ secondary: '#007197', // Day cyan
39
+ accent: '#9854f1', // Day magenta
40
+ destructive: '#f52a65', // Day red
41
+ colors: {
42
+ red: '#f52a65',
43
+ orange: '#b15c00',
44
+ yellow: '#8c6c3e',
45
+ green: '#587539',
46
+ blue: '#2e7de9',
47
+ purple: '#7847bd',
48
+ teal: '#118c74',
49
+ cyan: '#007197',
50
+ gray: '#8990b3', // Day dark3
51
+ },
52
+ },
53
+ dark: {
54
+ bg: '#1a1b26', // Night bg
55
+ surface: '#292e42', // Night bg_highlight
56
+ overlay: '#414868', // Night terminal_black
57
+ border: '#3b4261', // Night fg_gutter
58
+ text: '#c0caf5', // Night fg
59
+ textMuted: '#a9b1d6', // Night fg_dark
60
+ primary: '#7aa2f7', // Night blue
61
+ secondary: '#7dcfff', // Night cyan
62
+ accent: '#bb9af7', // Night magenta
63
+ destructive: '#f7768e', // Night red
64
+ colors: {
65
+ red: '#f7768e',
66
+ orange: '#ff9e64',
67
+ yellow: '#e0af68',
68
+ green: '#9ece6a',
69
+ blue: '#7aa2f7',
70
+ purple: '#bb9af7',
71
+ teal: '#1abc9c',
72
+ cyan: '#7dcfff',
73
+ gray: '#565f89', // Night comment
74
+ },
75
+ },
76
+ };
77
+
78
+ registerPalette(tokyoNightPalette);