diff --git a/UI_IMPROVEMENTS.md b/UI_IMPROVEMENTS.md new file mode 100644 index 0000000..4d17ba9 --- /dev/null +++ b/UI_IMPROVEMENTS.md @@ -0,0 +1,124 @@ +# BSC Score App - UI Improvements for Tablet Optimization + +## Overview +This document outlines the comprehensive UI improvements made to enhance the aesthetic appeal and tablet usage experience of the BSC Score application. + +## Key Improvements Implemented + +### 1. Design System Implementation +- **CSS Custom Properties**: Established a comprehensive design token system with consistent colors, spacing, typography, and transitions +- **Responsive Typography**: Tablet-specific font scaling for optimal readability +- **Touch Target Optimization**: Minimum 44px touch targets on mobile, 48-56px on tablets +- **Consistent Spacing**: 8px-based spacing system with semantic naming (--space-xs through --space-xxl) + +### 2. Enhanced Color System +- **Primary Color**: Orange (#ff9800) with hover states +- **Semantic Colors**: Success, danger, warning with consistent usage +- **Surface Colors**: Improved contrast and visual hierarchy +- **Text Colors**: Primary, secondary, and muted text colors for better readability + +### 3. Tablet-Specific Optimizations + +#### Layout Improvements +- **Max-width adjustments**: 900px for tablets vs 1200px for desktop +- **Adaptive padding**: Increased spacing on larger screens +- **Grid layouts**: Improved symmetry in filter buttons and game type selection + +#### Touch Experience +- **Larger touch targets**: 56px minimum on tablets +- **Hover effects**: Subtle animations and visual feedback +- **Improved button spacing**: Better gaps between interactive elements + +### 4. Component-Specific Enhancements + +#### Game List +- **Grid-based layout**: Improved symmetry with CSS Grid +- **Enhanced cards**: Better shadows, borders, and hover effects +- **Symmetric filter buttons**: Equal width distribution +- **Improved visual hierarchy**: Game type badges, centered player names, highlighted scores +- **Better delete buttons**: Larger touch targets with improved styling + +#### New Game Wizard +- **Progress indicator**: Visual step indicator with active state animations +- **Consistent spacing**: Uniform gaps throughout the form +- **Enhanced input fields**: Better focus states and clear buttons +- **Improved navigation**: Larger arrow buttons with better visual feedback +- **Game type/Race-to selection**: Grid-based layout for better alignment + +#### Button System +- **Unified styling**: Consistent button variants (primary, secondary, danger) +- **Micro-interactions**: Hover animations and press states +- **Size variants**: Small, medium, large with tablet adjustments +- **Focus indicators**: Improved accessibility with visible focus rings + +### 5. Responsive Design Enhancements + +#### Breakpoints +- **Mobile**: < 768px +- **Tablet**: 768px - 1024px +- **Desktop**: > 1024px + +#### Tablet-Specific Features +- **Horizontal navigation**: Better layout for tablet landscape mode +- **Increased font sizes**: Improved readability on tablet screens +- **Enhanced spacing**: More generous padding and margins +- **Grid adjustments**: Optimized column layouts for tablet screens + +### 6. Aesthetic Improvements + +#### Visual Polish +- **Gradient backgrounds**: Subtle gradients on player input sections +- **Enhanced shadows**: Layered shadow system for depth +- **Smooth transitions**: 0.15s to 0.3s transition durations +- **Border radius consistency**: Unified corner rounding +- **Backdrop blur**: Modal overlays with blur effects + +#### Typography +- **Font stack**: Inter font with system fallbacks +- **Improved line height**: 1.5 for better readability +- **Font smoothing**: Antialiased text rendering +- **Weight hierarchy**: Consistent font weight usage + +#### Interactive Elements +- **Shimmer effects**: Subtle shine animation on buttons +- **Transform effects**: Slight lift on hover states +- **Color transitions**: Smooth color changes on state updates +- **Scale animations**: Micro-interactions for button presses + +### 7. Accessibility Improvements +- **Focus management**: Visible focus indicators +- **Touch target sizes**: WCAG compliant minimum sizes +- **Color contrast**: Improved contrast ratios +- **Keyboard navigation**: Enhanced tab order and interactions + +## Testing Recommendations + +### Tablet Testing +1. **iPad (10.9")**: Test in both portrait and landscape orientations +2. **Android tablets**: Various screen sizes and densities +3. **Touch interactions**: Verify all buttons and inputs are easily tappable +4. **Scrolling performance**: Ensure smooth scrolling with -webkit-overflow-scrolling + +### Cross-Device Testing +1. **Mobile phones**: Verify mobile breakpoint adjustments +2. **Desktop browsers**: Ensure desktop experience isn't degraded +3. **Different orientations**: Test rotation on tablets + +## Performance Considerations +- **CSS Variables**: Minimal performance impact with better maintainability +- **Transform animations**: Hardware-accelerated for smooth performance +- **Optimized selectors**: Efficient CSS targeting without over-qualification + +## Future Enhancements +1. **Dark/Light theme toggle**: Leveraging CSS custom properties +2. **Advanced animations**: Page transitions and micro-interactions +3. **Gesture support**: Swipe gestures for tablet navigation +4. **Enhanced accessibility**: Screen reader optimizations + +## Browser Support +- **Modern browsers**: Chrome 88+, Firefox 85+, Safari 14+ +- **CSS Grid**: Full support across target browsers +- **CSS Custom Properties**: Native support, no fallbacks needed + +## Conclusion +These improvements create a more polished, professional, and tablet-optimized experience while maintaining consistency across all device sizes. The design system approach ensures easy maintenance and future scalability. \ No newline at end of file diff --git a/src/components/GameList.module.css b/src/components/GameList.module.css index d22a4a1..c76a41f 100644 --- a/src/components/GameList.module.css +++ b/src/components/GameList.module.css @@ -1,135 +1,277 @@ -/* GameList-specific styles only. Shared utility classes are now in global CSS. */ +/* GameList-specific styles using design system tokens */ .screen.active { display: block; opacity: 1; transform: translateX(0); position: relative; } + .screen-content { display: flex; flex-direction: column; min-height: 100vh; - padding: 20px; + padding: var(--space-lg); overflow-y: auto; -webkit-overflow-scrolling: touch; } + .screen-title { - font-size: 24px; - margin-bottom: 20px; + font-size: var(--font-size-xxl); + margin-bottom: var(--space-lg); + font-weight: 700; } + .game-list { width: 100%; flex: 1; overflow-y: auto; } + +/* Filter buttons with improved symmetry */ .filter-buttons { - display: flex; - gap: 8px; - margin: 24px 0 16px 0; + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: var(--space-sm); + margin: var(--space-lg) 0 var(--space-md) 0; + border-radius: var(--radius-md); + overflow: hidden; + box-shadow: var(--shadow-sm); } + .filter-button { - flex: 1; - background: #333; - color: #fff; + background: var(--color-secondary); + color: var(--color-text); border: none; - border-radius: 0; - font-size: 1.2rem; - padding: 18px 0; + font-size: var(--font-size-base); + padding: var(--space-md) 0; cursor: pointer; font-weight: 500; - transition: background 0.2s, color 0.2s; + transition: all var(--transition-base); + min-height: var(--touch-target-comfortable); + display: flex; + align-items: center; + justify-content: center; } + +.filter-button:hover { + background: var(--color-secondary-hover); + transform: translateY(-1px); +} + .filter-button.active { - background: #4CAF50; - color: #fff; + background: var(--color-primary); + color: white; + box-shadow: var(--shadow-md); } + +/* Games container with improved spacing */ .games-container { - width: 100%; - display: flex; - flex-direction: column; - gap: 16px; - margin-top: 24px; + width: 100%; + display: flex; + flex-direction: column; + gap: var(--space-md); + margin-top: var(--space-lg); } + +/* Game item with better symmetry and spacing */ .game-item { - display: flex; - align-items: center; - justify-content: space-between; - padding: 1.5rem; - border-radius: 0.5rem; - box-shadow: 0 2px 4px rgba(0,0,0,0.1); - transition: transform 0.1s ease, background-color 0.2s ease; - cursor: pointer; + display: grid; + grid-template-columns: auto 1fr auto; + align-items: center; + gap: var(--space-md); + padding: var(--space-lg); + border-radius: var(--radius-lg); + box-shadow: var(--shadow-sm); + transition: all var(--transition-base); + cursor: pointer; + background: var(--color-surface); + border: 1px solid var(--color-border); } + +.game-item:hover { + transform: translateY(-2px); + box-shadow: var(--shadow-md); + border-color: var(--color-primary); +} + .game-item.active { - background: #1e4620; + background: var(--color-success); + border-color: var(--color-success); } + .game-item.completed { - background: #333; - opacity: 0.85; + background: var(--color-surface); + opacity: 0.8; + border-color: var(--color-border); } + +/* Game info with improved layout */ .game-info { - flex: 1; - display: flex; - align-items: center; - gap: 2rem; + display: grid; + grid-template-columns: auto 1fr auto; + align-items: center; + gap: var(--space-lg); + width: 100%; + cursor: pointer; } + .game-type { - font-weight: bold; - font-size: 1.5rem; - min-width: 8rem; - color: #fff; + font-weight: 700; + font-size: var(--font-size-lg); + color: var(--color-text); + white-space: nowrap; + min-width: 120px; + text-align: center; + background: var(--color-secondary); + padding: var(--space-sm) var(--space-md); + border-radius: var(--radius-sm); } + .player-names { - color: #fff; - font-size: 1.5rem; - min-width: 16rem; + color: var(--color-text); + font-size: var(--font-size-lg); + font-weight: 500; + text-align: center; + flex: 1; } + .game-scores { - font-size: 2rem; - font-weight: bold; - min-width: 6rem; - text-align: center; - color: #fff; + font-size: var(--font-size-xl); + font-weight: 700; + text-align: center; + color: var(--color-primary); + min-width: 120px; + background: var(--color-background); + padding: var(--space-sm) var(--space-md); + border-radius: var(--radius-sm); } + +/* Delete button with improved touch target */ .delete-button { - width: 3rem; - height: 3rem; - border: none; - background: #ff4444; - color: white; - border-radius: 50%; - font-size: 1.5rem; - display: flex; - align-items: center; - justify-content: center; - margin-left: 1rem; - transition: background-color 0.2s; - position: relative; + width: var(--touch-target-comfortable); + height: var(--touch-target-comfortable); + border: none; + background: var(--color-danger); + color: white; + border-radius: 50%; + font-size: var(--font-size-lg); + display: flex; + align-items: center; + justify-content: center; + transition: all var(--transition-base); + cursor: pointer; + box-shadow: var(--shadow-sm); } + .delete-button::before { - content: '\1F5D1'; /* 🗑️ */ - font-size: 1.5rem; + content: '🗑️'; + font-size: var(--font-size-lg); } + .delete-button:hover { - background: #cc0000; + background: #cc0000; + transform: scale(1.05); + box-shadow: var(--shadow-md); } + .delete-button:active { - transform: scale(0.95); + transform: scale(0.95); } + +/* Empty state styling */ .empty-state { - text-align: center; - padding: 2rem; - color: #666; - font-size: 1.5rem; + text-align: center; + padding: var(--space-xxl); + color: var(--color-text-muted); + font-size: var(--font-size-lg); + background: var(--color-surface); + border-radius: var(--radius-lg); + border: 2px dashed var(--color-border); } + +/* Page header */ .page-header { - font-size: 2rem; - font-weight: 700; - color: #fff; - background: #181818; - padding: 24px 0 16px 0; - margin-bottom: 8px; - text-align: left; - width: 100%; - letter-spacing: 0.5px; + font-size: var(--font-size-xxxl); + font-weight: 700; + color: var(--color-text); + background: var(--color-surface); + padding: var(--space-lg) 0 var(--space-md) 0; + margin-bottom: var(--space-sm); + text-align: left; + width: 100%; + letter-spacing: 0.5px; + border-radius: var(--radius-lg); +} + +/* Tablet-specific improvements */ +@media (min-width: 768px) and (max-width: 1024px) { + .screen-content { + padding: var(--space-xl); + } + + .filter-buttons { + gap: var(--space-md); + margin: var(--space-xl) 0 var(--space-lg) 0; + } + + .filter-button { + font-size: var(--font-size-lg); + padding: var(--space-lg) 0; + min-height: var(--touch-target-comfortable); + } + + .game-item { + padding: var(--space-xl); + gap: var(--space-lg); + } + + .game-info { + gap: var(--space-xl); + } + + .game-type { + font-size: var(--font-size-xl); + min-width: 150px; + padding: var(--space-md) var(--space-lg); + } + + .player-names { + font-size: var(--font-size-xl); + } + + .game-scores { + font-size: var(--font-size-xxl); + min-width: 150px; + padding: var(--space-md) var(--space-lg); + } + + .delete-button { + width: 64px; + height: 64px; + font-size: var(--font-size-xl); + } + + .empty-state { + font-size: var(--font-size-xl); + padding: var(--space-xxl) var(--space-xl); + } +} + +/* Mobile adjustments */ +@media (max-width: 767px) { + .screen-content { + padding: var(--space-md); + } + + .game-info { + grid-template-columns: 1fr; + gap: var(--space-md); + text-align: center; + } + + .game-type, + .game-scores { + min-width: auto; + width: 100%; + } } \ No newline at end of file diff --git a/src/components/NewGame.module.css b/src/components/NewGame.module.css index e1b5ddb..f21a40e 100644 --- a/src/components/NewGame.module.css +++ b/src/components/NewGame.module.css @@ -8,291 +8,324 @@ display: none; opacity: 0; transform: translateX(100%); - transition: transform 0.3s ease, opacity 0.3s ease; + transition: transform var(--transition-slow), opacity var(--transition-slow); } .screen-content { display: flex; flex-direction: column; min-height: 100vh; - padding: 20px; + padding: var(--space-lg); overflow-y: auto; -webkit-overflow-scrolling: touch; } .screen-title { - font-size: 2rem; + font-size: var(--font-size-xxl); font-weight: 700; - color: #fff; - margin-bottom: 32px; + color: var(--color-text); + margin-bottom: var(--space-xl); letter-spacing: 0.5px; + text-align: center; } .player-inputs { display: flex; flex-direction: column; - gap: 24px; + gap: var(--space-lg); width: 100%; - margin-bottom: 32px; + margin-bottom: var(--space-xl); } .player-input { - background: #222; - border-radius: 8px; - padding: 20px 16px 16px 16px; - margin-bottom: 0; - box-shadow: 0 1px 4px rgba(0,0,0,0.12); + background: var(--color-background); + border-radius: var(--radius-md); + padding: var(--space-lg); + border: 2px solid var(--color-border); + transition: border-color var(--transition-base); + position: relative; +} +.player-input:focus-within { + border-color: var(--color-primary); + box-shadow: 0 0 0 3px var(--color-primary-light); } .player-input label { display: block; - margin-bottom: 12px; - color: #ccc; - font-size: 1.2rem; + margin-bottom: var(--space-md); + color: var(--color-text); + font-size: var(--font-size-lg); font-weight: 600; } .name-input-container { display: flex; - gap: 12px; + gap: var(--space-md); + position: relative; } .name-input { - flex: 2; - padding: 14px 12px; - border: 2px solid #333; - background: #2a2a2a; - color: white; - font-size: 1.1rem; - min-height: 44px; - border-radius: 0 6px 6px 0; + flex: 1; + padding: var(--space-md); + border: 2px solid var(--color-border); + background: var(--color-surface); + color: var(--color-text); + font-size: var(--font-size-base); + min-height: var(--touch-target-comfortable); + border-radius: var(--radius-md); + transition: all var(--transition-base); +} +.name-input:focus { + outline: none; + border-color: var(--color-primary); + box-shadow: 0 0 0 3px var(--color-primary-light); } .game-settings { margin-top: 0; width: 100%; - margin-bottom: 32px; + margin-bottom: var(--space-xl); } .setting-group { - margin-bottom: 20px; + margin-bottom: var(--space-lg); } .setting-group label { display: block; - margin-bottom: 10px; - color: #ccc; - font-size: 1.1rem; + margin-bottom: var(--space-md); + color: var(--color-text); + font-size: var(--font-size-lg); font-weight: 600; } .setting-group select, .setting-group input { width: 100%; - padding: 14px 12px; - border: 2px solid #333; - background: #2a2a2a; - color: white; - font-size: 1.1rem; - min-height: 44px; - border-radius: 6px; + padding: var(--space-md); + border: 2px solid var(--color-border); + background: var(--color-surface); + color: var(--color-text); + font-size: var(--font-size-base); + min-height: var(--touch-target-comfortable); + border-radius: var(--radius-md); + transition: border-color var(--transition-base); } .setting-group input:focus, .setting-group select:focus { outline: none; - border-color: #666; + border-color: var(--color-primary); + box-shadow: 0 0 0 3px var(--color-primary-light); } .validation-error { - color: #f44336; - background: #2a2a2a; - border-radius: 6px; - padding: 12px; - margin-bottom: 16px; - font-size: 1.1rem; + color: var(--color-danger); + background: var(--color-surface); + border: 1px solid var(--color-danger); + border-radius: var(--radius-md); + padding: var(--space-md); + margin-bottom: var(--space-md); + font-size: var(--font-size-base); text-align: center; + font-weight: 500; } .new-game-form { width: 100%; - max-width: 700px; - margin: 32px auto 0 auto; - background: #181818; - border-radius: 12px; - box-shadow: 0 2px 16px rgba(0,0,0,0.4); - padding: 32px 24px 24px 24px; + max-width: 600px; + margin: var(--space-xl) auto 0 auto; + background: var(--color-surface); + border-radius: var(--radius-xl); + box-shadow: var(--shadow-lg); + padding: var(--space-xl) var(--space-lg) var(--space-lg) var(--space-lg); display: flex; flex-direction: column; - gap: 0; + gap: var(--space-lg); + border: 1px solid var(--color-border); } .progress-indicator { display: flex; justify-content: center; align-items: center; - gap: 10px; - margin-bottom: 16px; + gap: var(--space-md); + margin-bottom: var(--space-lg); } .progress-dot { - width: 14px; - height: 14px; + width: 16px; + height: 16px; border-radius: 50%; - background: #444; + background: var(--color-border); opacity: 0.4; - transition: background 0.2s, opacity 0.2s; + transition: all var(--transition-base); + position: relative; } .progress-dot.active { - background: #fff; + background: var(--color-primary); opacity: 1; + transform: scale(1.2); + box-shadow: 0 0 0 4px var(--color-primary-light); } .quick-pick-btn { min-width: 80px; - min-height: 44px; - font-size: 1.1rem; - border-radius: 8px; - background: #333; - color: #fff; - border: none; + min-height: var(--touch-target-comfortable); + font-size: var(--font-size-base); + border-radius: var(--radius-md); + background: var(--color-secondary); + color: var(--color-text); + border: 1px solid var(--color-border); cursor: pointer; - margin-bottom: 8px; - transition: background 0.2s; + padding: var(--space-sm) var(--space-md); + transition: all var(--transition-base); + font-weight: 500; } -.quick-pick-btn:active, .quick-pick-btn:focus { - background: #555; +.quick-pick-btn:hover, .quick-pick-btn:focus { + background: var(--color-secondary-hover); + border-color: var(--color-primary); + transform: translateY(-1px); outline: none; } .arrow-nav { display: flex; justify-content: space-between; align-items: center; - margin-top: 48px; + margin-top: var(--space-xxl); width: 100%; + gap: var(--space-lg); } .arrow-btn { font-size: 48px; width: 80px; height: 80px; border-radius: 50%; - background: #222; - color: #fff; - border: none; - box-shadow: 0 2px 8px rgba(0,0,0,0.15); + background: var(--color-secondary); + color: var(--color-text); + border: 2px solid var(--color-border); + box-shadow: var(--shadow-md); cursor: pointer; display: flex; align-items: center; justify-content: center; - transition: background 0.2s, color 0.2s; + transition: all var(--transition-base); + font-weight: bold; } -.arrow-btn:active, .arrow-btn:focus { - background: #444; - color: #fff; +.arrow-btn:hover, .arrow-btn:focus { + background: var(--color-secondary-hover); + border-color: var(--color-primary); + transform: translateY(-2px); + box-shadow: var(--shadow-lg); outline: none; } +.arrow-btn:active { + transform: translateY(0); +} .clear-input-btn { position: absolute; - right: 8px; + right: var(--space-sm); top: 50%; transform: translateY(-50%); background: none; border: none; cursor: pointer; - font-size: 24px; - color: #aaa; - padding: 0; + font-size: var(--font-size-xl); + color: var(--color-text-muted); + padding: var(--space-xs); z-index: 2; + transition: color var(--transition-base); + border-radius: var(--radius-sm); + min-height: var(--touch-target-min); + min-width: var(--touch-target-min); + display: flex; + align-items: center; + justify-content: center; } -.clear-input-btn:active, .clear-input-btn:focus { - color: #fff; +.clear-input-btn:hover, .clear-input-btn:focus { + color: var(--color-text); + background: var(--color-secondary); outline: none; } .game-type-selection { display: grid; grid-template-columns: 1fr 1fr; - gap: 16px; + gap: var(--space-md); width: 100%; - margin: 16px 0; + margin: var(--space-md) 0; } .game-type-btn { - background: #2a2a2a; - border: 2px solid #333; - color: #fff; - font-size: 1.4rem; + background: var(--color-background); + border: 2px solid var(--color-border); + color: var(--color-text); + font-size: var(--font-size-lg); font-weight: 600; - padding: 24px; - border-radius: 8px; + padding: var(--space-xl); + border-radius: var(--radius-md); cursor: pointer; text-align: center; - transition: background 0.2s, border-color 0.2s; + transition: all var(--transition-base); + min-height: var(--touch-target-comfortable); } .game-type-btn:hover { - background: #333; - border-color: #555; + background: var(--color-surface); + border-color: var(--color-primary); + transform: translateY(-1px); } .game-type-btn.selected { - background: #4a4a4a; - border-color: #777; + background: var(--color-primary); + border-color: var(--color-primary); + color: white; + box-shadow: var(--shadow-md); } - .race-to-selection { display: grid; - grid-template-columns: repeat(auto-fit, minmax(60px, 1fr)); - gap: 12px; + grid-template-columns: repeat(auto-fit, minmax(80px, 1fr)); + gap: var(--space-md); width: 100%; - margin: 16px 0; + margin: var(--space-md) 0; } - .race-to-btn { - background: #2a2a2a; - border: 2px solid #333; - color: #fff; - font-size: 1.3rem; + background: var(--color-background); + border: 2px solid var(--color-border); + color: var(--color-text); + font-size: var(--font-size-lg); font-weight: 600; - padding: 16px 8px; - border-radius: 8px; + padding: var(--space-lg) var(--space-sm); + border-radius: var(--radius-md); cursor: pointer; text-align: center; - transition: background 0.2s, border-color 0.2s; - min-height: 70px; + transition: all var(--transition-base); + min-height: 80px; + display: flex; + align-items: center; + justify-content: center; } - .race-to-btn:hover { - background: #333; - border-color: #555; + background: var(--color-surface); + border-color: var(--color-primary); + transform: translateY(-1px); } - .race-to-btn.selected { - background: #4a4a4a; - border-color: #777; + background: var(--color-primary); + border-color: var(--color-primary); + color: white; + box-shadow: var(--shadow-md); } - .custom-race-to { display: flex; - gap: 12px; - margin-top: 24px; + gap: var(--space-md); + margin-top: var(--space-lg); align-items: center; } - .custom-race-to input { flex-grow: 1; } - .custom-race-to .arrow-btn { width: 60px; height: 60px; font-size: 32px; flex-shrink: 0; } - .endlos-container { width: 100%; margin-bottom: 12px; } - .endlos-btn { width: 100%; } - .player1-input.player-input { - background: #43a047; - color: #fff; - border: 2px solid #388e3c; - box-shadow: 0 2px 12px rgba(67,160,71,0.12); + border-color: var(--color-success); + background: linear-gradient(135deg, var(--color-success) 0%, rgba(76, 175, 80, 0.1) 100%); } .player2-input.player-input { - background: #1565c0; - color: #fff; - border: 2px solid #0d47a1; - box-shadow: 0 2px 12px rgba(21,101,192,0.12); + border-color: #1565c0; + background: linear-gradient(135deg, #1565c0 0%, rgba(21, 101, 192, 0.1) 100%); } .player3-input.player-input { - background: #333; - color: #fff; - border: 2px solid #222; - box-shadow: 0 2px 12px rgba(51,51,51,0.12); + border-color: var(--color-secondary); + background: linear-gradient(135deg, var(--color-secondary) 0%, rgba(51, 51, 51, 0.1) 100%); } .player1-input.player-input input, .player2-input.player-input input, @@ -300,4 +333,55 @@ background: #fff; color: #222; border: 1px solid #ccc; +} +@media (min-width: 768px) and (max-width: 1024px) { + .screen-content { + padding: var(--space-xl); + } + .new-game-form { + max-width: 700px; + padding: var(--space-xxl) var(--space-xl) var(--space-xl) var(--space-xl); + } + .screen-title { + font-size: var(--font-size-xxxl); + } + .arrow-btn { + width: 100px; + height: 100px; + font-size: 56px; + } + .game-type-btn, + .race-to-btn { + padding: var(--space-xl); + font-size: var(--font-size-xl); + min-height: var(--touch-target-comfortable); + } + .quick-pick-btn { + min-height: var(--touch-target-comfortable); + font-size: var(--font-size-lg); + padding: var(--space-md) var(--space-lg); + } +} +@media (max-width: 767px) { + .screen-content { + padding: var(--space-md); + } + .new-game-form { + margin: var(--space-lg) auto 0 auto; + padding: var(--space-lg); + } + .game-type-selection { + grid-template-columns: 1fr; + } + .race-to-selection { + grid-template-columns: repeat(3, 1fr); + } + .arrow-nav { + gap: var(--space-md); + } + .arrow-btn { + width: 70px; + height: 70px; + font-size: 40px; + } } \ No newline at end of file diff --git a/src/components/ui/Button.module.css b/src/components/ui/Button.module.css index cb6ae93..0abd045 100644 --- a/src/components/ui/Button.module.css +++ b/src/components/ui/Button.module.css @@ -1,29 +1,36 @@ -/* Design tokens */ -:root { - --color-primary: #ff9800; - --color-primary-hover: #ffa726; - --color-secondary: #333; - --color-secondary-hover: #444; - --color-danger: #f44336; - --color-danger-hover: #ef5350; - --color-white: #fff; - --border-radius: 6px; - --transition: all 0.2s ease; -} - +/* Use CSS custom properties from global design system */ .button { border: none; - border-radius: var(--border-radius); + border-radius: var(--radius-md); cursor: pointer; font-weight: 600; - transition: var(--transition); + transition: var(--transition-base); touch-action: manipulation; display: inline-flex; align-items: center; justify-content: center; - gap: 8px; + gap: var(--space-sm); text-decoration: none; user-select: none; + font-family: inherit; + position: relative; + overflow: hidden; +} + +.button::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: linear-gradient(45deg, transparent 30%, rgba(255, 255, 255, 0.1) 50%, transparent 70%); + transform: translateX(-100%); + transition: transform 0.3s ease; +} + +.button:hover::before { + transform: translateX(100%); } .button:focus-visible { @@ -31,52 +38,97 @@ outline-offset: 2px; } +.button:active { + transform: translateY(1px); +} + /* Variants */ .primary { background: var(--color-primary); - color: var(--color-white); + color: white; + box-shadow: var(--shadow-md); } .primary:hover:not(.disabled) { background: var(--color-primary-hover); + box-shadow: var(--shadow-lg); + transform: translateY(-1px); } .secondary { background: var(--color-secondary); - color: var(--color-white); + color: var(--color-text); + box-shadow: var(--shadow-sm); } .secondary:hover:not(.disabled) { background: var(--color-secondary-hover); + box-shadow: var(--shadow-md); + transform: translateY(-1px); } .danger { background: var(--color-danger); - color: var(--color-white); + color: white; + box-shadow: var(--shadow-md); } .danger:hover:not(.disabled) { - background: var(--color-danger-hover); + background: #ef5350; + box-shadow: var(--shadow-lg); + transform: translateY(-1px); } -/* Sizes */ +/* Sizes with improved touch targets for tablets */ .small { - padding: 8px 16px; - font-size: 0.875rem; + padding: var(--space-sm) var(--space-md); + font-size: var(--font-size-sm); + min-height: var(--touch-target-min); + border-radius: var(--radius-sm); } .medium { - padding: 12px 24px; - font-size: 1rem; + padding: var(--space-md) var(--space-lg); + font-size: var(--font-size-base); + min-height: var(--touch-target-comfortable); + border-radius: var(--radius-md); } .large { - padding: 18px 32px; - font-size: 1.25rem; + padding: var(--space-lg) var(--space-xl); + font-size: var(--font-size-lg); + min-height: 56px; + border-radius: var(--radius-lg); +} + +/* Tablet-specific size adjustments */ +@media (min-width: 768px) and (max-width: 1024px) { + .small { + min-height: var(--touch-target-comfortable); + padding: var(--space-md) var(--space-lg); + font-size: var(--font-size-base); + } + + .medium { + min-height: var(--touch-target-comfortable); + padding: var(--space-lg) var(--space-xl); + font-size: var(--font-size-lg); + } + + .large { + min-height: 64px; + padding: var(--space-xl) var(--space-xxl); + font-size: var(--font-size-xl); + } } /* States */ .disabled { opacity: 0.5; cursor: not-allowed; + transform: none !important; +} + +.disabled:hover::before { + transform: translateX(-100%); } \ No newline at end of file diff --git a/src/components/ui/Layout.module.css b/src/components/ui/Layout.module.css index a581650..c9c2f7d 100644 --- a/src/components/ui/Layout.module.css +++ b/src/components/ui/Layout.module.css @@ -1,13 +1,17 @@ .layout { min-height: 100vh; - background-color: #1a1a1a; - color: white; + background-color: var(--color-background); + color: var(--color-text); + display: flex; + flex-direction: column; } .content { - max-width: 800px; + flex: 1; + max-width: 1200px; margin: 0 auto; - padding: 16px; + padding: var(--space-md); + width: 100%; } .screen { @@ -17,8 +21,24 @@ flex-direction: column; } -@media (max-width: 768px) { +/* Tablet optimizations */ +@media (min-width: 768px) and (max-width: 1024px) { .content { - padding: 12px; + padding: var(--space-lg) var(--space-xl); + max-width: 900px; + } +} + +/* Large tablet and small desktop */ +@media (min-width: 1025px) { + .content { + padding: var(--space-xl); + } +} + +/* Mobile adjustments */ +@media (max-width: 767px) { + .content { + padding: var(--space-sm) var(--space-md); } } \ No newline at end of file diff --git a/src/styles/index.css b/src/styles/index.css index 8159edb..43470c6 100644 --- a/src/styles/index.css +++ b/src/styles/index.css @@ -11,91 +11,216 @@ user-select: none; -webkit-tap-highlight-color: transparent; } -body { - font-family: Arial, sans-serif; - background-color: #1a1a1a; - color: white; - min-height: 100vh; - overscroll-behavior: none; -} -input, select { - min-height: 44px; - padding: 12px; - font-size: 1.2rem; + +/* Design system tokens */ +:root { + /* Colors */ + --color-primary: #ff9800; + --color-primary-hover: #ffa726; + --color-primary-light: rgba(255, 152, 0, 0.1); + --color-secondary: #333; + --color-secondary-hover: #444; + --color-background: #1a1a1a; + --color-surface: #222; + --color-surface-hover: #2a2a2a; + --color-text: #fff; + --color-text-secondary: #ccc; + --color-text-muted: #999; + --color-border: #333; + --color-success: #4caf50; + --color-danger: #f44336; + --color-warning: #ff9800; + + /* Spacing system - 8px base */ + --space-xs: 0.25rem; /* 4px */ + --space-sm: 0.5rem; /* 8px */ + --space-md: 1rem; /* 16px */ + --space-lg: 1.5rem; /* 24px */ + --space-xl: 2rem; /* 32px */ + --space-xxl: 3rem; /* 48px */ + + /* Typography */ + --font-size-xs: 0.75rem; /* 12px */ + --font-size-sm: 0.875rem; /* 14px */ + --font-size-base: 1rem; /* 16px */ + --font-size-lg: 1.125rem; /* 18px */ + --font-size-xl: 1.25rem; /* 20px */ + --font-size-xxl: 1.5rem; /* 24px */ + --font-size-xxxl: 2rem; /* 32px */ + + /* Touch targets */ + --touch-target-min: 44px; + --touch-target-comfortable: 48px; + + /* Border radius */ + --radius-sm: 4px; + --radius-md: 8px; + --radius-lg: 12px; + --radius-xl: 16px; + + /* Shadows */ + --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.12); + --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.16); + --shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.24); + + /* Transitions */ + --transition-fast: 0.15s ease; + --transition-base: 0.2s ease; + --transition-slow: 0.3s ease; } -/* Responsive adjustments for fullscreen toggle button */ -@media screen and (max-width: 480px) { - .fullscreenToggle { - bottom: 15px; - right: 15px; - width: 40px; - height: 40px; +/* Tablet-specific design tokens */ +@media (min-width: 768px) and (max-width: 1024px) { + :root { + --touch-target-min: 48px; + --touch-target-comfortable: 56px; + --space-md: 1.25rem; /* 20px */ + --space-lg: 2rem; /* 32px */ + --space-xl: 2.5rem; /* 40px */ + --font-size-base: 1.125rem; /* 18px */ + --font-size-lg: 1.25rem; /* 20px */ + --font-size-xl: 1.5rem; /* 24px */ + --font-size-xxl: 1.75rem; /* 28px */ + --font-size-xxxl: 2.25rem; /* 36px */ } } -/* Utility button for new game (global, not component-specific) */ +body { + font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; + background-color: var(--color-background); + color: var(--color-text); + min-height: 100vh; + overscroll-behavior: none; + line-height: 1.5; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +/* Improved input styling for better tablet experience */ +input, select { + min-height: var(--touch-target-comfortable); + padding: var(--space-md); + font-size: var(--font-size-base); + border: 2px solid var(--color-border); + border-radius: var(--radius-md); + background: var(--color-surface); + color: var(--color-text); + transition: border-color var(--transition-base); +} + +input:focus, select:focus { + outline: none; + border-color: var(--color-primary); + box-shadow: 0 0 0 3px var(--color-primary-light); +} + +/* Enhanced button styling */ +.btn { + min-height: var(--touch-target-comfortable); + padding: var(--space-md) var(--space-lg); + color: var(--color-text); + background: var(--color-secondary); + border: none; + border-radius: var(--radius-md); + font-size: var(--font-size-base); + font-weight: 600; + cursor: pointer; + touch-action: manipulation; + transition: all var(--transition-base); + display: inline-flex; + align-items: center; + justify-content: center; + gap: var(--space-sm); + text-decoration: none; + user-select: none; +} + +.btn:hover { + background: var(--color-secondary-hover); + transform: translateY(-1px); +} + +.btn:active { + transform: translateY(0); +} + +.btn-primary { + background: var(--color-primary); + color: white; +} + +.btn-primary:hover { + background: var(--color-primary-hover); +} + +/* Utility button for new game with better spacing */ .new-game-button { width: 100%; - background: #ff9800; - color: #fff; + background: var(--color-primary); + color: white; border: none; - border-radius: 12px; - font-size: 2rem; + border-radius: var(--radius-lg); + font-size: var(--font-size-xxl); font-weight: 700; - padding: 28px 0; - margin-bottom: 24px; + padding: var(--space-xl) var(--space-lg); + margin-bottom: var(--space-lg); cursor: pointer; - transition: background 0.2s, color 0.2s, box-shadow 0.2s; + transition: all var(--transition-base); text-align: center; display: flex; align-items: center; justify-content: center; - box-shadow: 0 4px 24px rgba(255, 152, 0, 0.25), 0 1.5px 6px rgba(0,0,0,0.12); + box-shadow: var(--shadow-lg); letter-spacing: 0.5px; - gap: 16px; + gap: var(--space-md); + min-height: var(--touch-target-comfortable); } .new-game-button::before { content: '+'; font-size: 2.2rem; font-weight: 900; - margin-right: 12px; display: inline-block; line-height: 1; } .new-game-button:hover { - background: #ffa726; - box-shadow: 0 6px 32px rgba(255, 152, 0, 0.35), 0 2px 8px rgba(0,0,0,0.16); + background: var(--color-primary-hover); + transform: translateY(-2px); + box-shadow: 0 8px 40px rgba(255, 152, 0, 0.4); } -/* Shared utility classes for buttons and layout */ -.btn { - flex: 1; - min-width: 100px; - padding: 18px; - color: white; - background: #333; - border: none; - border-radius: 6px; - font-size: 1.2rem; - font-weight: 600; - cursor: pointer; - touch-action: manipulation; - transition: background 0.2s, color 0.2s; -} -.btn:hover { - background: #444; +.new-game-button:active { + transform: translateY(-1px); } + +/* Navigation buttons with improved spacing */ .nav-buttons { display: flex; flex-direction: column; - gap: 12px; - margin: 16px 0 0 0; + gap: var(--space-md); + margin: var(--space-lg) 0 0 0; } -/* Modal overlay (global, not component-specific) */ +/* Tablet-specific improvements */ +@media (min-width: 768px) and (max-width: 1024px) { + .nav-buttons { + flex-direction: row; + gap: var(--space-lg); + } + + .btn { + flex: 1; + min-height: var(--touch-target-comfortable); + } + + .new-game-button { + padding: var(--space-xxl) var(--space-xl); + font-size: var(--font-size-xxxl); + } +} + +/* Enhanced modal styling */ .modal { position: fixed; top: 0; @@ -103,12 +228,33 @@ input, select { width: 100vw; height: 100vh; background-color: rgba(0, 0, 0, 0.8); + backdrop-filter: blur(4px); z-index: 9999; display: flex; justify-content: center; align-items: center; + padding: var(--space-lg); } .modal.show { display: flex; +} + +/* Responsive fullscreen toggle */ +@media screen and (max-width: 480px) { + .fullscreenToggle { + bottom: var(--space-md); + right: var(--space-md); + width: 40px; + height: 40px; + } +} + +@media (min-width: 768px) and (max-width: 1024px) { + .fullscreenToggle { + bottom: var(--space-lg); + right: var(--space-lg); + width: 56px; + height: 56px; + } } \ No newline at end of file