diff --git a/frontend/src/components/react/ThemeSwitcher.tsx b/frontend/src/components/react/ThemeSwitcher.tsx index be34a2c..0782f42 100644 --- a/frontend/src/components/react/ThemeSwitcher.tsx +++ b/frontend/src/components/react/ThemeSwitcher.tsx @@ -3,15 +3,14 @@ import { useState, useEffect, useRef } from 'react'; const THEMES = [ { value: 'salon', label: 'Salon' }, { value: 'salon-noir', label: 'Salon Noir' }, - { value: 'latte', label: 'Latte' }, - { value: 'mocha', label: 'Mocha' }, + { value: 'gothic', label: 'Gothic' }, ]; interface Props { defaultTheme?: string; } -export default function ThemeSwitcher({ defaultTheme = 'mocha' }: Props) { +export default function ThemeSwitcher({ defaultTheme = 'salon' }: Props) { const [theme, setTheme] = useState(() => { if (typeof window !== 'undefined') { return localStorage.getItem('user-theme') || defaultTheme; diff --git a/frontend/src/components/react/admin/Settings.tsx b/frontend/src/components/react/admin/Settings.tsx index 995629d..0c66e11 100644 --- a/frontend/src/components/react/admin/Settings.tsx +++ b/frontend/src/components/react/admin/Settings.tsx @@ -68,10 +68,9 @@ export default function Settings() { > - - + -

Salon and Salon Noir are tuned for the gallery aesthetic.

+

All three are tuned for the gallery aesthetic. Gothic leans into deep violet-black with cathedral indigo and blood-crimson accents.

diff --git a/frontend/src/styles/global.css b/frontend/src/styles/global.css index 6117cbc..7eabefe 100644 --- a/frontend/src/styles/global.css +++ b/frontend/src/styles/global.css @@ -101,29 +101,36 @@ --rosewater: #F4E5C9; } -/* Legacy Catppuccin themes — kept for users that already opted in. */ -.mocha { - --crust: #11111b; --mantle: #181825; --base: #1e1e2e; - --surface0: #313244; --surface1: #45475a; --surface2: #585b70; - --overlay0: #6c7086; --overlay1: #7f849c; --overlay2: #9399b2; - --text: #cdd6f4; --subtext0: #a6adc8; --subtext1: #bac2de; - --blue: #89b4fa; --lavender: #b4befe; --sapphire: #74c7ec; - --sky: #89dceb; --teal: #94e2d5; --green: #a6e3a1; - --yellow: #f9e2af; --peach: #fab387; --maroon: #eba0ac; - --red: #f38ba8; --mauve: #cba6f7; --pink: #f5c2e7; - --flamingo: #f2cdcd; --rosewater: #f5e0dc; -} - -.latte { - --crust: #dce0e8; --mantle: #e6e9ef; --base: #eff1f5; - --surface0: #ccd0da; --surface1: #bcc0cc; --surface2: #acb0be; - --overlay0: #7c7f93; --overlay1: #6c6f85; --overlay2: #5c5f77; - --text: #1e1e2e; --subtext0: #3c3f59; --subtext1: #4c4f69; - --blue: #1e66f5; --lavender: #7287fd; --sapphire: #209fb5; - --sky: #04a5e5; --teal: #179299; --green: #40a02b; - --yellow: #df8e1d; --peach: #fe640b; --maroon: #e64553; - --red: #d20f39; --mauve: #8839ef; --pink: #ea76cb; - --flamingo: #dd7878; --rosewater: #dc8a78; +/* GOTHIC — cathedral nightfall. Midnight violet ground, blood crimson, + * tarnished candle gold, stained-glass indigo. Catholic-gothic + Sisters of + * Mercy + Bauhaus stark. Primary accent: cathedral velvet mauve. */ +.gothic { + --crust: #030104; + --mantle: #0A0710; + --base: #110B18; + --surface0: #1A1224; + --surface1: #261A36; + --surface2: #382550; + --overlay0: #4F3970; + --overlay1: #6E5293; + --overlay2: #8D72B1; + --text: #EDE3F2; /* bone, violet wash */ + --subtext0: #9B8AB0; + --subtext1: #C0AED2; + --blue: #4239A4; /* stained-glass deep */ + --lavender: #9B7BD4; /* candlelight through purple glass */ + --sapphire: #5947B2; + --sky: #7C68C9; + --teal: #487B8A; /* verdigris on bronze */ + --green: #5E7842; /* cemetery moss */ + --yellow: #D4A82B; /* taper / tarnished brass */ + --peach: #B45A38; /* rust */ + --maroon: #5B1A24; + --red: #A41827; /* arterial */ + --mauve: #8B2C9E; /* cathedral velvet — primary accent */ + --pink: #B25288; /* dried rose */ + --flamingo: #C57B96; + --rosewater: #F0DDE8; } html { @@ -168,6 +175,13 @@ body::after { html.salon-noir body::after { opacity: 0.5; } +.gothic body::after, +html.gothic body::after { + opacity: 0.55; + background-image: + url("data:image/svg+xml;utf8,"); + mix-blend-mode: screen; +} /* Floating motes of pigment — far background, very subtle. */ .salon-atmosphere { @@ -437,7 +451,9 @@ code, pre, kbd, samp { border-radius: 2px; } .salon-noir .prose figure img, -.salon-noir .prose img { +.salon-noir .prose img, +.gothic .prose figure img, +.gothic .prose img { background: linear-gradient(var(--surface0), var(--surface0)) padding-box, linear-gradient(135deg, var(--surface2), var(--surface1)) border-box; @@ -445,6 +461,13 @@ code, pre, kbd, samp { 0 18px 38px -22px rgba(0, 0, 0, 0.7), 0 2px 6px -2px rgba(0, 0, 0, 0.5); } +.gothic .prose figure img, +.gothic .prose img { + box-shadow: + 0 18px 38px -22px rgba(0, 0, 0, 0.85), + 0 2px 6px -2px rgba(0, 0, 0, 0.6), + 0 0 0 1px color-mix(in srgb, var(--mauve) 22%, transparent); +} .prose figure figcaption { font-family: var(--font-display); font-style: italic; @@ -500,7 +523,8 @@ code, pre, kbd, samp { transition: transform 0.4s cubic-bezier(0.2, 0.6, 0.2, 1), box-shadow 0.4s cubic-bezier(0.2, 0.6, 0.2, 1); } -.salon-noir .plate { +.salon-noir .plate, +.gothic .plate { background: var(--surface0); } .plate:hover { @@ -690,9 +714,16 @@ code, pre, kbd, samp { 0 10px 30px -20px rgba(20, 16, 12, 0.45); border-radius: 2px; } -.salon-noir .glass { +.salon-noir .glass, +.gothic .glass { background-color: color-mix(in srgb, var(--surface0) 70%, transparent); } +.gothic .glass { + border-color: color-mix(in srgb, var(--mauve) 35%, var(--surface2)); + box-shadow: + inset 0 0 0 1px color-mix(in srgb, var(--mauve) 18%, transparent), + 0 14px 40px -24px rgba(0, 0, 0, 0.85); +} /* ───── Buttons ───── */ .btn-stamp { @@ -848,6 +879,7 @@ code, pre, kbd, samp { input[type="checkbox"] { accent-color: var(--mauve); } input[type="date"] { color-scheme: light; } .salon-noir input[type="date"] { color-scheme: dark; } +.gothic input[type="date"] { color-scheme: dark; } /* Reading progress bar - thin terracotta line */ .reading-progress {