From 9a3056fbd88c91530f5bfd89e48ca90acb694f17 Mon Sep 17 00:00:00 2001 From: gosangam Date: Mon, 11 May 2026 01:58:02 +0530 Subject: [PATCH] theme update --- app/globals.css | 144 +++++++++++++++++++++++++++++ app/transcriptions/[slug]/page.tsx | 10 +- components/reading-settings.tsx | 139 +++++++++++++++++++++++++++- 3 files changed, 287 insertions(+), 6 deletions(-) diff --git a/app/globals.css b/app/globals.css index 53c43cfd..de8d0a58 100644 --- a/app/globals.css +++ b/app/globals.css @@ -89,6 +89,78 @@ --reading-text-align: start; } +/* ── Light palette — "Tulasī Garden" ── + A fresh, distinctly GREEN palette — noticeably green background + (not just a green-tinted white), with deep forest text and primary. */ +:root:not(.dark)[data-light-palette="tulasi-garden"] { + --background: oklch(0.92 0.07 152); + --foreground: oklch(0.22 0.09 155); + --card: oklch(0.95 0.055 150); + --card-foreground: oklch(0.22 0.09 155); + --popover: oklch(0.95 0.055 150); + --popover-foreground: oklch(0.22 0.09 155); + --primary: oklch(0.45 0.19 150); + --primary-foreground: oklch(0.97 0.04 150); + --secondary: oklch(0.85 0.1 152); + --secondary-foreground: oklch(0.22 0.09 155); + --muted: oklch(0.87 0.09 152); + --muted-foreground: oklch(0.42 0.11 150); + --accent: oklch(0.87 0.09 152); + --accent-foreground: oklch(0.22 0.09 155); + --border: oklch(0.76 0.12 150); + --input: oklch(0.76 0.12 150); + --ring: oklch(0.56 0.17 150); + --chart-1: oklch(0.45 0.19 150); + --chart-2: oklch(0.42 0.11 150); + --chart-3: oklch(0.56 0.17 150); + --chart-4: oklch(0.34 0.12 145); + --chart-5: oklch(0.22 0.09 155); + --sidebar: oklch(0.95 0.055 150); + --sidebar-foreground: oklch(0.22 0.09 155); + --sidebar-primary: oklch(0.45 0.19 150); + --sidebar-primary-foreground: oklch(0.97 0.04 150); + --sidebar-accent: oklch(0.87 0.09 152); + --sidebar-accent-foreground: oklch(0.22 0.09 155); + --sidebar-border: oklch(0.76 0.12 150); + --sidebar-ring: oklch(0.56 0.17 150); +} + +/* ── Light palette — "Yamunā Mist" ── + A distinctly BLUE palette inspired by the sacred Yamunā river — + noticeably blue background (not just a blue-tinted white). */ +:root:not(.dark)[data-light-palette="yamuna-mist"] { + --background: oklch(0.92 0.05 230); + --foreground: oklch(0.24 0.09 240); + --card: oklch(0.95 0.04 230); + --card-foreground: oklch(0.24 0.09 240); + --popover: oklch(0.95 0.04 230); + --popover-foreground: oklch(0.24 0.09 240); + --primary: oklch(0.52 0.2 240); + --primary-foreground: oklch(0.97 0.03 230); + --secondary: oklch(0.85 0.08 232); + --secondary-foreground: oklch(0.24 0.09 240); + --muted: oklch(0.87 0.07 232); + --muted-foreground: oklch(0.44 0.11 235); + --accent: oklch(0.87 0.07 232); + --accent-foreground: oklch(0.24 0.09 240); + --border: oklch(0.76 0.1 232); + --input: oklch(0.76 0.1 232); + --ring: oklch(0.62 0.15 235); + --chart-1: oklch(0.52 0.2 240); + --chart-2: oklch(0.44 0.11 235); + --chart-3: oklch(0.62 0.15 235); + --chart-4: oklch(0.38 0.13 240); + --chart-5: oklch(0.24 0.09 240); + --sidebar: oklch(0.95 0.04 230); + --sidebar-foreground: oklch(0.24 0.09 240); + --sidebar-primary: oklch(0.52 0.2 240); + --sidebar-primary-foreground: oklch(0.97 0.03 230); + --sidebar-accent: oklch(0.87 0.07 232); + --sidebar-accent-foreground: oklch(0.24 0.09 240); + --sidebar-border: oklch(0.76 0.1 232); + --sidebar-ring: oklch(0.62 0.15 235); +} + /* ── Dark mode — "Ancient Manuscript" ── */ .dark { --background: oklch(0.197 0.013 55.5); @@ -124,6 +196,78 @@ --sidebar-ring: oklch(0.636 0.08 86.9); } +/* ── Dark palette — "Nīlamaṇi" ── + "Blue jewel" — Kṛṣṇa's sapphire complexion. Deep navy with + bright sky-blue accents — cool and distinctly BLUE. */ +.dark[data-dark-palette="nilamani"] { + --background: oklch(0.16 0.05 255); + --foreground: oklch(0.92 0.04 220); + --card: oklch(0.21 0.06 252); + --card-foreground: oklch(0.92 0.04 220); + --popover: oklch(0.21 0.06 252); + --popover-foreground: oklch(0.92 0.04 220); + --primary: oklch(0.72 0.18 235); + --primary-foreground: oklch(0.16 0.05 255); + --secondary: oklch(0.28 0.06 248); + --secondary-foreground: oklch(0.92 0.04 220); + --muted: oklch(0.28 0.06 248); + --muted-foreground: oklch(0.7 0.07 230); + --accent: oklch(0.28 0.06 248); + --accent-foreground: oklch(0.92 0.04 220); + --border: oklch(0.7 0.12 235 / 22%); + --input: oklch(0.7 0.12 235 / 26%); + --ring: oklch(0.66 0.14 235); + --chart-1: oklch(0.72 0.18 235); + --chart-2: oklch(0.7 0.07 230); + --chart-3: oklch(0.66 0.14 235); + --chart-4: oklch(0.46 0.1 240); + --chart-5: oklch(0.28 0.06 248); + --sidebar: oklch(0.21 0.06 252); + --sidebar-foreground: oklch(0.92 0.04 220); + --sidebar-primary: oklch(0.72 0.18 235); + --sidebar-primary-foreground: oklch(0.16 0.05 255); + --sidebar-accent: oklch(0.28 0.06 248); + --sidebar-accent-foreground: oklch(0.92 0.04 220); + --sidebar-border: oklch(0.7 0.12 235 / 22%); + --sidebar-ring: oklch(0.66 0.14 235); +} + +/* ── Dark palette — "Vraja Twilight" ── + The crimson dusk over Vraja — deep wine background with warm + rose-red accents. Distinctly RED/WARM, no overlap with the others. */ +.dark[data-dark-palette="vraja-twilight"] { + --background: oklch(0.18 0.05 15); + --foreground: oklch(0.92 0.03 25); + --card: oklch(0.22 0.06 12); + --card-foreground: oklch(0.92 0.03 25); + --popover: oklch(0.22 0.06 12); + --popover-foreground: oklch(0.92 0.03 25); + --primary: oklch(0.72 0.18 25); + --primary-foreground: oklch(0.18 0.05 15); + --secondary: oklch(0.28 0.06 15); + --secondary-foreground: oklch(0.92 0.03 25); + --muted: oklch(0.28 0.06 15); + --muted-foreground: oklch(0.7 0.07 22); + --accent: oklch(0.28 0.06 15); + --accent-foreground: oklch(0.92 0.03 25); + --border: oklch(0.7 0.12 25 / 22%); + --input: oklch(0.7 0.12 25 / 26%); + --ring: oklch(0.66 0.14 25); + --chart-1: oklch(0.72 0.18 25); + --chart-2: oklch(0.7 0.07 22); + --chart-3: oklch(0.66 0.14 25); + --chart-4: oklch(0.46 0.1 20); + --chart-5: oklch(0.28 0.06 15); + --sidebar: oklch(0.22 0.06 12); + --sidebar-foreground: oklch(0.92 0.03 25); + --sidebar-primary: oklch(0.72 0.18 25); + --sidebar-primary-foreground: oklch(0.18 0.05 15); + --sidebar-accent: oklch(0.28 0.06 15); + --sidebar-accent-foreground: oklch(0.92 0.03 25); + --sidebar-border: oklch(0.7 0.12 25 / 22%); + --sidebar-ring: oklch(0.66 0.14 25); +} + @layer base { * { @apply border-border outline-ring/50; diff --git a/app/transcriptions/[slug]/page.tsx b/app/transcriptions/[slug]/page.tsx index 275dfd15..d0725eab 100644 --- a/app/transcriptions/[slug]/page.tsx +++ b/app/transcriptions/[slug]/page.tsx @@ -117,16 +117,16 @@ export default async function TranscriptionPage({ {/* Audio + Participants row */} -
+
{/* Participants */} {t.participants.length > 0 && ( <> -
-
+
+
Participants:
-
+
{t.participants.map((p, i) => ( +
p.id); +const DARK_PALETTE_IDS = DARK_PALETTES.map((p) => p.id); + const FONT_SIZES = [ { value: "xs", label: "XS" }, { value: "sm", label: "S" }, @@ -58,6 +128,12 @@ function loadPrefs(): ReadingPrefs { typeof parsed.justified === "boolean" ? parsed.justified : DEFAULT_PREFS.justified, + lightPalette: LIGHT_PALETTE_IDS.includes(parsed.lightPalette) + ? parsed.lightPalette + : DEFAULT_PREFS.lightPalette, + darkPalette: DARK_PALETTE_IDS.includes(parsed.darkPalette) + ? parsed.darkPalette + : DEFAULT_PREFS.darkPalette, }; } catch { return DEFAULT_PREFS; @@ -86,6 +162,11 @@ function applyClasses(prefs: ReadingPrefs) { // Justified root.classList.toggle("reading-justified", prefs.justified); + + // Palettes — always set both attributes so the appropriate one takes + // effect when the user toggles light ↔ dark. + root.setAttribute("data-light-palette", prefs.lightPalette); + root.setAttribute("data-dark-palette", prefs.darkPalette); } function Toggle({ @@ -128,7 +209,7 @@ export function ReadingSettings() { const [prefs, setPrefs] = useState(() => loadPrefs()); const panelRef = useRef(null); const buttonRef = useRef(null); - const { theme, setTheme } = useTheme(); + const { theme, setTheme, resolvedTheme } = useTheme(); const mounted = useMounted(); // Apply classes on mount (prefs already loaded via lazy initializer) @@ -178,6 +259,14 @@ export function ReadingSettings() { const fontSizeIndex = FONT_SIZES.findIndex((f) => f.value === prefs.fontSize); const currentFontSizeLabel = FONT_SIZES[fontSizeIndex]?.label ?? "M"; + // Show palettes matching the currently visible mode. Falls back to light if + // resolvedTheme hasn't been determined yet (e.g. first render). + const isDark = resolvedTheme === "dark"; + const visiblePalettes = isDark ? DARK_PALETTES : LIGHT_PALETTES; + const activePaletteId = isDark ? prefs.darkPalette : prefs.lightPalette; + const activePaletteName = + visiblePalettes.find((p) => p.id === activePaletteId)?.name ?? ""; + if (!mounted) { return (
+ {/* Palette selector — shows light or dark palettes depending on + the currently resolved theme. */} +
+
+ + Palette + + + {activePaletteName} + +
+
+ {visiblePalettes.map((p) => { + const isActive = activePaletteId === p.id; + return ( + + ); + })} +
+
+
Reading