|
1 | 1 | 'use client' |
| 2 | + |
2 | 3 | import { createTheme } from '@mui/material/styles' |
3 | 4 |
|
4 | | -declare module '@mui/material/styles' { |
5 | | - interface Palette { |
6 | | - active: Palette['primary'] |
7 | | - warning: Palette['primary'] |
8 | | - critical: Palette['primary'] |
9 | | - rest: Palette['primary'] |
10 | | - } |
11 | | - |
12 | | - interface PaletteOptions { |
13 | | - active?: PaletteOptions['primary'] |
14 | | - warning?: PaletteOptions['primary'] |
15 | | - critical?: PaletteOptions['primary'] |
16 | | - rest?: PaletteOptions['primary'] |
17 | | - } |
18 | | -} |
| 5 | +/** |
| 6 | + * HRM Application Design System |
| 7 | + * |
| 8 | + * Goals: |
| 9 | + * - Consistent 8px spacing grid |
| 10 | + * - Clear typography hierarchy |
| 11 | + * - Cohesive color palette with proper contrast |
| 12 | + * - Standard shadows and elevation |
| 13 | + * - Unified border radius |
| 14 | + * - Mobile-first with accessible touch targets (48px min) |
| 15 | + */ |
19 | 16 |
|
20 | 17 | const theme = createTheme({ |
| 18 | + // Color Palette - Vibrant fitness-focused colors |
21 | 19 | palette: { |
22 | | - mode: 'dark', |
23 | 20 | primary: { |
24 | | - main: '#FFFFFF', |
| 21 | + main: '#F44336', // Red - matches Peak HR zone, high energy |
| 22 | + light: '#EF5350', |
| 23 | + dark: '#D32F2F', |
| 24 | + contrastText: '#FFFFFF', |
25 | 25 | }, |
26 | 26 | secondary: { |
27 | | - main: '#B0B0B0', |
| 27 | + main: '#2196F3', // Blue - matches Warm-up zone |
| 28 | + light: '#42A5F5', |
| 29 | + dark: '#1976D2', |
| 30 | + contrastText: '#FFFFFF', |
| 31 | + }, |
| 32 | + success: { |
| 33 | + main: '#4CAF50', // Green - matches Fat Burn zone |
| 34 | + light: '#66BB6A', |
| 35 | + dark: '#388E3C', |
| 36 | + }, |
| 37 | + warning: { |
| 38 | + main: '#FFEB3B', // Yellow - matches Cardio zone |
| 39 | + light: '#FFF176', |
| 40 | + dark: '#FBC02D', |
| 41 | + contrastText: '#000000', |
| 42 | + }, |
| 43 | + error: { |
| 44 | + main: '#F44336', // Red - matches Peak zone |
| 45 | + light: '#EF5350', |
| 46 | + dark: '#D32F2F', |
| 47 | + }, |
| 48 | + info: { |
| 49 | + main: '#2196F3', // Blue |
28 | 50 | }, |
| 51 | + // Background colors |
29 | 52 | background: { |
30 | | - default: '#000000', |
31 | | - paper: 'rgba(255, 255, 255, 0.1)', |
| 53 | + default: '#F5F5F5', // Light grey for main background |
| 54 | + paper: '#FFFFFF', |
32 | 55 | }, |
33 | | - active: { |
34 | | - main: '#76FF03', // Bright Green |
| 56 | + // Text colors |
| 57 | + text: { |
| 58 | + primary: '#212121', |
| 59 | + secondary: '#757575', |
| 60 | + disabled: '#BDBDBD', |
35 | 61 | }, |
36 | | - warning: { |
37 | | - main: '#FFC107', // Amber |
| 62 | + // Dividers |
| 63 | + divider: '#E0E0E0', |
| 64 | + }, |
| 65 | + |
| 66 | + // Typography - Clear hierarchy |
| 67 | + typography: { |
| 68 | + fontFamily: [ |
| 69 | + '-apple-system', |
| 70 | + 'BlinkMacSystemFont', |
| 71 | + '"Segoe UI"', |
| 72 | + 'Roboto', |
| 73 | + '"Helvetica Neue"', |
| 74 | + 'Arial', |
| 75 | + 'sans-serif', |
| 76 | + ].join(','), |
| 77 | + |
| 78 | + // Large display numbers (HR values, timer) |
| 79 | + h1: { |
| 80 | + fontSize: '4rem', // 64px |
| 81 | + fontWeight: 700, |
| 82 | + lineHeight: 1.2, |
| 83 | + letterSpacing: '-0.02em', |
| 84 | + }, |
| 85 | + |
| 86 | + // Section headings |
| 87 | + h2: { |
| 88 | + fontSize: '2.5rem', // 40px |
| 89 | + fontWeight: 600, |
| 90 | + lineHeight: 1.3, |
| 91 | + letterSpacing: '-0.01em', |
| 92 | + }, |
| 93 | + |
| 94 | + // Card titles |
| 95 | + h3: { |
| 96 | + fontSize: '2rem', // 32px |
| 97 | + fontWeight: 600, |
| 98 | + lineHeight: 1.4, |
| 99 | + }, |
| 100 | + |
| 101 | + // Subsection headings |
| 102 | + h4: { |
| 103 | + fontSize: '1.5rem', // 24px |
| 104 | + fontWeight: 600, |
| 105 | + lineHeight: 1.4, |
| 106 | + }, |
| 107 | + |
| 108 | + // Component labels |
| 109 | + h5: { |
| 110 | + fontSize: '1.25rem', // 20px |
| 111 | + fontWeight: 600, |
| 112 | + lineHeight: 1.5, |
| 113 | + }, |
| 114 | + |
| 115 | + // Small headings |
| 116 | + h6: { |
| 117 | + fontSize: '1rem', // 16px |
| 118 | + fontWeight: 600, |
| 119 | + lineHeight: 1.5, |
| 120 | + }, |
| 121 | + |
| 122 | + // Body text |
| 123 | + body1: { |
| 124 | + fontSize: '1rem', // 16px |
| 125 | + lineHeight: 1.5, |
38 | 126 | }, |
39 | | - critical: { |
40 | | - main: '#FF1744', // Bright Red |
| 127 | + |
| 128 | + // Secondary body text |
| 129 | + body2: { |
| 130 | + fontSize: '0.875rem', // 14px |
| 131 | + lineHeight: 1.5, |
| 132 | + }, |
| 133 | + |
| 134 | + // Button text |
| 135 | + button: { |
| 136 | + fontSize: '0.875rem', // 14px |
| 137 | + fontWeight: 600, |
| 138 | + textTransform: 'none', // Don't force uppercase |
| 139 | + letterSpacing: '0.02em', |
41 | 140 | }, |
42 | | - rest: { |
43 | | - main: '#2979FF', // Bright Blue |
| 141 | + |
| 142 | + // Captions |
| 143 | + caption: { |
| 144 | + fontSize: '0.75rem', // 12px |
| 145 | + lineHeight: 1.5, |
| 146 | + }, |
| 147 | + |
| 148 | + // Overlines (labels above content) |
| 149 | + overline: { |
| 150 | + fontSize: '0.75rem', // 12px |
| 151 | + fontWeight: 600, |
| 152 | + textTransform: 'uppercase', |
| 153 | + letterSpacing: '0.08em', |
44 | 154 | }, |
45 | 155 | }, |
| 156 | + |
| 157 | + // Spacing - 8px grid system |
| 158 | + spacing: 8, // Base unit = 8px, theme.spacing(1) = 8px, theme.spacing(2) = 16px, etc. |
| 159 | + |
| 160 | + // Shape - Consistent border radius |
| 161 | + shape: { |
| 162 | + borderRadius: 8, // 8px rounded corners for cards, buttons |
| 163 | + }, |
| 164 | + |
| 165 | + // Shadows - Consistent elevation |
46 | 166 | shadows: [ |
47 | 167 | 'none', |
48 | | - '0 0 5px rgba(118, 255, 3, 0.5)', |
49 | | - '0 0 10px rgba(118, 255, 3, 0.5)', |
50 | | - '0 0 15px rgba(118, 255, 3, 0.5)', |
51 | | - '0 0 20px rgba(255, 193, 7, 0.5)', |
52 | | - '0 0 25px rgba(255, 193, 7, 0.5)', |
53 | | - '0 0 30px rgba(255, 193, 7, 0.5)', |
54 | | - '0 0 35px rgba(255, 23, 68, 0.5)', |
55 | | - '0 0 40px rgba(255, 23, 68, 0.5)', |
56 | | - '0 0 45px rgba(255, 23, 68, 0.5)', |
57 | | - 'none', |
58 | | - 'none', |
59 | | - 'none', |
60 | | - 'none', |
61 | | - 'none', |
62 | | - 'none', |
63 | | - 'none', |
64 | | - 'none', |
65 | | - 'none', |
66 | | - 'none', |
67 | | - 'none', |
68 | | - 'none', |
69 | | - 'none', |
70 | | - 'none', |
71 | | - 'none', |
| 168 | + '0 1px 2px 0 rgba(0, 0, 0, 0.05)', // elevation 1 |
| 169 | + '0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)', // elevation 2 |
| 170 | + '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)', // elevation 3 |
| 171 | + '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)', // elevation 4 |
| 172 | + '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)', // elevation 5 |
| 173 | + '0 25px 50px -12px rgba(0, 0, 0, 0.25)', // elevation 6 |
| 174 | + '0 25px 50px -12px rgba(0, 0, 0, 0.25)', // elevation 7 |
| 175 | + '0 25px 50px -12px rgba(0, 0, 0, 0.25)', // elevation 8 |
| 176 | + '0 25px 50px -12px rgba(0, 0, 0, 0.25)', // elevation 9 |
| 177 | + '0 25px 50px -12px rgba(0, 0, 0, 0.25)', // elevation 10 |
| 178 | + '0 25px 50px -12px rgba(0, 0, 0, 0.25)', // elevation 11 |
| 179 | + '0 25px 50px -12px rgba(0, 0, 0, 0.25)', // elevation 12 |
| 180 | + '0 25px 50px -12px rgba(0, 0, 0, 0.25)', // elevation 13 |
| 181 | + '0 25px 50px -12px rgba(0, 0, 0, 0.25)', // elevation 14 |
| 182 | + '0 25px 50px -12px rgba(0, 0, 0, 0.25)', // elevation 15 |
| 183 | + '0 25px 50px -12px rgba(0, 0, 0, 0.25)', // elevation 16 |
| 184 | + '0 25px 50px -12px rgba(0, 0, 0, 0.25)', // elevation 17 |
| 185 | + '0 25px 50px -12px rgba(0, 0, 0, 0.25)', // elevation 18 |
| 186 | + '0 25px 50px -12px rgba(0, 0, 0, 0.25)', // elevation 19 |
| 187 | + '0 25px 50px -12px rgba(0, 0, 0, 0.25)', // elevation 20 |
| 188 | + '0 25px 50px -12px rgba(0, 0, 0, 0.25)', // elevation 21 |
| 189 | + '0 25px 50px -12px rgba(0, 0, 0, 0.25)', // elevation 22 |
| 190 | + '0 25px 50px -12px rgba(0, 0, 0, 0.25)', // elevation 23 |
| 191 | + '0 25px 50px -12px rgba(0, 0, 0, 0.25)', // elevation 24 |
72 | 192 | ], |
| 193 | + |
| 194 | + // Component-specific overrides |
73 | 195 | components: { |
| 196 | + MuiButton: { |
| 197 | + styleOverrides: { |
| 198 | + root: { |
| 199 | + borderRadius: 8, |
| 200 | + padding: '10px 24px', |
| 201 | + minHeight: 48, // Accessible touch target |
| 202 | + fontSize: '0.875rem', |
| 203 | + fontWeight: 600, |
| 204 | + textTransform: 'none', |
| 205 | + boxShadow: 'none', |
| 206 | + '&:hover': { |
| 207 | + boxShadow: |
| 208 | + '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)', |
| 209 | + }, |
| 210 | + }, |
| 211 | + contained: { |
| 212 | + boxShadow: |
| 213 | + '0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)', |
| 214 | + '&:hover': { |
| 215 | + boxShadow: |
| 216 | + '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)', |
| 217 | + }, |
| 218 | + }, |
| 219 | + sizeLarge: { |
| 220 | + padding: '12px 32px', |
| 221 | + fontSize: '1rem', |
| 222 | + minHeight: 56, |
| 223 | + }, |
| 224 | + sizeSmall: { |
| 225 | + padding: '6px 16px', |
| 226 | + fontSize: '0.8125rem', |
| 227 | + minHeight: 40, |
| 228 | + }, |
| 229 | + }, |
| 230 | + }, |
| 231 | + MuiIconButton: { |
| 232 | + styleOverrides: { |
| 233 | + root: { |
| 234 | + minWidth: 48, // Accessible touch target |
| 235 | + minHeight: 48, |
| 236 | + }, |
| 237 | + }, |
| 238 | + }, |
74 | 239 | MuiCard: { |
75 | 240 | styleOverrides: { |
76 | 241 | root: { |
77 | | - backdropFilter: 'blur(10px)', |
78 | | - backgroundColor: 'rgba(255, 255, 255, 0.05)', |
79 | | - border: '1px solid rgba(255, 255, 255, 0.1)', |
80 | | - backgroundImage: |
81 | | - 'linear-gradient(rgba(255, 255, 255, 0.05), rgba(255, 255, 255, 0.1))', |
| 242 | + borderRadius: 12, // Slightly more rounded for cards |
| 243 | + boxShadow: |
| 244 | + '0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)', |
82 | 245 | }, |
83 | 246 | }, |
84 | 247 | }, |
85 | 248 | MuiPaper: { |
| 249 | + styleOverrides: { |
| 250 | + rounded: { |
| 251 | + borderRadius: 12, |
| 252 | + }, |
| 253 | + elevation1: { |
| 254 | + boxShadow: '0 1px 2px 0 rgba(0, 0, 0, 0.05)', |
| 255 | + }, |
| 256 | + elevation2: { |
| 257 | + boxShadow: |
| 258 | + '0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)', |
| 259 | + }, |
| 260 | + elevation3: { |
| 261 | + boxShadow: |
| 262 | + '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)', |
| 263 | + }, |
| 264 | + elevation4: { |
| 265 | + boxShadow: |
| 266 | + '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)', |
| 267 | + }, |
| 268 | + }, |
| 269 | + }, |
| 270 | + MuiOutlinedInput: { |
| 271 | + styleOverrides: { |
| 272 | + root: { |
| 273 | + borderRadius: 8, |
| 274 | + }, |
| 275 | + }, |
| 276 | + }, |
| 277 | + MuiTextField: { |
| 278 | + defaultProps: { |
| 279 | + variant: 'outlined', |
| 280 | + margin: 'normal', |
| 281 | + }, |
| 282 | + }, |
| 283 | + MuiChip: { |
| 284 | + styleOverrides: { |
| 285 | + root: { |
| 286 | + borderRadius: 16, |
| 287 | + fontWeight: 600, |
| 288 | + }, |
| 289 | + }, |
| 290 | + }, |
| 291 | + MuiAppBar: { |
86 | 292 | styleOverrides: { |
87 | 293 | root: { |
88 | | - backdropFilter: 'blur(10px)', |
89 | | - backgroundColor: 'rgba(255, 255, 255, 0.05)', |
90 | | - border: '1px solid rgba(255, 255, 255, 0.1)', |
91 | | - backgroundImage: |
92 | | - 'linear-gradient(rgba(255, 255, 255, 0.05), rgba(255, 255, 255, 0.1))', |
| 294 | + boxShadow: |
| 295 | + '0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)', |
93 | 296 | }, |
94 | 297 | }, |
95 | 298 | }, |
96 | 299 | }, |
| 300 | + |
| 301 | + // Breakpoints for responsive design |
| 302 | + breakpoints: { |
| 303 | + values: { |
| 304 | + xs: 0, |
| 305 | + sm: 600, |
| 306 | + md: 960, |
| 307 | + lg: 1280, |
| 308 | + xl: 1920, |
| 309 | + }, |
| 310 | + }, |
| 311 | + |
| 312 | + // Transitions - Consistent animation timing |
| 313 | + transitions: { |
| 314 | + duration: { |
| 315 | + shortest: 150, |
| 316 | + shorter: 200, |
| 317 | + short: 250, |
| 318 | + standard: 300, |
| 319 | + complex: 375, |
| 320 | + enteringScreen: 225, |
| 321 | + leavingScreen: 195, |
| 322 | + }, |
| 323 | + easing: { |
| 324 | + easeInOut: 'cubic-bezier(0.4, 0, 0.2, 1)', |
| 325 | + easeOut: 'cubic-bezier(0.0, 0, 0.2, 1)', |
| 326 | + easeIn: 'cubic-bezier(0.4, 0, 1, 1)', |
| 327 | + sharp: 'cubic-bezier(0.4, 0, 0.6, 1)', |
| 328 | + }, |
| 329 | + }, |
97 | 330 | }) |
98 | 331 |
|
99 | 332 | export default theme |
0 commit comments