diff --git a/frontend/src/components/react/ThemeSwitcher.tsx b/frontend/src/components/react/ThemeSwitcher.tsx index 0782f42..c9c9e7a 100644 --- a/frontend/src/components/react/ThemeSwitcher.tsx +++ b/frontend/src/components/react/ThemeSwitcher.tsx @@ -4,6 +4,7 @@ const THEMES = [ { value: 'salon', label: 'Salon' }, { value: 'salon-noir', label: 'Salon Noir' }, { value: 'gothic', label: 'Gothic' }, + { value: 'breakcore', label: 'Breakcore' }, ]; interface Props { diff --git a/frontend/src/components/react/admin/Settings.tsx b/frontend/src/components/react/admin/Settings.tsx index 728a0ff..77d7e0b 100644 --- a/frontend/src/components/react/admin/Settings.tsx +++ b/frontend/src/components/react/admin/Settings.tsx @@ -98,8 +98,9 @@ export default function Settings() { + -

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

+

Salon trio tuned for the gallery aesthetic. Breakcore swaps that for early-2000s web rot — hot magenta on CRT violet, acid green, scanline noise.

diff --git a/frontend/src/styles/global.css b/frontend/src/styles/global.css index 38d4139..3ad2665 100644 --- a/frontend/src/styles/global.css +++ b/frontend/src/styles/global.css @@ -101,6 +101,38 @@ --rosewater: #F4E5C9; } +/* BREAKCORE — early-2000s web rot + breakcore. CRT-violet ground, hot + * magenta primary, acid green / electric cyan / hazard yellow accents. + * Glitchy, blown-out, MSN-era saturation. */ +.breakcore { + --crust: #02000A; + --mantle: #06031A; + --base: #0A0612; + --surface0: #150929; + --surface1: #22113F; + --surface2: #3A1B62; + --overlay0: #5A2D8E; + --overlay1: #7B45B8; + --overlay2: #A06AD8; + --text: #F2F0FF; + --subtext0: #B9A8E0; + --subtext1: #D8CCFA; + --blue: #00B7FF; /* MSN cyan */ + --lavender: #B98CFF; /* CRT violet */ + --sapphire: #4B6BFF; /* hyperlink */ + --sky: #66E1FF; /* aqua chrome */ + --teal: #00F5C8; /* matrix mint */ + --green: #B6FF00; /* acid */ + --yellow: #FFD400; /* hazard */ + --peach: #FF8A3D; /* GIF-era flame */ + --maroon: #8B0A4B; + --red: #FF1F4F; /* siren */ + --mauve: #FF2EA6; /* hot magenta — primary accent */ + --pink: #FF7AD8; /* bubblegum */ + --flamingo: #FFA2C4; + --rosewater: #FFE8F6; +} + /* 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. */ @@ -182,6 +214,23 @@ html.gothic body::after { url("data:image/svg+xml;utf8,"); mix-blend-mode: screen; } +/* Breakcore: blown-out RGB-tinted digital noise + CRT scanlines. */ +.breakcore body::after, +html.breakcore body::after { + opacity: 0.55; + background-image: + url("data:image/svg+xml;utf8,"), + repeating-linear-gradient( + 0deg, + rgba(0, 0, 0, 0) 0, + rgba(0, 0, 0, 0) 2px, + rgba(0, 0, 0, 0.28) 3px, + rgba(0, 0, 0, 0) 4px + ); + mix-blend-mode: screen; +} +.breakcore .salon-atmosphere::before { opacity: 0.32; } +.breakcore .salon-atmosphere::after { opacity: 0.28; } /* Floating motes of pigment — far background, very subtle. */ .salon-atmosphere { @@ -221,6 +270,22 @@ code, pre, kbd, samp { color: var(--rosewater); } +/* Breakcore: chromatic-aberration glow on display headings + nameplate. */ +.breakcore .prose h1, +.breakcore .prose h2, +.breakcore h1.font-display, +.breakcore .nameplate-title { + text-shadow: + -1px 0 0 color-mix(in srgb, var(--teal) 70%, transparent), + 1px 0 0 color-mix(in srgb, var(--mauve) 70%, transparent), + 0 0 18px color-mix(in srgb, var(--mauve) 35%, transparent); +} +.breakcore ::selection { + background: var(--green); + color: var(--crust); + text-shadow: 0 0 6px var(--mauve); +} + /* ───── Display utilities ───── */ .font-display { font-family: var(--font-display); @@ -453,7 +518,9 @@ code, pre, kbd, samp { .salon-noir .prose figure img, .salon-noir .prose img, .gothic .prose figure img, -.gothic .prose img { +.gothic .prose img, +.breakcore .prose figure img, +.breakcore .prose img { background: linear-gradient(var(--surface0), var(--surface0)) padding-box, linear-gradient(135deg, var(--surface2), var(--surface1)) border-box; @@ -524,9 +591,17 @@ code, pre, kbd, samp { box-shadow 0.4s cubic-bezier(0.2, 0.6, 0.2, 1); } .salon-noir .plate, -.gothic .plate { +.gothic .plate, +.breakcore .plate { background: var(--surface0); } +.breakcore .plate { + box-shadow: + inset 0 0 0 1px color-mix(in srgb, var(--mauve) 35%, transparent), + 0 0 0 1px color-mix(in srgb, var(--mauve) 20%, transparent), + 0 22px 42px -28px rgba(255, 46, 166, 0.35), + 0 0 24px -8px color-mix(in srgb, var(--mauve) 40%, transparent); +} .plate:hover { transform: translateY(-4px) rotate(-0.25deg); box-shadow: @@ -733,7 +808,8 @@ code, pre, kbd, samp { border-radius: 2px; } .salon-noir .glass, -.gothic .glass { +.gothic .glass, +.breakcore .glass { background-color: color-mix(in srgb, var(--surface0) 70%, transparent); } .gothic .glass { @@ -742,6 +818,13 @@ code, pre, kbd, samp { inset 0 0 0 1px color-mix(in srgb, var(--mauve) 18%, transparent), 0 14px 40px -24px rgba(0, 0, 0, 0.85); } +.breakcore .glass { + border-color: color-mix(in srgb, var(--mauve) 45%, var(--surface2)); + box-shadow: + inset 0 0 0 1px color-mix(in srgb, var(--mauve) 25%, transparent), + 0 0 0 1px color-mix(in srgb, var(--teal) 15%, transparent), + 0 14px 40px -24px rgba(0, 0, 0, 0.9); +} /* ───── Buttons ───── */ .btn-stamp { @@ -899,6 +982,7 @@ 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; } +.breakcore input[type="date"] { color-scheme: dark; } /* Reading progress bar - thin terracotta line */ .reading-progress {