From 4a596abedfabd3c5a081c0c1c4c275a189912159 Mon Sep 17 00:00:00 2001 From: Drew Galbraith Date: Mon, 22 Sep 2025 20:43:03 -0700 Subject: [PATCH] Set colorscheme. --- frontend/app/app.css | 59 +-------- frontend/app/components/Layout.tsx | 65 ++++----- frontend/app/root.tsx | 18 +-- frontend/app/theme.ts | 204 ++++++++--------------------- frontend/package-lock.json | 1 - frontend/package.json | 1 - frontend/tailwind.config.js | 76 ----------- 7 files changed, 80 insertions(+), 344 deletions(-) delete mode 100644 frontend/tailwind.config.js diff --git a/frontend/app/app.css b/frontend/app/app.css index ba71dcb..e4d1dd9 100644 --- a/frontend/app/app.css +++ b/frontend/app/app.css @@ -1,59 +1,8 @@ -@import 'tailwindcss'; - -@theme { - --font-sans: - 'Inter', ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', - 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; - - /* Captain's Log Design Tokens */ - --color-primary-50: #eff6ff; - --color-primary-100: #dbeafe; - --color-primary-500: #3b82f6; - --color-primary-950: #172554; - - --color-task-todo: #3b82f6; - --color-task-done: #22c55e; - --color-task-backlog: #6b7280; -} +/* Captain's Log - Global Styles */ +/* Base font family is handled by Material-UI theme */ html, body { - @apply bg-gray-50 dark:bg-gray-950 text-gray-900 dark:text-gray-100; - - @media (prefers-color-scheme: dark) { - color-scheme: dark; - } -} - -/* Captain's Log Component Styles */ -.task-card { - @apply bg-white dark:bg-gray-800 rounded-xl shadow-sm border border-gray-200 dark:border-gray-700 p-4 transition-all duration-200; -} - -.task-card:hover { - @apply shadow-md border-gray-300 dark:border-gray-600; -} - -.quick-capture { - @apply bg-white dark:bg-gray-800 border-2 border-dashed border-gray-300 dark:border-gray-600 rounded-xl p-4 transition-colors duration-200; -} - -.quick-capture:focus-within { - @apply border-blue-500 bg-blue-50 dark:bg-blue-950; -} - -.status-badge { - @apply inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium; -} - -.status-todo { - @apply bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200; -} - -.status-done { - @apply bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200; -} - -.status-backlog { - @apply bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-200; + margin: 0; + padding: 0; } diff --git a/frontend/app/components/Layout.tsx b/frontend/app/components/Layout.tsx index de7c05f..169e9f5 100644 --- a/frontend/app/components/Layout.tsx +++ b/frontend/app/components/Layout.tsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect } from 'react' +import React, { useState } from 'react' import { AppBar, Box, @@ -21,8 +21,6 @@ import { Dashboard as DashboardIcon, Add as AddIcon, Settings as SettingsIcon, - DarkMode as DarkModeIcon, - LightMode as LightModeIcon, } from '@mui/icons-material' const drawerWidth = 240 @@ -35,28 +33,11 @@ interface LayoutProps { export default function Layout({ children, loading = false }: LayoutProps) { const theme = useTheme() const [mobileOpen, setMobileOpen] = useState(false) - const [darkMode, setDarkMode] = useState(false) - - // Check system preference and localStorage on mount - useEffect(() => { - const savedTheme = localStorage.getItem('theme') - const prefersDark = window.matchMedia( - '(prefers-color-scheme: dark)' - ).matches - setDarkMode(savedTheme === 'dark' || (!savedTheme && prefersDark)) - }, []) const handleDrawerToggle = () => { setMobileOpen(!mobileOpen) } - const handleThemeToggle = () => { - const newTheme = !darkMode - setDarkMode(newTheme) - localStorage.setItem('theme', newTheme ? 'dark' : 'light') - document.documentElement.classList.toggle('dark', newTheme) - } - const menuItems = [ { text: 'Tasks', @@ -72,17 +53,7 @@ export default function Layout({ children, loading = false }: LayoutProps) { const drawer = (
- - - Captain's Log - - - + {menuItems.map(item => ( @@ -149,17 +122,21 @@ export default function Layout({ children, loading = false }: LayoutProps) { - - Captain's Log - - - - {darkMode ? : } - + ⚓ Captain's Log + @@ -196,6 +173,8 @@ export default function Layout({ children, loading = false }: LayoutProps) { '& .MuiDrawer-paper': { boxSizing: 'border-box', width: drawerWidth, + top: '64px', // Position below AppBar + height: 'calc(100% - 64px)', // Adjust height to account for AppBar }, }} open diff --git a/frontend/app/root.tsx b/frontend/app/root.tsx index ffb6f0b..c7b440f 100644 --- a/frontend/app/root.tsx +++ b/frontend/app/root.tsx @@ -10,7 +10,7 @@ import { ThemeProvider } from '@mui/material/styles' import { CssBaseline } from '@mui/material' import type { Route } from './+types/root' -import { theme, darkTheme } from './theme' +import { theme } from './theme' import AppLayout from './components/Layout' import './app.css' @@ -46,14 +46,8 @@ export function Layout({ children }: { children: React.ReactNode }) { } export default function App() { - const isDarkMode = - typeof window !== 'undefined' && - (localStorage.getItem('theme') === 'dark' || - (!localStorage.getItem('theme') && - window.matchMedia('(prefers-color-scheme: dark)').matches)) - return ( - + @@ -78,14 +72,8 @@ export function ErrorBoundary({ error }: Route.ErrorBoundaryProps) { stack = error.stack } - const isDarkMode = - typeof window !== 'undefined' && - (localStorage.getItem('theme') === 'dark' || - (!localStorage.getItem('theme') && - window.matchMedia('(prefers-color-scheme: dark)').matches)) - return ( - +
diff --git a/frontend/app/theme.ts b/frontend/app/theme.ts index c138103..d89fee5 100644 --- a/frontend/app/theme.ts +++ b/frontend/app/theme.ts @@ -1,5 +1,24 @@ import { createTheme } from '@mui/material/styles' +// Color palette constants +const colors = { + // Primary Colors + deepNavy: '#1e3a5f', // Main brand color for headers and primary actions + oceanBlue: '#2c5282', // Secondary blue for links and active states + compassGold: '#d69e2e', // Accent color for highlights and call-to-actions + + // Status Colors + chartGreen: '#48bb78', // Completed tasks and success states + sunsetCoral: '#f56565', // Urgent tasks and error states + seaFoam: '#4fd1c7', // Information and notification states + + // Neutrals + parchment: '#f7fafc', // Clean background color + fogGray: '#e2e8f0', // Subtle borders and dividers + stormGray: '#718096', // Secondary text + anchorDark: '#2d3748', // Primary text and headings +} + declare module '@mui/material/styles' { interface Theme { custom: { @@ -26,29 +45,37 @@ export const theme = createTheme({ palette: { mode: 'light', primary: { - 50: '#eff6ff', - 100: '#dbeafe', - 500: '#3b82f6', - main: '#3b82f6', + main: colors.deepNavy, + light: colors.oceanBlue, contrastText: '#ffffff', }, + secondary: { + main: colors.compassGold, + contrastText: '#ffffff', + }, + success: { + main: colors.chartGreen, + }, + error: { + main: colors.sunsetCoral, + }, + info: { + main: colors.seaFoam, + }, background: { - default: '#f9fafb', + default: colors.parchment, paper: '#ffffff', }, text: { - primary: '#111827', - secondary: '#6b7280', + primary: colors.anchorDark, + secondary: colors.stormGray, }, grey: { - 50: '#f9fafb', - 100: '#f3f4f6', - 200: '#e5e7eb', - 300: '#d1d5db', - 600: '#4b5563', - 700: '#374151', - 800: '#1f2937', - 900: '#111827', + 100: '#edf2f7', + 200: colors.fogGray, + 300: '#cbd5e0', + 500: colors.stormGray, + 700: colors.anchorDark, }, }, typography: { @@ -84,11 +111,11 @@ export const theme = createTheme({ MuiAppBar: { styleOverrides: { root: { - backgroundColor: '#ffffff', - color: '#111827', + backgroundColor: colors.deepNavy, + color: '#ffffff', boxShadow: '0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)', - borderBottom: '1px solid #e5e7eb', + borderBottom: 'none', }, }, }, @@ -96,7 +123,7 @@ export const theme = createTheme({ styleOverrides: { paper: { backgroundColor: '#ffffff', - borderRight: '1px solid #e5e7eb', + borderRight: `1px solid ${colors.fogGray}`, }, }, }, @@ -122,11 +149,11 @@ export const theme = createTheme({ borderRadius: '0.75rem', boxShadow: '0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)', - border: '1px solid #e5e7eb', + border: `1px solid ${colors.fogGray}`, '&:hover': { boxShadow: '0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)', - borderColor: '#d1d5db', + borderColor: '#cbd5e0', }, }, }, @@ -143,138 +170,9 @@ export const theme = createTheme({ }, custom: { task: { - todo: '#3b82f6', - done: '#22c55e', - backlog: '#6b7280', - }, - }, -}) - -export const darkTheme = createTheme({ - palette: { - mode: 'dark', - primary: { - 50: '#eff6ff', - 100: '#dbeafe', - 500: '#3b82f6', - main: '#3b82f6', - contrastText: '#ffffff', - }, - background: { - default: '#030712', - paper: '#1f2937', - }, - text: { - primary: '#f9fafb', - secondary: '#9ca3af', - }, - grey: { - 50: '#f9fafb', - 100: '#f3f4f6', - 200: '#e5e7eb', - 300: '#d1d5db', - 600: '#4b5563', - 700: '#374151', - 800: '#1f2937', - 900: '#111827', - }, - }, - typography: { - fontFamily: '"Inter", ui-sans-serif, system-ui, sans-serif', - h1: { - fontSize: '2rem', - fontWeight: 700, - lineHeight: 1.2, - }, - h2: { - fontSize: '1.5rem', - fontWeight: 600, - lineHeight: 1.3, - }, - h3: { - fontSize: '1.25rem', - fontWeight: 600, - lineHeight: 1.4, - }, - body1: { - fontSize: '1rem', - lineHeight: 1.6, - }, - body2: { - fontSize: '0.875rem', - lineHeight: 1.5, - }, - }, - shape: { - borderRadius: 12, - }, - components: { - MuiAppBar: { - styleOverrides: { - root: { - backgroundColor: '#1f2937', - color: '#f9fafb', - boxShadow: - '0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)', - borderBottom: '1px solid #374151', - }, - }, - }, - MuiDrawer: { - styleOverrides: { - paper: { - backgroundColor: '#1f2937', - borderRight: '1px solid #374151', - }, - }, - }, - MuiButton: { - styleOverrides: { - root: { - textTransform: 'none', - borderRadius: '0.75rem', - fontWeight: 500, - }, - contained: { - boxShadow: '0 1px 2px 0 rgb(0 0 0 / 0.05)', - '&:hover': { - boxShadow: - '0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)', - }, - }, - }, - }, - MuiCard: { - styleOverrides: { - root: { - backgroundColor: '#1f2937', - borderRadius: '0.75rem', - boxShadow: - '0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)', - border: '1px solid #374151', - '&:hover': { - boxShadow: - '0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)', - borderColor: '#4b5563', - }, - }, - }, - }, - MuiTextField: { - styleOverrides: { - root: { - '& .MuiOutlinedInput-root': { - borderRadius: '0.75rem', - }, - }, - }, - }, - }, - custom: { - task: { - todo: '#3b82f6', - done: '#22c55e', - backlog: '#6b7280', + todo: colors.oceanBlue, + done: colors.chartGreen, + backlog: colors.stormGray, }, }, }) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 981e3aa..3eeffb4 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -33,7 +33,6 @@ "eslint-plugin-react-refresh": "^0.4.20", "jsdom": "^27.0.0", "prettier": "^3.6.2", - "tailwindcss": "^4.1.4", "typescript": "^5.8.3", "typescript-eslint": "^8.44.0", "vite": "^6.3.3", diff --git a/frontend/package.json b/frontend/package.json index d8d7315..95643b1 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -43,7 +43,6 @@ "eslint-plugin-react-refresh": "^0.4.20", "jsdom": "^27.0.0", "prettier": "^3.6.2", - "tailwindcss": "^4.1.4", "typescript": "^5.8.3", "typescript-eslint": "^8.44.0", "vite": "^6.3.3", diff --git a/frontend/tailwind.config.js b/frontend/tailwind.config.js deleted file mode 100644 index 7a4c415..0000000 --- a/frontend/tailwind.config.js +++ /dev/null @@ -1,76 +0,0 @@ -/** @type {import('tailwindcss').Config} */ -export default { - content: [ - "./app/**/*.{js,jsx,ts,tsx}", - ], - theme: { - extend: { - fontFamily: { - sans: ["Inter", "ui-sans-serif", "system-ui", "sans-serif"], - }, - colors: { - primary: { - 50: '#eff6ff', - 100: '#dbeafe', - 200: '#bfdbfe', - 300: '#93c5fd', - 400: '#60a5fa', - 500: '#3b82f6', - 600: '#2563eb', - 700: '#1d4ed8', - 800: '#1e40af', - 900: '#1e3a8a', - }, - success: { - 50: '#f0fdf4', - 100: '#dcfce7', - 200: '#bbf7d0', - 300: '#86efac', - 400: '#4ade80', - 500: '#22c55e', - 600: '#16a34a', - 700: '#15803d', - 800: '#166534', - 900: '#14532d', - }, - warning: { - 50: '#fffbeb', - 100: '#fef3c7', - 200: '#fde68a', - 300: '#fcd34d', - 400: '#fbbf24', - 500: '#f59e0b', - 600: '#d97706', - 700: '#b45309', - 800: '#92400e', - 900: '#78350f', - }, - danger: { - 50: '#fef2f2', - 100: '#fee2e2', - 200: '#fecaca', - 300: '#fca5a5', - 400: '#f87171', - 500: '#ef4444', - 600: '#dc2626', - 700: '#b91c1c', - 800: '#991b1b', - 900: '#7f1d1d', - }, - }, - spacing: { - '18': '4.5rem', - '88': '22rem', - }, - borderRadius: { - 'xl': '0.75rem', - '2xl': '1rem', - }, - boxShadow: { - 'card': '0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)', - 'card-hover': '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)', - }, - }, - }, - plugins: [], -} \ No newline at end of file