- pnpm monorepo (apps/client + apps/server) - Server: Express + node:sqlite with numbered migration runner, REST API for all 9 features (members, events, chores, shopping, meals, messages, countdowns, photos, settings) - Client: React 18 + Vite + TypeScript + Tailwind + Framer Motion + Zustand - Theme system: dark/light + 5 accent colors, CSS custom properties, anti-FOUC script, ThemeToggle on every surface - AppShell: collapsible sidebar, animated route transitions, mobile drawer - Phase 2 features: Calendar (custom month grid, event chips, add/edit modal), Chores (card grid, complete/reset, member filter, streaks), Shopping (multi-list tabs, animated check-off, quick-add bar, member assign) - Family member CRUD with avatar, color picker - Settings page: theme/accent, photo folder, slideshow, weather, date/time - Docker: multi-stage Dockerfile, docker-compose.yml, entrypoint with PUID/PGID - Unraid: CA XML template, CLI install script, UNRAID.md guide - .gitignore covering node_modules, dist, db files, secrets, build artifacts Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
66 lines
2.9 KiB
CSS
66 lines
2.9 KiB
CSS
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap');
|
|
@tailwind base;
|
|
@tailwind components;
|
|
@tailwind utilities;
|
|
|
|
/* ─── Base token defaults (light) — overridden by JS applyTheme() ──── */
|
|
:root {
|
|
--color-bg: #f8fafc;
|
|
--color-surface: #ffffff;
|
|
--color-surface-raised: #f1f5f9;
|
|
--color-border: #e2e8f0;
|
|
--color-text-primary: #0f172a;
|
|
--color-text-secondary: #475569;
|
|
--color-text-muted: #94a3b8;
|
|
--color-accent: #6366f1;
|
|
--color-accent-light: #e0e7ff;
|
|
}
|
|
|
|
/* ─── Smooth theme transitions on every surface ───────────────────── */
|
|
*, *::before, *::after {
|
|
transition-property: background-color, color, border-color;
|
|
transition-duration: 200ms;
|
|
transition-timing-function: ease;
|
|
}
|
|
|
|
/* But NOT on animations / transforms */
|
|
[data-no-transition], [data-no-transition] * {
|
|
transition: none !important;
|
|
}
|
|
|
|
/* ─── Base body ───────────────────────────────────────────────────── */
|
|
body {
|
|
background-color: var(--color-bg);
|
|
color: var(--color-text-primary);
|
|
font-family: 'Inter', system-ui, sans-serif;
|
|
-webkit-font-smoothing: antialiased;
|
|
-moz-osx-font-smoothing: grayscale;
|
|
}
|
|
|
|
/* ─── Scrollbar styling ────────────────────────────────────────────── */
|
|
::-webkit-scrollbar { width: 6px; height: 6px; }
|
|
::-webkit-scrollbar-track { background: transparent; }
|
|
::-webkit-scrollbar-thumb { background: var(--color-border); border-radius: 3px; }
|
|
::-webkit-scrollbar-thumb:hover { background: var(--color-text-muted); }
|
|
|
|
/* ─── Focus ring ───────────────────────────────────────────────────── */
|
|
:focus-visible {
|
|
outline: 2px solid var(--color-accent);
|
|
outline-offset: 2px;
|
|
}
|
|
|
|
/* ─── Utility layer ────────────────────────────────────────────────── */
|
|
@layer utilities {
|
|
.bg-surface { background-color: var(--color-surface); }
|
|
.bg-surface-raised { background-color: var(--color-surface-raised); }
|
|
.bg-app { background-color: var(--color-bg); }
|
|
.border-theme { border-color: var(--color-border); }
|
|
.text-primary { color: var(--color-text-primary); }
|
|
.text-secondary { color: var(--color-text-secondary); }
|
|
.text-muted { color: var(--color-text-muted); }
|
|
.text-accent { color: var(--color-accent); }
|
|
.bg-accent { background-color: var(--color-accent); }
|
|
.bg-accent-light { background-color: var(--color-accent-light); }
|
|
.ring-accent { --tw-ring-color: var(--color-accent); }
|
|
}
|