export const SKIN_IDS = ['classic', 'modern'] as const
export const THEME_IDS = [
'catppuccin-latte',
+ 'dracula',
+ 'gruvbox-dark',
+ 'rose-pine',
'sap-horizon',
'teal-dark',
'teal-light',
| Theme | Style | Source |
| ------------------- | ----- | ---------------------------------------------------------------- |
| `tokyo-night-storm` | Dark | [Tokyo Night](https://github.com/enkia/tokyo-night-vscode-theme) |
+| `dracula` | Dark | [Dracula](https://github.com/dracula/dracula-theme) |
+| `gruvbox-dark` | Dark | [Gruvbox](https://github.com/morhetz/gruvbox) |
+| `rose-pine` | Dark | [Rosé Pine](https://github.com/rose-pine/rose-pine-theme) |
| `teal-dark` | Dark | Material Teal |
| `teal-light` | Light | Material Teal |
| `catppuccin-latte` | Light | [Catppuccin](https://github.com/catppuccin/catppuccin) |
--color-bg-caption: var(--ctp-crust);
--color-bg-button: var(--ctp-blue);
--color-bg-button-hover: color-mix(in srgb, var(--ctp-blue) 67%, transparent);
- --color-text: var(--ctp-text);
- --color-text-strong: var(--ctp-subtext1);
+ --color-text: var(--ctp-subtext1);
+ --color-text-strong: var(--ctp-text);
--color-text-muted: var(--ctp-overlay1);
--color-text-on-button: var(--ctp-base);
--color-primary: var(--ctp-blue);
--color-shadow-inset: rgba(0, 0, 0, 0.1);
/* Surface hierarchy */
- --color-bg-raised: var(--ctp-surface0);
- --color-bg-sunken: var(--ctp-mantle);
+ --color-bg-raised: var(--ctp-base);
+ --color-bg-sunken: var(--ctp-crust);
/* State colors (Material 700 for light mode readability) */
--color-state-ok: #2e7d32;
--- /dev/null
+/* Dracula */
+
+:root[data-theme='dracula'] {
+ /* Palette */
+ --drac-bg: #282a36;
+ --drac-bg-dark: #21222c;
+ --drac-current: #44475a;
+ --drac-highlight: #515672;
+ --drac-border: #363848;
+ --drac-fg: #f8f8f2;
+ --drac-comment: #6272a4;
+ --drac-purple: #bd93f9;
+ --drac-pink: #ff79c6;
+ --drac-green: #50fa7b;
+ --drac-red: #ff5555;
+ --drac-orange: #ffb86c;
+ --drac-yellow: #f1fa8c;
+ --drac-cyan: #8be9fd;
+
+ /* Semantic */
+ --color-bg: var(--drac-bg);
+ --color-bg-surface: var(--drac-bg-dark);
+ --color-bg-input: var(--drac-bg-dark);
+ --color-bg-hover: var(--drac-current);
+ --color-bg-active: var(--drac-highlight);
+ --color-bg-header: var(--drac-bg-dark);
+ --color-bg-caption: var(--drac-current);
+ --color-bg-button: var(--drac-purple);
+ --color-bg-button-hover: color-mix(in srgb, var(--drac-purple) 67%, transparent);
+ --color-text: var(--drac-fg);
+ --color-text-strong: var(--drac-fg);
+ --color-text-muted: var(--drac-comment);
+ --color-text-on-button: var(--drac-bg);
+ --color-primary: var(--drac-purple);
+ --color-border: var(--drac-current);
+ --color-border-row: var(--drac-border);
+ --color-accent: var(--drac-pink);
+ --color-shadow-inset: rgba(0, 0, 0, 0.4);
+
+ /* Surface hierarchy */
+ --color-bg-raised: var(--drac-current);
+ --color-bg-sunken: var(--drac-bg-dark);
+
+ /* State colors */
+ --color-state-ok: var(--drac-green);
+ --color-state-warn: var(--drac-orange);
+ --color-state-err: var(--drac-red);
+ --color-state-idle: var(--drac-comment);
+
+ color-scheme: dark;
+}
--- /dev/null
+/* Gruvbox Dark */
+
+:root[data-theme='gruvbox-dark'] {
+ /* Palette */
+ --grv-bg0-hard: #1d2021;
+ --grv-bg0: #282828;
+ --grv-bg1: #3c3836;
+ --grv-bg2: #504945;
+ --grv-bg3: #665c54;
+ --grv-fg0: #fbf1c7;
+ --grv-fg1: #ebdbb2;
+ --grv-fg3: #bdae93;
+ --grv-fg4: #a89984;
+ --grv-orange: #fe8019;
+ --grv-yellow: #fabd2f;
+ --grv-green: #b8bb26;
+ --grv-red: #fb4934;
+ --grv-aqua: #8ec07c;
+
+ /* Semantic */
+ --color-bg: var(--grv-bg0);
+ --color-bg-surface: var(--grv-bg0-hard);
+ --color-bg-input: var(--grv-bg0-hard);
+ --color-bg-hover: var(--grv-bg1);
+ --color-bg-active: var(--grv-bg2);
+ --color-bg-header: var(--grv-bg0-hard);
+ --color-bg-caption: var(--grv-bg1);
+ --color-bg-button: var(--grv-orange);
+ --color-bg-button-hover: color-mix(in srgb, var(--grv-orange) 67%, transparent);
+ --color-text: var(--grv-fg1);
+ --color-text-strong: var(--grv-fg0);
+ --color-text-muted: var(--grv-fg4);
+ --color-text-on-button: var(--grv-bg0);
+ --color-primary: var(--grv-orange);
+ --color-border: var(--grv-bg1);
+ --color-border-row: var(--grv-bg2);
+ --color-accent: var(--grv-aqua);
+ --color-shadow-inset: rgba(0, 0, 0, 0.4);
+
+ /* Surface hierarchy */
+ --color-bg-raised: var(--grv-bg2);
+ --color-bg-sunken: var(--grv-bg0-hard);
+
+ /* State colors */
+ --color-state-ok: var(--grv-green);
+ --color-state-warn: var(--grv-yellow);
+ --color-state-err: var(--grv-red);
+ --color-state-idle: var(--grv-fg4);
+
+ color-scheme: dark;
+}
--- /dev/null
+/* Rosé Pine */
+
+:root[data-theme='rose-pine'] {
+ /* Palette */
+ --rp-base: #191724;
+ --rp-surface: #1f1d2e;
+ --rp-overlay: #26233a;
+ --rp-highlight-low: #2a2740;
+ --rp-highlight-med: #312e48;
+ --rp-muted: #6e6a86;
+ --rp-subtle: #908caa;
+ --rp-text: #e0def4;
+ --rp-love: #eb6f92;
+ --rp-gold: #f6c177;
+ --rp-rose: #ebbcba;
+ --rp-pine: #31748f;
+ --rp-foam: #9ccfd8;
+ --rp-iris: #c4a7e7;
+
+ /* Semantic */
+ --color-bg: var(--rp-surface);
+ --color-bg-surface: var(--rp-base);
+ --color-bg-input: var(--rp-base);
+ --color-bg-hover: var(--rp-overlay);
+ --color-bg-active: var(--rp-highlight-med);
+ --color-bg-header: var(--rp-base);
+ --color-bg-caption: var(--rp-overlay);
+ --color-bg-button: var(--rp-iris);
+ --color-bg-button-hover: color-mix(in srgb, var(--rp-iris) 67%, transparent);
+ --color-text: var(--rp-text);
+ --color-text-strong: var(--rp-text);
+ --color-text-muted: var(--rp-subtle);
+ --color-text-on-button: var(--rp-base);
+ --color-primary: var(--rp-iris);
+ --color-border: var(--rp-overlay);
+ --color-border-row: var(--rp-highlight-low);
+ --color-accent: var(--rp-rose);
+ --color-shadow-inset: rgba(0, 0, 0, 0.4);
+
+ /* Surface hierarchy */
+ --color-bg-raised: var(--rp-overlay);
+ --color-bg-sunken: var(--rp-base);
+
+ /* State colors */
+ --color-state-ok: var(--rp-foam);
+ --color-state-warn: var(--rp-gold);
+ --color-state-err: var(--rp-love);
+ --color-state-idle: var(--rp-muted);
+
+ color-scheme: dark;
+}
--color-shadow-inset: rgba(34, 53, 72, 0.15);
/* Surface hierarchy */
- --color-bg-raised: var(--sap-bg-shell);
+ --color-bg-raised: var(--sap-bg-base);
--color-bg-sunken: var(--sap-hover);
/* State colors (SAP Horizon palette) */
--color-text-muted: var(--tl-fg-muted);
--color-text-on-button: var(--tl-white);
--color-primary: var(--tl-teal);
- --color-border: #e4e7eb;
- --color-border-row: #eef0f3;
+ --color-border: var(--tl-bg-active);
+ --color-border-row: var(--tl-bg-hover);
--color-accent: var(--tl-teal-dim);
--color-shadow-inset: rgba(16, 24, 40, 0.1);
/* Surface hierarchy */
- --color-bg-raised: var(--tl-bg-hover);
- --color-bg-sunken: var(--tl-bg-raised);
+ --color-bg-raised: var(--tl-bg-base);
+ --color-bg-sunken: var(--tl-bg-active);
/* State colors */
--color-state-ok: #2e7d32;
import './assets/shared.css'
import './assets/themes/base.css'
import './assets/themes/catppuccin-latte.css'
+import './assets/themes/dracula.css'
+import './assets/themes/gruvbox-dark.css'
+import './assets/themes/rose-pine.css'
import './assets/themes/sap-horizon.css'
import './assets/themes/teal-dark.css'
import './assets/themes/teal-light.css'
expect(activeThemeId.value).toBe('tokyo-night-storm')
})
- it('should return availableThemes with 5 entries', () => {
+ it('should return availableThemes with 8 entries', () => {
const { availableThemes } = useTheme()
- expect(availableThemes.length).toBe(5)
+ expect(availableThemes.length).toBe(8)
expect(availableThemes).toContain('tokyo-night-storm')
expect(availableThemes).toContain('catppuccin-latte')
+ expect(availableThemes).toContain('dracula')
+ expect(availableThemes).toContain('gruvbox-dark')
+ expect(availableThemes).toContain('rose-pine')
expect(availableThemes).toContain('teal-dark')
expect(availableThemes).toContain('teal-light')
expect(availableThemes).toContain('sap-horizon')