diff --git a/astro.config.mjs b/astro.config.mjs
index df86a5c..3447f60 100644
--- a/astro.config.mjs
+++ b/astro.config.mjs
@@ -27,6 +27,12 @@ export default defineConfig({
starlight({
title: 'The App Fair Project',
favicon: '/favicon.png',
+ head: [
+ {
+ tag: 'script',
+ content: `(function(){try{var t=localStorage.getItem('appfair-theme-style');if(t&&t!=='original'){document.documentElement.setAttribute('data-theme-style',t);}}catch(e){}})();`,
+ },
+ ],
logo: {
src: './public/assets/icons/appfair-icon.svg',
replacesTitle: true,
diff --git a/public/assets/fonts/themes/brutalist/archivo-black-400.woff2 b/public/assets/fonts/themes/brutalist/archivo-black-400.woff2
new file mode 100644
index 0000000..a88b0b5
Binary files /dev/null and b/public/assets/fonts/themes/brutalist/archivo-black-400.woff2 differ
diff --git a/public/assets/fonts/themes/brutalist/space-mono-400.woff2 b/public/assets/fonts/themes/brutalist/space-mono-400.woff2
new file mode 100644
index 0000000..2752f60
Binary files /dev/null and b/public/assets/fonts/themes/brutalist/space-mono-400.woff2 differ
diff --git a/public/assets/fonts/themes/brutalist/space-mono-700.woff2 b/public/assets/fonts/themes/brutalist/space-mono-700.woff2
new file mode 100644
index 0000000..6563bad
Binary files /dev/null and b/public/assets/fonts/themes/brutalist/space-mono-700.woff2 differ
diff --git a/public/assets/fonts/themes/cyberpunk/jetbrains-mono-400.woff2 b/public/assets/fonts/themes/cyberpunk/jetbrains-mono-400.woff2
new file mode 100644
index 0000000..5858873
Binary files /dev/null and b/public/assets/fonts/themes/cyberpunk/jetbrains-mono-400.woff2 differ
diff --git a/public/assets/fonts/themes/cyberpunk/jetbrains-mono-700.woff2 b/public/assets/fonts/themes/cyberpunk/jetbrains-mono-700.woff2
new file mode 100644
index 0000000..3a4e333
Binary files /dev/null and b/public/assets/fonts/themes/cyberpunk/jetbrains-mono-700.woff2 differ
diff --git a/public/assets/fonts/themes/cyberpunk/major-mono-400.woff2 b/public/assets/fonts/themes/cyberpunk/major-mono-400.woff2
new file mode 100644
index 0000000..1624f0c
Binary files /dev/null and b/public/assets/fonts/themes/cyberpunk/major-mono-400.woff2 differ
diff --git a/public/assets/fonts/themes/dharma/ibm-plex-mono-400.woff2 b/public/assets/fonts/themes/dharma/ibm-plex-mono-400.woff2
new file mode 100644
index 0000000..0804aaf
Binary files /dev/null and b/public/assets/fonts/themes/dharma/ibm-plex-mono-400.woff2 differ
diff --git a/public/assets/fonts/themes/dharma/ibm-plex-mono-700.woff2 b/public/assets/fonts/themes/dharma/ibm-plex-mono-700.woff2
new file mode 100644
index 0000000..5d7ff0c
Binary files /dev/null and b/public/assets/fonts/themes/dharma/ibm-plex-mono-700.woff2 differ
diff --git a/public/assets/fonts/themes/futurism/barlow-condensed-400.woff2 b/public/assets/fonts/themes/futurism/barlow-condensed-400.woff2
new file mode 100644
index 0000000..ebb34ad
Binary files /dev/null and b/public/assets/fonts/themes/futurism/barlow-condensed-400.woff2 differ
diff --git a/public/assets/fonts/themes/futurism/barlow-condensed-700.woff2 b/public/assets/fonts/themes/futurism/barlow-condensed-700.woff2
new file mode 100644
index 0000000..3726e9d
Binary files /dev/null and b/public/assets/fonts/themes/futurism/barlow-condensed-700.woff2 differ
diff --git a/public/assets/fonts/themes/futurism/bebas-neue-400.woff2 b/public/assets/fonts/themes/futurism/bebas-neue-400.woff2
new file mode 100644
index 0000000..92d6a0f
Binary files /dev/null and b/public/assets/fonts/themes/futurism/bebas-neue-400.woff2 differ
diff --git a/public/assets/fonts/themes/herbarium/eb-garamond-400.woff2 b/public/assets/fonts/themes/herbarium/eb-garamond-400.woff2
new file mode 100644
index 0000000..ffed311
Binary files /dev/null and b/public/assets/fonts/themes/herbarium/eb-garamond-400.woff2 differ
diff --git a/public/assets/fonts/themes/herbarium/eb-garamond-700.woff2 b/public/assets/fonts/themes/herbarium/eb-garamond-700.woff2
new file mode 100644
index 0000000..85d5209
Binary files /dev/null and b/public/assets/fonts/themes/herbarium/eb-garamond-700.woff2 differ
diff --git a/public/assets/fonts/themes/herbarium/italianno-400.woff2 b/public/assets/fonts/themes/herbarium/italianno-400.woff2
new file mode 100644
index 0000000..a4dbe3e
Binary files /dev/null and b/public/assets/fonts/themes/herbarium/italianno-400.woff2 differ
diff --git a/public/assets/fonts/themes/memphis/fjalla-one-400.woff2 b/public/assets/fonts/themes/memphis/fjalla-one-400.woff2
new file mode 100644
index 0000000..c11e512
Binary files /dev/null and b/public/assets/fonts/themes/memphis/fjalla-one-400.woff2 differ
diff --git a/public/assets/fonts/themes/memphis/lexend-400.woff2 b/public/assets/fonts/themes/memphis/lexend-400.woff2
new file mode 100644
index 0000000..a656473
Binary files /dev/null and b/public/assets/fonts/themes/memphis/lexend-400.woff2 differ
diff --git a/public/assets/fonts/themes/memphis/lexend-700.woff2 b/public/assets/fonts/themes/memphis/lexend-700.woff2
new file mode 100644
index 0000000..1639b34
Binary files /dev/null and b/public/assets/fonts/themes/memphis/lexend-700.woff2 differ
diff --git a/public/assets/fonts/themes/minimalist/inter-400.woff2 b/public/assets/fonts/themes/minimalist/inter-400.woff2
new file mode 100644
index 0000000..f15b025
Binary files /dev/null and b/public/assets/fonts/themes/minimalist/inter-400.woff2 differ
diff --git a/public/assets/fonts/themes/minimalist/inter-700.woff2 b/public/assets/fonts/themes/minimalist/inter-700.woff2
new file mode 100644
index 0000000..a68fb10
Binary files /dev/null and b/public/assets/fonts/themes/minimalist/inter-700.woff2 differ
diff --git a/public/assets/fonts/themes/natural/fraunces-400.woff2 b/public/assets/fonts/themes/natural/fraunces-400.woff2
new file mode 100644
index 0000000..83cbd8f
Binary files /dev/null and b/public/assets/fonts/themes/natural/fraunces-400.woff2 differ
diff --git a/public/assets/fonts/themes/natural/fraunces-700.woff2 b/public/assets/fonts/themes/natural/fraunces-700.woff2
new file mode 100644
index 0000000..71bbace
Binary files /dev/null and b/public/assets/fonts/themes/natural/fraunces-700.woff2 differ
diff --git a/public/assets/fonts/themes/natural/karla-400.woff2 b/public/assets/fonts/themes/natural/karla-400.woff2
new file mode 100644
index 0000000..afdcd56
Binary files /dev/null and b/public/assets/fonts/themes/natural/karla-400.woff2 differ
diff --git a/public/assets/fonts/themes/natural/karla-700.woff2 b/public/assets/fonts/themes/natural/karla-700.woff2
new file mode 100644
index 0000000..de136ca
Binary files /dev/null and b/public/assets/fonts/themes/natural/karla-700.woff2 differ
diff --git a/public/assets/fonts/themes/newspaper/playfair-400.woff2 b/public/assets/fonts/themes/newspaper/playfair-400.woff2
new file mode 100644
index 0000000..141ea84
Binary files /dev/null and b/public/assets/fonts/themes/newspaper/playfair-400.woff2 differ
diff --git a/public/assets/fonts/themes/newspaper/playfair-700.woff2 b/public/assets/fonts/themes/newspaper/playfair-700.woff2
new file mode 100644
index 0000000..39eefe0
Binary files /dev/null and b/public/assets/fonts/themes/newspaper/playfair-700.woff2 differ
diff --git a/public/assets/fonts/themes/newspaper/pt-serif-400.woff2 b/public/assets/fonts/themes/newspaper/pt-serif-400.woff2
new file mode 100644
index 0000000..02448bc
Binary files /dev/null and b/public/assets/fonts/themes/newspaper/pt-serif-400.woff2 differ
diff --git a/public/assets/fonts/themes/newspaper/pt-serif-700.woff2 b/public/assets/fonts/themes/newspaper/pt-serif-700.woff2
new file mode 100644
index 0000000..b7aaf51
Binary files /dev/null and b/public/assets/fonts/themes/newspaper/pt-serif-700.woff2 differ
diff --git a/public/assets/fonts/themes/protest/anton-400.woff2 b/public/assets/fonts/themes/protest/anton-400.woff2
new file mode 100644
index 0000000..69d48b9
Binary files /dev/null and b/public/assets/fonts/themes/protest/anton-400.woff2 differ
diff --git a/public/assets/fonts/themes/protest/special-elite-400.woff2 b/public/assets/fonts/themes/protest/special-elite-400.woff2
new file mode 100644
index 0000000..569a27e
Binary files /dev/null and b/public/assets/fonts/themes/protest/special-elite-400.woff2 differ
diff --git a/public/assets/fonts/themes/solarpunk/marcellus-400.woff2 b/public/assets/fonts/themes/solarpunk/marcellus-400.woff2
new file mode 100644
index 0000000..e765ed6
Binary files /dev/null and b/public/assets/fonts/themes/solarpunk/marcellus-400.woff2 differ
diff --git a/public/assets/fonts/themes/solarpunk/sora-400.woff2 b/public/assets/fonts/themes/solarpunk/sora-400.woff2
new file mode 100644
index 0000000..99ede34
Binary files /dev/null and b/public/assets/fonts/themes/solarpunk/sora-400.woff2 differ
diff --git a/public/assets/fonts/themes/solarpunk/sora-700.woff2 b/public/assets/fonts/themes/solarpunk/sora-700.woff2
new file mode 100644
index 0000000..930c60f
Binary files /dev/null and b/public/assets/fonts/themes/solarpunk/sora-700.woff2 differ
diff --git a/public/assets/fonts/themes/space-age/orbitron-700.woff2 b/public/assets/fonts/themes/space-age/orbitron-700.woff2
new file mode 100644
index 0000000..46db8dd
Binary files /dev/null and b/public/assets/fonts/themes/space-age/orbitron-700.woff2 differ
diff --git a/public/assets/fonts/themes/space-age/quicksand-400.woff2 b/public/assets/fonts/themes/space-age/quicksand-400.woff2
new file mode 100644
index 0000000..8018cfd
Binary files /dev/null and b/public/assets/fonts/themes/space-age/quicksand-400.woff2 differ
diff --git a/public/assets/fonts/themes/space-age/quicksand-700.woff2 b/public/assets/fonts/themes/space-age/quicksand-700.woff2
new file mode 100644
index 0000000..42f7a0b
Binary files /dev/null and b/public/assets/fonts/themes/space-age/quicksand-700.woff2 differ
diff --git a/public/assets/fonts/themes/sumi-e/cormorant-400.woff2 b/public/assets/fonts/themes/sumi-e/cormorant-400.woff2
new file mode 100644
index 0000000..096df0a
Binary files /dev/null and b/public/assets/fonts/themes/sumi-e/cormorant-400.woff2 differ
diff --git a/public/assets/fonts/themes/sumi-e/noto-serif-jp-400.woff2 b/public/assets/fonts/themes/sumi-e/noto-serif-jp-400.woff2
new file mode 100644
index 0000000..0ee56d4
Binary files /dev/null and b/public/assets/fonts/themes/sumi-e/noto-serif-jp-400.woff2 differ
diff --git a/public/assets/fonts/themes/sumi-e/noto-serif-jp-700.woff2 b/public/assets/fonts/themes/sumi-e/noto-serif-jp-700.woff2
new file mode 100644
index 0000000..f3e23ad
Binary files /dev/null and b/public/assets/fonts/themes/sumi-e/noto-serif-jp-700.woff2 differ
diff --git a/public/assets/fonts/themes/syndicalist/big-shoulders-display-700.woff2 b/public/assets/fonts/themes/syndicalist/big-shoulders-display-700.woff2
new file mode 100644
index 0000000..bddf629
Binary files /dev/null and b/public/assets/fonts/themes/syndicalist/big-shoulders-display-700.woff2 differ
diff --git a/public/assets/fonts/themes/syndicalist/roboto-slab-400.woff2 b/public/assets/fonts/themes/syndicalist/roboto-slab-400.woff2
new file mode 100644
index 0000000..490784f
Binary files /dev/null and b/public/assets/fonts/themes/syndicalist/roboto-slab-400.woff2 differ
diff --git a/public/assets/fonts/themes/syndicalist/roboto-slab-700.woff2 b/public/assets/fonts/themes/syndicalist/roboto-slab-700.woff2
new file mode 100644
index 0000000..8b3858c
Binary files /dev/null and b/public/assets/fonts/themes/syndicalist/roboto-slab-700.woff2 differ
diff --git a/public/assets/fonts/themes/whole-earth/bevan-400.woff2 b/public/assets/fonts/themes/whole-earth/bevan-400.woff2
new file mode 100644
index 0000000..95549ab
Binary files /dev/null and b/public/assets/fonts/themes/whole-earth/bevan-400.woff2 differ
diff --git a/public/assets/fonts/themes/whole-earth/special-elite-400.woff2 b/public/assets/fonts/themes/whole-earth/special-elite-400.woff2
new file mode 100644
index 0000000..569a27e
Binary files /dev/null and b/public/assets/fonts/themes/whole-earth/special-elite-400.woff2 differ
diff --git a/src/components/CustomHeader.astro b/src/components/CustomHeader.astro
index ffa4374..593407b 100644
--- a/src/components/CustomHeader.astro
+++ b/src/components/CustomHeader.astro
@@ -6,6 +6,7 @@ import Search from '@astrojs/starlight/components/Search.astro';
import SiteTitle from './SiteTitle.astro';
import SocialIcons from '@astrojs/starlight/components/SocialIcons.astro';
import ThemeSelect from './ThemeSelect.astro';
+import ThemeStyleSelect from './ThemeStyleSelect.astro';
const curLocale = Astro.locals.starlightRoute.locale;
const slug = Astro.locals.starlightRoute.entry.slug;
@@ -63,6 +64,7 @@ const links: Link[] = [
{/* — disabled until the docs site has translations to offer */}
+
diff --git a/src/components/ThemeStyleSelect.astro b/src/components/ThemeStyleSelect.astro
new file mode 100644
index 0000000..4ca7199
--- /dev/null
+++ b/src/components/ThemeStyleSelect.astro
@@ -0,0 +1,120 @@
+---
+import { Icon } from '@astrojs/starlight/components';
+---
+
+
+
+
+
+
+
+
diff --git a/src/styles/custom.css b/src/styles/custom.css
index 59dd20a..eba6321 100644
--- a/src/styles/custom.css
+++ b/src/styles/custom.css
@@ -1,4 +1,21 @@
+/* ---- Selectable site themes (loaded before all other rules) ---- */
+@import './themes/futurism.css';
+@import './themes/space-age.css';
+@import './themes/dharma.css';
+@import './themes/minimalist.css';
+@import './themes/natural.css';
+@import './themes/solarpunk.css';
+@import './themes/brutalist.css';
+@import './themes/cyberpunk.css';
+@import './themes/newspaper.css';
+@import './themes/sumi-e.css';
+@import './themes/memphis.css';
+@import './themes/herbarium.css';
+@import './themes/protest.css';
+@import './themes/whole-earth.css';
+@import './themes/syndicalist.css';
+
/* See theme editor at https://starlight.astro.build/guides/css-and-tailwind/#color-theme-editor */
/* Material Symbols Rounded icon font */
diff --git a/src/styles/themes/brutalist.css b/src/styles/themes/brutalist.css
new file mode 100644
index 0000000..262d3ca
--- /dev/null
+++ b/src/styles/themes/brutalist.css
@@ -0,0 +1,91 @@
+/* ======================================================================
+ THEME: Brutalist Concrete
+ Raw, harsh, mid-century concrete. Pure black, raw concrete grey, hi-vis
+ orange single accent. Heavy display headings, monospace body. No rounded
+ corners, dense layouts.
+ ====================================================================== */
+
+@font-face {
+ font-family: "Archivo Black";
+ src: url('/assets/fonts/themes/brutalist/archivo-black-400.woff2') format('woff2');
+ font-weight: 400; font-style: normal; font-display: swap;
+}
+@font-face {
+ font-family: "Space Mono";
+ src: url('/assets/fonts/themes/brutalist/space-mono-400.woff2') format('woff2');
+ font-weight: 400; font-style: normal; font-display: swap;
+}
+@font-face {
+ font-family: "Space Mono";
+ src: url('/assets/fonts/themes/brutalist/space-mono-700.woff2') format('woff2');
+ font-weight: 700; font-style: normal; font-display: swap;
+}
+
+/* ---- Dark mode (default) ---- */
+:root[data-theme-style="brutalist"] {
+ --sl-color-black: #000000;
+ --sl-color-bg: #000000;
+ --sl-color-bg-nav: #000000;
+ --sl-color-bg-sidebar: #0a0a0a;
+ --sl-color-bg-inline-code: #1a1a1a;
+ --sl-color-white: #f0f0ec;
+ --sl-color-gray-1: #d4d4d0;
+ --sl-color-gray-2: #a8a8a4;
+ --sl-color-gray-3: #7c7c78;
+ --sl-color-gray-4: #50504c;
+ --sl-color-gray-5: #2a2a26;
+ --sl-color-gray-6: #16161a;
+ --sl-color-gray-7: #0a0a0a;
+ --sl-color-accent-low: #3a1c00;
+ --sl-color-accent: #ff6b00;
+ --sl-color-accent-high: #ffa066;
+ --sl-color-text: #c4c4c0;
+ --sl-color-text-accent: #ff6b00;
+
+ --theme-font-body: "Space Mono", "JetBrains Mono", "Courier New", ui-monospace, monospace;
+ --theme-font-heading: "Archivo Black", "Helvetica Black", Impact, sans-serif;
+}
+
+/* ---- Light mode ---- */
+:root[data-theme="light"][data-theme-style="brutalist"] {
+ --sl-color-black: #d4d2cb;
+ --sl-color-bg: #d4d2cb;
+ --sl-color-bg-nav: #d4d2cb;
+ --sl-color-bg-sidebar: #c2c0b8;
+ --sl-color-bg-inline-code: #b0aea5;
+ --sl-color-white: #000000;
+ --sl-color-gray-1: #0a0a0a;
+ --sl-color-gray-2: #1c1c1c;
+ --sl-color-gray-3: #3a3a36;
+ --sl-color-gray-4: #5e5e58;
+ --sl-color-gray-5: #8a8884;
+ --sl-color-gray-6: #b0aea5;
+ --sl-color-gray-7: #c2c0b8;
+ --sl-color-accent-low: #ffd9b8;
+ --sl-color-accent: #c44a00;
+ --sl-color-accent-high: #8a3300;
+ --sl-color-text: #1a1a1a;
+ --sl-color-text-accent: #c44a00;
+}
+
+/* ---- Typography & harsh structural rules ---- */
+[data-theme-style="brutalist"] body { font-family: var(--theme-font-body); font-weight: 400; letter-spacing: -0.02em; }
+[data-theme-style="brutalist"] h1,
+[data-theme-style="brutalist"] h2,
+[data-theme-style="brutalist"] h3,
+[data-theme-style="brutalist"] h4,
+[data-theme-style="brutalist"] h5,
+[data-theme-style="brutalist"] h6 {
+ font-family: var(--theme-font-heading);
+ font-weight: 400;
+ text-transform: uppercase;
+ letter-spacing: -0.01em;
+ line-height: 1;
+}
+[data-theme-style="brutalist"] h1 { font-size: 2.6em; }
+[data-theme-style="brutalist"] code,
+[data-theme-style="brutalist"] pre code,
+[data-theme-style="brutalist"] kbd { font-family: var(--theme-font-body); }
+[data-theme-style="brutalist"] a { text-decoration: underline; text-underline-offset: 0.2em; text-decoration-thickness: 2px; }
+[data-theme-style="brutalist"] hr { border: 0; border-top: 4px solid var(--sl-color-accent); }
+[data-theme-style="brutalist"] .site-title { font-family: var(--theme-font-heading); text-transform: uppercase; letter-spacing: 0; }
diff --git a/src/styles/themes/cyberpunk.css b/src/styles/themes/cyberpunk.css
new file mode 100644
index 0000000..fcc11d4
--- /dev/null
+++ b/src/styles/themes/cyberpunk.css
@@ -0,0 +1,91 @@
+/* ======================================================================
+ THEME: Cyberpunk Neon
+ Vaporwave / Blade Runner. Deep magenta-purple, electric cyan, hot pink.
+ All-mono typography. Glowing text-shadows. Scan-line feel.
+ ====================================================================== */
+
+@font-face {
+ font-family: "Major Mono Display";
+ src: url('/assets/fonts/themes/cyberpunk/major-mono-400.woff2') format('woff2');
+ font-weight: 400; font-style: normal; font-display: swap;
+}
+@font-face {
+ font-family: "JetBrains Mono";
+ src: url('/assets/fonts/themes/cyberpunk/jetbrains-mono-400.woff2') format('woff2');
+ font-weight: 400; font-style: normal; font-display: swap;
+}
+@font-face {
+ font-family: "JetBrains Mono";
+ src: url('/assets/fonts/themes/cyberpunk/jetbrains-mono-700.woff2') format('woff2');
+ font-weight: 700; font-style: normal; font-display: swap;
+}
+
+/* ---- Dark mode (default — the canonical cyberpunk look) ---- */
+:root[data-theme-style="cyberpunk"] {
+ --sl-color-black: #0a0014;
+ --sl-color-bg: #0a0014;
+ --sl-color-bg-nav: #0a0014;
+ --sl-color-bg-sidebar: #100022;
+ --sl-color-bg-inline-code: #1a0033;
+ --sl-color-white: #e6f7ff;
+ --sl-color-gray-1: #b8e3f0;
+ --sl-color-gray-2: #8a9fd0;
+ --sl-color-gray-3: #6075a8;
+ --sl-color-gray-4: #3d4a78;
+ --sl-color-gray-5: #251847;
+ --sl-color-gray-6: #1a0033;
+ --sl-color-gray-7: #100022;
+ --sl-color-accent-low: #3d0033;
+ --sl-color-accent: #ff0080;
+ --sl-color-accent-high: #ff66b3;
+ --sl-color-text: #b8e3f0;
+ --sl-color-text-accent: #00ffd5;
+
+ --theme-font-body: "JetBrains Mono", "Fira Code", "SF Mono", Menlo, ui-monospace, monospace;
+ --theme-font-heading: "Major Mono Display", "JetBrains Mono", "Courier New", ui-monospace, monospace;
+}
+
+/* ---- Light mode (the daylight-cyberpunk variant) ---- */
+:root[data-theme="light"][data-theme-style="cyberpunk"] {
+ --sl-color-black: #fce6ff;
+ --sl-color-bg: #fce6ff;
+ --sl-color-bg-nav: #fce6ff;
+ --sl-color-bg-sidebar: #f5d6ff;
+ --sl-color-bg-inline-code: #ebc1f5;
+ --sl-color-white: #1a0033;
+ --sl-color-gray-1: #251847;
+ --sl-color-gray-2: #3d2a6a;
+ --sl-color-gray-3: #5c468f;
+ --sl-color-gray-4: #8a73ad;
+ --sl-color-gray-5: #b8a4cc;
+ --sl-color-gray-6: #ebc1f5;
+ --sl-color-gray-7: #f5d6ff;
+ --sl-color-accent-low: #ffb8db;
+ --sl-color-accent: #c4006b;
+ --sl-color-accent-high: #8a004a;
+ --sl-color-text: #251847;
+ --sl-color-text-accent: #006b7a;
+}
+
+/* ---- Typography & glow effects ---- */
+[data-theme-style="cyberpunk"] body { font-family: var(--theme-font-body); font-weight: 400; letter-spacing: 0.02em; }
+[data-theme-style="cyberpunk"] h1,
+[data-theme-style="cyberpunk"] h2,
+[data-theme-style="cyberpunk"] h3,
+[data-theme-style="cyberpunk"] h4,
+[data-theme-style="cyberpunk"] h5,
+[data-theme-style="cyberpunk"] h6 {
+ font-family: var(--theme-font-heading);
+ font-weight: 400;
+ letter-spacing: 0.1em;
+ text-transform: lowercase;
+ line-height: 1.25;
+}
+[data-theme-style="cyberpunk"] h1 { letter-spacing: 0.18em; }
+[data-theme-style="cyberpunk"] h2 { letter-spacing: 0.14em; }
+[data-theme-style="cyberpunk"] a { text-shadow: 0 0 8px currentColor; }
+[data-theme="light"][data-theme-style="cyberpunk"] a { text-shadow: none; }
+[data-theme-style="cyberpunk"] code,
+[data-theme-style="cyberpunk"] pre code,
+[data-theme-style="cyberpunk"] kbd { font-family: var(--theme-font-body); }
+[data-theme-style="cyberpunk"] .site-title { font-family: var(--theme-font-heading); letter-spacing: 0.15em; text-transform: lowercase; }
diff --git a/src/styles/themes/dharma.css b/src/styles/themes/dharma.css
new file mode 100644
index 0000000..ddaa74c
--- /dev/null
+++ b/src/styles/themes/dharma.css
@@ -0,0 +1,81 @@
+/* ======================================================================
+ THEME: Dharma Initiative
+ 1970s scientific research institute. Parchment & charcoal & amber.
+ IBM Plex Mono throughout for a typewriter / research-document feel.
+ ====================================================================== */
+
+@font-face {
+ font-family: "IBM Plex Mono";
+ src: url('/assets/fonts/themes/dharma/ibm-plex-mono-400.woff2') format('woff2');
+ font-weight: 400; font-style: normal; font-display: swap;
+}
+@font-face {
+ font-family: "IBM Plex Mono";
+ src: url('/assets/fonts/themes/dharma/ibm-plex-mono-700.woff2') format('woff2');
+ font-weight: 700; font-style: normal; font-display: swap;
+}
+
+/* ---- Dark mode (default) ---- */
+:root[data-theme-style="dharma"] {
+ --sl-color-black: #16140f;
+ --sl-color-bg: #16140f;
+ --sl-color-bg-nav: #16140f;
+ --sl-color-bg-sidebar: #1c1a14;
+ --sl-color-bg-inline-code: #28241b;
+ --sl-color-white: #f5f1e6;
+ --sl-color-gray-1: #ede6cf;
+ --sl-color-gray-2: #c8c0a8;
+ --sl-color-gray-3: #948c75;
+ --sl-color-gray-4: #6a634f;
+ --sl-color-gray-5: #3b362a;
+ --sl-color-gray-6: #28241b;
+ --sl-color-gray-7: #1c1a14;
+ --sl-color-accent-low: #3a2308;
+ --sl-color-accent: #d4a017;
+ --sl-color-accent-high: #ffd770;
+ --sl-color-text: #d4cdb4;
+ --sl-color-text-accent: #fbbf24;
+
+ --theme-font-body: "IBM Plex Mono", "SF Mono", "Menlo", "Consolas", ui-monospace, monospace;
+ --theme-font-heading: "IBM Plex Mono", "SF Mono", "Menlo", "Consolas", ui-monospace, monospace;
+}
+
+/* ---- Light mode ---- */
+:root[data-theme="light"][data-theme-style="dharma"] {
+ --sl-color-black: #f1e9d7;
+ --sl-color-bg: #f1e9d7;
+ --sl-color-bg-nav: #f1e9d7;
+ --sl-color-bg-sidebar: #e8dec5;
+ --sl-color-bg-inline-code: #e0d4b3;
+ --sl-color-white: #16140f;
+ --sl-color-gray-1: #1c1a14;
+ --sl-color-gray-2: #2d2a20;
+ --sl-color-gray-3: #4b4538;
+ --sl-color-gray-4: #6a634f;
+ --sl-color-gray-5: #948c75;
+ --sl-color-gray-6: #c8c0a8;
+ --sl-color-gray-7: #e0d4b3;
+ --sl-color-accent-low: #f4e3b3;
+ --sl-color-accent: #92590a;
+ --sl-color-accent-high: #5a3a0a;
+ --sl-color-text: #2d2a20;
+ --sl-color-text-accent: #b45309;
+}
+
+/* ---- Typography ---- */
+[data-theme-style="dharma"] body { font-family: var(--theme-font-body); font-weight: 400; letter-spacing: 0; }
+[data-theme-style="dharma"] h1,
+[data-theme-style="dharma"] h2,
+[data-theme-style="dharma"] h3,
+[data-theme-style="dharma"] h4,
+[data-theme-style="dharma"] h5,
+[data-theme-style="dharma"] h6 {
+ font-family: var(--theme-font-heading);
+ font-weight: 700;
+ letter-spacing: 0.05em;
+ text-transform: uppercase;
+}
+[data-theme-style="dharma"] h1 { letter-spacing: 0.08em; }
+[data-theme-style="dharma"] code,
+[data-theme-style="dharma"] pre code { font-family: var(--theme-font-body); }
+[data-theme-style="dharma"] .site-title { font-family: var(--theme-font-heading); letter-spacing: 0.1em; text-transform: uppercase; font-weight: 700; }
diff --git a/src/styles/themes/futurism.css b/src/styles/themes/futurism.css
new file mode 100644
index 0000000..68f539a
--- /dev/null
+++ b/src/styles/themes/futurism.css
@@ -0,0 +1,87 @@
+/* ======================================================================
+ THEME: Italian Futurism
+ Mechanical, aggressive, high-contrast. Vermilion red, charcoal, cream.
+ Condensed sans-serif typography. All-caps headings with letter-spacing.
+ ====================================================================== */
+
+@font-face {
+ font-family: "Bebas Neue";
+ src: url('/assets/fonts/themes/futurism/bebas-neue-400.woff2') format('woff2');
+ font-weight: 400; font-style: normal; font-display: swap;
+}
+@font-face {
+ font-family: "Barlow Condensed";
+ src: url('/assets/fonts/themes/futurism/barlow-condensed-400.woff2') format('woff2');
+ font-weight: 400; font-style: normal; font-display: swap;
+}
+@font-face {
+ font-family: "Barlow Condensed";
+ src: url('/assets/fonts/themes/futurism/barlow-condensed-700.woff2') format('woff2');
+ font-weight: 700; font-style: normal; font-display: swap;
+}
+
+/* ---- Dark mode (default) ---- */
+:root[data-theme-style="futurism"] {
+ --sl-color-black: #0c0c0d;
+ --sl-color-bg: #0c0c0d;
+ --sl-color-bg-nav: #0c0c0d;
+ --sl-color-bg-sidebar: #131314;
+ --sl-color-bg-inline-code: #1a1a1b;
+ --sl-color-white: #f1e9d7;
+ --sl-color-gray-1: #e6dec9;
+ --sl-color-gray-2: #b8b1a0;
+ --sl-color-gray-3: #8a8478;
+ --sl-color-gray-4: #5a554c;
+ --sl-color-gray-5: #38342e;
+ --sl-color-gray-6: #1f1d1a;
+ --sl-color-gray-7: #131211;
+ --sl-color-accent-low: #3a1310;
+ --sl-color-accent: #c8312a;
+ --sl-color-accent-high: #f4a5a0;
+ --sl-color-text: #d9d2bf;
+ --sl-color-text-accent: #ffffff;
+
+ --theme-font-body: "Barlow Condensed", "Helvetica Neue Condensed", "Roboto Condensed", system-ui, sans-serif;
+ --theme-font-heading: "Bebas Neue", "Oswald", Impact, sans-serif;
+}
+
+/* ---- Light mode ---- */
+:root[data-theme="light"][data-theme-style="futurism"] {
+ --sl-color-black: #f1e9d7;
+ --sl-color-bg: #f1e9d7;
+ --sl-color-bg-nav: #f1e9d7;
+ --sl-color-bg-sidebar: #ebe2cd;
+ --sl-color-bg-inline-code: #e4dabf;
+ --sl-color-white: #0c0c0d;
+ --sl-color-gray-1: #1a1a1b;
+ --sl-color-gray-2: #2d2d2e;
+ --sl-color-gray-3: #5a554c;
+ --sl-color-gray-4: #8a8478;
+ --sl-color-gray-5: #b8b1a0;
+ --sl-color-gray-6: #d4cbb3;
+ --sl-color-gray-7: #ebe2cd;
+ --sl-color-accent-low: #f4ccc9;
+ --sl-color-accent: #a8261f;
+ --sl-color-accent-high: #6e1611;
+ --sl-color-text: #1a1a1b;
+ --sl-color-text-accent: #0c0c0d;
+}
+
+/* ---- Typography ---- */
+[data-theme-style="futurism"] body { font-family: var(--theme-font-body); letter-spacing: 0.01em; }
+[data-theme-style="futurism"] h1,
+[data-theme-style="futurism"] h2,
+[data-theme-style="futurism"] h3,
+[data-theme-style="futurism"] h4,
+[data-theme-style="futurism"] h5,
+[data-theme-style="futurism"] h6 {
+ font-family: var(--theme-font-heading);
+ font-weight: 400;
+ letter-spacing: 0.06em;
+ text-transform: uppercase;
+ line-height: 1.1;
+}
+[data-theme-style="futurism"] h1 { letter-spacing: 0.08em; }
+[data-theme-style="futurism"] .site-title,
+[data-theme-style="futurism"] a.site-title,
+[data-theme-style="futurism"] .header a { font-family: var(--theme-font-heading); letter-spacing: 0.08em; text-transform: uppercase; font-weight: 400; }
diff --git a/src/styles/themes/herbarium.css b/src/styles/themes/herbarium.css
new file mode 100644
index 0000000..adefe03
--- /dev/null
+++ b/src/styles/themes/herbarium.css
@@ -0,0 +1,107 @@
+/* ======================================================================
+ THEME: Botanical Herbarium
+ Victorian pressed-flower herbarium plate. Aged-paper cream, olive sage,
+ sepia ink. Calligraphic Italianno display, EB Garamond classical body.
+ Scholarly, hand-prepared, museum-archive feel.
+ ====================================================================== */
+
+@font-face {
+ font-family: "Italianno";
+ src: url('/assets/fonts/themes/herbarium/italianno-400.woff2') format('woff2');
+ font-weight: 400; font-style: normal; font-display: swap;
+}
+@font-face {
+ font-family: "EB Garamond";
+ src: url('/assets/fonts/themes/herbarium/eb-garamond-400.woff2') format('woff2');
+ font-weight: 400; font-style: normal; font-display: swap;
+}
+@font-face {
+ font-family: "EB Garamond";
+ src: url('/assets/fonts/themes/herbarium/eb-garamond-700.woff2') format('woff2');
+ font-weight: 700; font-style: normal; font-display: swap;
+}
+
+/* ---- Dark mode (the closed-cabinet variant) ---- */
+:root[data-theme-style="herbarium"] {
+ --sl-color-black: #14180f;
+ --sl-color-bg: #14180f;
+ --sl-color-bg-nav: #14180f;
+ --sl-color-bg-sidebar: #1c2017;
+ --sl-color-bg-inline-code: #262a1f;
+ --sl-color-white: #f0e8d4;
+ --sl-color-gray-1: #e0d8c0;
+ --sl-color-gray-2: #b8b098;
+ --sl-color-gray-3: #8a8470;
+ --sl-color-gray-4: #5a564a;
+ --sl-color-gray-5: #36392c;
+ --sl-color-gray-6: #262a1f;
+ --sl-color-gray-7: #1c2017;
+ --sl-color-accent-low: #1a2a14;
+ --sl-color-accent: #9bb074;
+ --sl-color-accent-high: #c8d99c;
+ --sl-color-text: #d0c8b0;
+ --sl-color-text-accent: #e0d4a0;
+
+ --theme-font-body: "EB Garamond", "Adobe Garamond Pro", Garamond, "Times New Roman", serif;
+ --theme-font-heading: "EB Garamond", "Adobe Garamond Pro", Garamond, Georgia, serif;
+ --theme-font-display: "Italianno", "Snell Roundhand", "Apple Chancery", cursive;
+}
+
+/* ---- Light mode (the canonical sun-bleached herbarium leaf) ---- */
+:root[data-theme="light"][data-theme-style="herbarium"] {
+ --sl-color-black: #f0e8d4;
+ --sl-color-bg: #f0e8d4;
+ --sl-color-bg-nav: #f0e8d4;
+ --sl-color-bg-sidebar: #e7debf;
+ --sl-color-bg-inline-code: #ddd2a8;
+ --sl-color-white: #14180f;
+ --sl-color-gray-1: #1c2017;
+ --sl-color-gray-2: #2d3220;
+ --sl-color-gray-3: #4a4d35;
+ --sl-color-gray-4: #6e6f50;
+ --sl-color-gray-5: #969078;
+ --sl-color-gray-6: #c4bc9a;
+ --sl-color-gray-7: #e7debf;
+ --sl-color-accent-low: #d6e0b8;
+ --sl-color-accent: #506033;
+ --sl-color-accent-high: #2e3818;
+ --sl-color-text: #2d3220;
+ --sl-color-text-accent: #6e3a14;
+}
+
+/* ---- Typography — calligraphic H1, classical H2-H6 ---- */
+[data-theme-style="herbarium"] body { font-family: var(--theme-font-body); font-weight: 400; line-height: 1.7; font-feature-settings: "liga", "kern", "onum"; }
+[data-theme-style="herbarium"] h1,
+[data-theme-style="herbarium"] h2,
+[data-theme-style="herbarium"] h3,
+[data-theme-style="herbarium"] h4,
+[data-theme-style="herbarium"] h5,
+[data-theme-style="herbarium"] h6 {
+ font-family: var(--theme-font-heading);
+ font-weight: 400;
+ letter-spacing: 0.01em;
+ line-height: 1.2;
+}
+[data-theme-style="herbarium"] h1 {
+ font-family: var(--theme-font-display);
+ font-weight: 400;
+ font-size: 3.6em;
+ line-height: 1;
+ letter-spacing: 0;
+}
+[data-theme-style="herbarium"] h2 { font-style: italic; font-weight: 400; }
+[data-theme-style="herbarium"] h3 { font-variant: small-caps; letter-spacing: 0.08em; font-weight: 700; }
+[data-theme-style="herbarium"] blockquote {
+ font-family: var(--theme-font-heading);
+ font-style: italic;
+ border-inline-start: 2px solid var(--sl-color-accent);
+}
+[data-theme-style="herbarium"] hr {
+ border: 0;
+ height: 1px;
+ background: var(--sl-color-accent);
+ opacity: 0.5;
+ margin-inline: auto;
+ width: 40%;
+}
+[data-theme-style="herbarium"] .site-title { font-family: var(--theme-font-display); font-size: 1.6em; font-weight: 400; }
diff --git a/src/styles/themes/memphis.css b/src/styles/themes/memphis.css
new file mode 100644
index 0000000..df97656
--- /dev/null
+++ b/src/styles/themes/memphis.css
@@ -0,0 +1,90 @@
+/* ======================================================================
+ THEME: Memphis Design
+ 1980s Memphis Group / Ettore Sottsass. Loud, playful, primary-coloured.
+ Hot pink, electric cyan, sunshine yellow, charcoal. Fjalla One blocky
+ display, Lexend rounded body.
+ ====================================================================== */
+
+@font-face {
+ font-family: "Fjalla One";
+ src: url('/assets/fonts/themes/memphis/fjalla-one-400.woff2') format('woff2');
+ font-weight: 400; font-style: normal; font-display: swap;
+}
+@font-face {
+ font-family: "Lexend";
+ src: url('/assets/fonts/themes/memphis/lexend-400.woff2') format('woff2');
+ font-weight: 400; font-style: normal; font-display: swap;
+}
+@font-face {
+ font-family: "Lexend";
+ src: url('/assets/fonts/themes/memphis/lexend-700.woff2') format('woff2');
+ font-weight: 700; font-style: normal; font-display: swap;
+}
+
+/* ---- Dark mode (the after-hours Memphis variant) ---- */
+:root[data-theme-style="memphis"] {
+ --sl-color-black: #14122a;
+ --sl-color-bg: #14122a;
+ --sl-color-bg-nav: #14122a;
+ --sl-color-bg-sidebar: #1c1a36;
+ --sl-color-bg-inline-code: #2a2747;
+ --sl-color-white: #f6f1e8;
+ --sl-color-gray-1: #e8e0d0;
+ --sl-color-gray-2: #b8b0a0;
+ --sl-color-gray-3: #8a82a8;
+ --sl-color-gray-4: #5a5478;
+ --sl-color-gray-5: #3a345c;
+ --sl-color-gray-6: #2a2747;
+ --sl-color-gray-7: #1c1a36;
+ --sl-color-accent-low: #3a0a2a;
+ --sl-color-accent: #ff3d8b;
+ --sl-color-accent-high: #ffd23f;
+ --sl-color-text: #d6d0bc;
+ --sl-color-text-accent: #06d6e8;
+
+ --theme-font-body: "Lexend", "Avenir Next", -apple-system, BlinkMacSystemFont, sans-serif;
+ --theme-font-heading: "Fjalla One", "Oswald", Impact, sans-serif;
+}
+
+/* ---- Light mode (the canonical bright Memphis look) ---- */
+:root[data-theme="light"][data-theme-style="memphis"] {
+ --sl-color-black: #f6f1e8;
+ --sl-color-bg: #f6f1e8;
+ --sl-color-bg-nav: #f6f1e8;
+ --sl-color-bg-sidebar: #ede6d6;
+ --sl-color-bg-inline-code: #e0d5be;
+ --sl-color-white: #14122a;
+ --sl-color-gray-1: #1c1a36;
+ --sl-color-gray-2: #2a2747;
+ --sl-color-gray-3: #4a4670;
+ --sl-color-gray-4: #6e6890;
+ --sl-color-gray-5: #968fb0;
+ --sl-color-gray-6: #c0b9d0;
+ --sl-color-gray-7: #ede6d6;
+ --sl-color-accent-low: #ffd0e0;
+ --sl-color-accent: #c41858;
+ --sl-color-accent-high: #8a0e3d;
+ --sl-color-text: #2a2747;
+ --sl-color-text-accent: #006a78;
+}
+
+/* ---- Typography — chunky display + readable body ---- */
+[data-theme-style="memphis"] body { font-family: var(--theme-font-body); font-weight: 400; letter-spacing: -0.005em; }
+[data-theme-style="memphis"] h1,
+[data-theme-style="memphis"] h2,
+[data-theme-style="memphis"] h3,
+[data-theme-style="memphis"] h4,
+[data-theme-style="memphis"] h5,
+[data-theme-style="memphis"] h6 {
+ font-family: var(--theme-font-heading);
+ font-weight: 400;
+ letter-spacing: 0.02em;
+ text-transform: uppercase;
+ line-height: 1.1;
+}
+[data-theme-style="memphis"] h1 { font-size: 2.6em; letter-spacing: 0; }
+[data-theme-style="memphis"] hr { border: 0; height: 6px; background: repeating-linear-gradient(90deg, var(--sl-color-accent) 0 12px, transparent 12px 18px); }
+[data-theme-style="memphis"] code,
+[data-theme-style="memphis"] pre code,
+[data-theme-style="memphis"] kbd { font-family: "JetBrains Mono", "Courier New", ui-monospace, monospace; background: var(--sl-color-bg-inline-code); }
+[data-theme-style="memphis"] .site-title { font-family: var(--theme-font-heading); text-transform: uppercase; letter-spacing: 0.02em; }
diff --git a/src/styles/themes/minimalist.css b/src/styles/themes/minimalist.css
new file mode 100644
index 0000000..4dc6e4c
--- /dev/null
+++ b/src/styles/themes/minimalist.css
@@ -0,0 +1,80 @@
+/* ======================================================================
+ THEME: Minimalist
+ Clean, spacious, modern. Pure neutrals only — no chroma in the base.
+ Inter throughout. Tight line-heights for headings, generous body.
+ ====================================================================== */
+
+@font-face {
+ font-family: "Inter";
+ src: url('/assets/fonts/themes/minimalist/inter-400.woff2') format('woff2');
+ font-weight: 400; font-style: normal; font-display: swap;
+}
+@font-face {
+ font-family: "Inter";
+ src: url('/assets/fonts/themes/minimalist/inter-700.woff2') format('woff2');
+ font-weight: 700; font-style: normal; font-display: swap;
+}
+
+/* ---- Dark mode (default) ---- */
+:root[data-theme-style="minimalist"] {
+ --sl-color-black: #0a0a0a;
+ --sl-color-bg: #0a0a0a;
+ --sl-color-bg-nav: #0a0a0a;
+ --sl-color-bg-sidebar: #111111;
+ --sl-color-bg-inline-code: #1a1a1a;
+ --sl-color-white: #fafafa;
+ --sl-color-gray-1: #e5e5e5;
+ --sl-color-gray-2: #b4b4b4;
+ --sl-color-gray-3: #888888;
+ --sl-color-gray-4: #555555;
+ --sl-color-gray-5: #333333;
+ --sl-color-gray-6: #1a1a1a;
+ --sl-color-gray-7: #111111;
+ --sl-color-accent-low: #1a1a1a;
+ --sl-color-accent: #fafafa;
+ --sl-color-accent-high: #ffffff;
+ --sl-color-text: #cccccc;
+ --sl-color-text-accent: #fafafa;
+
+ --theme-font-body: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
+ --theme-font-heading: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
+}
+
+/* ---- Light mode ---- */
+:root[data-theme="light"][data-theme-style="minimalist"] {
+ --sl-color-black: #ffffff;
+ --sl-color-bg: #ffffff;
+ --sl-color-bg-nav: #ffffff;
+ --sl-color-bg-sidebar: #fafafa;
+ --sl-color-bg-inline-code: #f4f4f4;
+ --sl-color-white: #0a0a0a;
+ --sl-color-gray-1: #1a1a1a;
+ --sl-color-gray-2: #333333;
+ --sl-color-gray-3: #555555;
+ --sl-color-gray-4: #888888;
+ --sl-color-gray-5: #b4b4b4;
+ --sl-color-gray-6: #e5e5e5;
+ --sl-color-gray-7: #f4f4f4;
+ --sl-color-accent-low: #f0f0f0;
+ --sl-color-accent: #0a0a0a;
+ --sl-color-accent-high: #000000;
+ --sl-color-text: #333333;
+ --sl-color-text-accent: #0a0a0a;
+}
+
+/* ---- Typography ---- */
+[data-theme-style="minimalist"] body { font-family: var(--theme-font-body); font-weight: 400; letter-spacing: -0.005em; }
+[data-theme-style="minimalist"] h1,
+[data-theme-style="minimalist"] h2,
+[data-theme-style="minimalist"] h3,
+[data-theme-style="minimalist"] h4,
+[data-theme-style="minimalist"] h5,
+[data-theme-style="minimalist"] h6 {
+ font-family: var(--theme-font-heading);
+ font-weight: 700;
+ letter-spacing: -0.025em;
+ line-height: 1.15;
+}
+[data-theme-style="minimalist"] h1 { letter-spacing: -0.035em; }
+[data-theme-style="minimalist"] .site-title { font-family: var(--theme-font-heading); font-weight: 700; letter-spacing: -0.02em; }
+[data-theme-style="minimalist"] a { text-underline-offset: 0.25em; }
diff --git a/src/styles/themes/natural.css b/src/styles/themes/natural.css
new file mode 100644
index 0000000..2e2844a
--- /dev/null
+++ b/src/styles/themes/natural.css
@@ -0,0 +1,91 @@
+/* ======================================================================
+ THEME: Natural and Serene
+ Warm, earthy, organic. Sage green, terracotta, warm cream.
+ Fraunces serif for headings, Karla sans-serif for body.
+ ====================================================================== */
+
+@font-face {
+ font-family: "Fraunces";
+ src: url('/assets/fonts/themes/natural/fraunces-400.woff2') format('woff2');
+ font-weight: 400; font-style: normal; font-display: swap;
+}
+@font-face {
+ font-family: "Fraunces";
+ src: url('/assets/fonts/themes/natural/fraunces-700.woff2') format('woff2');
+ font-weight: 700; font-style: normal; font-display: swap;
+}
+@font-face {
+ font-family: "Karla";
+ src: url('/assets/fonts/themes/natural/karla-400.woff2') format('woff2');
+ font-weight: 400; font-style: normal; font-display: swap;
+}
+@font-face {
+ font-family: "Karla";
+ src: url('/assets/fonts/themes/natural/karla-700.woff2') format('woff2');
+ font-weight: 700; font-style: normal; font-display: swap;
+}
+
+/* ---- Dark mode (default) ---- */
+:root[data-theme-style="natural"] {
+ --sl-color-black: #1c2520;
+ --sl-color-bg: #1c2520;
+ --sl-color-bg-nav: #1c2520;
+ --sl-color-bg-sidebar: #232c27;
+ --sl-color-bg-inline-code: #2d3631;
+ --sl-color-white: #f5efe1;
+ --sl-color-gray-1: #e9e0cb;
+ --sl-color-gray-2: #c4b89c;
+ --sl-color-gray-3: #8a8576;
+ --sl-color-gray-4: #5a5849;
+ --sl-color-gray-5: #38362d;
+ --sl-color-gray-6: #2d3631;
+ --sl-color-gray-7: #232c27;
+ --sl-color-accent-low: #2b3a30;
+ --sl-color-accent: #b8835c;
+ --sl-color-accent-high: #e4b993;
+ --sl-color-text: #d6cdb4;
+ --sl-color-text-accent: #f0d4b3;
+
+ --theme-font-body: "Karla", "Source Sans Pro", -apple-system, BlinkMacSystemFont, sans-serif;
+ --theme-font-heading: "Fraunces", "Cormorant Garamond", Georgia, "Times New Roman", serif;
+}
+
+/* ---- Light mode ---- */
+:root[data-theme="light"][data-theme-style="natural"] {
+ --sl-color-black: #faf6ec;
+ --sl-color-bg: #faf6ec;
+ --sl-color-bg-nav: #faf6ec;
+ --sl-color-bg-sidebar: #f2ecd9;
+ --sl-color-bg-inline-code: #ebe2c8;
+ --sl-color-white: #1c2520;
+ --sl-color-gray-1: #232c27;
+ --sl-color-gray-2: #38362d;
+ --sl-color-gray-3: #5a5849;
+ --sl-color-gray-4: #8a8576;
+ --sl-color-gray-5: #c4b89c;
+ --sl-color-gray-6: #ebe2c8;
+ --sl-color-gray-7: #f2ecd9;
+ --sl-color-accent-low: #e8d9c4;
+ --sl-color-accent: #8a5a3a;
+ --sl-color-accent-high: #4d2e1a;
+ --sl-color-text: #2d3631;
+ --sl-color-text-accent: #4d6e4f;
+}
+
+/* ---- Typography ---- */
+[data-theme-style="natural"] body { font-family: var(--theme-font-body); font-weight: 400; }
+[data-theme-style="natural"] h1,
+[data-theme-style="natural"] h2,
+[data-theme-style="natural"] h3,
+[data-theme-style="natural"] h4,
+[data-theme-style="natural"] h5,
+[data-theme-style="natural"] h6 {
+ font-family: var(--theme-font-heading);
+ font-weight: 400;
+ letter-spacing: -0.01em;
+ line-height: 1.2;
+ font-variation-settings: "opsz" 144, "SOFT" 50;
+}
+[data-theme-style="natural"] h1 { font-weight: 400; font-style: italic; }
+[data-theme-style="natural"] h2 { font-weight: 700; }
+[data-theme-style="natural"] .site-title { font-family: var(--theme-font-heading); font-weight: 700; letter-spacing: 0; }
diff --git a/src/styles/themes/newspaper.css b/src/styles/themes/newspaper.css
new file mode 100644
index 0000000..1469b96
--- /dev/null
+++ b/src/styles/themes/newspaper.css
@@ -0,0 +1,98 @@
+/* ======================================================================
+ THEME: Newspaper Broadsheet
+ Editorial, classical, print-publication. Aged newsprint cream, deep ink
+ black, sepia-brown rule colour. Playfair Display headlines, PT Serif
+ body. Tight, justified prose feel.
+ ====================================================================== */
+
+@font-face {
+ font-family: "Playfair Display";
+ src: url('/assets/fonts/themes/newspaper/playfair-400.woff2') format('woff2');
+ font-weight: 400; font-style: normal; font-display: swap;
+}
+@font-face {
+ font-family: "Playfair Display";
+ src: url('/assets/fonts/themes/newspaper/playfair-700.woff2') format('woff2');
+ font-weight: 700; font-style: normal; font-display: swap;
+}
+@font-face {
+ font-family: "PT Serif";
+ src: url('/assets/fonts/themes/newspaper/pt-serif-400.woff2') format('woff2');
+ font-weight: 400; font-style: normal; font-display: swap;
+}
+@font-face {
+ font-family: "PT Serif";
+ src: url('/assets/fonts/themes/newspaper/pt-serif-700.woff2') format('woff2');
+ font-weight: 700; font-style: normal; font-display: swap;
+}
+
+/* ---- Dark mode (the late-night-edition variant) ---- */
+:root[data-theme-style="newspaper"] {
+ --sl-color-black: #14110d;
+ --sl-color-bg: #14110d;
+ --sl-color-bg-nav: #14110d;
+ --sl-color-bg-sidebar: #1c1813;
+ --sl-color-bg-inline-code: #261f17;
+ --sl-color-white: #f4ecd6;
+ --sl-color-gray-1: #e6dcc0;
+ --sl-color-gray-2: #bdb398;
+ --sl-color-gray-3: #8a8270;
+ --sl-color-gray-4: #5a5443;
+ --sl-color-gray-5: #3a3326;
+ --sl-color-gray-6: #261f17;
+ --sl-color-gray-7: #1c1813;
+ --sl-color-accent-low: #3d2a18;
+ --sl-color-accent: #c8965a;
+ --sl-color-accent-high: #e8ba80;
+ --sl-color-text: #d8cca8;
+ --sl-color-text-accent: #e6c285;
+
+ --theme-font-body: "PT Serif", "Georgia", "Times New Roman", "Iowan Old Style", serif;
+ --theme-font-heading: "Playfair Display", "Didot", "Bodoni 72", Georgia, serif;
+}
+
+/* ---- Light mode (the canonical broadsheet) ---- */
+:root[data-theme="light"][data-theme-style="newspaper"] {
+ --sl-color-black: #f4ecd6;
+ --sl-color-bg: #f4ecd6;
+ --sl-color-bg-nav: #f4ecd6;
+ --sl-color-bg-sidebar: #ebe1c4;
+ --sl-color-bg-inline-code: #e0d3ac;
+ --sl-color-white: #14110d;
+ --sl-color-gray-1: #1c1813;
+ --sl-color-gray-2: #2d251a;
+ --sl-color-gray-3: #4d4332;
+ --sl-color-gray-4: #6e6451;
+ --sl-color-gray-5: #968a6e;
+ --sl-color-gray-6: #c4b894;
+ --sl-color-gray-7: #ebe1c4;
+ --sl-color-accent-low: #e8d4ad;
+ --sl-color-accent: #8a5a14;
+ --sl-color-accent-high: #4d3008;
+ --sl-color-text: #2d251a;
+ --sl-color-text-accent: #6e3a08;
+}
+
+/* ---- Typography & editorial flourishes ---- */
+[data-theme-style="newspaper"] body { font-family: var(--theme-font-body); font-weight: 400; line-height: 1.65; }
+[data-theme-style="newspaper"] h1,
+[data-theme-style="newspaper"] h2,
+[data-theme-style="newspaper"] h3,
+[data-theme-style="newspaper"] h4,
+[data-theme-style="newspaper"] h5,
+[data-theme-style="newspaper"] h6 {
+ font-family: var(--theme-font-heading);
+ font-weight: 700;
+ letter-spacing: -0.01em;
+ line-height: 1.15;
+}
+[data-theme-style="newspaper"] h1 { font-weight: 400; font-size: 2.6em; letter-spacing: -0.02em; }
+[data-theme-style="newspaper"] h2 { font-style: italic; font-weight: 400; }
+[data-theme-style="newspaper"] blockquote {
+ font-family: var(--theme-font-heading);
+ font-style: italic;
+ font-size: 1.2em;
+ border-inline-start: 3px solid var(--sl-color-accent);
+}
+[data-theme-style="newspaper"] hr { border: 0; border-top: 1px solid var(--sl-color-accent); border-bottom: 1px solid var(--sl-color-accent); height: 4px; }
+[data-theme-style="newspaper"] .site-title { font-family: var(--theme-font-heading); font-weight: 700; letter-spacing: -0.01em; }
diff --git a/src/styles/themes/protest.css b/src/styles/themes/protest.css
new file mode 100644
index 0000000..cb54026
--- /dev/null
+++ b/src/styles/themes/protest.css
@@ -0,0 +1,96 @@
+/* ======================================================================
+ THEME: 60s Protest
+ Atelier Populaire silkscreens, Black Panther broadsides, May '68 Paris.
+ Day-Glo mustard paper, silkscreen blood-red, photocopy-black ink.
+ Anton screams in all-caps, Special Elite types the manifesto below.
+ ====================================================================== */
+
+@font-face {
+ font-family: "Anton";
+ src: url('/assets/fonts/themes/protest/anton-400.woff2') format('woff2');
+ font-weight: 400; font-style: normal; font-display: swap;
+}
+@font-face {
+ font-family: "Special Elite";
+ src: url('/assets/fonts/themes/protest/special-elite-400.woff2') format('woff2');
+ font-weight: 400; font-style: normal; font-display: swap;
+}
+
+/* ---- Dark mode (the after-curfew variant) ---- */
+:root[data-theme-style="protest"] {
+ --sl-color-black: #0d0606;
+ --sl-color-bg: #0d0606;
+ --sl-color-bg-nav: #0d0606;
+ --sl-color-bg-sidebar: #170808;
+ --sl-color-bg-inline-code: #200a0a;
+ --sl-color-white: #f4e8c8;
+ --sl-color-gray-1: #e6d8a8;
+ --sl-color-gray-2: #c4b888;
+ --sl-color-gray-3: #8e8260;
+ --sl-color-gray-4: #5a5240;
+ --sl-color-gray-5: #2e1a1a;
+ --sl-color-gray-6: #200a0a;
+ --sl-color-gray-7: #170808;
+ --sl-color-accent-low: #3a0a0d;
+ --sl-color-accent: #ff3d2d;
+ --sl-color-accent-high: #ffd23f;
+ --sl-color-text: #e0d4a8;
+ --sl-color-text-accent: #ffd23f;
+
+ --theme-font-body: "Special Elite", "American Typewriter", "Courier New", ui-monospace, monospace;
+ --theme-font-heading: "Anton", "Bebas Neue", "Oswald", Impact, "Arial Narrow", sans-serif;
+}
+
+/* ---- Light mode (the canonical mustard-paper silkscreen) ---- */
+:root[data-theme="light"][data-theme-style="protest"] {
+ --sl-color-black: #f4dc88;
+ --sl-color-bg: #f4dc88;
+ --sl-color-bg-nav: #f4dc88;
+ --sl-color-bg-sidebar: #ecd070;
+ --sl-color-bg-inline-code: #e0c050;
+ --sl-color-white: #0a0a0a;
+ --sl-color-gray-1: #0a0a0a;
+ --sl-color-gray-2: #1a1a1a;
+ --sl-color-gray-3: #3a3026;
+ --sl-color-gray-4: #5a4a3a;
+ --sl-color-gray-5: #968460;
+ --sl-color-gray-6: #d4c060;
+ --sl-color-gray-7: #ecd070;
+ --sl-color-accent-low: #ffb0a0;
+ --sl-color-accent: #c8202d;
+ --sl-color-accent-high: #8a0e16;
+ --sl-color-text: #0a0a0a;
+ --sl-color-text-accent: #c8202d;
+}
+
+/* ---- Typography — assertive, all-caps, hand-printed energy ---- */
+[data-theme-style="protest"] body { font-family: var(--theme-font-body); font-weight: 400; letter-spacing: 0; line-height: 1.6; }
+[data-theme-style="protest"] h1,
+[data-theme-style="protest"] h2,
+[data-theme-style="protest"] h3,
+[data-theme-style="protest"] h4,
+[data-theme-style="protest"] h5,
+[data-theme-style="protest"] h6 {
+ font-family: var(--theme-font-heading);
+ font-weight: 400;
+ text-transform: uppercase;
+ letter-spacing: 0.02em;
+ line-height: 1;
+}
+[data-theme-style="protest"] h1 { font-size: 3em; letter-spacing: 0; }
+[data-theme-style="protest"] h2 { font-size: 2em; }
+[data-theme-style="protest"] strong { color: var(--sl-color-accent); font-weight: 400; text-transform: uppercase; }
+[data-theme-style="protest"] hr { border: 0; height: 6px; background: var(--sl-color-accent); }
+[data-theme-style="protest"] blockquote {
+ font-family: var(--theme-font-heading);
+ text-transform: uppercase;
+ font-size: 1.4em;
+ line-height: 1.15;
+ letter-spacing: 0.01em;
+ border-inline-start: 6px solid var(--sl-color-accent);
+ padding-inline-start: 1.25rem;
+}
+[data-theme-style="protest"] code,
+[data-theme-style="protest"] pre code,
+[data-theme-style="protest"] kbd { font-family: var(--theme-font-body); }
+[data-theme-style="protest"] .site-title { font-family: var(--theme-font-heading); text-transform: uppercase; letter-spacing: 0.02em; }
diff --git a/src/styles/themes/solarpunk.css b/src/styles/themes/solarpunk.css
new file mode 100644
index 0000000..d73073a
--- /dev/null
+++ b/src/styles/themes/solarpunk.css
@@ -0,0 +1,84 @@
+/* ======================================================================
+ THEME: Solarpunk
+ Lush, hopeful, ornate. Deep forest green, gold, warm cream.
+ Marcellus serif for elegant display, Sora sans-serif for body.
+ ====================================================================== */
+
+@font-face {
+ font-family: "Marcellus";
+ src: url('/assets/fonts/themes/solarpunk/marcellus-400.woff2') format('woff2');
+ font-weight: 400; font-style: normal; font-display: swap;
+}
+@font-face {
+ font-family: "Sora";
+ src: url('/assets/fonts/themes/solarpunk/sora-400.woff2') format('woff2');
+ font-weight: 400; font-style: normal; font-display: swap;
+}
+@font-face {
+ font-family: "Sora";
+ src: url('/assets/fonts/themes/solarpunk/sora-700.woff2') format('woff2');
+ font-weight: 700; font-style: normal; font-display: swap;
+}
+
+/* ---- Dark mode (default) ---- */
+:root[data-theme-style="solarpunk"] {
+ --sl-color-black: #0f1f17;
+ --sl-color-bg: #0f1f17;
+ --sl-color-bg-nav: #0f1f17;
+ --sl-color-bg-sidebar: #14271d;
+ --sl-color-bg-inline-code: #1c3327;
+ --sl-color-white: #f5f0e1;
+ --sl-color-gray-1: #e9e1c8;
+ --sl-color-gray-2: #c2bca5;
+ --sl-color-gray-3: #8e9485;
+ --sl-color-gray-4: #5e6e60;
+ --sl-color-gray-5: #2d4232;
+ --sl-color-gray-6: #1c3327;
+ --sl-color-gray-7: #14271d;
+ --sl-color-accent-low: #2b1a0a;
+ --sl-color-accent: #d4a017;
+ --sl-color-accent-high: #f0c757;
+ --sl-color-text: #d8d0b8;
+ --sl-color-text-accent: #f7c948;
+
+ --theme-font-body: "Sora", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
+ --theme-font-heading: "Marcellus", "Cormorant Garamond", "Trajan Pro", Georgia, serif;
+}
+
+/* ---- Light mode ---- */
+:root[data-theme="light"][data-theme-style="solarpunk"] {
+ --sl-color-black: #f5f0e1;
+ --sl-color-bg: #f5f0e1;
+ --sl-color-bg-nav: #f5f0e1;
+ --sl-color-bg-sidebar: #ede6cb;
+ --sl-color-bg-inline-code: #e5dbb8;
+ --sl-color-white: #0f1f17;
+ --sl-color-gray-1: #14271d;
+ --sl-color-gray-2: #2d4232;
+ --sl-color-gray-3: #5e6e60;
+ --sl-color-gray-4: #8e9485;
+ --sl-color-gray-5: #c2bca5;
+ --sl-color-gray-6: #e5dbb8;
+ --sl-color-gray-7: #ede6cb;
+ --sl-color-accent-low: #f0e0a8;
+ --sl-color-accent: #7a4a14;
+ --sl-color-accent-high: #4a2a08;
+ --sl-color-text: #1c3327;
+ --sl-color-text-accent: #2e7d4f;
+}
+
+/* ---- Typography ---- */
+[data-theme-style="solarpunk"] body { font-family: var(--theme-font-body); font-weight: 400; }
+[data-theme-style="solarpunk"] h1,
+[data-theme-style="solarpunk"] h2,
+[data-theme-style="solarpunk"] h3,
+[data-theme-style="solarpunk"] h4,
+[data-theme-style="solarpunk"] h5,
+[data-theme-style="solarpunk"] h6 {
+ font-family: var(--theme-font-heading);
+ font-weight: 400;
+ letter-spacing: 0.01em;
+ line-height: 1.2;
+}
+[data-theme-style="solarpunk"] h1 { letter-spacing: 0.02em; }
+[data-theme-style="solarpunk"] .site-title { font-family: var(--theme-font-heading); font-weight: 400; letter-spacing: 0.04em; }
diff --git a/src/styles/themes/space-age.css b/src/styles/themes/space-age.css
new file mode 100644
index 0000000..cd3a397
--- /dev/null
+++ b/src/styles/themes/space-age.css
@@ -0,0 +1,86 @@
+/* ======================================================================
+ THEME: Space Age
+ Mid-century atomic-age retrofuturism. Turquoise, orange, mustard yellow.
+ Orbitron for display headings, Quicksand for rounded friendly body.
+ ====================================================================== */
+
+@font-face {
+ font-family: "Orbitron";
+ src: url('/assets/fonts/themes/space-age/orbitron-700.woff2') format('woff2');
+ font-weight: 700; font-style: normal; font-display: swap;
+}
+@font-face {
+ font-family: "Quicksand";
+ src: url('/assets/fonts/themes/space-age/quicksand-400.woff2') format('woff2');
+ font-weight: 400; font-style: normal; font-display: swap;
+}
+@font-face {
+ font-family: "Quicksand";
+ src: url('/assets/fonts/themes/space-age/quicksand-700.woff2') format('woff2');
+ font-weight: 700; font-style: normal; font-display: swap;
+}
+
+/* ---- Dark mode (default) ---- */
+:root[data-theme-style="space-age"] {
+ --sl-color-black: #0d1f24;
+ --sl-color-bg: #0d1f24;
+ --sl-color-bg-nav: #0d1f24;
+ --sl-color-bg-sidebar: #112a31;
+ --sl-color-bg-inline-code: #173943;
+ --sl-color-white: #f5e9c8;
+ --sl-color-gray-1: #e8dab2;
+ --sl-color-gray-2: #c9bb95;
+ --sl-color-gray-3: #95a0a3;
+ --sl-color-gray-4: #5a7480;
+ --sl-color-gray-5: #1f4651;
+ --sl-color-gray-6: #173943;
+ --sl-color-gray-7: #102a31;
+ --sl-color-accent-low: #0c3a40;
+ --sl-color-accent: #1d9aaa;
+ --sl-color-accent-high: #6cd5e2;
+ --sl-color-text: #d8cba5;
+ --sl-color-text-accent: #ffd770;
+
+ --theme-font-body: "Quicksand", "Avenir Next", "Segoe UI", system-ui, sans-serif;
+ --theme-font-heading: "Orbitron", "Avenir Next", "Helvetica Neue", sans-serif;
+}
+
+/* ---- Light mode ---- */
+:root[data-theme="light"][data-theme-style="space-age"] {
+ --sl-color-black: #f5ecd2;
+ --sl-color-bg: #f7eed4;
+ --sl-color-bg-nav: #f7eed4;
+ --sl-color-bg-sidebar: #f0e3c0;
+ --sl-color-bg-inline-code: #e8dab2;
+ --sl-color-white: #0d1f24;
+ --sl-color-gray-1: #102a31;
+ --sl-color-gray-2: #1f4651;
+ --sl-color-gray-3: #5a7480;
+ --sl-color-gray-4: #95a0a3;
+ --sl-color-gray-5: #c9bb95;
+ --sl-color-gray-6: #e8dab2;
+ --sl-color-gray-7: #f0e3c0;
+ --sl-color-accent-low: #ccecef;
+ --sl-color-accent: #0d6a76;
+ --sl-color-accent-high: #053b42;
+ --sl-color-text: #102a31;
+ --sl-color-text-accent: #c45213;
+}
+
+/* ---- Typography ---- */
+[data-theme-style="space-age"] body { font-family: var(--theme-font-body); font-weight: 400; }
+[data-theme-style="space-age"] h1,
+[data-theme-style="space-age"] h2,
+[data-theme-style="space-age"] h3,
+[data-theme-style="space-age"] h4,
+[data-theme-style="space-age"] h5,
+[data-theme-style="space-age"] h6 {
+ font-family: var(--theme-font-heading);
+ font-weight: 700;
+ letter-spacing: 0.04em;
+ line-height: 1.15;
+}
+[data-theme-style="space-age"] h1 { letter-spacing: 0.06em; text-transform: uppercase; }
+[data-theme-style="space-age"] .site-title { font-family: var(--theme-font-heading); letter-spacing: 0.06em; font-weight: 700; }
+[data-theme-style="space-age"] code,
+[data-theme-style="space-age"] pre code { font-family: "JetBrains Mono", "Courier New", ui-monospace, monospace; }
diff --git a/src/styles/themes/sumi-e.css b/src/styles/themes/sumi-e.css
new file mode 100644
index 0000000..2680e14
--- /dev/null
+++ b/src/styles/themes/sumi-e.css
@@ -0,0 +1,92 @@
+/* ======================================================================
+ THEME: Sumi-e Ink Wash
+ Japanese ink-painting minimalism. Sumi-black ink, washi-paper cream, a
+ single restrained vermilion-seal accent. Quiet, spacious, contemplative.
+ ====================================================================== */
+
+@font-face {
+ font-family: "Noto Serif JP";
+ src: url('/assets/fonts/themes/sumi-e/noto-serif-jp-400.woff2') format('woff2');
+ font-weight: 400; font-style: normal; font-display: swap;
+}
+@font-face {
+ font-family: "Noto Serif JP";
+ src: url('/assets/fonts/themes/sumi-e/noto-serif-jp-700.woff2') format('woff2');
+ font-weight: 700; font-style: normal; font-display: swap;
+}
+@font-face {
+ font-family: "Cormorant Garamond";
+ src: url('/assets/fonts/themes/sumi-e/cormorant-400.woff2') format('woff2');
+ font-weight: 400; font-style: normal; font-display: swap;
+}
+
+/* ---- Dark mode (the night-ink variant) ---- */
+:root[data-theme-style="sumi-e"] {
+ --sl-color-black: #0a0908;
+ --sl-color-bg: #0a0908;
+ --sl-color-bg-nav: #0a0908;
+ --sl-color-bg-sidebar: #14120f;
+ --sl-color-bg-inline-code: #1f1b16;
+ --sl-color-white: #f0eadf;
+ --sl-color-gray-1: #e0d8c4;
+ --sl-color-gray-2: #b8b09c;
+ --sl-color-gray-3: #888272;
+ --sl-color-gray-4: #5a5448;
+ --sl-color-gray-5: #2e2a22;
+ --sl-color-gray-6: #1f1b16;
+ --sl-color-gray-7: #14120f;
+ --sl-color-accent-low: #3a0c0a;
+ --sl-color-accent: #c43a3a;
+ --sl-color-accent-high: #e88080;
+ --sl-color-text: #cec6b2;
+ --sl-color-text-accent: #e0e0d8;
+
+ --theme-font-body: "Noto Serif JP", "Hiragino Mincho ProN", "Yu Mincho", "Georgia", serif;
+ --theme-font-heading: "Cormorant Garamond", "Noto Serif JP", "Hiragino Mincho ProN", Georgia, serif;
+}
+
+/* ---- Light mode (the canonical washi-paper look) ---- */
+:root[data-theme="light"][data-theme-style="sumi-e"] {
+ --sl-color-black: #f5efe2;
+ --sl-color-bg: #f5efe2;
+ --sl-color-bg-nav: #f5efe2;
+ --sl-color-bg-sidebar: #ede5d0;
+ --sl-color-bg-inline-code: #e0d6b8;
+ --sl-color-white: #0a0908;
+ --sl-color-gray-1: #14120f;
+ --sl-color-gray-2: #26221a;
+ --sl-color-gray-3: #4a4438;
+ --sl-color-gray-4: #6e6757;
+ --sl-color-gray-5: #9a9382;
+ --sl-color-gray-6: #c4bca6;
+ --sl-color-gray-7: #ede5d0;
+ --sl-color-accent-low: #e8c0c0;
+ --sl-color-accent: #a3262c;
+ --sl-color-accent-high: #6e1417;
+ --sl-color-text: #26221a;
+ --sl-color-text-accent: #2a2a20;
+}
+
+/* ---- Typography — quiet, generous, spacious ---- */
+[data-theme-style="sumi-e"] body { font-family: var(--theme-font-body); font-weight: 400; line-height: 1.8; letter-spacing: 0.01em; }
+[data-theme-style="sumi-e"] h1,
+[data-theme-style="sumi-e"] h2,
+[data-theme-style="sumi-e"] h3,
+[data-theme-style="sumi-e"] h4,
+[data-theme-style="sumi-e"] h5,
+[data-theme-style="sumi-e"] h6 {
+ font-family: var(--theme-font-heading);
+ font-weight: 400;
+ letter-spacing: 0.04em;
+ line-height: 1.3;
+}
+[data-theme-style="sumi-e"] h1 { font-style: italic; font-size: 2.4em; letter-spacing: 0.06em; }
+[data-theme-style="sumi-e"] h2 { font-weight: 400; letter-spacing: 0.05em; }
+[data-theme-style="sumi-e"] blockquote {
+ font-family: var(--theme-font-heading);
+ font-style: italic;
+ border-inline-start: 1px solid var(--sl-color-accent);
+ padding-inline-start: 1.5rem;
+}
+[data-theme-style="sumi-e"] hr { border: 0; border-top: 1px solid var(--sl-color-gray-4); opacity: 0.4; }
+[data-theme-style="sumi-e"] .site-title { font-family: var(--theme-font-heading); font-weight: 400; letter-spacing: 0.05em; }
diff --git a/src/styles/themes/syndicalist.css b/src/styles/themes/syndicalist.css
new file mode 100644
index 0000000..670595d
--- /dev/null
+++ b/src/styles/themes/syndicalist.css
@@ -0,0 +1,108 @@
+/* ======================================================================
+ THEME: Syndicalist
+ Anarcho-syndicalist / IWW / CNT-FAI labour-press iconography. Pure
+ black and red, no compromise. Wood-type industrial gothic display
+ over a sober slab-serif manifesto body.
+ ====================================================================== */
+
+@font-face {
+ font-family: "Big Shoulders Display";
+ src: url('/assets/fonts/themes/syndicalist/big-shoulders-display-700.woff2') format('woff2');
+ font-weight: 700; font-style: normal; font-display: swap;
+}
+@font-face {
+ font-family: "Roboto Slab";
+ src: url('/assets/fonts/themes/syndicalist/roboto-slab-400.woff2') format('woff2');
+ font-weight: 400; font-style: normal; font-display: swap;
+}
+@font-face {
+ font-family: "Roboto Slab";
+ src: url('/assets/fonts/themes/syndicalist/roboto-slab-700.woff2') format('woff2');
+ font-weight: 700; font-style: normal; font-display: swap;
+}
+
+/* ---- Dark mode (the canonical black-and-red banner) ---- */
+:root[data-theme-style="syndicalist"] {
+ --sl-color-black: #060606;
+ --sl-color-bg: #060606;
+ --sl-color-bg-nav: #060606;
+ --sl-color-bg-sidebar: #0e0e0e;
+ --sl-color-bg-inline-code: #1a0808;
+ --sl-color-white: #f4ede0;
+ --sl-color-gray-1: #e6dec9;
+ --sl-color-gray-2: #b8b0a0;
+ --sl-color-gray-3: #8a8276;
+ --sl-color-gray-4: #5a5448;
+ --sl-color-gray-5: #2e1c1c;
+ --sl-color-gray-6: #1a0808;
+ --sl-color-gray-7: #0e0e0e;
+ --sl-color-accent-low: #3a0608;
+ --sl-color-accent: #e63329;
+ --sl-color-accent-high: #ff8478;
+ --sl-color-text: #d8d0bc;
+ --sl-color-text-accent: #ffffff;
+
+ --theme-font-body: "Roboto Slab", "Rockwell", "Georgia", serif;
+ --theme-font-heading: "Big Shoulders Display", "Oswald", "Arial Narrow Black", Impact, sans-serif;
+}
+
+/* ---- Light mode (the printers'-ink-on-cream variant) ---- */
+:root[data-theme="light"][data-theme-style="syndicalist"] {
+ --sl-color-black: #f4ede0;
+ --sl-color-bg: #f4ede0;
+ --sl-color-bg-nav: #f4ede0;
+ --sl-color-bg-sidebar: #ebe2cd;
+ --sl-color-bg-inline-code: #e0d4b3;
+ --sl-color-white: #060606;
+ --sl-color-gray-1: #0e0e0e;
+ --sl-color-gray-2: #1a1a1a;
+ --sl-color-gray-3: #383838;
+ --sl-color-gray-4: #5e5e5e;
+ --sl-color-gray-5: #8a8478;
+ --sl-color-gray-6: #c8c0a8;
+ --sl-color-gray-7: #ebe2cd;
+ --sl-color-accent-low: #ffcfc6;
+ --sl-color-accent: #b81818;
+ --sl-color-accent-high: #7a0a0a;
+ --sl-color-text: #0e0e0e;
+ --sl-color-text-accent: #b81818;
+}
+
+/* ---- Typography — wood-type display, slab-serif manifesto body ---- */
+[data-theme-style="syndicalist"] body { font-family: var(--theme-font-body); font-weight: 400; line-height: 1.6; }
+[data-theme-style="syndicalist"] h1,
+[data-theme-style="syndicalist"] h2,
+[data-theme-style="syndicalist"] h3,
+[data-theme-style="syndicalist"] h4,
+[data-theme-style="syndicalist"] h5,
+[data-theme-style="syndicalist"] h6 {
+ font-family: var(--theme-font-heading);
+ font-weight: 700;
+ text-transform: uppercase;
+ letter-spacing: 0.04em;
+ line-height: 0.95;
+}
+[data-theme-style="syndicalist"] h1 { font-size: 3.2em; letter-spacing: 0.02em; }
+[data-theme-style="syndicalist"] h2 { font-size: 2em; letter-spacing: 0.04em; }
+[data-theme-style="syndicalist"] strong { color: var(--sl-color-accent); font-weight: 700; }
+[data-theme-style="syndicalist"] hr {
+ border: 0;
+ height: 0;
+ border-top: 6px solid var(--sl-color-accent);
+ border-bottom: 2px solid currentColor;
+ padding-block-end: 2px;
+}
+[data-theme-style="syndicalist"] blockquote {
+ font-family: var(--theme-font-heading);
+ text-transform: uppercase;
+ font-size: 1.3em;
+ font-weight: 700;
+ letter-spacing: 0.03em;
+ line-height: 1.1;
+ border-inline-start: 8px solid var(--sl-color-accent);
+ padding-inline-start: 1.25rem;
+}
+[data-theme-style="syndicalist"] code,
+[data-theme-style="syndicalist"] pre code,
+[data-theme-style="syndicalist"] kbd { font-family: "JetBrains Mono", "Courier New", ui-monospace, monospace; }
+[data-theme-style="syndicalist"] .site-title { font-family: var(--theme-font-heading); text-transform: uppercase; letter-spacing: 0.05em; font-weight: 700; }
diff --git a/src/styles/themes/whole-earth.css b/src/styles/themes/whole-earth.css
new file mode 100644
index 0000000..cd86029
--- /dev/null
+++ b/src/styles/themes/whole-earth.css
@@ -0,0 +1,99 @@
+/* ======================================================================
+ THEME: Whole Earth Catalog
+ Stewart Brand's 1968-71 mail-order catalogue of tools. Yellowed
+ newsprint, IBM Selectric body, heavy slab-serif catalog headlines,
+ earth-tone palette. Hand-pasted-up DIY counterculture feel.
+ ====================================================================== */
+
+@font-face {
+ font-family: "Bevan";
+ src: url('/assets/fonts/themes/whole-earth/bevan-400.woff2') format('woff2');
+ font-weight: 400; font-style: normal; font-display: swap;
+}
+@font-face {
+ font-family: "Special Elite";
+ src: url('/assets/fonts/themes/whole-earth/special-elite-400.woff2') format('woff2');
+ font-weight: 400; font-style: normal; font-display: swap;
+}
+
+/* ---- Dark mode (the after-hours commune variant) ---- */
+:root[data-theme-style="whole-earth"] {
+ --sl-color-black: #14100a;
+ --sl-color-bg: #14100a;
+ --sl-color-bg-nav: #14100a;
+ --sl-color-bg-sidebar: #1c1810;
+ --sl-color-bg-inline-code: #281f12;
+ --sl-color-white: #f0e0a8;
+ --sl-color-gray-1: #e0d090;
+ --sl-color-gray-2: #b8a878;
+ --sl-color-gray-3: #8a7e58;
+ --sl-color-gray-4: #5e5238;
+ --sl-color-gray-5: #3a2e1c;
+ --sl-color-gray-6: #281f12;
+ --sl-color-gray-7: #1c1810;
+ --sl-color-accent-low: #2a1a08;
+ --sl-color-accent: #d4a017;
+ --sl-color-accent-high: #f0c757;
+ --sl-color-text: #d8c490;
+ --sl-color-text-accent: #8db358;
+
+ --theme-font-body: "Special Elite", "American Typewriter", "Courier Prime", "Courier New", ui-monospace, monospace;
+ --theme-font-heading: "Bevan", "Rockwell", "Roboto Slab", "Georgia", serif;
+}
+
+/* ---- Light mode (the canonical yellowed-newsprint look) ---- */
+:root[data-theme="light"][data-theme-style="whole-earth"] {
+ --sl-color-black: #f0e6c8;
+ --sl-color-bg: #f0e6c8;
+ --sl-color-bg-nav: #f0e6c8;
+ --sl-color-bg-sidebar: #e6dab2;
+ --sl-color-bg-inline-code: #d8c890;
+ --sl-color-white: #1a1108;
+ --sl-color-gray-1: #2c1f0d;
+ --sl-color-gray-2: #3e2c14;
+ --sl-color-gray-3: #5e4824;
+ --sl-color-gray-4: #806640;
+ --sl-color-gray-5: #a89070;
+ --sl-color-gray-6: #c4b088;
+ --sl-color-gray-7: #e6dab2;
+ --sl-color-accent-low: #e8d4a0;
+ --sl-color-accent: #6b4517;
+ --sl-color-accent-high: #3e2608;
+ --sl-color-text: #2c1f0d;
+ --sl-color-text-accent: #2c5530;
+}
+
+/* ---- Typography — chunky catalog masthead + DIY typewriter body ---- */
+[data-theme-style="whole-earth"] body { font-family: var(--theme-font-body); font-weight: 400; line-height: 1.55; }
+[data-theme-style="whole-earth"] h1,
+[data-theme-style="whole-earth"] h2,
+[data-theme-style="whole-earth"] h3,
+[data-theme-style="whole-earth"] h4,
+[data-theme-style="whole-earth"] h5,
+[data-theme-style="whole-earth"] h6 {
+ font-family: var(--theme-font-heading);
+ font-weight: 400;
+ letter-spacing: 0;
+ line-height: 1.05;
+ text-transform: uppercase;
+}
+[data-theme-style="whole-earth"] h1 { font-size: 2.8em; }
+[data-theme-style="whole-earth"] h2 { font-size: 1.8em; }
+[data-theme-style="whole-earth"] h3 { font-size: 1.3em; text-transform: none; }
+[data-theme-style="whole-earth"] hr {
+ border: 0;
+ height: 4px;
+ background: var(--sl-color-accent);
+ border-top: 1px solid var(--sl-color-accent);
+ border-bottom: 1px solid var(--sl-color-accent);
+}
+[data-theme-style="whole-earth"] blockquote {
+ font-family: var(--theme-font-body);
+ font-size: 1.05em;
+ border-inline-start: 3px double var(--sl-color-accent);
+ padding-inline-start: 1rem;
+}
+[data-theme-style="whole-earth"] code,
+[data-theme-style="whole-earth"] pre code,
+[data-theme-style="whole-earth"] kbd { font-family: var(--theme-font-body); }
+[data-theme-style="whole-earth"] .site-title { font-family: var(--theme-font-heading); text-transform: uppercase; letter-spacing: 0; }