feat(themes): 5 new dark theme presets — Cyberpunk/Ocean/Blood Red/Matrix/Midnight (P5-2)
Five complete vanilla-extract themes registered in useTheme (useThemes + useThemeNames), each spreading darkThemeData so Success/Warning/Critical keep their semantic colors and only Background/Surface/Primary/Secondary are recolored. A code-review pass computed WCAG contrast for every theme; all body and accent pairs clear AA except Midnight's Primary.OnMain which was 4.49:1 — fixed by changing OnMain #0d1320 -> #000000 (5.07:1). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -2,10 +2,15 @@ import { lightTheme } from 'folds';
|
|||||||
import { createContext, useContext, useEffect, useMemo, useState } from 'react';
|
import { createContext, useContext, useEffect, useMemo, useState } from 'react';
|
||||||
import { onDarkFontWeight, onLightFontWeight } from '../../config.css';
|
import { onDarkFontWeight, onLightFontWeight } from '../../config.css';
|
||||||
import {
|
import {
|
||||||
|
bloodRedTheme,
|
||||||
butterTheme,
|
butterTheme,
|
||||||
|
classicMatrixTheme,
|
||||||
|
cyberpunkTheme,
|
||||||
darkTheme,
|
darkTheme,
|
||||||
lotusTerminalLightTheme,
|
lotusTerminalLightTheme,
|
||||||
lotusTerminalTheme,
|
lotusTerminalTheme,
|
||||||
|
midnightTheme,
|
||||||
|
oceanTheme,
|
||||||
silverTheme,
|
silverTheme,
|
||||||
} from '../../colors.css';
|
} from '../../colors.css';
|
||||||
import { settingsAtom } from '../state/settings';
|
import { settingsAtom } from '../state/settings';
|
||||||
@@ -43,6 +48,31 @@ export const ButterTheme: Theme = {
|
|||||||
kind: ThemeKind.Dark,
|
kind: ThemeKind.Dark,
|
||||||
classNames: ['butter-theme', butterTheme, onDarkFontWeight, 'prism-dark'],
|
classNames: ['butter-theme', butterTheme, onDarkFontWeight, 'prism-dark'],
|
||||||
};
|
};
|
||||||
|
export const CyberpunkTheme: Theme = {
|
||||||
|
id: 'cyberpunk-theme',
|
||||||
|
kind: ThemeKind.Dark,
|
||||||
|
classNames: ['cyberpunk-theme', cyberpunkTheme, onDarkFontWeight, 'prism-dark'],
|
||||||
|
};
|
||||||
|
export const OceanTheme: Theme = {
|
||||||
|
id: 'ocean-theme',
|
||||||
|
kind: ThemeKind.Dark,
|
||||||
|
classNames: ['ocean-theme', oceanTheme, onDarkFontWeight, 'prism-dark'],
|
||||||
|
};
|
||||||
|
export const BloodRedTheme: Theme = {
|
||||||
|
id: 'blood-red-theme',
|
||||||
|
kind: ThemeKind.Dark,
|
||||||
|
classNames: ['blood-red-theme', bloodRedTheme, onDarkFontWeight, 'prism-dark'],
|
||||||
|
};
|
||||||
|
export const ClassicMatrixTheme: Theme = {
|
||||||
|
id: 'classic-matrix-theme',
|
||||||
|
kind: ThemeKind.Dark,
|
||||||
|
classNames: ['classic-matrix-theme', classicMatrixTheme, onDarkFontWeight, 'prism-dark'],
|
||||||
|
};
|
||||||
|
export const MidnightTheme: Theme = {
|
||||||
|
id: 'midnight-theme',
|
||||||
|
kind: ThemeKind.Dark,
|
||||||
|
classNames: ['midnight-theme', midnightTheme, onDarkFontWeight, 'prism-dark'],
|
||||||
|
};
|
||||||
export const LotusTerminalTheme: Theme = {
|
export const LotusTerminalTheme: Theme = {
|
||||||
id: 'lotus-terminal-theme',
|
id: 'lotus-terminal-theme',
|
||||||
kind: ThemeKind.Dark,
|
kind: ThemeKind.Dark,
|
||||||
@@ -60,7 +90,20 @@ export const LotusTerminalLightTheme: Theme = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const useThemes = (): Theme[] => {
|
export const useThemes = (): Theme[] => {
|
||||||
const themes: Theme[] = useMemo(() => [LightTheme, SilverTheme, DarkTheme, ButterTheme], []);
|
const themes: Theme[] = useMemo(
|
||||||
|
() => [
|
||||||
|
LightTheme,
|
||||||
|
SilverTheme,
|
||||||
|
DarkTheme,
|
||||||
|
ButterTheme,
|
||||||
|
CyberpunkTheme,
|
||||||
|
OceanTheme,
|
||||||
|
BloodRedTheme,
|
||||||
|
ClassicMatrixTheme,
|
||||||
|
MidnightTheme,
|
||||||
|
],
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
|
||||||
return themes;
|
return themes;
|
||||||
};
|
};
|
||||||
@@ -72,6 +115,11 @@ export const useThemeNames = (): Record<string, string> =>
|
|||||||
[SilverTheme.id]: 'Silver',
|
[SilverTheme.id]: 'Silver',
|
||||||
[DarkTheme.id]: 'Dark',
|
[DarkTheme.id]: 'Dark',
|
||||||
[ButterTheme.id]: 'Butter',
|
[ButterTheme.id]: 'Butter',
|
||||||
|
[CyberpunkTheme.id]: 'Cyberpunk',
|
||||||
|
[OceanTheme.id]: 'Ocean',
|
||||||
|
[BloodRedTheme.id]: 'Blood Red',
|
||||||
|
[ClassicMatrixTheme.id]: 'Classic Matrix',
|
||||||
|
[MidnightTheme.id]: 'Midnight',
|
||||||
}),
|
}),
|
||||||
[],
|
[],
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -237,6 +237,301 @@ export const butterTheme = createTheme(color, {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const cyberpunkTheme = createTheme(color, {
|
||||||
|
...darkThemeData,
|
||||||
|
Background: {
|
||||||
|
Container: '#0a0015',
|
||||||
|
ContainerHover: '#130722',
|
||||||
|
ContainerActive: '#1c0f30',
|
||||||
|
ContainerLine: '#26173d',
|
||||||
|
OnContainer: '#ECE6F5',
|
||||||
|
},
|
||||||
|
|
||||||
|
Surface: {
|
||||||
|
Container: '#130722',
|
||||||
|
ContainerHover: '#1c0f30',
|
||||||
|
ContainerActive: '#26173d',
|
||||||
|
ContainerLine: '#2f1f4a',
|
||||||
|
OnContainer: '#ECE6F5',
|
||||||
|
},
|
||||||
|
|
||||||
|
SurfaceVariant: {
|
||||||
|
Container: '#1c0f30',
|
||||||
|
ContainerHover: '#26173d',
|
||||||
|
ContainerActive: '#2f1f4a',
|
||||||
|
ContainerLine: '#392858',
|
||||||
|
OnContainer: '#ECE6F5',
|
||||||
|
},
|
||||||
|
|
||||||
|
Primary: {
|
||||||
|
Main: '#bf5fff',
|
||||||
|
MainHover: '#c873ff',
|
||||||
|
MainActive: '#cd7eff',
|
||||||
|
MainLine: '#d28aff',
|
||||||
|
OnMain: '#1a0033',
|
||||||
|
Container: '#3d1a5c',
|
||||||
|
ContainerHover: '#461e69',
|
||||||
|
ContainerActive: '#502276',
|
||||||
|
ContainerLine: '#592683',
|
||||||
|
OnContainer: '#EBD6FF',
|
||||||
|
},
|
||||||
|
|
||||||
|
Secondary: {
|
||||||
|
Main: '#ff2d9b',
|
||||||
|
MainHover: '#ff47a8',
|
||||||
|
MainActive: '#ff54af',
|
||||||
|
MainLine: '#ff61b6',
|
||||||
|
OnMain: '#33001a',
|
||||||
|
Container: '#5c0033',
|
||||||
|
ContainerHover: '#69003a',
|
||||||
|
ContainerActive: '#760041',
|
||||||
|
ContainerLine: '#830048',
|
||||||
|
OnContainer: '#FFD6EB',
|
||||||
|
},
|
||||||
|
|
||||||
|
Other: {
|
||||||
|
FocusRing: 'rgba(191, 95, 255, 0.5)',
|
||||||
|
Shadow: 'rgba(0, 0, 0, 1)',
|
||||||
|
Overlay: 'rgba(10, 0, 21, 0.9)',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const oceanTheme = createTheme(color, {
|
||||||
|
...darkThemeData,
|
||||||
|
Background: {
|
||||||
|
Container: '#020b18',
|
||||||
|
ContainerHover: '#051426',
|
||||||
|
ContainerActive: '#091d34',
|
||||||
|
ContainerLine: '#0e2742',
|
||||||
|
OnContainer: '#DCEAF2',
|
||||||
|
},
|
||||||
|
|
||||||
|
Surface: {
|
||||||
|
Container: '#051426',
|
||||||
|
ContainerHover: '#091d34',
|
||||||
|
ContainerActive: '#0e2742',
|
||||||
|
ContainerLine: '#143150',
|
||||||
|
OnContainer: '#DCEAF2',
|
||||||
|
},
|
||||||
|
|
||||||
|
SurfaceVariant: {
|
||||||
|
Container: '#091d34',
|
||||||
|
ContainerHover: '#0e2742',
|
||||||
|
ContainerActive: '#143150',
|
||||||
|
ContainerLine: '#1a3b5e',
|
||||||
|
OnContainer: '#DCEAF2',
|
||||||
|
},
|
||||||
|
|
||||||
|
Primary: {
|
||||||
|
Main: '#00c9b1',
|
||||||
|
MainHover: '#1ad2bd',
|
||||||
|
MainActive: '#29d7c4',
|
||||||
|
MainLine: '#38dccb',
|
||||||
|
OnMain: '#00231f',
|
||||||
|
Container: '#004c43',
|
||||||
|
ContainerHover: '#00564c',
|
||||||
|
ContainerActive: '#006155',
|
||||||
|
ContainerLine: '#006b5e',
|
||||||
|
OnContainer: '#B3F0E8',
|
||||||
|
},
|
||||||
|
|
||||||
|
Secondary: {
|
||||||
|
Main: '#0096d6',
|
||||||
|
MainHover: '#1aa3dc',
|
||||||
|
MainActive: '#29aadf',
|
||||||
|
MainLine: '#38b1e2',
|
||||||
|
OnMain: '#001a26',
|
||||||
|
Container: '#003a52',
|
||||||
|
ContainerHover: '#00425e',
|
||||||
|
ContainerActive: '#004b6b',
|
||||||
|
ContainerLine: '#005377',
|
||||||
|
OnContainer: '#B3E2F5',
|
||||||
|
},
|
||||||
|
|
||||||
|
Other: {
|
||||||
|
FocusRing: 'rgba(0, 201, 177, 0.5)',
|
||||||
|
Shadow: 'rgba(0, 0, 0, 1)',
|
||||||
|
Overlay: 'rgba(2, 11, 24, 0.9)',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const bloodRedTheme = createTheme(color, {
|
||||||
|
...darkThemeData,
|
||||||
|
Background: {
|
||||||
|
Container: '#0d0203',
|
||||||
|
ContainerHover: '#180608',
|
||||||
|
ContainerActive: '#240a0d',
|
||||||
|
ContainerLine: '#300e12',
|
||||||
|
OnContainer: '#F2DDDD',
|
||||||
|
},
|
||||||
|
|
||||||
|
Surface: {
|
||||||
|
Container: '#180608',
|
||||||
|
ContainerHover: '#240a0d',
|
||||||
|
ContainerActive: '#300e12',
|
||||||
|
ContainerLine: '#3c1318',
|
||||||
|
OnContainer: '#F2DDDD',
|
||||||
|
},
|
||||||
|
|
||||||
|
SurfaceVariant: {
|
||||||
|
Container: '#240a0d',
|
||||||
|
ContainerHover: '#300e12',
|
||||||
|
ContainerActive: '#3c1318',
|
||||||
|
ContainerLine: '#48181e',
|
||||||
|
OnContainer: '#F2DDDD',
|
||||||
|
},
|
||||||
|
|
||||||
|
Primary: {
|
||||||
|
Main: '#ff2233',
|
||||||
|
MainHover: '#ff3d4b',
|
||||||
|
MainActive: '#ff4a57',
|
||||||
|
MainLine: '#ff5763',
|
||||||
|
OnMain: '#330003',
|
||||||
|
Container: '#7a0010',
|
||||||
|
ContainerHover: '#8a0013',
|
||||||
|
ContainerActive: '#990015',
|
||||||
|
ContainerLine: '#a80018',
|
||||||
|
OnContainer: '#FFD1D6',
|
||||||
|
},
|
||||||
|
|
||||||
|
Secondary: {
|
||||||
|
Main: '#FFFFFF',
|
||||||
|
MainHover: '#E5E5E5',
|
||||||
|
MainActive: '#D9D9D9',
|
||||||
|
MainLine: '#CCCCCC',
|
||||||
|
OnMain: '#0d0203',
|
||||||
|
Container: '#3c1318',
|
||||||
|
ContainerHover: '#48181e',
|
||||||
|
ContainerActive: '#541d24',
|
||||||
|
ContainerLine: '#60222a',
|
||||||
|
OnContainer: '#F2DDDD',
|
||||||
|
},
|
||||||
|
|
||||||
|
Other: {
|
||||||
|
FocusRing: 'rgba(255, 34, 51, 0.5)',
|
||||||
|
Shadow: 'rgba(0, 0, 0, 1)',
|
||||||
|
Overlay: 'rgba(13, 2, 3, 0.9)',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const classicMatrixTheme = createTheme(color, {
|
||||||
|
...darkThemeData,
|
||||||
|
Background: {
|
||||||
|
Container: '#000000',
|
||||||
|
ContainerHover: '#0a0f0a',
|
||||||
|
ContainerActive: '#121a12',
|
||||||
|
ContainerLine: '#1c281c',
|
||||||
|
OnContainer: '#C8E6C8',
|
||||||
|
},
|
||||||
|
|
||||||
|
Surface: {
|
||||||
|
Container: '#0a0f0a',
|
||||||
|
ContainerHover: '#121a12',
|
||||||
|
ContainerActive: '#1c281c',
|
||||||
|
ContainerLine: '#263626',
|
||||||
|
OnContainer: '#C8E6C8',
|
||||||
|
},
|
||||||
|
|
||||||
|
SurfaceVariant: {
|
||||||
|
Container: '#121a12',
|
||||||
|
ContainerHover: '#1c281c',
|
||||||
|
ContainerActive: '#263626',
|
||||||
|
ContainerLine: '#304530',
|
||||||
|
OnContainer: '#C8E6C8',
|
||||||
|
},
|
||||||
|
|
||||||
|
Primary: {
|
||||||
|
Main: '#00ff41',
|
||||||
|
MainHover: '#1aff57',
|
||||||
|
MainActive: '#29ff63',
|
||||||
|
MainLine: '#38ff6f',
|
||||||
|
OnMain: '#001a08',
|
||||||
|
Container: '#003311',
|
||||||
|
ContainerHover: '#003d14',
|
||||||
|
ContainerActive: '#004718',
|
||||||
|
ContainerLine: '#00521b',
|
||||||
|
OnContainer: '#9DFFB8',
|
||||||
|
},
|
||||||
|
|
||||||
|
Secondary: {
|
||||||
|
Main: '#C8E6C8',
|
||||||
|
MainHover: '#baddba',
|
||||||
|
MainActive: '#b0d6b0',
|
||||||
|
MainLine: '#a3cca3',
|
||||||
|
OnMain: '#000000',
|
||||||
|
Container: '#263626',
|
||||||
|
ContainerHover: '#304530',
|
||||||
|
ContainerActive: '#3a543a',
|
||||||
|
ContainerLine: '#446344',
|
||||||
|
OnContainer: '#DFF2DF',
|
||||||
|
},
|
||||||
|
|
||||||
|
Other: {
|
||||||
|
FocusRing: 'rgba(0, 255, 65, 0.5)',
|
||||||
|
Shadow: 'rgba(0, 0, 0, 1)',
|
||||||
|
Overlay: 'rgba(0, 0, 0, 0.9)',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const midnightTheme = createTheme(color, {
|
||||||
|
...darkThemeData,
|
||||||
|
Background: {
|
||||||
|
Container: '#111827',
|
||||||
|
ContainerHover: '#1a2234',
|
||||||
|
ContainerActive: '#232d42',
|
||||||
|
ContainerLine: '#2c3850',
|
||||||
|
OnContainer: '#E5E9F0',
|
||||||
|
},
|
||||||
|
|
||||||
|
Surface: {
|
||||||
|
Container: '#1a2234',
|
||||||
|
ContainerHover: '#232d42',
|
||||||
|
ContainerActive: '#2c3850',
|
||||||
|
ContainerLine: '#35435e',
|
||||||
|
OnContainer: '#E5E9F0',
|
||||||
|
},
|
||||||
|
|
||||||
|
SurfaceVariant: {
|
||||||
|
Container: '#232d42',
|
||||||
|
ContainerHover: '#2c3850',
|
||||||
|
ContainerActive: '#35435e',
|
||||||
|
ContainerLine: '#3e4e6c',
|
||||||
|
OnContainer: '#E5E9F0',
|
||||||
|
},
|
||||||
|
|
||||||
|
Primary: {
|
||||||
|
Main: '#6b7ca8',
|
||||||
|
MainHover: '#7989b1',
|
||||||
|
MainActive: '#8493b8',
|
||||||
|
MainLine: '#8f9dbf',
|
||||||
|
OnMain: '#000000',
|
||||||
|
Container: '#2e3a55',
|
||||||
|
ContainerHover: '#354161',
|
||||||
|
ContainerActive: '#3c496d',
|
||||||
|
ContainerLine: '#435179',
|
||||||
|
OnContainer: '#D2DAEC',
|
||||||
|
},
|
||||||
|
|
||||||
|
Secondary: {
|
||||||
|
Main: '#E5E9F0',
|
||||||
|
MainHover: '#d4d9e3',
|
||||||
|
MainActive: '#c9cfdb',
|
||||||
|
MainLine: '#bdc4d3',
|
||||||
|
OnMain: '#111827',
|
||||||
|
Container: '#35435e',
|
||||||
|
ContainerHover: '#3e4e6c',
|
||||||
|
ContainerActive: '#47597a',
|
||||||
|
ContainerLine: '#506488',
|
||||||
|
OnContainer: '#E5E9F0',
|
||||||
|
},
|
||||||
|
|
||||||
|
Other: {
|
||||||
|
FocusRing: 'rgba(107, 124, 168, 0.5)',
|
||||||
|
Shadow: 'rgba(0, 0, 0, 1)',
|
||||||
|
Overlay: 'rgba(17, 24, 39, 0.9)',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
export const lotusTerminalTheme = createTheme(color, {
|
export const lotusTerminalTheme = createTheme(color, {
|
||||||
Background: {
|
Background: {
|
||||||
Container: '#030508',
|
Container: '#030508',
|
||||||
|
|||||||
Reference in New Issue
Block a user