// Shared theme — light/dark + palette
// Accent changed from shu (朱/vermilion) to fukamidori (深緑/deep green)
// to better align with food/craft/nature associations.
const CULINA_THEME = {
light: {
paper: '#f4efe6', // warm off-white (washi)
paperDeep: '#ece5d5', // one shade darker paper
ink: '#1a1613', // sumi black
sumi: '#2d2824', // soft black
accent: '#2d6a4f', // fukamidori — deep green
accentDeep: '#1f4d38', // forest green
accentSoft: '#2d6a4f33',// accent @ 20%
muted: '#8a7f72',
mutedLight: '#b5ab9a',
line: '#d9cfbe',
surface: '#f4efe6',
},
dark: {
paper: '#0f0e0c', // sumi base
paperDeep: '#161411', // slightly lifted
ink: '#ede5d4', // warm cream ink
sumi: '#cfc6b5', // softer ink
accent: '#6fb88f', // lighter green for dark bg legibility
accentDeep: '#4a9873',
accentSoft: '#6fb88f33',
muted: '#7a7266',
mutedLight: '#9b9283',
line: '#2a2622',
surface: '#0f0e0c',
},
fonts: {
serif: "'Shippori Mincho', 'Noto Serif JP', serif",
sans: "'Inter', 'Noto Sans JP', sans-serif",
mono: "'JetBrains Mono', monospace",
},
};
// Theme context — any page component can call useTheme()
const ThemeContext = React.createContext({ mode: 'light', theme: CULINA_THEME.light, toggle: () => {} });
const useTheme = () => React.useContext(ThemeContext);
const ThemeProvider = ({ children }) => {
const [mode, setMode] = React.useState(() => {
try { return localStorage.getItem('culina-theme') || 'light'; } catch { return 'light'; }
});
React.useEffect(() => {
try { localStorage.setItem('culina-theme', mode); } catch {}
}, [mode]);
const theme = { ...CULINA_THEME[mode], fonts: CULINA_THEME.fonts, mode };
const toggle = () => setMode(m => m === 'light' ? 'dark' : 'light');
return (
{children}
);
};
// Floating theme toggle — placed bottom-right of any page
const ThemeToggle = () => {
const { mode, toggle } = useTheme();
const t = CULINA_THEME[mode];
// Lightweight viewport check (doesn't depend on site-common.jsx load order)
const [isMobile, setIsMobile] = React.useState(() =>
typeof window !== 'undefined' && window.innerWidth < 768);
React.useEffect(() => {
const on = () => setIsMobile(window.innerWidth < 768);
window.addEventListener('resize', on);
return () => window.removeEventListener('resize', on);
}, []);
return (
);
};
Object.assign(window, { CULINA_THEME, ThemeProvider, ThemeContext, useTheme, ThemeToggle });