From 468195357e91dbaea51bf987770b31e761cd8e37 Mon Sep 17 00:00:00 2001 From: Tymek Date: Sat, 14 Feb 2026 02:09:54 +0100 Subject: [PATCH 1/2] Add Catppuccin themes --- package-lock.json | 17 ++++++ package.json | 1 + src/app/hooks/useTheme.ts | 53 +++++++++++++++++- src/colors.css.ts | 115 +++++++++++++++++++++++++++++++++++++- src/index.css | 5 +- 5 files changed, 187 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4c12e9db..365a1615 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,7 @@ "@atlaskit/pragmatic-drag-and-drop": "1.1.6", "@atlaskit/pragmatic-drag-and-drop-auto-scroll": "1.3.0", "@atlaskit/pragmatic-drag-and-drop-hitbox": "1.0.3", + "@catppuccin/palette": "1.7.1", "@fontsource/inter": "4.5.14", "@tanstack/react-query": "5.24.1", "@tanstack/react-query-devtools": "5.24.1", @@ -1649,6 +1650,22 @@ "node": ">=6.9.0" } }, + "node_modules/@catppuccin/palette": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/@catppuccin/palette/-/palette-1.7.1.tgz", + "integrity": "sha512-aRc1tbzrevOTV7nFTT9SRdF26w/MIwT4Jwt4fDMc9itRZUDXCuEDBLyz4TQMlqO9ZP8mf5Hu4Jr6D03NLFc6Gw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/catppuccin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/catppuccin" + } + ], + "license": "MIT" + }, "node_modules/@emotion/hash": { "version": "0.9.2", "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz", diff --git a/package.json b/package.json index 00535bd8..c26e24a5 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "@atlaskit/pragmatic-drag-and-drop": "1.1.6", "@atlaskit/pragmatic-drag-and-drop-auto-scroll": "1.3.0", "@atlaskit/pragmatic-drag-and-drop-hitbox": "1.0.3", + "@catppuccin/palette": "1.7.1", "@fontsource/inter": "4.5.14", "@tanstack/react-query": "5.24.1", "@tanstack/react-query-devtools": "5.24.1", diff --git a/src/app/hooks/useTheme.ts b/src/app/hooks/useTheme.ts index cdbb9dba..8d7c8349 100644 --- a/src/app/hooks/useTheme.ts +++ b/src/app/hooks/useTheme.ts @@ -1,7 +1,15 @@ import { lightTheme } from 'folds'; import { createContext, useContext, useEffect, useMemo, useState } from 'react'; import { onDarkFontWeight, onLightFontWeight } from '../../config.css'; -import { butterTheme, darkTheme, silverTheme } from '../../colors.css'; +import { + butterTheme, + darkTheme, + silverTheme, + catppuccinMochaTheme, + catppuccinMacchiatoTheme, + catppuccinFrappeTheme, + catppuccinLatteTheme, +} from '../../colors.css'; import { settingsAtom } from '../state/settings'; import { useSetting } from '../state/hooks/settings'; @@ -21,6 +29,11 @@ export const LightTheme: Theme = { kind: ThemeKind.Light, classNames: [lightTheme, onLightFontWeight, 'prism-light'], }; +export const CatppuccinLatteTheme: Theme = { + id: 'catppuccin-latte-theme', + kind: ThemeKind.Light, + classNames: ['catppuccin-latte-theme', catppuccinLatteTheme, onLightFontWeight, 'prism-light'], +}; export const SilverTheme: Theme = { id: 'silver-theme', @@ -37,9 +50,41 @@ export const ButterTheme: Theme = { kind: ThemeKind.Dark, classNames: ['butter-theme', butterTheme, onDarkFontWeight, 'prism-dark'], }; +export const CatppuccinFrappeTheme: Theme = { + id: 'catppuccin-frappe-theme', + kind: ThemeKind.Dark, + classNames: ['catppuccin-frappe-theme', catppuccinFrappeTheme, onDarkFontWeight, 'prism-dark'], +}; +export const CatppuccinMacchiatoTheme: Theme = { + id: 'catppuccin-macchiato-theme', + kind: ThemeKind.Dark, + classNames: [ + 'catppuccin-macchiato-theme', + catppuccinMacchiatoTheme, + onDarkFontWeight, + 'prism-dark', + ], +}; +export const CatppuccinMochaTheme: Theme = { + id: 'catppuccin-mocha-theme', + kind: ThemeKind.Dark, + classNames: ['catppuccin-mocha-theme', catppuccinMochaTheme, onDarkFontWeight, 'prism-dark'], +}; export const useThemes = (): Theme[] => { - const themes: Theme[] = useMemo(() => [LightTheme, SilverTheme, DarkTheme, ButterTheme], []); + const themes: Theme[] = useMemo( + () => [ + LightTheme, + SilverTheme, + DarkTheme, + ButterTheme, + CatppuccinLatteTheme, + CatppuccinFrappeTheme, + CatppuccinMacchiatoTheme, + CatppuccinMochaTheme, + ], + [] + ); return themes; }; @@ -51,6 +96,10 @@ export const useThemeNames = (): Record => [SilverTheme.id]: 'Silver', [DarkTheme.id]: 'Dark', [ButterTheme.id]: 'Butter', + [CatppuccinLatteTheme.id]: 'Catppuccin Latte', + [CatppuccinFrappeTheme.id]: 'Catppuccin Frappe', + [CatppuccinMacchiatoTheme.id]: 'Catppuccin Macchiato', + [CatppuccinMochaTheme.id]: 'Catppuccin Mocha', }), [] ); diff --git a/src/colors.css.ts b/src/colors.css.ts index 268cbf78..ea050d70 100644 --- a/src/colors.css.ts +++ b/src/colors.css.ts @@ -1,5 +1,8 @@ import { createTheme } from '@vanilla-extract/css'; import { color } from 'folds'; +import { flavors, FlavorName, ColorName } from '@catppuccin/palette'; + +type ThemeConfig = Parameters>[1]; export const silverTheme = createTheme(color, { Background: { @@ -98,7 +101,7 @@ export const silverTheme = createTheme(color, { }, }); -const darkThemeData = { +const darkThemeData: ThemeConfig = { Background: { Container: '#1A1A1A', ContainerHover: '#262626', @@ -236,3 +239,113 @@ export const butterTheme = createTheme(color, { OnContainer: '#F2EED3', }, }); + +const catppuccinTheme = (flavor: FlavorName): ThemeConfig => { + const c = (colorName: ColorName, opacity?: number) => { + const { r, g, b } = flavors[flavor].colors[colorName].rgb; + return opacity ? `rgba(${r}, ${g}, ${b}, ${opacity / 100})` : `rgb(${r}, ${g}, ${b})`; + }; + + return { + ...darkThemeData, + Background: { + Container: c('mantle'), + ContainerHover: c('base'), + ContainerActive: c('surface0'), + ContainerLine: c('surface1'), + OnContainer: c('text'), + }, + + Surface: { + Container: c('base'), + ContainerHover: c('surface0'), + ContainerActive: c('surface1'), + ContainerLine: c('surface2'), + OnContainer: c('text'), + }, + + SurfaceVariant: { + Container: c('mantle'), + ContainerHover: c('mantle', 50), + ContainerActive: c('surface0'), + ContainerLine: c('surface1'), + OnContainer: c('text'), + }, + + Primary: { + Main: c('mauve'), + MainHover: c('mauve', 85), + MainActive: c('mauve', 70), + MainLine: 'transparent', + OnMain: c('base'), + Container: c('mauve', 10), + ContainerHover: c('mauve', 15), + ContainerActive: c('mauve', 10), + ContainerLine: 'transparent', + OnContainer: c('mauve'), + }, + + Secondary: { + Main: c('subtext1'), + MainHover: c('subtext0'), + MainActive: c('overlay2'), + MainLine: 'transparent', + OnMain: c('base'), + Container: c('surface0'), + ContainerHover: c('surface1'), + ContainerActive: c('surface2'), + ContainerLine: c('overlay0'), + OnContainer: c('text'), + }, + + Success: { + Main: c('green'), + MainHover: c('green', 85), + MainActive: c('green', 70), + MainLine: 'transparent', + OnMain: c('mantle'), + Container: c('surface0'), + ContainerHover: c('green', 20), + ContainerActive: c('green', 15), + ContainerLine: c('surface0'), + OnContainer: c('green'), + }, + + Warning: { + Main: c('peach'), + MainHover: c('peach', 85), + MainActive: c('peach', 70), + MainLine: 'transparent', + OnMain: c('mantle'), + Container: c('surface0'), + ContainerHover: c('peach', 20), + ContainerActive: c('peach', 15), + ContainerLine: c('surface0'), + OnContainer: c('peach'), + }, + + Critical: { + Main: c('red'), + MainHover: c('red', 85), + MainActive: c('red', 70), + MainLine: 'transparent', + OnMain: c('mantle'), + Container: c('mantle'), + ContainerHover: c('red', 20), + ContainerActive: c('red', 15), + ContainerLine: c('surface0'), + OnContainer: c('red'), + }, + + Other: { + FocusRing: 'rgba(0 0 0 / 50%)', + Shadow: 'rgba(0 0 0 / 20%)', + Overlay: 'rgba(17, 17, 27, 0.6)', + }, + }; +}; + +export const catppuccinLatteTheme = createTheme(color, catppuccinTheme('latte')); +export const catppuccinFrappeTheme = createTheme(color, catppuccinTheme('frappe')); +export const catppuccinMacchiatoTheme = createTheme(color, catppuccinTheme('macchiato')); +export const catppuccinMochaTheme = createTheme(color, catppuccinTheme('mocha')); diff --git a/src/index.css b/src/index.css index ca28536d..d4b25371 100644 --- a/src/index.css +++ b/src/index.css @@ -23,7 +23,10 @@ } .dark-theme, -.butter-theme { +.butter-theme, +.catppuccin-frappe-theme, +.catppuccin-macchiato-theme, +.catppuccin-mocha-theme { --tc-link: hsl(213deg 100% 80%); --mx-uc-1: hsl(208, 100%, 75%); From 9c90d02d625dbd7cbed08cfa9e08d0a851e3682f Mon Sep 17 00:00:00 2001 From: Tymek Date: Sat, 14 Feb 2026 02:32:26 +0100 Subject: [PATCH 2/2] Fix typo --- src/app/hooks/useTheme.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/hooks/useTheme.ts b/src/app/hooks/useTheme.ts index 8d7c8349..535d7083 100644 --- a/src/app/hooks/useTheme.ts +++ b/src/app/hooks/useTheme.ts @@ -97,7 +97,7 @@ export const useThemeNames = (): Record => [DarkTheme.id]: 'Dark', [ButterTheme.id]: 'Butter', [CatppuccinLatteTheme.id]: 'Catppuccin Latte', - [CatppuccinFrappeTheme.id]: 'Catppuccin Frappe', + [CatppuccinFrappeTheme.id]: 'Catppuccin Frappé', [CatppuccinMacchiatoTheme.id]: 'Catppuccin Macchiato', [CatppuccinMochaTheme.id]: 'Catppuccin Mocha', }),