All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 12s
- Sidebar: dynamic brand-accent colors, brainstorm section restyled - AI chat general: popup panel with expand/collapse, hides when contextual AI open - AI chat contextual: tabs reordered (Actions first), X close button, height fix - Settings: all tabs restyled, 6 new color presets (sage, terracotta, iron, etc.) - Global color cleanup: emerald/orange hardcoded → brand-accent dynamic - Brainstorm page: orange → brand-accent throughout - PageEntry animation component added to key pages - Floating AI button: bg-brand-accent instead of hardcoded black - i18n: all 15 locales updated with new AI/billing keys - Billing: freemium quota tracking, BYOK, stripe subscription scaffolding - Admin: integrated into new design - AGENTS.md + CLAUDE.md project rules added
69 lines
2.2 KiB
TypeScript
69 lines
2.2 KiB
TypeScript
'use client'
|
|
|
|
import { useEffect } from 'react'
|
|
import { applyDocumentTheme, normalizeThemeId } from '@/lib/apply-document-theme'
|
|
|
|
interface ThemeInitializerProps {
|
|
theme?: string
|
|
fontSize?: string
|
|
fontFamily?: string
|
|
accentColor?: string
|
|
}
|
|
|
|
export function ThemeInitializer({ theme, fontSize, fontFamily, accentColor }: ThemeInitializerProps) {
|
|
useEffect(() => {
|
|
const applyFontSize = (s?: string) => {
|
|
const size = s || 'medium'
|
|
|
|
const fontSizeMap: Record<string, string> = {
|
|
small: '14px',
|
|
medium: '16px',
|
|
large: '18px',
|
|
'extra-large': '20px',
|
|
}
|
|
|
|
const fontSizeFactorMap: Record<string, number> = {
|
|
small: 0.95,
|
|
medium: 1.0,
|
|
large: 1.1,
|
|
'extra-large': 1.25,
|
|
}
|
|
|
|
const root = document.documentElement
|
|
root.style.setProperty('--user-font-size', fontSizeMap[size] || '16px')
|
|
root.style.setProperty('--user-font-size-factor', (fontSizeFactorMap[size] || 1).toString())
|
|
}
|
|
|
|
const localTheme = localStorage.getItem('theme-preference')
|
|
const effectiveTheme = localTheme || theme || 'light'
|
|
|
|
applyDocumentTheme(effectiveTheme)
|
|
|
|
if (!localTheme && theme) {
|
|
localStorage.setItem('theme-preference', normalizeThemeId(theme))
|
|
}
|
|
|
|
applyFontSize(fontSize)
|
|
|
|
const localFontFamily = localStorage.getItem('font-family')
|
|
const effectiveFontFamily = localFontFamily || fontFamily || 'inter'
|
|
const root = document.documentElement
|
|
root.classList.remove('font-system', 'font-playfair', 'font-jetbrains')
|
|
if (effectiveFontFamily === 'system') root.classList.add('font-system')
|
|
if (effectiveFontFamily === 'playfair') root.classList.add('font-playfair')
|
|
if (effectiveFontFamily === 'jetbrains') root.classList.add('font-jetbrains')
|
|
if (!localFontFamily && fontFamily) {
|
|
localStorage.setItem('font-family', fontFamily)
|
|
}
|
|
|
|
const localAccent = localStorage.getItem('accent-color')
|
|
const effectiveAccent = localAccent || accentColor || '#A47148'
|
|
document.documentElement.style.setProperty('--color-brand-accent', effectiveAccent)
|
|
if (!localAccent && accentColor) {
|
|
localStorage.setItem('accent-color', accentColor)
|
|
}
|
|
}, [theme, fontSize, fontFamily, accentColor])
|
|
|
|
return null
|
|
}
|