1use super::types::{AppTheme, Rgb};
9
10pub const THEME_NAMES: &[&str] = &[
14 "Default",
15 "Grape",
16 "Ocean",
17 "Sunset",
18 "Forest",
19 "Rose",
20 "Mono",
21 "Neon",
22 "Dracula",
23 "Nord",
24 "Solarized Dark",
25 "Solarized Light",
26 "Gruvbox Dark",
27 "Gruvbox Light",
28 "Catppuccin Latte",
29 "Catppuccin Frappé",
30 "Catppuccin Macchiato",
31 "Catppuccin Mocha",
32 "Tokyo Night",
33 "Tokyo Night Storm",
34 "Tokyo Night Light",
35 "Kanagawa Wave",
36 "Kanagawa Dragon",
37 "Kanagawa Lotus",
38 "Moonfly",
39 "Nightfly",
40 "Oxocarbon",
41 "Cyberpunk",
42];
43
44pub const THEME_COUNT: usize = 28;
46
47pub fn theme_by_index(index: usize) -> AppTheme {
49 match index {
50 0 => default(),
51 1 => grape(),
52 2 => ocean(),
53 3 => sunset(),
54 4 => forest(),
55 5 => rose(),
56 6 => mono(),
57 7 => neon(),
58 8 => dracula(),
59 9 => nord(),
60 10 => solarized_dark(),
61 11 => solarized_light(),
62 12 => gruvbox_dark(),
63 13 => gruvbox_light(),
64 14 => catppuccin_latte(),
65 15 => catppuccin_frappe(),
66 16 => catppuccin_macchiato(),
67 17 => catppuccin_mocha(),
68 18 => tokyo_night(),
69 19 => tokyo_night_storm(),
70 20 => tokyo_night_light(),
71 21 => kanagawa_wave(),
72 22 => kanagawa_dragon(),
73 23 => kanagawa_lotus(),
74 24 => moonfly(),
75 25 => nightfly(),
76 26 => oxocarbon(),
77 27 => cyberpunk(),
78 _ => default(),
79 }
80}
81
82pub fn theme_index_by_name(name: &str) -> usize {
85 THEME_NAMES
86 .iter()
87 .position(|n| n.eq_ignore_ascii_case(name))
88 .unwrap_or(0)
89}
90
91pub fn default() -> AppTheme {
94 AppTheme {
95 is_dark: true,
96 background: Rgb::new(13, 17, 23),
97 surface: Rgb::new(22, 27, 34),
98 border: Rgb::new(48, 54, 61),
99 selection: Rgb::new(40, 60, 80),
100 text_primary: Rgb::new(230, 237, 243),
101 text_secondary: Rgb::new(139, 148, 158),
102 text_muted: Rgb::new(72, 79, 88),
103 accent: Rgb::new(88, 166, 255),
104 success: Rgb::new(63, 185, 80),
105 warning: Rgb::new(210, 154, 34),
106 error: Rgb::new(248, 83, 73),
107 diff_add: Rgb::new(63, 185, 80),
108 diff_del: Rgb::new(248, 83, 73),
109 diff_context: Rgb::new(139, 148, 158),
110 diff_hunk: Rgb::new(88, 166, 255),
111 graph_colors: [
112 Rgb::new(88, 166, 255),
113 Rgb::new(63, 185, 80),
114 Rgb::new(248, 83, 73),
115 Rgb::new(210, 154, 34),
116 Rgb::new(188, 140, 255),
117 Rgb::new(0, 200, 180),
118 Rgb::new(255, 140, 60),
119 Rgb::new(255, 130, 160),
120 ],
121 }
122}
123
124pub fn grape() -> AppTheme {
125 AppTheme {
126 is_dark: true,
127 background: Rgb::new(24, 18, 36),
128 surface: Rgb::new(35, 28, 50),
129 border: Rgb::new(60, 50, 80),
130 selection: Rgb::new(50, 40, 70),
131 text_primary: Rgb::new(220, 210, 240),
132 text_secondary: Rgb::new(160, 140, 200),
133 text_muted: Rgb::new(100, 85, 130),
134 accent: Rgb::new(180, 130, 255),
135 success: Rgb::new(130, 230, 160),
136 warning: Rgb::new(240, 200, 100),
137 error: Rgb::new(255, 100, 120),
138 diff_add: Rgb::new(130, 230, 160),
139 diff_del: Rgb::new(255, 100, 120),
140 diff_context: Rgb::new(100, 85, 130),
141 diff_hunk: Rgb::new(150, 160, 255),
142 graph_colors: [
143 Rgb::new(180, 130, 255),
144 Rgb::new(130, 230, 160),
145 Rgb::new(255, 100, 120),
146 Rgb::new(240, 200, 100),
147 Rgb::new(100, 180, 255),
148 Rgb::new(255, 160, 200),
149 Rgb::new(120, 220, 220),
150 Rgb::new(255, 170, 100),
151 ],
152 }
153}
154
155pub fn ocean() -> AppTheme {
156 AppTheme {
157 is_dark: true,
158 background: Rgb::new(15, 25, 35),
159 surface: Rgb::new(22, 35, 48),
160 border: Rgb::new(40, 60, 80),
161 selection: Rgb::new(30, 55, 75),
162 text_primary: Rgb::new(200, 220, 240),
163 text_secondary: Rgb::new(100, 170, 200),
164 text_muted: Rgb::new(70, 100, 130),
165 accent: Rgb::new(80, 200, 180),
166 success: Rgb::new(80, 220, 120),
167 warning: Rgb::new(220, 200, 80),
168 error: Rgb::new(255, 100, 100),
169 diff_add: Rgb::new(80, 220, 120),
170 diff_del: Rgb::new(255, 100, 100),
171 diff_context: Rgb::new(70, 100, 130),
172 diff_hunk: Rgb::new(80, 200, 180),
173 graph_colors: [
174 Rgb::new(80, 200, 180),
175 Rgb::new(80, 220, 120),
176 Rgb::new(255, 100, 100),
177 Rgb::new(220, 200, 80),
178 Rgb::new(100, 160, 255),
179 Rgb::new(200, 130, 255),
180 Rgb::new(255, 180, 80),
181 Rgb::new(255, 130, 180),
182 ],
183 }
184}
185
186pub fn sunset() -> AppTheme {
187 AppTheme {
188 is_dark: true,
189 background: Rgb::new(35, 18, 18),
190 surface: Rgb::new(50, 28, 28),
191 border: Rgb::new(80, 45, 45),
192 selection: Rgb::new(70, 35, 35),
193 text_primary: Rgb::new(240, 220, 210),
194 text_secondary: Rgb::new(200, 150, 120),
195 text_muted: Rgb::new(140, 100, 80),
196 accent: Rgb::new(255, 140, 60),
197 success: Rgb::new(180, 220, 80),
198 warning: Rgb::new(255, 200, 50),
199 error: Rgb::new(255, 80, 80),
200 diff_add: Rgb::new(180, 220, 80),
201 diff_del: Rgb::new(255, 80, 80),
202 diff_context: Rgb::new(140, 100, 80),
203 diff_hunk: Rgb::new(255, 180, 100),
204 graph_colors: [
205 Rgb::new(255, 140, 60),
206 Rgb::new(180, 220, 80),
207 Rgb::new(255, 80, 80),
208 Rgb::new(255, 200, 50),
209 Rgb::new(200, 120, 255),
210 Rgb::new(80, 200, 200),
211 Rgb::new(255, 130, 160),
212 Rgb::new(100, 180, 255),
213 ],
214 }
215}
216
217pub fn forest() -> AppTheme {
218 AppTheme {
219 is_dark: true,
220 background: Rgb::new(18, 28, 18),
221 surface: Rgb::new(28, 40, 28),
222 border: Rgb::new(50, 70, 50),
223 selection: Rgb::new(35, 55, 35),
224 text_primary: Rgb::new(210, 230, 210),
225 text_secondary: Rgb::new(140, 180, 140),
226 text_muted: Rgb::new(80, 110, 80),
227 accent: Rgb::new(80, 180, 80),
228 success: Rgb::new(100, 220, 100),
229 warning: Rgb::new(220, 200, 80),
230 error: Rgb::new(220, 90, 70),
231 diff_add: Rgb::new(100, 220, 100),
232 diff_del: Rgb::new(220, 90, 70),
233 diff_context: Rgb::new(80, 110, 80),
234 diff_hunk: Rgb::new(120, 180, 120),
235 graph_colors: [
236 Rgb::new(80, 180, 80),
237 Rgb::new(100, 220, 100),
238 Rgb::new(220, 90, 70),
239 Rgb::new(220, 200, 80),
240 Rgb::new(100, 170, 220),
241 Rgb::new(180, 130, 200),
242 Rgb::new(200, 180, 100),
243 Rgb::new(140, 210, 200),
244 ],
245 }
246}
247
248pub fn rose() -> AppTheme {
249 AppTheme {
250 is_dark: true,
251 background: Rgb::new(30, 18, 25),
252 surface: Rgb::new(45, 28, 38),
253 border: Rgb::new(75, 45, 60),
254 selection: Rgb::new(60, 35, 50),
255 text_primary: Rgb::new(240, 220, 230),
256 text_secondary: Rgb::new(200, 140, 170),
257 text_muted: Rgb::new(130, 90, 110),
258 accent: Rgb::new(255, 130, 160),
259 success: Rgb::new(130, 220, 150),
260 warning: Rgb::new(240, 200, 100),
261 error: Rgb::new(255, 80, 100),
262 diff_add: Rgb::new(130, 220, 150),
263 diff_del: Rgb::new(255, 80, 100),
264 diff_context: Rgb::new(130, 90, 110),
265 diff_hunk: Rgb::new(220, 150, 200),
266 graph_colors: [
267 Rgb::new(255, 130, 160),
268 Rgb::new(130, 220, 150),
269 Rgb::new(255, 80, 100),
270 Rgb::new(240, 200, 100),
271 Rgb::new(130, 170, 255),
272 Rgb::new(200, 140, 255),
273 Rgb::new(80, 210, 210),
274 Rgb::new(255, 170, 100),
275 ],
276 }
277}
278
279pub fn mono() -> AppTheme {
280 AppTheme {
281 is_dark: true,
282 background: Rgb::new(20, 20, 20),
283 surface: Rgb::new(35, 35, 35),
284 border: Rgb::new(60, 60, 60),
285 selection: Rgb::new(50, 50, 50),
286 text_primary: Rgb::new(220, 220, 220),
287 text_secondary: Rgb::new(160, 160, 160),
288 text_muted: Rgb::new(100, 100, 100),
289 accent: Rgb::new(180, 180, 180),
290 success: Rgb::new(180, 220, 180),
291 warning: Rgb::new(220, 200, 160),
292 error: Rgb::new(220, 140, 140),
293 diff_add: Rgb::new(180, 220, 180),
294 diff_del: Rgb::new(220, 140, 140),
295 diff_context: Rgb::new(100, 100, 100),
296 diff_hunk: Rgb::new(180, 180, 180),
297 graph_colors: [
298 Rgb::new(180, 180, 180),
299 Rgb::new(180, 220, 180),
300 Rgb::new(220, 140, 140),
301 Rgb::new(220, 200, 160),
302 Rgb::new(140, 180, 220),
303 Rgb::new(200, 160, 200),
304 Rgb::new(200, 200, 140),
305 Rgb::new(160, 210, 210),
306 ],
307 }
308}
309
310pub fn neon() -> AppTheme {
311 AppTheme {
312 is_dark: true,
313 background: Rgb::new(10, 10, 18),
314 surface: Rgb::new(18, 18, 30),
315 border: Rgb::new(30, 30, 60),
316 selection: Rgb::new(25, 25, 50),
317 text_primary: Rgb::new(220, 240, 255),
318 text_secondary: Rgb::new(0, 200, 255),
319 text_muted: Rgb::new(60, 80, 120),
320 accent: Rgb::new(0, 255, 200),
321 success: Rgb::new(0, 255, 100),
322 warning: Rgb::new(255, 255, 0),
323 error: Rgb::new(255, 0, 80),
324 diff_add: Rgb::new(0, 255, 100),
325 diff_del: Rgb::new(255, 0, 80),
326 diff_context: Rgb::new(60, 80, 120),
327 diff_hunk: Rgb::new(200, 0, 255),
328 graph_colors: [
329 Rgb::new(0, 255, 200),
330 Rgb::new(0, 255, 100),
331 Rgb::new(255, 0, 80),
332 Rgb::new(255, 255, 0),
333 Rgb::new(0, 200, 255),
334 Rgb::new(200, 0, 255),
335 Rgb::new(255, 100, 0),
336 Rgb::new(255, 0, 200),
337 ],
338 }
339}
340
341pub fn dracula() -> AppTheme {
342 AppTheme {
343 is_dark: true,
344 background: Rgb::new(40, 42, 54),
345 surface: Rgb::new(68, 71, 90),
346 border: Rgb::new(98, 114, 164),
347 selection: Rgb::new(68, 71, 90),
348 text_primary: Rgb::new(248, 248, 242),
349 text_secondary: Rgb::new(189, 147, 249),
350 text_muted: Rgb::new(98, 114, 164),
351 accent: Rgb::new(189, 147, 249),
352 success: Rgb::new(80, 250, 123),
353 warning: Rgb::new(241, 250, 140),
354 error: Rgb::new(255, 85, 85),
355 diff_add: Rgb::new(80, 250, 123),
356 diff_del: Rgb::new(255, 85, 85),
357 diff_context: Rgb::new(98, 114, 164),
358 diff_hunk: Rgb::new(139, 233, 253),
359 graph_colors: [
360 Rgb::new(189, 147, 249),
361 Rgb::new(80, 250, 123),
362 Rgb::new(255, 85, 85),
363 Rgb::new(241, 250, 140),
364 Rgb::new(139, 233, 253),
365 Rgb::new(255, 121, 198),
366 Rgb::new(255, 184, 108),
367 Rgb::new(98, 114, 164),
368 ],
369 }
370}
371
372pub fn nord() -> AppTheme {
373 AppTheme {
374 is_dark: true,
375 background: Rgb::new(46, 52, 64),
376 surface: Rgb::new(59, 66, 82),
377 border: Rgb::new(76, 86, 106),
378 selection: Rgb::new(59, 66, 82),
379 text_primary: Rgb::new(216, 222, 233),
380 text_secondary: Rgb::new(129, 161, 193),
381 text_muted: Rgb::new(76, 86, 106),
382 accent: Rgb::new(136, 192, 208),
383 success: Rgb::new(163, 190, 140),
384 warning: Rgb::new(235, 203, 139),
385 error: Rgb::new(191, 97, 106),
386 diff_add: Rgb::new(163, 190, 140),
387 diff_del: Rgb::new(191, 97, 106),
388 diff_context: Rgb::new(76, 86, 106),
389 diff_hunk: Rgb::new(129, 161, 193),
390 graph_colors: [
391 Rgb::new(136, 192, 208),
392 Rgb::new(163, 190, 140),
393 Rgb::new(191, 97, 106),
394 Rgb::new(235, 203, 139),
395 Rgb::new(129, 161, 193),
396 Rgb::new(180, 142, 173),
397 Rgb::new(208, 135, 112),
398 Rgb::new(143, 188, 187),
399 ],
400 }
401}
402
403pub fn solarized_dark() -> AppTheme {
404 AppTheme {
405 is_dark: true,
406 background: Rgb::new(0, 43, 54),
407 surface: Rgb::new(7, 54, 66),
408 border: Rgb::new(88, 110, 117),
409 selection: Rgb::new(7, 54, 66),
410 text_primary: Rgb::new(131, 148, 150),
411 text_secondary: Rgb::new(42, 161, 152),
412 text_muted: Rgb::new(88, 110, 117),
413 accent: Rgb::new(38, 139, 210),
414 success: Rgb::new(133, 153, 0),
415 warning: Rgb::new(181, 137, 0),
416 error: Rgb::new(220, 50, 47),
417 diff_add: Rgb::new(133, 153, 0),
418 diff_del: Rgb::new(220, 50, 47),
419 diff_context: Rgb::new(88, 110, 117),
420 diff_hunk: Rgb::new(42, 161, 152),
421 graph_colors: [
422 Rgb::new(38, 139, 210),
423 Rgb::new(133, 153, 0),
424 Rgb::new(220, 50, 47),
425 Rgb::new(181, 137, 0),
426 Rgb::new(42, 161, 152),
427 Rgb::new(108, 113, 196),
428 Rgb::new(203, 75, 22),
429 Rgb::new(211, 54, 130),
430 ],
431 }
432}
433
434pub fn solarized_light() -> AppTheme {
435 AppTheme {
436 is_dark: false,
437 background: Rgb::new(253, 246, 227),
438 surface: Rgb::new(238, 232, 213),
439 border: Rgb::new(147, 161, 161),
440 selection: Rgb::new(238, 232, 213),
441 text_primary: Rgb::new(101, 123, 131),
442 text_secondary: Rgb::new(42, 161, 152),
443 text_muted: Rgb::new(147, 161, 161),
444 accent: Rgb::new(38, 139, 210),
445 success: Rgb::new(133, 153, 0),
446 warning: Rgb::new(181, 137, 0),
447 error: Rgb::new(220, 50, 47),
448 diff_add: Rgb::new(133, 153, 0),
449 diff_del: Rgb::new(220, 50, 47),
450 diff_context: Rgb::new(147, 161, 161),
451 diff_hunk: Rgb::new(42, 161, 152),
452 graph_colors: [
453 Rgb::new(38, 139, 210),
454 Rgb::new(133, 153, 0),
455 Rgb::new(220, 50, 47),
456 Rgb::new(181, 137, 0),
457 Rgb::new(42, 161, 152),
458 Rgb::new(108, 113, 196),
459 Rgb::new(203, 75, 22),
460 Rgb::new(211, 54, 130),
461 ],
462 }
463}
464
465pub fn gruvbox_dark() -> AppTheme {
466 AppTheme {
467 is_dark: true,
468 background: Rgb::new(40, 40, 40),
469 surface: Rgb::new(60, 56, 54),
470 border: Rgb::new(80, 73, 69),
471 selection: Rgb::new(60, 56, 54),
472 text_primary: Rgb::new(235, 219, 178),
473 text_secondary: Rgb::new(250, 189, 47),
474 text_muted: Rgb::new(146, 131, 116),
475 accent: Rgb::new(254, 128, 25),
476 success: Rgb::new(184, 187, 38),
477 warning: Rgb::new(250, 189, 47),
478 error: Rgb::new(251, 73, 52),
479 diff_add: Rgb::new(184, 187, 38),
480 diff_del: Rgb::new(251, 73, 52),
481 diff_context: Rgb::new(146, 131, 116),
482 diff_hunk: Rgb::new(142, 192, 124),
483 graph_colors: [
484 Rgb::new(254, 128, 25),
485 Rgb::new(184, 187, 38),
486 Rgb::new(251, 73, 52),
487 Rgb::new(250, 189, 47),
488 Rgb::new(131, 165, 152),
489 Rgb::new(211, 134, 155),
490 Rgb::new(142, 192, 124),
491 Rgb::new(69, 133, 136),
492 ],
493 }
494}
495
496pub fn gruvbox_light() -> AppTheme {
497 AppTheme {
498 is_dark: false,
499 background: Rgb::new(251, 241, 199),
500 surface: Rgb::new(213, 196, 161),
501 border: Rgb::new(168, 153, 132),
502 selection: Rgb::new(213, 196, 161),
503 text_primary: Rgb::new(60, 56, 54),
504 text_secondary: Rgb::new(215, 153, 33),
505 text_muted: Rgb::new(146, 131, 116),
506 accent: Rgb::new(214, 93, 14),
507 success: Rgb::new(121, 116, 14),
508 warning: Rgb::new(215, 153, 33),
509 error: Rgb::new(157, 0, 6),
510 diff_add: Rgb::new(121, 116, 14),
511 diff_del: Rgb::new(157, 0, 6),
512 diff_context: Rgb::new(146, 131, 116),
513 diff_hunk: Rgb::new(104, 157, 106),
514 graph_colors: [
515 Rgb::new(214, 93, 14),
516 Rgb::new(121, 116, 14),
517 Rgb::new(157, 0, 6),
518 Rgb::new(215, 153, 33),
519 Rgb::new(69, 133, 136),
520 Rgb::new(177, 98, 134),
521 Rgb::new(104, 157, 106),
522 Rgb::new(7, 102, 120),
523 ],
524 }
525}
526
527pub fn catppuccin_latte() -> AppTheme {
528 AppTheme {
529 is_dark: false,
530 background: Rgb::new(239, 241, 245),
532 surface: Rgb::new(204, 208, 218),
534 border: Rgb::new(172, 176, 190),
536 selection: Rgb::new(188, 192, 204),
538 text_primary: Rgb::new(76, 79, 105),
540 text_secondary: Rgb::new(92, 95, 119),
542 text_muted: Rgb::new(156, 160, 176),
544 accent: Rgb::new(136, 57, 239),
546 success: Rgb::new(64, 160, 43),
548 warning: Rgb::new(223, 142, 29),
550 error: Rgb::new(210, 15, 57),
552 diff_add: Rgb::new(64, 160, 43),
553 diff_del: Rgb::new(210, 15, 57),
554 diff_context: Rgb::new(156, 160, 176),
556 diff_hunk: Rgb::new(23, 146, 153),
558 graph_colors: [
559 Rgb::new(136, 57, 239), Rgb::new(64, 160, 43), Rgb::new(210, 15, 57), Rgb::new(223, 142, 29), Rgb::new(23, 146, 153), Rgb::new(30, 102, 245), Rgb::new(230, 69, 83), Rgb::new(32, 159, 181), ],
568 }
569}
570
571pub fn catppuccin_frappe() -> AppTheme {
572 AppTheme {
573 is_dark: true,
574 background: Rgb::new(48, 52, 70),
576 surface: Rgb::new(65, 69, 89),
578 border: Rgb::new(98, 104, 128),
580 selection: Rgb::new(81, 87, 109),
582 text_primary: Rgb::new(198, 208, 245),
584 text_secondary: Rgb::new(181, 191, 226),
586 text_muted: Rgb::new(115, 121, 148),
588 accent: Rgb::new(202, 158, 230),
590 success: Rgb::new(166, 209, 137),
592 warning: Rgb::new(229, 200, 144),
594 error: Rgb::new(231, 130, 132),
596 diff_add: Rgb::new(166, 209, 137),
597 diff_del: Rgb::new(231, 130, 132),
598 diff_context: Rgb::new(115, 121, 148),
600 diff_hunk: Rgb::new(129, 200, 190),
602 graph_colors: [
603 Rgb::new(202, 158, 230), Rgb::new(166, 209, 137), Rgb::new(231, 130, 132), Rgb::new(229, 200, 144), Rgb::new(140, 170, 238), Rgb::new(244, 184, 228), Rgb::new(129, 200, 190), Rgb::new(239, 159, 118), ],
612 }
613}
614
615pub fn catppuccin_macchiato() -> AppTheme {
616 AppTheme {
617 is_dark: true,
618 background: Rgb::new(36, 39, 58),
620 surface: Rgb::new(54, 58, 79),
622 border: Rgb::new(91, 96, 120),
624 selection: Rgb::new(73, 77, 100),
626 text_primary: Rgb::new(202, 211, 245),
628 text_secondary: Rgb::new(184, 192, 224),
630 text_muted: Rgb::new(110, 115, 141),
632 accent: Rgb::new(198, 160, 246),
634 success: Rgb::new(166, 218, 149),
636 warning: Rgb::new(238, 212, 159),
638 error: Rgb::new(237, 135, 150),
640 diff_add: Rgb::new(166, 218, 149),
641 diff_del: Rgb::new(237, 135, 150),
642 diff_context: Rgb::new(110, 115, 141),
644 diff_hunk: Rgb::new(139, 213, 202),
646 graph_colors: [
647 Rgb::new(198, 160, 246), Rgb::new(166, 218, 149), Rgb::new(237, 135, 150), Rgb::new(238, 212, 159), Rgb::new(138, 173, 244), Rgb::new(245, 189, 230), Rgb::new(139, 213, 202), Rgb::new(245, 169, 127), ],
656 }
657}
658
659pub fn catppuccin_mocha() -> AppTheme {
660 AppTheme {
661 is_dark: true,
662 background: Rgb::new(30, 30, 46),
664 surface: Rgb::new(49, 50, 68),
666 border: Rgb::new(88, 91, 112),
668 selection: Rgb::new(69, 71, 90),
670 text_primary: Rgb::new(205, 214, 244),
672 text_secondary: Rgb::new(186, 194, 222),
674 text_muted: Rgb::new(108, 112, 134),
676 accent: Rgb::new(203, 166, 247),
678 success: Rgb::new(166, 227, 161),
680 warning: Rgb::new(249, 226, 175),
682 error: Rgb::new(243, 139, 168),
684 diff_add: Rgb::new(166, 227, 161),
685 diff_del: Rgb::new(243, 139, 168),
686 diff_context: Rgb::new(108, 112, 134),
688 diff_hunk: Rgb::new(137, 180, 250),
690 graph_colors: [
691 Rgb::new(203, 166, 247), Rgb::new(166, 227, 161), Rgb::new(243, 139, 168), Rgb::new(249, 226, 175), Rgb::new(137, 180, 250), Rgb::new(245, 194, 231), Rgb::new(148, 226, 213), Rgb::new(250, 179, 135), ],
700 }
701}
702
703pub fn tokyo_night() -> AppTheme {
704 AppTheme {
705 is_dark: true,
706 background: Rgb::new(26, 27, 38),
707 surface: Rgb::new(41, 46, 66),
708 border: Rgb::new(59, 66, 97),
709 selection: Rgb::new(41, 46, 66),
710 text_primary: Rgb::new(192, 202, 245),
711 text_secondary: Rgb::new(122, 162, 247),
712 text_muted: Rgb::new(86, 95, 137),
713 accent: Rgb::new(122, 162, 247),
714 success: Rgb::new(158, 206, 106),
715 warning: Rgb::new(224, 175, 104),
716 error: Rgb::new(247, 118, 142),
717 diff_add: Rgb::new(158, 206, 106),
718 diff_del: Rgb::new(247, 118, 142),
719 diff_context: Rgb::new(86, 95, 137),
720 diff_hunk: Rgb::new(187, 154, 247),
721 graph_colors: [
722 Rgb::new(122, 162, 247),
723 Rgb::new(158, 206, 106),
724 Rgb::new(247, 118, 142),
725 Rgb::new(224, 175, 104),
726 Rgb::new(187, 154, 247),
727 Rgb::new(255, 117, 127),
728 Rgb::new(115, 218, 202),
729 Rgb::new(255, 158, 100),
730 ],
731 }
732}
733
734pub fn tokyo_night_storm() -> AppTheme {
735 AppTheme {
736 is_dark: true,
737 background: Rgb::new(36, 40, 59),
738 surface: Rgb::new(45, 49, 75),
739 border: Rgb::new(59, 66, 97),
740 selection: Rgb::new(45, 49, 75),
741 text_primary: Rgb::new(192, 202, 245),
742 text_secondary: Rgb::new(122, 162, 247),
743 text_muted: Rgb::new(86, 95, 137),
744 accent: Rgb::new(122, 162, 247),
745 success: Rgb::new(158, 206, 106),
746 warning: Rgb::new(224, 175, 104),
747 error: Rgb::new(247, 118, 142),
748 diff_add: Rgb::new(158, 206, 106),
749 diff_del: Rgb::new(247, 118, 142),
750 diff_context: Rgb::new(86, 95, 137),
751 diff_hunk: Rgb::new(187, 154, 247),
752 graph_colors: [
753 Rgb::new(122, 162, 247),
754 Rgb::new(158, 206, 106),
755 Rgb::new(247, 118, 142),
756 Rgb::new(224, 175, 104),
757 Rgb::new(187, 154, 247),
758 Rgb::new(255, 117, 127),
759 Rgb::new(115, 218, 202),
760 Rgb::new(255, 158, 100),
761 ],
762 }
763}
764
765pub fn tokyo_night_light() -> AppTheme {
766 AppTheme {
767 is_dark: false,
768 background: Rgb::new(213, 214, 219),
769 surface: Rgb::new(208, 213, 227),
770 border: Rgb::new(132, 140, 176),
771 selection: Rgb::new(208, 213, 227),
772 text_primary: Rgb::new(52, 59, 88),
773 text_secondary: Rgb::new(46, 126, 233),
774 text_muted: Rgb::new(132, 140, 176),
775 accent: Rgb::new(46, 126, 233),
776 success: Rgb::new(72, 94, 48),
777 warning: Rgb::new(140, 108, 62),
778 error: Rgb::new(143, 57, 85),
779 diff_add: Rgb::new(72, 94, 48),
780 diff_del: Rgb::new(143, 57, 85),
781 diff_context: Rgb::new(132, 140, 176),
782 diff_hunk: Rgb::new(90, 74, 120),
783 graph_colors: [
784 Rgb::new(46, 126, 233),
785 Rgb::new(72, 94, 48),
786 Rgb::new(143, 57, 85),
787 Rgb::new(140, 108, 62),
788 Rgb::new(90, 74, 120),
789 Rgb::new(166, 77, 121),
790 Rgb::new(15, 130, 130),
791 Rgb::new(180, 90, 50),
792 ],
793 }
794}
795
796pub fn kanagawa_wave() -> AppTheme {
797 AppTheme {
798 is_dark: true,
799 background: Rgb::new(31, 31, 40),
800 surface: Rgb::new(42, 42, 55),
801 border: Rgb::new(84, 84, 88),
802 selection: Rgb::new(42, 42, 55),
803 text_primary: Rgb::new(220, 215, 186),
804 text_secondary: Rgb::new(126, 156, 216),
805 text_muted: Rgb::new(114, 113, 105),
806 accent: Rgb::new(126, 156, 216),
807 success: Rgb::new(118, 148, 106),
808 warning: Rgb::new(220, 165, 97),
809 error: Rgb::new(195, 64, 67),
810 diff_add: Rgb::new(118, 148, 106),
811 diff_del: Rgb::new(195, 64, 67),
812 diff_context: Rgb::new(114, 113, 105),
813 diff_hunk: Rgb::new(210, 126, 153),
814 graph_colors: [
815 Rgb::new(126, 156, 216),
816 Rgb::new(118, 148, 106),
817 Rgb::new(195, 64, 67),
818 Rgb::new(220, 165, 97),
819 Rgb::new(210, 126, 153),
820 Rgb::new(160, 140, 200),
821 Rgb::new(106, 149, 137),
822 Rgb::new(228, 104, 118),
823 ],
824 }
825}
826
827pub fn kanagawa_dragon() -> AppTheme {
828 AppTheme {
829 is_dark: true,
830 background: Rgb::new(24, 21, 21),
831 surface: Rgb::new(40, 39, 39),
832 border: Rgb::new(80, 80, 78),
833 selection: Rgb::new(40, 39, 39),
834 text_primary: Rgb::new(197, 201, 197),
835 text_secondary: Rgb::new(139, 164, 176),
836 text_muted: Rgb::new(166, 166, 156),
837 accent: Rgb::new(139, 164, 176),
838 success: Rgb::new(135, 169, 135),
839 warning: Rgb::new(200, 170, 109),
840 error: Rgb::new(195, 64, 67),
841 diff_add: Rgb::new(135, 169, 135),
842 diff_del: Rgb::new(195, 64, 67),
843 diff_context: Rgb::new(166, 166, 156),
844 diff_hunk: Rgb::new(210, 126, 153),
845 graph_colors: [
846 Rgb::new(139, 164, 176),
847 Rgb::new(135, 169, 135),
848 Rgb::new(195, 64, 67),
849 Rgb::new(200, 170, 109),
850 Rgb::new(210, 126, 153),
851 Rgb::new(160, 140, 200),
852 Rgb::new(106, 149, 137),
853 Rgb::new(228, 104, 118),
854 ],
855 }
856}
857
858pub fn kanagawa_lotus() -> AppTheme {
859 AppTheme {
860 is_dark: false,
861 background: Rgb::new(245, 240, 215),
862 surface: Rgb::new(231, 219, 160),
863 border: Rgb::new(196, 178, 138),
864 selection: Rgb::new(231, 219, 160),
865 text_primary: Rgb::new(84, 84, 100),
866 text_secondary: Rgb::new(77, 105, 155),
867 text_muted: Rgb::new(196, 178, 138),
868 accent: Rgb::new(77, 105, 155),
869 success: Rgb::new(111, 137, 78),
870 warning: Rgb::new(119, 113, 63),
871 error: Rgb::new(195, 64, 67),
872 diff_add: Rgb::new(111, 137, 78),
873 diff_del: Rgb::new(195, 64, 67),
874 diff_context: Rgb::new(196, 178, 138),
875 diff_hunk: Rgb::new(160, 154, 190),
876 graph_colors: [
877 Rgb::new(77, 105, 155),
878 Rgb::new(111, 137, 78),
879 Rgb::new(195, 64, 67),
880 Rgb::new(119, 113, 63),
881 Rgb::new(160, 154, 190),
882 Rgb::new(155, 80, 117),
883 Rgb::new(75, 130, 120),
884 Rgb::new(180, 100, 55),
885 ],
886 }
887}
888
889pub fn moonfly() -> AppTheme {
890 AppTheme {
891 is_dark: true,
892 background: Rgb::new(8, 8, 8),
893 surface: Rgb::new(23, 23, 23),
894 border: Rgb::new(50, 50, 50),
895 selection: Rgb::new(23, 50, 80),
896 text_primary: Rgb::new(189, 189, 189),
897 text_secondary: Rgb::new(128, 160, 255),
898 text_muted: Rgb::new(99, 99, 99),
899 accent: Rgb::new(174, 129, 255),
900 success: Rgb::new(130, 170, 60),
901 warning: Rgb::new(230, 170, 50),
902 error: Rgb::new(255, 83, 112),
903 diff_add: Rgb::new(130, 170, 60),
904 diff_del: Rgb::new(255, 83, 112),
905 diff_context: Rgb::new(99, 99, 99),
906 diff_hunk: Rgb::new(128, 160, 255),
907 graph_colors: [
908 Rgb::new(174, 129, 255),
909 Rgb::new(130, 170, 60),
910 Rgb::new(255, 83, 112),
911 Rgb::new(230, 170, 50),
912 Rgb::new(128, 160, 255),
913 Rgb::new(255, 100, 180),
914 Rgb::new(80, 200, 180),
915 Rgb::new(255, 160, 80),
916 ],
917 }
918}
919
920pub fn nightfly() -> AppTheme {
921 AppTheme {
922 is_dark: true,
923 background: Rgb::new(1, 13, 32),
924 surface: Rgb::new(5, 22, 50),
925 border: Rgb::new(30, 50, 80),
926 selection: Rgb::new(10, 40, 80),
927 text_primary: Rgb::new(195, 204, 219),
928 text_secondary: Rgb::new(130, 170, 255),
929 text_muted: Rgb::new(99, 117, 150),
930 accent: Rgb::new(130, 170, 255),
931 success: Rgb::new(161, 217, 147),
932 warning: Rgb::new(236, 196, 100),
933 error: Rgb::new(252, 57, 49),
934 diff_add: Rgb::new(161, 217, 147),
935 diff_del: Rgb::new(252, 57, 49),
936 diff_context: Rgb::new(99, 117, 150),
937 diff_hunk: Rgb::new(174, 129, 255),
938 graph_colors: [
939 Rgb::new(130, 170, 255),
940 Rgb::new(161, 217, 147),
941 Rgb::new(252, 57, 49),
942 Rgb::new(236, 196, 100),
943 Rgb::new(174, 129, 255),
944 Rgb::new(255, 100, 180),
945 Rgb::new(33, 200, 170),
946 Rgb::new(255, 160, 90),
947 ],
948 }
949}
950
951pub fn oxocarbon() -> AppTheme {
952 AppTheme {
953 is_dark: true,
954 background: Rgb::new(22, 22, 22),
955 surface: Rgb::new(38, 38, 38),
956 border: Rgb::new(57, 57, 57),
957 selection: Rgb::new(38, 38, 38),
958 text_primary: Rgb::new(240, 240, 240),
959 text_secondary: Rgb::new(78, 154, 232),
960 text_muted: Rgb::new(82, 82, 82),
961 accent: Rgb::new(78, 154, 232),
962 success: Rgb::new(66, 190, 101),
963 warning: Rgb::new(190, 149, 255),
964 error: Rgb::new(238, 83, 120),
965 diff_add: Rgb::new(66, 190, 101),
966 diff_del: Rgb::new(238, 83, 120),
967 diff_context: Rgb::new(82, 82, 82),
968 diff_hunk: Rgb::new(51, 177, 255),
969 graph_colors: [
970 Rgb::new(78, 154, 232),
971 Rgb::new(66, 190, 101),
972 Rgb::new(238, 83, 120),
973 Rgb::new(190, 149, 255),
974 Rgb::new(51, 177, 255),
975 Rgb::new(255, 104, 159),
976 Rgb::new(8, 189, 186),
977 Rgb::new(255, 164, 90),
978 ],
979 }
980}
981
982pub fn cyberpunk() -> AppTheme {
985 AppTheme {
986 is_dark: true,
987 background: Rgb::new(10, 10, 16),
988 surface: Rgb::new(20, 20, 30),
989 border: Rgb::new(45, 45, 55),
990 selection: Rgb::new(50, 48, 20),
991 text_primary: Rgb::new(230, 230, 220),
992 text_secondary: Rgb::new(0, 210, 235),
993 text_muted: Rgb::new(90, 90, 100),
994 accent: Rgb::new(252, 238, 10),
995 success: Rgb::new(0, 220, 180),
996 warning: Rgb::new(255, 150, 0),
997 error: Rgb::new(255, 50, 70),
998 diff_add: Rgb::new(0, 220, 180),
999 diff_del: Rgb::new(255, 50, 70),
1000 diff_context: Rgb::new(90, 90, 100),
1001 diff_hunk: Rgb::new(0, 210, 235),
1002 graph_colors: [
1003 Rgb::new(252, 238, 10),
1004 Rgb::new(0, 210, 235),
1005 Rgb::new(0, 220, 180),
1006 Rgb::new(255, 150, 0),
1007 Rgb::new(180, 60, 255),
1008 Rgb::new(255, 80, 120),
1009 Rgb::new(100, 255, 220),
1010 Rgb::new(255, 200, 60),
1011 ],
1012 }
1013}
1014
1015#[cfg(test)]
1018mod tests {
1019 use super::*;
1020
1021 #[test]
1022 fn all_themes_resolve() {
1023 for i in 0..THEME_COUNT {
1024 let t = theme_by_index(i);
1025 assert!(
1027 t.text_primary.r > 0 || t.text_primary.g > 0 || t.text_primary.b > 0,
1028 "theme index {i} has zero text_primary"
1029 );
1030 }
1031 }
1032
1033 #[test]
1034 fn theme_count_matches_names() {
1035 assert_eq!(THEME_NAMES.len(), THEME_COUNT);
1036 }
1037
1038 #[test]
1039 fn index_by_name_round_trips() {
1040 for (i, name) in THEME_NAMES.iter().enumerate() {
1041 assert_eq!(
1042 theme_index_by_name(name),
1043 i,
1044 "round-trip failed for '{name}'"
1045 );
1046 }
1047 }
1048
1049 #[test]
1050 fn unknown_name_returns_zero() {
1051 assert_eq!(theme_index_by_name("nonexistent"), 0);
1052 }
1053
1054 #[test]
1055 fn out_of_range_returns_default() {
1056 let d = default();
1057 let oob = theme_by_index(999);
1058 assert_eq!(d.background, oob.background);
1059 assert_eq!(d.accent, oob.accent);
1060 }
1061
1062 #[test]
1063 fn graph_colors_populated_for_all_themes() {
1064 for i in 0..THEME_COUNT {
1065 let t = theme_by_index(i);
1066 assert_eq!(
1068 t.graph_colors.len(),
1069 8,
1070 "theme index {i} does not have 8 graph_colors"
1071 );
1072 let first = t.graph_colors[0];
1074 let all_same = t.graph_colors.iter().all(|c| *c == first);
1075 assert!(
1076 !all_same,
1077 "theme index {i} has all identical graph lane colours"
1078 );
1079 }
1080 }
1081
1082 #[test]
1083 fn graph_colors_channels_nonzero() {
1084 for i in 0..THEME_COUNT {
1085 let t = theme_by_index(i);
1086 for (lane, c) in t.graph_colors.iter().enumerate() {
1087 assert!(
1090 c.r > 0 || c.g > 0 || c.b > 0,
1091 "theme {i} graph_colors[{lane}] is pure black"
1092 );
1093 }
1094 }
1095 }
1096}