feat(themes): Omarchy catalog, 12 light themes, Dark/Light Appearance picker
Expand the catalog from 11 themes (10 dark, 1 light) to 37 (24/13): all 18 remaining Omarchy defaults (palettes from each theme's colors.toml) plus 8 canonical light themes (Tokyo Night Day, Solarized Light, One Light, Ayu Light, GitHub Light, Gruvbox Light, Everforest Light, Kanagawa Lotus). Lupine leads the light list as the default light theme; the app default stays tokyo-night. Appearance panel: Dark/Light segmented filter (SSR-initialized from the user's current theme), scrollable theme list, Bookshelf section pinned; active row revealed on open. Light themes carry color-scheme: light and the soft-shadow token set. Public-page theme selects get Dark/Light optgroups. New moon/sun icons. tailwind.config: safelist the new theme ids — Tailwind v3 purges custom @layer base class selectors that appear in no scanned content file, so an unsafelisted id silently ships without its CSS (found the hard way). theme.ts: applyTheme now swaps only theme-* classes (changing theme from the login select no longer wipes min-h-screen) and keeps the class in sync on <html> for the new ThemeFlashGuard — a pre-paint inline script on the four public pages that applies the saved theme before first paint. Kanagawa's UI accent uses crystalBlue (#7e9cd8) instead of Omarchy's foreground-as-accent so links stay distinguishable from text.
This commit is contained in:
1 parent
4f913da0b1
commit
d5bb874651
21 files changed
+1120
-289
No files matched your search
+84
-14
@@ -1,25 +1,95 @@
|
||||
package templates
|
||||
|
||||
// ThemeMode classifies a theme for the Appearance panel's Dark/Light filter.
|
||||
type ThemeMode string
|
||||
|
||||
const (
|
||||
ModeDark ThemeMode = "dark"
|
||||
ModeLight ThemeMode = "light"
|
||||
)
|
||||
|
||||
// ThemeOption describes a selectable color theme shown in the header picker.
|
||||
type ThemeOption struct {
|
||||
Name string // CSS theme suffix applied as class theme-<name>
|
||||
Label string // Human-readable label
|
||||
Color string // Hex swatch colour
|
||||
Name string // CSS theme suffix applied as class theme-<name>
|
||||
Label string // Human-readable label
|
||||
Color string // Hex swatch colour
|
||||
Mode ThemeMode // dark or light — drives the panel's mode filter
|
||||
}
|
||||
|
||||
// ThemeOptions is the full set of selectable colour themes, in display order.
|
||||
//
|
||||
// Dark themes come first, light themes after. Each mode's list keeps the
|
||||
// same shape: the default first, then the long-standing classics, then the
|
||||
// newer theme blocks sorted by background luminance (darkest → lightest),
|
||||
// the treatment the Catppuccin run introduced. The light list mirrors the
|
||||
// dark one: counterparts of the classics in the slots their dark siblings
|
||||
// occupy, Catppuccin Latte after them, the Omarchy light block last.
|
||||
var ThemeOptions = []ThemeOption{
|
||||
{"tokyo-night", "Tokyo Night", "#7aa2f7"},
|
||||
{"dracula", "Dracula", "#bd93f9"},
|
||||
{"nord", "Nord", "#88c0d0"},
|
||||
{"solarized-dark", "Solarized Dark", "#2aa198"},
|
||||
{"monokai", "Monokai", "#a6e22e"},
|
||||
{"one-dark-pro", "One Dark Pro", "#61dafb"},
|
||||
{"material-dark", "Material Dark", "#80cbc4"},
|
||||
{"catppuccin-mocha", "Catppuccin Mocha", "#f38ba8"},
|
||||
{"catppuccin-macchiato", "Catppuccin Macchiato", "#c6a0f6"},
|
||||
{"catppuccin-frappe", "Catppuccin Frappé", "#ca9ee6"},
|
||||
{"catppuccin-latte", "Catppuccin Latte", "#d20f39"},
|
||||
// Dark: the original set, order preserved.
|
||||
{"tokyo-night", "Tokyo Night", "#7aa2f7", ModeDark},
|
||||
{"dracula", "Dracula", "#bd93f9", ModeDark},
|
||||
{"nord", "Nord", "#88c0d0", ModeDark},
|
||||
{"solarized-dark", "Solarized Dark", "#2aa198", ModeDark},
|
||||
{"monokai", "Monokai", "#a6e22e", ModeDark},
|
||||
{"one-dark-pro", "One Dark Pro", "#61dafb", ModeDark},
|
||||
{"material-dark", "Material Dark", "#80cbc4", ModeDark},
|
||||
{"catppuccin-mocha", "Catppuccin Mocha", "#f38ba8", ModeDark},
|
||||
{"catppuccin-macchiato", "Catppuccin Macchiato", "#c6a0f6", ModeDark},
|
||||
{"catppuccin-frappe", "Catppuccin Frappé", "#ca9ee6", ModeDark},
|
||||
// Dark: Omarchy defaults, sorted by background luminance. Palettes come
|
||||
// from each theme's colors.toml (github.com/basecamp/omarchy).
|
||||
{"vantablack", "Vantablack", "#8d8d8d", ModeDark},
|
||||
{"last-horizon", "Last Horizon", "#b59790", ModeDark},
|
||||
{"ethereal", "Ethereal", "#7d82d9", ModeDark},
|
||||
{"hackerman", "Hackerman", "#82fb9c", ModeDark},
|
||||
{"matte-black", "Matte Black", "#e68e0d", ModeDark},
|
||||
{"solitude", "Solitude", "#798186", ModeDark},
|
||||
{"retro-82", "Retro 82", "#faa968", ModeDark},
|
||||
{"osaka-jade", "Osaka Jade", "#509475", ModeDark},
|
||||
{"kanagawa", "Kanagawa", "#7e9cd8", ModeDark},
|
||||
{"miasma", "Miasma", "#78824b", ModeDark},
|
||||
{"lumon", "Lumon", "#8bc9eb", ModeDark},
|
||||
{"ristretto", "Ristretto", "#f38d70", ModeDark},
|
||||
{"gruvbox", "Gruvbox", "#7daea3", ModeDark},
|
||||
{"everforest", "Everforest", "#7fbbb3", ModeDark},
|
||||
// Light themes. Lupine leads as the default light theme (the app's
|
||||
// real default remains tokyo-night); then counterparts of the classics.
|
||||
{"lupine", "Lupine", "#3264eb", ModeLight},
|
||||
{"tokyo-night-day", "Tokyo Night Day", "#2e7de9", ModeLight},
|
||||
{"solarized-light", "Solarized Light", "#268bd2", ModeLight},
|
||||
{"one-light", "One Light", "#4078f2", ModeLight},
|
||||
{"ayu-light", "Ayu Light", "#ff9933", ModeLight},
|
||||
{"github-light", "GitHub Light", "#0969da", ModeLight},
|
||||
{"gruvbox-light", "Gruvbox Light", "#076678", ModeLight},
|
||||
{"everforest-light", "Everforest Light", "#3a94c5", ModeLight},
|
||||
{"kanagawa-lotus", "Kanagawa Lotus", "#4d699b", ModeLight},
|
||||
{"catppuccin-latte", "Catppuccin Latte", "#d20f39", ModeLight},
|
||||
// Light: Omarchy defaults, sorted by background luminance.
|
||||
{"rose-pine", "Rosé Pine", "#56949f", ModeLight},
|
||||
{"flexoki-light", "Flexoki Light", "#205ea6", ModeLight},
|
||||
{"white", "White", "#6e6e6e", ModeLight},
|
||||
}
|
||||
|
||||
// ThemeOptionsFor returns the ordered subset of themes for one mode.
|
||||
func ThemeOptionsFor(mode ThemeMode) []ThemeOption {
|
||||
var out []ThemeOption
|
||||
for _, opt := range ThemeOptions {
|
||||
if opt.Mode == mode {
|
||||
out = append(out, opt)
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// ThemeModeOf returns the mode of a theme name. Unknown or empty ids fall
|
||||
// back to dark — the catalog's origin and home of the default theme.
|
||||
func ThemeModeOf(name string) ThemeMode {
|
||||
for _, opt := range ThemeOptions {
|
||||
if opt.Name == name {
|
||||
return opt.Mode
|
||||
}
|
||||
}
|
||||
return ModeDark
|
||||
}
|
||||
|
||||
// WoodOption describes a selectable bookshelf background texture.
|
||||
|
||||
Reference in new issue
Block a user