added theme selection

This commit is contained in:
2026-03-26 02:10:40 +01:00
parent 57c36ab652
commit 85549d41f8
3 changed files with 54 additions and 8 deletions

View File

@@ -30,7 +30,7 @@ try {
---
<!doctype html>
<html lang="en" class={siteConfig.theme}>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width" />
@@ -38,8 +38,12 @@ try {
<meta name="generator" content={Astro.generator} />
<title>{title} | {siteConfig.title}</title>
{siteConfig.custom_css && <style set:html={siteConfig.custom_css} />}
<script is:inline define:vars={{ defaultTheme: siteConfig.theme }}>
const savedTheme = localStorage.getItem('user-theme') || defaultTheme;
document.documentElement.className = savedTheme;
</script>
</head>
<body class={`bg-base text-text selection:bg-surface2 selection:text-text ${siteConfig.theme}`}>
<body class="bg-base text-text selection:bg-surface2 selection:text-text">
<!-- Dynamic Mesh Gradient Background -->
<div class="fixed inset-0 z-[-1] overflow-hidden bg-base">
<div class="absolute top-[-10%] left-[-10%] w-[60%] h-[50%] rounded-full bg-mauve/15 blur-[120px] opacity-70 animate-pulse" style="animation-duration: 10s;"></div>
@@ -48,16 +52,23 @@ try {
</div>
<nav class="max-w-6xl mx-auto px-4 md:px-6 py-4 md:py-8">
<header class="glass px-4 py-3 md:px-6 md:py-4 flex items-center justify-between">
<div>
<header class="glass px-4 py-3 md:px-6 md:py-4 flex flex-col md:flex-row items-center justify-between gap-4">
<div class="w-full md:w-auto text-center md:text-left">
<a href="/" class="text-xl md:text-2xl font-bold bg-clip-text text-transparent bg-gradient-to-r from-mauve to-blue block">
{siteConfig.title}
</a>
<p class="text-[8px] md:text-[10px] text-subtext0 uppercase tracking-widest">{siteConfig.subtitle}</p>
</div>
<div class="flex gap-3 md:gap-4 items-center text-sm md:text-base">
<div class="flex gap-3 md:gap-4 items-center text-sm md:text-base w-full md:w-auto justify-center md:justify-end">
<a href="/" class="text-subtext0 hover:text-text transition-colors">Home</a>
<a href="/admin" class="text-subtext0 hover:text-mauve transition-colors">Admin</a>
<select id="user-theme-switcher" class="bg-surface0/50 text-text border border-surface1 rounded px-2 py-1 text-xs focus:outline-none focus:border-mauve transition-colors cursor-pointer">
<option value="mocha">Mocha</option>
<option value="macchiato">Macchiato</option>
<option value="frappe">Frappe</option>
<option value="latte">Latte</option>
<option value="scaled-and-icy">Scaled and Icy</option>
</select>
</div>
</header>
</nav>
@@ -72,5 +83,21 @@ try {
&copy; {new Date().getFullYear()} {siteConfig.title}
</div>
</footer>
<script is:inline define:vars={{ defaultTheme: siteConfig.theme }}>
document.addEventListener('DOMContentLoaded', () => {
const switcher = document.getElementById('user-theme-switcher');
if (switcher) {
const savedTheme = localStorage.getItem('user-theme') || defaultTheme;
switcher.value = savedTheme;
switcher.addEventListener('change', (e) => {
const newTheme = e.target.value;
localStorage.setItem('user-theme', newTheme);
document.documentElement.className = newTheme;
});
}
});
</script>
</body>
</html>

View File

@@ -44,6 +44,7 @@ import AdminLayout from '../../layouts/AdminLayout.astro';
<option value="macchiato">Macchiato (Dark, Medium Contrast)</option>
<option value="frappe">Frappe (Dark, Low Contrast)</option>
<option value="latte">Latte (Light Mode)</option>
<option value="scaled-and-icy">Scaled and Icy (Vibrant Light)</option>
</select>
<p class="text-[10px] text-subtext0 mt-1">Select a predefined Catppuccin color palette.</p>
</div>

View File

@@ -67,9 +67,9 @@
.latte {
--crust: #e6e9ef; --mantle: #dce0e8; --base: #eff1f5;
--surface0: #e6e9ef; --surface1: #bcc0cc; --surface2: #acb0be;
--surface0: #ccd0da; --surface1: #bcc0cc; --surface2: #acb0be;
--overlay0: #9ca0b0; --overlay1: #8c8fa1; --overlay2: #7c7f93;
--text: #1e1e2e; --subtext0: #4c4f69; --subtext1: #5c5f77;
--text: #4c4f69; --subtext0: #5c5f77; --subtext1: #6c6f85;
--blue: #1e66f5; --lavender: #7287fd; --sapphire: #209fb5;
--sky: #04a5e5; --teal: #179299; --green: #40a02b;
--yellow: #df8e1d; --peach: #fe640b; --maroon: #e64553;
@@ -77,6 +77,18 @@
--flamingo: #dd7878; --rosewater: #dc8a78;
}
.scaled-and-icy {
--crust: #ffffff; --mantle: #f8f9fa; --base: #f0f2f5;
--surface0: #e4e7eb; --surface1: #d1d5db; --surface2: #9ca3af;
--overlay0: #6b7280; --overlay1: #4b5563; --overlay2: #374151;
--text: #111827; --subtext0: #374151; --subtext1: #4b5563;
--blue: #5cdbdf; --lavender: #8ab4f8; --sapphire: #38bdf8;
--sky: #0ea5e9; --teal: #2dd4bf; --green: #34d399;
--yellow: #fcd34d; --peach: #fbbf24; --maroon: #f43f5e;
--red: #ef4444; --mauve: #f0498b; --pink: #ec4899;
--flamingo: #f472b6; --rosewater: #fda4af;
}
body {
background-color: var(--base);
color: var(--text) !important;
@@ -99,6 +111,8 @@ body {
.cm-s-narlblog .CodeMirror-cursor { border-left-color: var(--text) !important; }
.cm-s-narlblog.cm-fat-cursor .CodeMirror-cursor { background: var(--text) !important; }
.cm-s-narlblog .CodeMirror-selected { background: var(--surface2) !important; }
.cm-s-narlblog .CodeMirror-line::selection, .cm-s-narlblog .CodeMirror-line > span::selection, .cm-s-narlblog .CodeMirror-line > span > span::selection { background: var(--surface2); }
.cm-s-narlblog .CodeMirror-line::-moz-selection, .cm-s-narlblog .CodeMirror-line > span::-moz-selection, .cm-s-narlblog .CodeMirror-line > span > span::-moz-selection { background: var(--surface2); }
/* Dynamic Highlight.js Theme */
.hljs { color: var(--text) !important; background: transparent !important; }
@@ -113,6 +127,10 @@ body {
.hljs-symbol, .hljs-bullet { color: var(--pink) !important; }
.hljs-built_in, .hljs-builtin-name { color: var(--red) !important; }
.hljs-meta { color: var(--overlay1) !important; font-weight: bold; }
.hljs-deletion { background: var(--maroon); color: var(--crust); }
.hljs-addition { background: var(--green); color: var(--crust); }
.hljs-emphasis { font-style: italic; }
.hljs-strong { font-weight: bold; }
/* Typography styles for Markdown */
.prose { color: var(--text) !important; }
@@ -132,7 +150,7 @@ body {
.glass {
background-color: color-mix(in srgb, var(--surface0) 60%, transparent);
backdrop-filter: blur(12px);
border: 1px solid rgba(255, 255, 255, 0.05);
border: 1px solid color-mix(in srgb, var(--text) 10%, transparent);
box-shadow: 0 10px 30px -10px rgba(0, 0, 0, 0.5);
border-radius: 1rem;
}