diff --git a/CLAUDE.md b/CLAUDE.md index 6c198e8..8c38e14 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -140,6 +140,17 @@ records.data → apply_transformations() → - Server.js has global error handler - Database functions return JSON with `success` boolean +## Light / dark mode + +Theme state lives in `ui/src/theme.jsx` — a React context (`ThemeContext`) with a `ThemeProvider` that wraps the app in `main.jsx`. + +- **Storage key:** `df_dark` in `localStorage`; falls back to `window.matchMedia('(prefers-color-scheme: dark)')` on first visit +- **Toggle:** button in the sidebar header in `App.jsx`; effect writes `localStorage` and toggles the `.dark` class on `` +- **CSS:** `ui/src/index.css` defines CSS custom properties under `:root` (light) and `.dark`. All Tailwind color overrides are written as `.dark .bg-white { ... }` etc. +- **Palette:** dark mode uses Perspective's "Pro Dark" colours (`--bg-primary: #242526`, panels `#2a2c2f`, gridlines `#3b3f46`, text `#c5c9d0`) +- **Perspective viewer:** `Pivot.jsx` calls `viewer.setAttribute('theme', dark ? 'Pro Dark' : 'Pro Light')` on initial load and in a `useEffect([dark])` so the viewer stays in sync when the toggle fires +- **Consuming the theme:** `import useTheme from '../theme.jsx'` then `const { dark, setDark } = useTheme()` + ## UI (React + Vite) The frontend lives in `ui/src/` and is built to `public/` via `npm run build` from the `ui/` directory. **Always run `npm run build` from `ui/` after any changes to `ui/src/` files.** diff --git a/ui/src/App.jsx b/ui/src/App.jsx index bac0aeb..e4f3025 100644 --- a/ui/src/App.jsx +++ b/ui/src/App.jsx @@ -1,6 +1,7 @@ import { useState, useEffect } from 'react' import { BrowserRouter, Routes, Route, NavLink, Navigate } from 'react-router-dom' import { api, setCredentials, clearCredentials } from './api' +import useTheme from './theme.jsx' import Login from './pages/Login' import Sources from './pages/Sources' import Import from './pages/Import' @@ -25,6 +26,7 @@ const NAV = [ ] export default function App() { + const { dark, setDark } = useTheme() const [authed, setAuthed] = useState(false) const [loginUser, setLoginUser] = useState('') const [sources, setSources] = useState([]) @@ -127,7 +129,32 @@ export default function App() {