03-03: Workout Experience Polish - enhanced exercise cards, progress badges, rest timer, KLART button, warmup styling

This commit is contained in:
2026-02-28 23:47:36 +01:00
parent 718b210a14
commit 3d28d9985b
4 changed files with 205 additions and 27 deletions
@@ -0,0 +1,64 @@
# Plan 03-02: Dashboard Polish
**Goal:** Transform dashboard from "functional but plain" to polished, enterprise-grade experience
## Current Issues
1. **Header** - Basic brand title, no logo mark like auth pages
2. **Stat cards** - Plain boxes, no depth or premium feel
3. **Calendar** - Functional but lacks visual polish
4. **Coach section** - Avatar icon looks basic, message bubble plain
5. **Today's workout card** - Needs better visual weight and polish
6. **Spacing rhythm** - Inconsistent paddings/margins throughout
## Implementation
### Files to Modify
- frontend/src/pages/Dashboard.jsx
- frontend/src/App.css (dashboard section)
### Changes
**1. Header Branding**
- Replace "Gravl" text with Logo component (reuse from LoginPage)
- Add gradient text or subtle brand treatment
- Better nav button styling with active states
**2. Stat Cards Enhancement**
- Gradient backgrounds or subtle depth
- Better number typography (larger, bolder)
- Icons with color accents
- Improved spacing and hover states
**3. Calendar Polish**
- Today highlight with brand color
- Better day cell sizing and spacing
- Subtle shadows on workout days
- Smoother transitions
**4. Coach Section**
- Better avatar styling (circle with gradient bg)
- Message bubble with subtle background
- Improved typography hierarchy
**5. Today's Workout Card**
- Full-width card with improved styling
- Better exercise count/time display
- Arrow button with hover animation
- Subtle gradient or depth
**6. CSS Polish**
- Consistent section spacing (use --space-* variables)
- Improve typography scale
- Add subtle animations/transitions
- Better mobile touch targets
## Success Criteria
- [ ] Header uses same Logo component as auth pages
- [ ] Stat cards feel premium (depth/color/accent)
- [ ] Calendar has improved today indicator
- [ ] Coach section looks polished and friendly
- [ ] Workout card has clear visual hierarchy
- [ ] Consistent spacing throughout dashboard
@@ -0,0 +1,73 @@
# Plan 03-03: Workout Experience Polish
**Goal:** Transform the workout session from "functional" to a polished, motivating experience
## Current Issues
1. **Exercise cards** - Plain layout, no visual polish, basic text styling
2. **Set logging UX** - Stepper inputs work but lack visual refinement
3. **Progress indicators** - Progress badges are basic, no visual hierarchy
4. **Warmup section** - Collapsible but visually plain, checklist items lack polish
5. **Rest timer** - Functional but doesn't feel integrated or premium
6. **Alternative exercise modal** - Just implemented (02-02), needs polish pass
## Implementation
### Files to Modify
- frontend/src/pages/WorkoutPage.jsx
- frontend/src/components/AlternativeModal.jsx
- frontend/src/App.css (workout section)
### Changes
**1. Exercise Cards Enhancement**
- Add subtle card depth/shadow
- Better exercise name typography (larger, weight hierarchy)
- Muscle group badges with color coding
- Improved spacing between elements
- Subtle hover/focus states for interactive elements
**2. Set Logging UX Polish**
- Refined stepper input styling (consistent with dashboard buttons)
- Better "Log Set" button - more prominent when active
- Clearer visual distinction between logged/unlogged sets
- Improved checkmark animation on completion
**3. Progress Indicators**
- Premium progress badges (gradient or subtle depth)
- Better "All Done" state - celebration micro-interaction
- Visual progress bar or completion percentage
**4. Warmup Section Polish**
- Cleaner checklist styling (custom checkboxes)
- Better expansion animation
- Subtle completion progress indicator
**5. Rest Timer Enhancement**
- Better visual integration with set cards
- Circular progress indicator or countdown animation
- Brand color accent when timer active
- Gentle pulse animation when running
**6. Alternative Modal Polish**
- Consistent styling with other modals
- Better exercise card layouts in modal
- Hover states for alternative options
**7. CSS Polish**
- Consistent use of CSS variables (--space-*, --radius-*)
- Better typography scale for workout context
- Subtle animations (card entry, completion)
- Mobile-optimized spacing
## Success Criteria
- [ ] Exercise cards have visual depth and hierarchy
- [ ] Set logging feels smooth and responsive
- [ ] Progress badges look premium
- [ ] Warmup section feels motivating, not tedious
- [ ] Rest timer is visually integrated
- [ ] Alternative modal matches app polish level
- [ ] All animations feel smooth (not janky)
- [ ] Mobile experience is thumb-friendly
+6 -11
View File
@@ -1,13 +1,8 @@
{
"lastRun": "2026-02-28T22:49:00+01:00",
"status": "completed",
"tasksCompleted": [
"emoji-replacement",
"alternative-modal",
"workout-page-ux-redesign",
"chat-onboarding",
"03-01-login-onboarding-polish"
],
"currentPhase": "03-design-polish",
"notes": "03-01 klar: Logo.jsx med SVG barbell, LoginPage/RegisterPage uppdaterade med logotyp, taglines, index.css polerad med animationer."
"lastRun": "2026-02-28T23:33:00+01:00",
"status": "in_progress",
"tasksCompleted": ["emoji-replacement", "alternative-modal", "workout-page-ux-redish", "chat-onboarding", "03-01-login-onboarding-polish", "03-02-dashboard-polish"],
"activeTask": "03-03-workout-experience",
"nextTask": null,
"notes": "Starting 03-03 Workout Experience Polish - spawning frontend agent"
}
+62 -16
View File
@@ -133,7 +133,7 @@
.day-card {
background: var(--bg-card);
border-radius: var(--radius-lg);
border-radius: var(--radius-xl);
padding: var(--space-4);
margin-bottom: var(--space-3);
cursor: pointer;
@@ -234,7 +234,7 @@
.exercise-card {
background: var(--bg-card);
border-radius: var(--radius-lg);
border-radius: var(--radius-xl);
margin-bottom: var(--space-3);
overflow: hidden;
border: 1px solid var(--border);
@@ -459,7 +459,7 @@
.klart-btn {
width: 100%;
min-height: 52px;
border-radius: var(--radius-lg);
border-radius: var(--radius-xl);
background: var(--accent);
color: white;
border: none;
@@ -851,7 +851,7 @@
color: white;
border: none;
padding: var(--space-4);
border-radius: var(--radius-lg);
border-radius: var(--radius-xl);
font-size: var(--font-base);
font-weight: 600;
cursor: pointer;
@@ -925,7 +925,7 @@
.stat-card {
background: var(--bg-card);
border-radius: var(--radius-lg);
border-radius: var(--radius-xl);
padding: var(--space-4);
text-align: center;
border: 1px solid var(--border);
@@ -990,7 +990,7 @@
gap: var(--space-4);
background: var(--bg-card);
padding: var(--space-4);
border-radius: var(--radius-lg);
border-radius: var(--radius-xl);
border: 1px solid var(--border);
cursor: pointer;
transition: all var(--transition-base);
@@ -1384,7 +1384,7 @@
.measurement-card {
background: var(--bg-secondary);
padding: var(--space-4);
border-radius: var(--radius-lg);
border-radius: var(--radius-xl);
display: flex;
flex-direction: column;
align-items: center;
@@ -1418,7 +1418,7 @@
justify-content: space-between;
padding: var(--space-4);
background: var(--bg-secondary);
border-radius: var(--radius-lg);
border-radius: var(--radius-xl);
}
.strength-exercise {
@@ -1445,7 +1445,7 @@
gap: var(--space-2);
background: var(--bg-card);
padding: var(--space-2);
border-radius: var(--radius-lg);
border-radius: var(--radius-xl);
border: 1px solid var(--border);
}
@@ -1666,7 +1666,7 @@
.rest-timer-btn {
min-height: 48px;
border-radius: var(--radius-lg);
border-radius: var(--radius-xl);
border: 1px solid var(--border);
font-weight: 600;
cursor: pointer;
@@ -1888,7 +1888,7 @@
padding: var(--space-4);
background: var(--bg-secondary);
border: 2px dashed var(--border);
border-radius: var(--radius-lg);
border-radius: var(--radius-xl);
color: var(--text-muted);
font-size: var(--font-sm);
cursor: pointer;
@@ -2502,7 +2502,7 @@
width: 56px;
height: 56px;
min-width: 56px;
border-radius: var(--radius-lg);
border-radius: var(--radius-xl);
display: flex;
align-items: center;
justify-content: center;
@@ -2583,7 +2583,7 @@
background: var(--accent);
color: white;
border: none;
border-radius: var(--radius-lg);
border-radius: var(--radius-xl);
font-size: var(--font-lg);
font-weight: 600;
cursor: pointer;
@@ -2687,7 +2687,7 @@
width: 100%;
background: var(--bg-elevated);
border: 1.5px solid var(--border);
border-radius: var(--radius-lg);
border-radius: var(--radius-xl);
padding: var(--space-4) var(--space-5);
color: var(--text-primary);
font-size: 16px; /* prevents iOS auto-zoom */
@@ -2711,7 +2711,7 @@
background: var(--accent);
color: white;
border: none;
border-radius: var(--radius-lg);
border-radius: var(--radius-xl);
font-size: var(--font-base);
font-weight: 600;
cursor: pointer;
@@ -2860,7 +2860,7 @@
/* ── Calendar day cells: tighter spacing, better font ────── */
.calendar-day {
border-radius: var(--radius-lg);
border-radius: var(--radius-xl);
gap: var(--space-1);
min-height: 64px;
}
@@ -2912,3 +2912,49 @@
.week-calendar { animation: sectionIn 300ms ease both; }
.coach-section { animation: sectionIn 300ms ease 80ms both; }
.quick-stats { animation: sectionIn 300ms ease 160ms both; }
/* WORKOUT POLISH - 03-03 */
.exercise-card { position: relative; }
.exercise-card::before {
content: ''; position: absolute; top: 0; left: 0; right: 0; height: 3px;
background: linear-gradient(90deg, var(--accent), #ff8a65); opacity: 0;
transition: opacity 0.2s ease;
}
.exercise-card.expanded::before { opacity: 1; }
.exercise-card.all-done::before {
background: linear-gradient(90deg, var(--success), #4ade80); opacity: 1;
}
.exercise-info h3 { font-size: var(--font-lg); font-weight: 700; }
.muscle-group {
display: inline-block; font-size: var(--font-xs); font-weight: 600;
text-transform: uppercase; padding: var(--space-1) var(--space-2);
background: var(--bg-tertiary); border-radius: var(--radius-full);
}
.progress-badge {
background: linear-gradient(135deg, var(--bg-secondary), var(--bg-tertiary));
}
.progress-badge.complete {
background: linear-gradient(135deg, var(--success), #16a34a);
box-shadow: 0 4px 12px rgba(34, 197, 94, 0.3);
}
.rest-timer-card {
box-shadow: 0 4px 16px rgba(255, 107, 74, 0.1);
}
.rest-timer-time.running {
text-shadow: 0 0 20px rgba(255, 107, 74, 0.4);
animation: pulse-timer 1s ease-in-out infinite;
}
@keyframes pulse-timer { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.02); } }
.klart-btn {
background: linear-gradient(135deg, var(--accent), #e85a3c);
border-radius: var(--radius-xl);
}
.klart-btn.done {
background: linear-gradient(135deg, var(--success), #16a34a);
animation: success-bounce 0.5s ease;
}
@keyframes success-bounce { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.05); } }
.warmup-check {
width: 22px; height: 22px; border-radius: var(--radius-md);
border: 2px solid var(--border); display: flex; align-items: center; justify-content: center;
}
.warmup-item.done .warmup-check { background: var(--success); border-color: var(--success); color: white; }