Files
dashboard/frontend/src/theme/theme.ts

358 lines
7.4 KiB
TypeScript

import { createTheme, ThemeOptions } from '@mui/material/styles';
/** Golden ratio constant for proportional spacing/sizing */
export const GOLDEN_RATIO = 1.618;
// Fire department red color palette
const primaryRed = {
main: '#d32f2f',
light: '#ff6659',
dark: '#9a0007',
contrastText: '#ffffff',
};
const secondaryBlue = {
main: '#1976d2',
light: '#63a4ff',
dark: '#004ba0',
contrastText: '#ffffff',
};
const lightThemeOptions: ThemeOptions = {
palette: {
mode: 'light',
primary: primaryRed,
secondary: secondaryBlue,
background: {
default: '#f0f2f5',
paper: '#ffffff',
},
divider: 'rgba(0, 0, 0, 0.08)',
error: {
main: '#ef4444',
},
warning: {
main: '#f59e0b',
},
info: {
main: '#3b82f6',
},
success: {
main: '#22c55e',
},
},
typography: {
fontFamily: [
'Inter',
'-apple-system',
'BlinkMacSystemFont',
'"Segoe UI"',
'Roboto',
'"Helvetica Neue"',
'Arial',
'sans-serif',
].join(','),
h1: {
fontSize: '2.25rem',
fontWeight: 700,
lineHeight: 1.2,
letterSpacing: '-0.02em',
},
h2: {
fontSize: '1.875rem',
fontWeight: 700,
lineHeight: 1.3,
letterSpacing: '-0.01em',
},
h3: {
fontSize: '1.5rem',
fontWeight: 700,
lineHeight: 1.4,
},
h4: {
fontSize: '1.25rem',
fontWeight: 700,
lineHeight: 1.4,
},
h5: {
fontSize: '1.125rem',
fontWeight: 700,
lineHeight: 1.5,
},
h6: {
fontSize: '1rem',
fontWeight: 600,
lineHeight: 1.6,
},
subtitle1: {
fontSize: '0.9375rem',
fontWeight: 600,
lineHeight: 1.5,
},
body1: {
fontSize: '0.9375rem',
lineHeight: 1.6,
},
body2: {
fontSize: '0.8125rem',
lineHeight: 1.5,
},
caption: {
fontSize: '0.6875rem',
fontWeight: 500,
lineHeight: 1.5,
letterSpacing: '0.04em',
},
button: {
textTransform: 'none',
fontWeight: 600,
fontSize: '0.8125rem',
},
},
spacing: 8,
shape: {
borderRadius: 10,
},
components: {
MuiCssBaseline: {
styleOverrides: {
body: {
WebkitFontSmoothing: 'antialiased',
MozOsxFontSmoothing: 'grayscale',
},
},
},
MuiButton: {
styleOverrides: {
root: {
borderRadius: 8,
padding: '8px 18px',
fontWeight: 600,
},
contained: {
boxShadow: 'none',
'&:hover': {
boxShadow: '0 2px 8px rgba(0,0,0,0.15)',
},
},
outlined: {
borderWidth: 1.5,
'&:hover': {
borderWidth: 1.5,
},
},
},
},
MuiCard: {
styleOverrides: {
root: {
borderRadius: 14,
border: '1px solid rgba(0, 0, 0, 0.06)',
boxShadow: '0 1px 2px rgba(0,0,0,0.04)',
transition: 'border-color 0.2s ease, box-shadow 0.2s ease',
'&:hover': {
borderColor: 'rgba(0, 0, 0, 0.12)',
boxShadow: '0 2px 8px rgba(0,0,0,0.08)',
},
},
},
},
MuiPaper: {
styleOverrides: {
root: {
borderRadius: 10,
},
elevation0: {
boxShadow: 'none',
},
elevation1: {
border: '1px solid rgba(0, 0, 0, 0.06)',
boxShadow: '0 1px 2px rgba(0,0,0,0.04)',
},
elevation2: {
boxShadow: '0 2px 8px rgba(0,0,0,0.08)',
},
elevation3: {
boxShadow: '0 4px 16px rgba(0,0,0,0.1)',
},
},
},
MuiAppBar: {
styleOverrides: {
root: {
boxShadow: '0 1px 0 rgba(0,0,0,0.06)',
},
},
},
MuiChip: {
styleOverrides: {
root: {
fontWeight: 500,
borderRadius: 6,
},
sizeSmall: {
height: 22,
fontSize: '0.6875rem',
},
},
},
MuiTextField: {
defaultProps: {
InputLabelProps: {
shrink: true,
},
},
},
MuiOutlinedInput: {
styleOverrides: {
root: {
borderRadius: 8,
'& .MuiOutlinedInput-notchedOutline': {
borderColor: 'rgba(0, 0, 0, 0.12)',
},
'& .MuiOutlinedInput-notchedOutline legend': {
fontSize: '0.75em',
},
},
},
},
MuiTableHead: {
styleOverrides: {
root: {
'& .MuiTableCell-head': {
textTransform: 'uppercase',
fontSize: '0.6875rem',
fontWeight: 600,
letterSpacing: '0.06em',
color: 'rgba(0, 0, 0, 0.5)',
borderBottom: '2px solid rgba(0, 0, 0, 0.06)',
},
},
},
},
MuiTableRow: {
styleOverrides: {
root: {
'&.MuiTableRow-hover:hover': {
backgroundColor: 'rgba(0, 0, 0, 0.02)',
},
},
},
},
MuiTableCell: {
styleOverrides: {
root: {
borderBottom: '1px solid rgba(0, 0, 0, 0.04)',
},
},
},
MuiDialog: {
styleOverrides: {
paper: {
borderRadius: 14,
},
},
},
MuiDivider: {
styleOverrides: {
root: {
borderColor: 'rgba(0, 0, 0, 0.06)',
},
},
},
MuiTooltip: {
styleOverrides: {
tooltip: {
borderRadius: 6,
fontSize: '0.75rem',
},
},
},
},
};
const darkThemeOptions: ThemeOptions = {
...lightThemeOptions,
palette: {
mode: 'dark',
primary: primaryRed,
secondary: secondaryBlue,
background: {
default: '#0f1117',
paper: '#1a1d27',
},
divider: 'rgba(255, 255, 255, 0.08)',
error: {
main: '#ef4444',
},
warning: {
main: '#f59e0b',
},
info: {
main: '#3b82f6',
},
success: {
main: '#22c55e',
},
},
components: {
...lightThemeOptions.components,
MuiTableHead: {
styleOverrides: {
root: {
'& .MuiTableCell-head': {
textTransform: 'uppercase',
fontSize: '0.6875rem',
fontWeight: 600,
letterSpacing: '0.06em',
color: 'rgba(255, 255, 255, 0.5)',
borderBottom: '2px solid rgba(255, 255, 255, 0.08)',
},
},
},
},
MuiTableRow: {
styleOverrides: {
root: {
'&.MuiTableRow-hover:hover': {
backgroundColor: 'rgba(255, 255, 255, 0.04)',
},
},
},
},
MuiTableCell: {
styleOverrides: {
root: {
borderBottom: '1px solid rgba(255, 255, 255, 0.08)',
},
},
},
MuiCard: {
styleOverrides: {
root: {
borderRadius: 14,
border: '1px solid rgba(255, 255, 255, 0.06)',
boxShadow: '0 1px 2px rgba(0,0,0,0.2)',
transition: 'border-color 0.2s ease, box-shadow 0.2s ease',
'&:hover': {
borderColor: 'rgba(255, 255, 255, 0.12)',
boxShadow: '0 2px 8px rgba(0,0,0,0.3)',
},
},
},
},
MuiDivider: {
styleOverrides: {
root: {
borderColor: 'rgba(255, 255, 255, 0.08)',
},
},
},
},
};
export const lightTheme = createTheme(lightThemeOptions);
export const darkTheme = createTheme(darkThemeOptions);
export default lightTheme;