diff --git a/.pm-checkpoint.json b/.pm-checkpoint.json
new file mode 100644
index 0000000..c376f89
--- /dev/null
+++ b/.pm-checkpoint.json
@@ -0,0 +1,8 @@
+{
+ "lastRun": "2026-02-28T23:45:00+01:00",
+ "status": "completed",
+ "tasksCompleted": ["emoji-replacement", "alternative-modal", "workout-page-ux-redish", "chat-onboarding", "03-01-login-onboarding-polish", "03-02-dashboard-polish", "03-03-workout-experience-polish"],
+ "activeTask": null,
+ "nextTask": null,
+ "notes": "03-03 Workout Experience Polish complete (commit f6b1379). Phase 3 complete: login/onboarding, dashboard, and workout experience all polished."
+}
diff --git a/backend/src/index.js b/backend/src/index.js
index faa4fca..044336a 100644
--- a/backend/src/index.js
+++ b/backend/src/index.js
@@ -248,6 +248,61 @@ app.get('/api/days/:dayId/exercises', async (req, res) => {
}
});
+// Get alternative exercises for a given exercise (same muscle group)
+app.get('/api/exercises/:id/alternatives', async (req, res) => {
+ try {
+ const exerciseResult = await pool.query(
+ 'SELECT muscle_group FROM exercises WHERE id = $1',
+ [req.params.id]
+ );
+
+ if (!exerciseResult.rows.length) {
+ return res.status(404).json({ error: 'Exercise not found' });
+ }
+
+ const muscleGroup = exerciseResult.rows[0].muscle_group;
+ const alternatives = await pool.query(
+ `SELECT id, name, muscle_group, description
+ FROM exercises
+ WHERE muscle_group = $1 AND id <> $2
+ ORDER BY name`,
+ [muscleGroup, req.params.id]
+ );
+
+ res.json(alternatives.rows);
+ } catch (err) {
+ console.error('Error fetching alternatives:', err);
+ res.status(500).json({ error: 'Database error' });
+ }
+});
+
+// Get last workout for a specific exercise id
+app.get('/api/exercises/:id/last-workout', async (req, res) => {
+ try {
+ const { user_id } = req.query;
+ const result = await pool.query(`
+ WITH latest AS (
+ SELECT wl.date
+ FROM workout_logs wl
+ JOIN program_exercises pe ON wl.program_exercise_id = pe.id
+ WHERE pe.exercise_id = $1 AND wl.user_id = $2
+ ORDER BY wl.date DESC
+ LIMIT 1
+ )
+ SELECT wl.*
+ FROM workout_logs wl
+ JOIN program_exercises pe ON wl.program_exercise_id = pe.id
+ JOIN latest l ON wl.date = l.date
+ WHERE pe.exercise_id = $1 AND wl.user_id = $2
+ ORDER BY wl.set_number ASC
+ `, [req.params.id, user_id || 1]);
+ res.json(result.rows);
+ } catch (err) {
+ console.error('Error fetching last workout for exercise:', err);
+ res.status(500).json({ error: 'Database error' });
+ }
+});
+
// Get workout logs for a user and date
app.get('/api/logs', async (req, res) => {
try {
diff --git a/frontend/src/App.css b/frontend/src/App.css
index bc3f59c..0ae13cd 100644
--- a/frontend/src/App.css
+++ b/frontend/src/App.css
@@ -7,7 +7,7 @@
.app.loading {
justify-content: center;
align-items: center;
- gap: 1rem;
+ gap: var(--space-4);
}
.spinner {
@@ -23,10 +23,13 @@
to { transform: rotate(360deg); }
}
-/* Header */
+/* ============================================
+ HEADER - Refined
+ ============================================ */
+
.header {
background: var(--bg-secondary);
- padding: 1rem 1.25rem;
+ padding: var(--space-4) var(--space-5);
display: flex;
justify-content: space-between;
align-items: center;
@@ -34,17 +37,19 @@
position: sticky;
top: 0;
z-index: 100;
+ backdrop-filter: blur(12px);
+ -webkit-backdrop-filter: blur(12px);
}
.header h1 {
- font-size: 1.5rem;
+ font-size: var(--font-xl);
font-weight: 700;
}
.week-selector {
display: flex;
align-items: center;
- gap: 0.75rem;
+ gap: var(--space-3);
}
.week-selector button {
@@ -52,13 +57,22 @@
color: var(--text-primary);
width: 44px;
height: 44px;
- border-radius: 8px;
- font-size: 1.1rem;
- transition: all 0.2s;
+ min-width: 44px;
+ min-height: 44px;
+ border-radius: var(--radius-md);
+ font-size: var(--font-lg);
+ transition: all var(--transition-base);
+ border: 1px solid var(--border);
}
.week-selector button:hover:not(:disabled) {
background: var(--accent);
+ border-color: var(--accent);
+ box-shadow: 0 4px 12px rgba(255, 107, 74, 0.25);
+}
+
+.week-selector button:active:not(:disabled) {
+ transform: scale(0.95);
}
.week-selector button:disabled {
@@ -72,54 +86,67 @@
text-align: center;
}
-/* Main */
+/* ============================================
+ MAIN CONTENT
+ ============================================ */
+
.main {
flex: 1;
- padding: 1rem;
+ padding: var(--space-4);
max-width: 600px;
margin: 0 auto;
width: 100%;
}
-/* Program Info */
+/* ============================================
+ PROGRAM INFO
+ ============================================ */
+
.program-info {
- margin-bottom: 1.5rem;
+ margin-bottom: var(--space-6);
}
.program-info h2 {
- font-size: 1.25rem;
- margin-bottom: 0.5rem;
+ font-size: var(--font-lg);
+ margin-bottom: var(--space-2);
color: var(--accent);
}
.program-info p {
color: var(--text-secondary);
- font-size: 0.9rem;
- line-height: 1.5;
+ font-size: var(--font-sm);
+ line-height: 1.6;
}
-/* Days List */
+/* ============================================
+ DAYS LIST - Refined Cards
+ ============================================ */
+
.days-list h3 {
- font-size: 1rem;
- color: var(--text-secondary);
- margin-bottom: 1rem;
+ font-size: var(--font-sm);
+ color: var(--text-muted);
+ margin-bottom: var(--space-4);
text-transform: uppercase;
letter-spacing: 0.5px;
+ font-weight: 600;
}
.day-card {
background: var(--bg-card);
- border-radius: 12px;
- padding: 1rem;
- margin-bottom: 0.75rem;
+ border-radius: var(--radius-xl);
+ padding: var(--space-4);
+ margin-bottom: var(--space-3);
cursor: pointer;
- transition: all 0.2s;
- border: 1px solid transparent;
+ transition: all var(--transition-base);
+ border: 1px solid var(--border);
+ box-shadow: var(--shadow-card);
}
.day-card:hover {
background: var(--bg-card-hover);
border-color: var(--accent);
+ transform: translateY(-2px);
+ box-shadow: var(--shadow-md);
}
.day-card:active {
@@ -130,141 +157,194 @@
display: flex;
justify-content: space-between;
align-items: center;
- margin-bottom: 0.75rem;
+ margin-bottom: var(--space-3);
}
.day-number {
- font-size: 0.8rem;
- color: var(--text-secondary);
+ font-size: var(--font-xs);
+ color: var(--text-muted);
text-transform: uppercase;
+ font-weight: 500;
+ letter-spacing: 0.5px;
}
.day-name {
- font-size: 1.1rem;
+ font-size: var(--font-lg);
font-weight: 600;
}
.day-exercises {
display: flex;
flex-wrap: wrap;
- gap: 0.5rem;
- margin-bottom: 0.75rem;
+ gap: var(--space-2);
+ margin-bottom: var(--space-3);
}
.exercise-tag {
background: var(--bg-secondary);
- padding: 0.25rem 0.5rem;
- border-radius: 4px;
- font-size: 0.75rem;
+ padding: var(--space-1) var(--space-2);
+ border-radius: var(--radius-sm);
+ font-size: var(--font-xs);
color: var(--text-secondary);
+ border: 1px solid var(--border);
}
.exercise-tag.more {
background: var(--accent);
color: white;
+ border-color: var(--accent);
}
.day-action {
text-align: right;
color: var(--accent);
font-weight: 600;
- font-size: 0.9rem;
+ font-size: var(--font-sm);
}
-/* Workout View */
+/* ============================================
+ WORKOUT VIEW
+ ============================================ */
+
.workout-header {
flex-direction: column;
align-items: flex-start;
- gap: 0.5rem;
+ gap: var(--space-2);
}
.back-btn {
background: none;
color: var(--accent);
- font-size: 0.9rem;
- padding: 0.25rem 0;
+ font-size: var(--font-sm);
+ padding: var(--space-1) 0;
}
.header-title h1 {
- font-size: 1.25rem;
+ font-size: var(--font-lg);
}
.header-subtitle {
- font-size: 0.85rem;
- color: var(--text-secondary);
+ font-size: var(--font-sm);
+ color: var(--text-muted);
}
-/* Exercise Card */
+/* ============================================
+ EXERCISE CARD - Premium
+ ============================================ */
+
.exercise-card {
background: var(--bg-card);
- border-radius: 12px;
- margin-bottom: 0.75rem;
+ border-radius: var(--radius-xl);
+ margin-bottom: var(--space-3);
overflow: hidden;
- border: 1px solid transparent;
- transition: all 0.2s;
+ border: 1px solid var(--border);
+ transition: all var(--transition-base);
+ box-shadow: var(--shadow-card);
}
.exercise-card.expanded {
border-color: var(--accent);
+ box-shadow: 0 4px 16px rgba(255, 107, 74, 0.15);
+}
+
+.exercise-card.all-done {
+ border-color: var(--success);
+ background: var(--bg-card);
}
.exercise-header {
- padding: 1rem;
+ padding: var(--space-4);
display: flex;
justify-content: space-between;
align-items: center;
cursor: pointer;
}
+.exercise-actions {
+ display: flex;
+ align-items: center;
+ gap: var(--space-3);
+}
+
+.swap-btn {
+ border: 1px solid var(--border);
+ background: var(--bg-secondary);
+ color: var(--text-secondary);
+ width: 34px;
+ height: 34px;
+ border-radius: var(--radius-full);
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ cursor: pointer;
+ transition: all var(--transition-base);
+}
+
+.swap-btn:hover {
+ color: var(--accent);
+ border-color: var(--accent);
+ background: var(--bg-tertiary);
+}
+
+.swap-badge {
+ font-size: var(--font-xs);
+ color: var(--accent);
+}
+
.exercise-info h3 {
- font-size: 1rem;
- margin-bottom: 0.25rem;
+ font-size: var(--font-base);
+ margin-bottom: var(--space-1);
}
.muscle-group {
- font-size: 0.8rem;
- color: var(--text-secondary);
+ font-size: var(--font-xs);
+ color: var(--text-muted);
}
.exercise-meta {
display: flex;
flex-direction: column;
align-items: flex-end;
- gap: 0.25rem;
+ gap: var(--space-1);
}
.sets-info {
- font-size: 0.9rem;
+ font-size: var(--font-sm);
color: var(--text-secondary);
}
.progress-badge {
background: var(--bg-secondary);
- padding: 0.2rem 0.5rem;
- border-radius: 10px;
- font-size: 0.75rem;
+ padding: var(--space-1) var(--space-2);
+ border-radius: var(--radius-full);
+ font-size: var(--font-xs);
font-weight: 600;
+ border: 1px solid var(--border);
}
.progress-badge.complete {
background: var(--success);
- color: var(--bg-primary);
+ color: white;
+ border-color: var(--success);
}
-/* Exercise Body */
+/* ============================================
+ EXERCISE BODY
+ ============================================ */
+
.exercise-body {
- padding: 0 1rem 1rem;
+ padding: 0 var(--space-4) var(--space-4);
border-top: 1px solid var(--border);
- padding-top: 1rem;
+ padding-top: var(--space-4);
}
.progression-hint {
- background: rgba(233, 69, 96, 0.1);
- border: 1px solid var(--accent);
- border-radius: 8px;
- padding: 0.75rem;
- margin-bottom: 1rem;
- font-size: 0.85rem;
+ background: var(--accent-subtle);
+ border: 1px solid rgba(255, 107, 74, 0.3);
+ border-radius: var(--radius-md);
+ padding: var(--space-3);
+ margin-bottom: var(--space-4);
+ font-size: var(--font-sm);
color: var(--text-secondary);
}
@@ -272,90 +352,165 @@
color: var(--accent);
}
-/* Sets List */
+/* ============================================
+ SETS LIST
+ ============================================ */
+
.sets-list {
display: flex;
flex-direction: column;
- gap: 0.5rem;
+ gap: var(--space-2);
}
.set-row {
display: flex;
- align-items: flex-start;
- gap: 0.75rem;
- padding: 0.75rem;
+ flex-direction: column;
+ gap: var(--space-3);
+ padding: var(--space-4);
background: var(--bg-secondary);
- border-radius: 8px;
- transition: all 0.2s;
+ border-radius: var(--radius-md);
+ border: 1px solid transparent;
+ transition: all var(--transition-base);
}
.set-row.completed {
- background: rgba(78, 204, 163, 0.15);
- border: 1px solid var(--success);
+ background: var(--success-subtle);
+ border-color: var(--success);
}
.set-number {
- font-size: 0.85rem;
- color: var(--text-secondary);
- min-width: 45px;
+ font-size: var(--font-sm);
+ color: var(--text-muted);
+ font-weight: 500;
}
-.set-inputs {
- flex: 1;
+.set-row-top {
display: flex;
- align-items: flex-start;
- gap: 0.75rem;
+ align-items: center;
+ justify-content: space-between;
+ gap: var(--space-3);
}
-.input-separator {
- color: var(--text-secondary);
+.set-controls {
+ display: grid;
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+ gap: var(--space-3);
}
-.complete-btn {
+.set-metric {
+ background: var(--bg-card);
+ border-radius: var(--radius-md);
+ border: 1px solid var(--border);
+ padding: var(--space-3);
+ display: flex;
+ flex-direction: column;
+ gap: var(--space-2);
+}
+
+.metric-label {
+ font-size: var(--font-xs);
+ color: var(--text-muted);
+ text-transform: uppercase;
+ letter-spacing: 0.5px;
+ font-weight: 600;
+}
+
+.metric-controls {
+ display: grid;
+ grid-template-columns: 44px 1fr 44px;
+ align-items: center;
+ gap: var(--space-2);
+}
+
+.metric-btn {
width: 44px;
height: 44px;
- border-radius: 50%;
- background: var(--bg-card);
- color: var(--text-secondary);
- font-size: 1.25rem;
- transition: all 0.2s;
+ border-radius: var(--radius-md);
+ border: 1px solid var(--border);
+ background: var(--bg-secondary);
+ font-size: var(--font-lg);
+ font-weight: 600;
+ cursor: pointer;
+ transition: all var(--transition-base);
}
-.complete-btn:hover {
+.metric-btn:hover {
+ border-color: var(--accent);
+ color: var(--accent);
+}
+
+.metric-value {
+ display: flex;
+ align-items: baseline;
+ justify-content: center;
+ gap: var(--space-1);
+ font-size: var(--font-lg);
+ font-weight: 700;
+ min-height: 44px;
+ color: var(--text-primary);
+}
+
+.metric-suffix {
+ font-size: var(--font-sm);
+ color: var(--text-muted);
+ font-weight: 500;
+}
+
+.klart-btn {
+ width: 100%;
+ min-height: 52px;
+ border-radius: var(--radius-xl);
background: var(--accent);
color: white;
+ border: none;
+ font-size: var(--font-base);
+ font-weight: 700;
+ letter-spacing: 1px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: var(--space-2);
+ cursor: pointer;
+ transition: all var(--transition-base);
}
-.complete-btn.done {
+.klart-btn:hover {
+ transform: translateY(-1px);
+ box-shadow: 0 10px 24px rgba(255, 107, 74, 0.25);
+}
+
+.klart-btn.done {
background: var(--success);
- color: var(--bg-primary);
+ box-shadow: 0 10px 24px rgba(34, 197, 94, 0.3);
}
-/* Mobile optimizations */
+/* ============================================
+ MOBILE OPTIMIZATIONS
+ ============================================ */
+
@media (max-width: 480px) {
.header {
- padding: 0.75rem 1rem;
+ padding: var(--space-3) var(--space-4);
}
-
+
.header h1 {
- font-size: 1.25rem;
+ font-size: var(--font-lg);
}
-
+
.main {
- padding: 0.75rem;
+ padding: var(--space-3);
}
-
}
/* Safe area for notched phones */
@supports (padding: env(safe-area-inset-bottom)) {
.main {
- padding-bottom: calc(1rem + env(safe-area-inset-bottom));
+ padding-bottom: calc(var(--space-4) + env(safe-area-inset-bottom));
}
}
/* ============================================
- DASHBOARD STYLES
+ DASHBOARD STYLES - Premium
============================================ */
.dashboard {
@@ -368,17 +523,19 @@
flex-direction: column;
justify-content: center;
align-items: center;
- gap: 1rem;
+ gap: var(--space-4);
}
/* Dashboard Header */
.dashboard-header {
background: var(--bg-secondary);
- padding: 1rem 1.25rem;
+ padding: var(--space-4) var(--space-5);
border-bottom: 1px solid var(--border);
position: sticky;
top: 0;
z-index: 100;
+ backdrop-filter: blur(12px);
+ -webkit-backdrop-filter: blur(12px);
}
.header-top {
@@ -388,66 +545,96 @@
}
.header-top h1 {
- font-size: 1.5rem;
+ font-size: var(--font-xl);
font-weight: 700;
}
.nav-menu {
display: flex;
- gap: 0.25rem;
+ gap: var(--space-1);
}
.nav-btn {
background: transparent;
border: none;
color: var(--text-muted);
- padding: 0.5rem 0.75rem;
- border-radius: 8px;
- font-size: 0.85rem;
+ padding: var(--space-2) var(--space-3);
+ border-radius: var(--radius-md);
+ font-size: var(--font-sm);
cursor: pointer;
- transition: all 0.2s;
+ transition: all var(--transition-base);
+ min-height: 44px;
+ min-width: 44px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
}
.nav-btn:hover,
.nav-btn.active {
- background: var(--bg);
- color: var(--text);
+ background: var(--bg-card);
+ color: var(--text-primary);
+}
+
+.nav-btn.active {
+ color: var(--accent);
}
.nav-btn.logout {
color: var(--text-muted);
}
+.nav-btn.logout:hover {
+ color: var(--error);
+}
+
/* Dashboard Main */
.dashboard-main {
- padding: 1rem;
+ padding: var(--space-4);
display: flex;
flex-direction: column;
- gap: 1.5rem;
+ gap: var(--space-5);
max-width: 600px;
margin: 0 auto;
}
-/* Coach Greeting */
+/* ============================================
+ COACH GREETING - Premium Card
+ ============================================ */
+
.coach-greeting {
display: flex;
- gap: 1rem;
- padding: 1rem;
+ gap: var(--space-4);
+ padding: var(--space-5);
background: linear-gradient(135deg, var(--accent) 0%, #6366f1 100%);
- border-radius: 16px;
+ border-radius: var(--radius-xl);
color: white;
+ box-shadow: 0 8px 24px rgba(99, 102, 241, 0.25);
+ position: relative;
+ overflow: hidden;
+}
+
+.coach-greeting::before {
+ content: '';
+ position: absolute;
+ inset: 0;
+ background: linear-gradient(180deg, rgba(255,255,255,0.1) 0%, transparent 50%);
+ pointer-events: none;
}
.coach-avatar {
- width: 52px;
- height: 52px;
+ width: 56px;
+ height: 56px;
+ min-width: 56px;
background: rgba(255,255,255,0.15);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
- color: rgba(255,255,255,0.9);
+ color: rgba(255,255,255,0.95);
+ backdrop-filter: blur(8px);
+ border: 2px solid rgba(255,255,255,0.2);
}
.coach-message {
@@ -456,160 +643,192 @@
}
.coach-message p {
- font-size: 1.1rem;
+ font-size: var(--font-lg);
font-weight: 500;
line-height: 1.4;
+ position: relative;
+ z-index: 1;
}
-/* Week Calendar */
+/* ============================================
+ WEEK CALENDAR - Premium
+ ============================================ */
+
.week-calendar {
- background: var(--bg-secondary);
- border-radius: 16px;
- padding: 1rem;
+ background: var(--bg-card);
+ border-radius: var(--radius-xl);
+ padding: var(--space-4);
border: 1px solid var(--border);
+ box-shadow: var(--shadow-card);
}
.calendar-header {
display: flex;
justify-content: space-between;
align-items: center;
- margin-bottom: 1rem;
+ margin-bottom: var(--space-4);
}
.calendar-title {
font-weight: 600;
text-transform: capitalize;
+ font-size: var(--font-base);
}
.calendar-nav {
- background: var(--bg);
+ background: var(--bg-secondary);
border: 1px solid var(--border);
width: 44px;
height: 44px;
- border-radius: 8px;
+ min-width: 44px;
+ min-height: 44px;
+ border-radius: var(--radius-md);
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
- color: var(--text);
- transition: all 0.2s;
+ color: var(--text-primary);
+ transition: all var(--transition-base);
}
.calendar-nav:hover {
background: var(--accent);
color: white;
border-color: var(--accent);
+ box-shadow: 0 4px 12px rgba(255, 107, 74, 0.25);
+}
+
+.calendar-nav:active {
+ transform: scale(0.95);
}
.calendar-days {
display: grid;
grid-template-columns: repeat(7, 1fr);
- gap: 0.5rem;
+ gap: var(--space-1);
}
.calendar-day {
display: flex;
flex-direction: column;
align-items: center;
- padding: 0.5rem;
- border-radius: 12px;
+ padding: var(--space-2);
+ border-radius: var(--radius-md);
cursor: pointer;
- transition: all 0.2s;
+ transition: all var(--transition-base);
position: relative;
+ min-height: 60px;
+ justify-content: center;
}
.calendar-day:hover {
- background: var(--bg);
+ background: var(--bg-secondary);
}
.calendar-day.today {
background: var(--accent);
color: white;
+ box-shadow: 0 4px 12px rgba(255, 107, 74, 0.3);
}
+.calendar-day.has-workout:not(.today) {
+ background: var(--bg-secondary);
+}
.day-name {
- font-size: 0.7rem;
+ font-size: var(--font-xs);
text-transform: uppercase;
color: var(--text-muted);
- margin-bottom: 0.25rem;
+ margin-bottom: var(--space-1);
+ font-weight: 500;
+ letter-spacing: 0.5px;
}
.calendar-day.today .day-name {
- color: rgba(255,255,255,0.8);
+ color: rgba(255,255,255,0.85);
}
.day-date {
- font-size: 1rem;
+ font-size: var(--font-base);
font-weight: 600;
}
.day-dot {
- width: 4px;
- height: 4px;
+ width: 5px;
+ height: 5px;
border-radius: 50%;
background: var(--success);
- margin-top: 0.25rem;
+ margin-top: var(--space-1);
}
.calendar-day.today .day-dot {
- background: rgba(255,255,255,0.8);
+ background: rgba(255,255,255,0.85);
}
-/* Today's Workout */
+/* ============================================
+ TODAY'S WORKOUT - Premium Card
+ ============================================ */
+
.todays-workout {
display: flex;
flex-direction: column;
- gap: 1rem;
+ gap: var(--space-4);
}
.todays-workout h2 {
- font-size: 1.1rem;
+ font-size: var(--font-base);
font-weight: 600;
+ color: var(--text-secondary);
}
.workout-card {
- background: var(--bg-secondary);
- border-radius: 16px;
- padding: 1.25rem;
+ background: var(--bg-card);
+ border-radius: var(--radius-xl);
+ padding: var(--space-5);
border: 1px solid var(--border);
cursor: pointer;
- transition: all 0.2s;
+ transition: all var(--transition-base);
+ box-shadow: var(--shadow-card);
}
.workout-card:hover {
border-color: var(--accent);
transform: translateY(-2px);
+ box-shadow: var(--shadow-md);
+}
+
+.workout-card:active {
+ transform: scale(0.98);
}
.workout-card-header {
display: flex;
justify-content: space-between;
align-items: center;
- margin-bottom: 1rem;
+ margin-bottom: var(--space-4);
}
.workout-card-header h3 {
- font-size: 1.2rem;
+ font-size: var(--font-lg);
font-weight: 600;
}
.workout-duration {
- font-size: 0.85rem;
+ font-size: var(--font-sm);
color: var(--text-muted);
}
.workout-exercises {
display: flex;
flex-direction: column;
- gap: 0.5rem;
- margin-bottom: 1rem;
+ gap: var(--space-2);
+ margin-bottom: var(--space-4);
}
.exercise-preview {
display: flex;
justify-content: space-between;
- padding: 0.5rem 0;
+ padding: var(--space-2) 0;
border-bottom: 1px solid var(--border);
}
@@ -623,7 +842,7 @@
.exercise-sets {
color: var(--text-muted);
- font-size: 0.9rem;
+ font-size: var(--font-sm);
}
.start-workout-btn {
@@ -631,83 +850,109 @@
background: var(--accent);
color: white;
border: none;
- padding: 1rem;
- border-radius: 12px;
- font-size: 1rem;
+ padding: var(--space-4);
+ border-radius: var(--radius-xl);
+ font-size: var(--font-base);
font-weight: 600;
cursor: pointer;
- transition: all 0.2s;
- min-height: 44px;
+ transition: all var(--transition-base);
+ min-height: 48px;
+ box-shadow: 0 4px 12px rgba(255, 107, 74, 0.3);
}
.start-workout-btn:hover {
background: var(--accent-hover);
- transform: scale(1.02);
+ transform: translateY(-1px);
+ box-shadow: 0 6px 20px rgba(255, 107, 74, 0.4);
}
-/* Rest Day Card */
+.start-workout-btn:active {
+ transform: translateY(0);
+}
+
+/* ============================================
+ REST DAY CARD
+ ============================================ */
+
.rest-day-card {
- background: var(--bg-secondary);
- border-radius: 16px;
- padding: 2rem;
+ background: var(--bg-card);
+ border-radius: var(--radius-xl);
+ padding: var(--space-10);
border: 1px solid var(--border);
text-align: center;
+ box-shadow: var(--shadow-card);
}
.rest-icon {
font-size: 3rem;
- margin-bottom: 1rem;
+ margin-bottom: var(--space-4);
}
.rest-day-card h3 {
- font-size: 1.2rem;
- margin-bottom: 0.5rem;
+ font-size: var(--font-lg);
+ margin-bottom: var(--space-2);
}
.rest-day-card p {
color: var(--text-muted);
- margin-bottom: 1rem;
+ margin-bottom: var(--space-4);
}
.rest-tips {
display: flex;
justify-content: center;
- gap: 1rem;
+ gap: var(--space-3);
+ flex-wrap: wrap;
}
.rest-tips span {
- background: var(--bg);
- padding: 0.5rem 0.75rem;
- border-radius: 20px;
- font-size: 0.85rem;
+ background: var(--bg-secondary);
+ padding: var(--space-2) var(--space-3);
+ border-radius: var(--radius-full);
+ font-size: var(--font-sm);
+ border: 1px solid var(--border);
}
-/* Quick Stats */
+/* ============================================
+ QUICK STATS - Premium
+ ============================================ */
+
.quick-stats {
display: grid;
grid-template-columns: repeat(3, 1fr);
- gap: 0.75rem;
+ gap: var(--space-3);
}
.stat-card {
- background: var(--bg-secondary);
- border-radius: 12px;
- padding: 1rem;
+ background: var(--bg-card);
+ border-radius: var(--radius-xl);
+ padding: var(--space-4);
text-align: center;
border: 1px solid var(--border);
+ box-shadow: var(--shadow-card);
+ transition: all var(--transition-base);
+}
+
+.stat-card:hover {
+ border-color: var(--border-hover);
+ transform: translateY(-1px);
}
.stat-value {
display: block;
- font-size: 1.5rem;
+ font-size: var(--font-2xl);
font-weight: 700;
color: var(--accent);
+ line-height: 1.2;
}
.stat-label {
- font-size: 0.75rem;
+ font-size: var(--font-xs);
color: var(--text-muted);
text-transform: uppercase;
+ letter-spacing: 0.5px;
+ font-weight: 500;
+ margin-top: var(--space-1);
}
.stat-icon {
@@ -720,52 +965,190 @@
.brand-title {
display: flex;
align-items: center;
- gap: 0.5rem;
+ gap: var(--space-2);
}
-/* Upcoming Workouts */
+/* ============================================
+ UPCOMING WORKOUTS
+ ============================================ */
+
.upcoming-workouts h2 {
- font-size: 1.1rem;
+ font-size: var(--font-base);
font-weight: 600;
- margin-bottom: 0.75rem;
+ margin-bottom: var(--space-3);
}
.upcoming-list {
display: flex;
flex-direction: column;
- gap: 0.5rem;
+ gap: var(--space-2);
}
.upcoming-item {
display: flex;
align-items: center;
- gap: 1rem;
- background: var(--bg-secondary);
- padding: 1rem;
- border-radius: 12px;
+ gap: var(--space-4);
+ background: var(--bg-card);
+ padding: var(--space-4);
+ border-radius: var(--radius-xl);
border: 1px solid var(--border);
cursor: pointer;
- transition: all 0.2s;
+ transition: all var(--transition-base);
+ box-shadow: var(--shadow-card);
}
.upcoming-item:hover {
border-color: var(--accent);
+ transform: translateX(4px);
}
.upcoming-day {
font-weight: 600;
width: 40px;
color: var(--accent);
+ font-size: var(--font-sm);
}
.upcoming-name {
flex: 1;
+ font-weight: 500;
}
.upcoming-arrow {
color: var(--text-muted);
}
+/* ============================================
+ COACH SECTION (redesigned)
+ ============================================ */
+
+.coach-section {
+ display: flex;
+ flex-direction: column;
+ gap: var(--space-4);
+}
+
+.today-action {
+ /* Container for workout card or rest tips */
+}
+
+.today-workout-card {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ background: linear-gradient(135deg, var(--accent) 0%, #6366f1 100%);
+ border-radius: var(--radius-xl);
+ padding: var(--space-5);
+ cursor: pointer;
+ transition: all var(--transition-base);
+ color: white;
+ box-shadow: 0 8px 24px rgba(99, 102, 241, 0.25);
+ position: relative;
+ overflow: hidden;
+}
+
+.today-workout-card::before {
+ content: '';
+ position: absolute;
+ inset: 0;
+ background: linear-gradient(180deg, rgba(255,255,255,0.1) 0%, transparent 50%);
+ pointer-events: none;
+}
+
+.today-workout-card:hover {
+ transform: translateY(-2px);
+ box-shadow: 0 12px 32px rgba(99, 102, 241, 0.3);
+}
+
+.today-workout-card:active {
+ transform: scale(0.98);
+}
+
+.workout-info h3 {
+ font-size: var(--font-lg);
+ font-weight: 600;
+ margin-bottom: var(--space-1);
+}
+
+.workout-meta {
+ font-size: var(--font-sm);
+ opacity: 0.9;
+}
+
+.workout-action {
+ background: rgba(255,255,255,0.2);
+ width: 48px;
+ height: 48px;
+ min-width: 48px;
+ min-height: 48px;
+ border-radius: 50%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ backdrop-filter: blur(8px);
+ border: 2px solid rgba(255,255,255,0.2);
+}
+
+.action-arrow {
+ font-size: var(--font-xl);
+}
+
+/* Rest Day Section */
+.rest-day-section {
+ display: flex;
+ flex-direction: column;
+ gap: var(--space-4);
+}
+
+.rest-day-section .rest-tips {
+ display: flex;
+ flex-wrap: wrap;
+ gap: var(--space-2);
+}
+
+.tip-badge {
+ display: flex;
+ align-items: center;
+ gap: var(--space-2);
+ background: var(--bg-card);
+ border: 1px solid var(--border);
+ padding: var(--space-2) var(--space-3);
+ border-radius: var(--radius-full);
+ font-size: var(--font-sm);
+ transition: all var(--transition-base);
+}
+
+.tip-badge:hover {
+ border-color: var(--accent);
+}
+
+.add-workout-btn {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: var(--space-2);
+ background: var(--bg-card);
+ border: 2px dashed var(--border);
+ border-radius: var(--radius-xl);
+ padding: var(--space-5);
+ cursor: pointer;
+ color: var(--text-muted);
+ transition: all var(--transition-base);
+ font-size: var(--font-base);
+ min-height: 56px;
+}
+
+.add-workout-btn:hover {
+ border-color: var(--accent);
+ color: var(--accent);
+ background: var(--bg-secondary);
+}
+
+.add-icon {
+ font-size: var(--font-2xl);
+ font-weight: 300;
+}
+
/* ============================================
PROFILE PAGE STYLES
============================================ */
@@ -782,13 +1165,13 @@
flex-direction: column;
justify-content: center;
align-items: center;
- gap: 1rem;
+ gap: var(--space-4);
}
/* Page Header */
.page-header {
background: var(--bg-secondary);
- padding: 1rem 1.25rem;
+ padding: var(--space-4) var(--space-5);
display: flex;
justify-content: space-between;
align-items: center;
@@ -796,10 +1179,12 @@
position: sticky;
top: 0;
z-index: 100;
+ backdrop-filter: blur(12px);
+ -webkit-backdrop-filter: blur(12px);
}
.page-header h1 {
- font-size: 1.25rem;
+ font-size: var(--font-lg);
font-weight: 600;
}
@@ -807,77 +1192,91 @@
background: transparent;
border: none;
color: var(--accent);
- font-size: 1rem;
+ font-size: var(--font-base);
cursor: pointer;
- padding: 0.5rem;
+ padding: var(--space-2);
display: flex;
align-items: center;
- gap: 0.25rem;
+ gap: var(--space-1);
min-height: 44px;
+ transition: opacity var(--transition-fast);
+}
+
+.back-btn:hover {
+ opacity: 0.8;
}
/* Page Main */
.page-main {
- padding: 1rem;
+ padding: var(--space-4);
max-width: 600px;
margin: 0 auto;
display: flex;
flex-direction: column;
- gap: 1.5rem;
+ gap: var(--space-5);
}
/* Profile Section */
.profile-section {
- background: var(--bg-secondary);
- border-radius: 16px;
- padding: 1.25rem;
+ background: var(--bg-card);
+ border-radius: var(--radius-xl);
+ padding: var(--space-5);
border: 1px solid var(--border);
+ box-shadow: var(--shadow-card);
}
.section-header {
display: flex;
justify-content: space-between;
align-items: center;
- margin-bottom: 1rem;
+ margin-bottom: var(--space-4);
}
.section-header h2 {
- font-size: 1.1rem;
+ font-size: var(--font-lg);
font-weight: 600;
}
.edit-btn {
- background: var(--bg);
+ background: var(--bg-secondary);
border: 1px solid var(--border);
- padding: 0.5rem 0.75rem;
- border-radius: 8px;
+ padding: var(--space-2) var(--space-3);
+ border-radius: var(--radius-md);
cursor: pointer;
- font-size: 0.85rem;
- color: var(--text);
+ font-size: var(--font-sm);
+ color: var(--text-primary);
min-height: 44px;
+ transition: all var(--transition-base);
+}
+
+.edit-btn:hover {
+ border-color: var(--accent);
+ color: var(--accent);
}
/* Info Grid */
.info-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
- gap: 1rem;
+ gap: var(--space-4);
}
.info-item {
display: flex;
flex-direction: column;
- gap: 0.25rem;
+ gap: var(--space-1);
}
.info-label {
- font-size: 0.75rem;
+ font-size: var(--font-xs);
color: var(--text-muted);
text-transform: uppercase;
+ letter-spacing: 0.5px;
+ font-weight: 500;
}
.info-value {
- font-size: 1rem;
+ font-size: var(--font-base);
font-weight: 500;
}
@@ -885,69 +1284,90 @@
.edit-form {
display: flex;
flex-direction: column;
- gap: 1rem;
+ gap: var(--space-4);
}
.form-row {
display: grid;
grid-template-columns: 1fr 1fr;
- gap: 1rem;
+ gap: var(--space-4);
}
.form-group {
display: flex;
flex-direction: column;
- gap: 0.5rem;
+ gap: var(--space-2);
}
.form-group label {
- font-size: 0.85rem;
+ font-size: var(--font-sm);
color: var(--text-muted);
+ font-weight: 500;
}
.form-group input,
.form-group select {
- padding: 0.75rem;
+ padding: var(--space-3) var(--space-4);
border: 1px solid var(--border);
- border-radius: 8px;
- background: var(--bg);
- color: var(--text);
- font-size: 1rem;
+ border-radius: var(--radius-md);
+ background: var(--bg-secondary);
+ color: var(--text-primary);
+ font-size: 16px;
+ transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
+}
+
+.form-group input:hover,
+.form-group select:hover {
+ border-color: var(--border-hover);
}
.form-group input:focus,
.form-group select:focus {
outline: none;
border-color: var(--accent);
+ box-shadow: 0 0 0 3px var(--accent-subtle);
}
.form-actions {
display: flex;
- gap: 1rem;
- margin-top: 0.5rem;
+ gap: var(--space-3);
+ margin-top: var(--space-2);
}
.cancel-btn {
flex: 1;
- padding: 0.75rem;
+ padding: var(--space-3);
border: 1px solid var(--border);
- background: var(--bg);
- border-radius: 8px;
+ background: var(--bg-secondary);
+ border-radius: var(--radius-md);
cursor: pointer;
- color: var(--text);
- min-height: 44px;
+ color: var(--text-primary);
+ min-height: 48px;
+ transition: all var(--transition-base);
+}
+
+.cancel-btn:hover {
+ border-color: var(--border-hover);
}
.save-btn {
flex: 1;
- padding: 0.75rem;
+ padding: var(--space-3);
border: none;
background: var(--accent);
color: white;
- border-radius: 8px;
+ border-radius: var(--radius-md);
cursor: pointer;
font-weight: 600;
- min-height: 44px;
+ min-height: 48px;
+ box-shadow: 0 4px 12px rgba(255, 107, 74, 0.3);
+ transition: all var(--transition-base);
+}
+
+.save-btn:hover:not(:disabled) {
+ background: var(--accent-hover);
+ transform: translateY(-1px);
+ box-shadow: 0 6px 20px rgba(255, 107, 74, 0.4);
}
.save-btn:disabled {
@@ -958,31 +1378,31 @@
.measurements-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
- gap: 1rem;
+ gap: var(--space-4);
}
.measurement-card {
- background: var(--bg);
- padding: 1rem;
- border-radius: 12px;
+ background: var(--bg-secondary);
+ padding: var(--space-4);
+ border-radius: var(--radius-xl);
display: flex;
flex-direction: column;
align-items: center;
- gap: 0.25rem;
+ gap: var(--space-1);
}
.measurement-icon {
- font-size: 1.5rem;
+ font-size: var(--font-xl);
}
.measurement-value {
- font-size: 1.25rem;
+ font-size: var(--font-lg);
font-weight: 700;
color: var(--accent);
}
.measurement-label {
- font-size: 0.75rem;
+ font-size: var(--font-xs);
color: var(--text-muted);
}
@@ -990,15 +1410,15 @@
.strength-grid {
display: flex;
flex-direction: column;
- gap: 0.75rem;
+ gap: var(--space-3);
}
.strength-card {
display: flex;
justify-content: space-between;
- padding: 1rem;
- background: var(--bg);
- border-radius: 12px;
+ padding: var(--space-4);
+ background: var(--bg-secondary);
+ border-radius: var(--radius-xl);
}
.strength-exercise {
@@ -1013,7 +1433,7 @@
.no-data {
color: var(--text-muted);
text-align: center;
- padding: 1rem;
+ padding: var(--space-4);
}
/* ============================================
@@ -1022,51 +1442,54 @@
.progress-tabs {
display: flex;
- gap: 0.5rem;
- background: var(--bg-secondary);
- padding: 0.5rem;
- border-radius: 12px;
+ gap: var(--space-2);
+ background: var(--bg-card);
+ padding: var(--space-2);
+ border-radius: var(--radius-xl);
border: 1px solid var(--border);
}
.tab-btn {
flex: 1;
- padding: 0.75rem;
+ padding: var(--space-3);
border: none;
background: transparent;
- border-radius: 8px;
+ border-radius: var(--radius-md);
cursor: pointer;
- font-size: 0.9rem;
+ font-size: var(--font-sm);
color: var(--text-muted);
- transition: all 0.2s;
- min-height: 44px;
+ transition: all var(--transition-base);
+ min-height: 48px;
}
.tab-btn.active {
background: var(--accent);
color: white;
+ box-shadow: 0 4px 12px rgba(255, 107, 74, 0.25);
}
.tab-btn:hover:not(.active) {
- background: var(--bg);
+ background: var(--bg-secondary);
+ color: var(--text-primary);
}
/* Chart Section */
.chart-section {
- background: var(--bg-secondary);
- border-radius: 16px;
- padding: 1.25rem;
+ background: var(--bg-card);
+ border-radius: var(--radius-xl);
+ padding: var(--space-5);
border: 1px solid var(--border);
+ box-shadow: var(--shadow-card);
}
.chart-section h2 {
- font-size: 1.1rem;
+ font-size: var(--font-lg);
font-weight: 600;
- margin-bottom: 1rem;
+ margin-bottom: var(--space-4);
}
.chart-container {
- margin-bottom: 1rem;
+ margin-bottom: var(--space-4);
}
.line-chart {
@@ -1077,29 +1500,29 @@
.chart-labels {
display: flex;
justify-content: space-between;
- font-size: 0.75rem;
+ font-size: var(--font-xs);
color: var(--text-muted);
- padding: 0 0.5rem;
+ padding: 0 var(--space-2);
}
/* Strength Charts */
.strength-charts {
display: flex;
flex-direction: column;
- gap: 2rem;
+ gap: var(--space-6);
}
.strength-chart-item h3 {
- font-size: 1rem;
- margin-bottom: 0.75rem;
+ font-size: var(--font-base);
+ margin-bottom: var(--space-3);
}
/* Progress Stats */
.progress-stats {
display: grid;
grid-template-columns: repeat(3, 1fr);
- gap: 0.5rem;
- padding-top: 0.5rem;
+ gap: var(--space-2);
+ padding-top: var(--space-3);
border-top: 1px solid var(--border);
}
@@ -1108,22 +1531,23 @@
}
.progress-stats .stat-label {
- font-size: 0.7rem;
+ font-size: var(--font-xs);
color: var(--text-muted);
text-transform: uppercase;
+ letter-spacing: 0.5px;
}
.progress-stats .stat-value {
- font-size: 0.9rem;
+ font-size: var(--font-sm);
font-weight: 600;
}
.trend-up {
- color: #10b981;
+ color: var(--success);
}
.trend-down {
- color: #ef4444;
+ color: var(--error);
}
.trend-neutral {
@@ -1133,13 +1557,13 @@
/* Empty State */
.empty-state {
text-align: center;
- padding: 2rem;
+ padding: var(--space-10);
}
.empty-icon {
font-size: 3rem;
display: block;
- margin-bottom: 1rem;
+ margin-bottom: var(--space-4);
}
.empty-state p {
@@ -1147,8 +1571,8 @@
}
.empty-hint {
- font-size: 0.85rem;
- margin-top: 0.5rem;
+ font-size: var(--font-sm);
+ margin-top: var(--space-2);
}
/* ============================================
@@ -1163,7 +1587,7 @@
.workout-page .page-header {
display: grid;
grid-template-columns: auto 1fr auto;
- gap: 1rem;
+ gap: var(--space-4);
align-items: center;
}
@@ -1172,27 +1596,119 @@
}
.workout-page .header-center h1 {
- font-size: 1.1rem;
+ font-size: var(--font-base);
font-weight: 600;
margin: 0;
}
.workout-page .header-subtitle {
- font-size: 0.8rem;
+ font-size: var(--font-xs);
color: var(--text-muted);
}
.workout-page .header-progress {
background: var(--accent);
color: white;
- padding: 0.4rem 0.75rem;
- border-radius: 20px;
- font-size: 0.85rem;
+ padding: var(--space-1) var(--space-3);
+ border-radius: var(--radius-full);
+ font-size: var(--font-sm);
font-weight: 600;
}
.workout-page .workout-main {
- padding-bottom: 2rem;
+ padding-bottom: var(--space-8);
+}
+
+/* Rest timer */
+.rest-timer-card {
+ background: linear-gradient(135deg, rgba(255, 107, 74, 0.14), rgba(34, 197, 94, 0.12));
+ border: 1px solid var(--border);
+ border-radius: var(--radius-xl);
+ padding: var(--space-4);
+ margin-bottom: var(--space-5);
+ box-shadow: var(--shadow-card);
+ display: flex;
+ flex-direction: column;
+ gap: var(--space-3);
+}
+
+.rest-timer-header {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: var(--space-3);
+}
+
+.rest-timer-label {
+ font-size: var(--font-xs);
+ text-transform: uppercase;
+ letter-spacing: 1px;
+ font-weight: 600;
+ color: var(--text-secondary);
+}
+
+.rest-timer-time {
+ font-size: 2rem;
+ font-weight: 700;
+ color: var(--text-primary);
+ letter-spacing: 1px;
+}
+
+.rest-timer-time.running {
+ color: var(--accent);
+}
+
+.rest-timer-actions {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: var(--space-3);
+}
+
+.rest-timer-btn {
+ min-height: 48px;
+ border-radius: var(--radius-xl);
+ border: 1px solid var(--border);
+ font-weight: 600;
+ cursor: pointer;
+ transition: all var(--transition-base);
+}
+
+.rest-timer-btn.primary {
+ background: var(--accent);
+ color: white;
+ border-color: var(--accent);
+}
+
+.rest-timer-btn.primary:hover {
+ transform: translateY(-1px);
+ box-shadow: 0 8px 20px rgba(255, 107, 74, 0.25);
+}
+
+.rest-timer-btn.secondary {
+ background: var(--bg-card);
+ color: var(--text-secondary);
+}
+
+.rest-timer-presets {
+ display: flex;
+ flex-wrap: wrap;
+ gap: var(--space-2);
+}
+
+.rest-timer-chip {
+ padding: var(--space-2) var(--space-3);
+ background: var(--bg-card);
+ border-radius: var(--radius-full);
+ border: 1px solid var(--border);
+ font-size: var(--font-sm);
+ font-weight: 600;
+ cursor: pointer;
+ transition: all var(--transition-base);
+}
+
+.rest-timer-chip:hover {
+ border-color: var(--accent);
+ color: var(--accent);
}
/* Progress Bar */
@@ -1200,7 +1716,7 @@
height: 4px;
background: var(--border);
border-radius: 2px;
- margin-bottom: 1.5rem;
+ margin-bottom: var(--space-5);
overflow: hidden;
}
@@ -1208,29 +1724,33 @@
height: 100%;
background: linear-gradient(90deg, var(--accent), var(--success));
border-radius: 2px;
- transition: width 0.3s ease;
+ transition: width var(--transition-slow);
}
-/* Uppvärmningssektion */
+/* ============================================
+ WARMUP SECTION
+ ============================================ */
+
.warmup-section {
- background: var(--bg-secondary);
- border-radius: 16px;
+ background: var(--bg-card);
+ border-radius: var(--radius-xl);
border: 1px solid var(--border);
- margin-bottom: 1.5rem;
+ margin-bottom: var(--space-5);
overflow: hidden;
- transition: all 0.3s;
+ transition: all var(--transition-base);
+ box-shadow: var(--shadow-card);
}
.warmup-section.completed {
border-color: var(--success);
- background: rgba(78, 204, 163, 0.05);
+ background: var(--success-subtle);
}
.warmup-header {
display: flex;
justify-content: space-between;
align-items: center;
- padding: 1rem 1.25rem;
+ padding: var(--space-4) var(--space-5);
cursor: pointer;
user-select: none;
}
@@ -1238,7 +1758,7 @@
.warmup-title {
display: flex;
align-items: center;
- gap: 0.75rem;
+ gap: var(--space-3);
}
.warmup-icon {
@@ -1248,24 +1768,25 @@
}
.warmup-title h2 {
- font-size: 1.1rem;
+ font-size: var(--font-base);
font-weight: 600;
margin: 0;
}
.warmup-progress {
- background: var(--bg);
- padding: 0.25rem 0.6rem;
- border-radius: 12px;
- font-size: 0.8rem;
+ background: var(--bg-secondary);
+ padding: var(--space-1) var(--space-3);
+ border-radius: var(--radius-full);
+ font-size: var(--font-xs);
color: var(--text-muted);
+ font-weight: 500;
}
.expand-icon {
display: flex;
align-items: center;
color: var(--text-muted);
- transition: transform 0.2s;
+ transition: transform var(--transition-base);
}
.expand-icon.expanded {
@@ -1273,48 +1794,51 @@
}
.warmup-content {
- padding: 0 1.25rem 1.25rem;
+ padding: 0 var(--space-5) var(--space-5);
}
.warmup-category {
- margin-bottom: 1.25rem;
+ margin-bottom: var(--space-5);
}
.warmup-category:last-of-type {
- margin-bottom: 1rem;
+ margin-bottom: var(--space-4);
}
.warmup-category h3 {
- font-size: 0.85rem;
+ font-size: var(--font-sm);
color: var(--text-muted);
- margin-bottom: 0.75rem;
+ margin-bottom: var(--space-3);
font-weight: 500;
}
.warmup-list {
display: flex;
flex-direction: column;
- gap: 0.5rem;
+ gap: var(--space-2);
}
.warmup-item {
display: flex;
align-items: center;
- gap: 0.75rem;
- padding: 0.75rem;
- background: var(--bg);
- border-radius: 10px;
+ gap: var(--space-3);
+ padding: var(--space-3);
+ background: var(--bg-secondary);
+ border-radius: var(--radius-md);
cursor: pointer;
- transition: all 0.2s;
- min-height: 44px;
+ transition: all var(--transition-base);
+ min-height: 48px;
+ border: 1px solid transparent;
}
.warmup-item:hover {
- background: var(--bg-card-hover, var(--bg));
+ background: var(--bg-tertiary);
+ border-color: var(--border);
}
.warmup-item.done {
- background: rgba(78, 204, 163, 0.15);
+ background: var(--success-subtle);
+ border-color: rgba(34, 197, 94, 0.3);
}
.warmup-item.done .warmup-name {
@@ -1323,54 +1847,57 @@
}
.warmup-check {
- width: 24px;
- height: 24px;
+ width: 26px;
+ height: 26px;
+ min-width: 26px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
- background: var(--bg-secondary);
+ background: var(--bg-card);
color: var(--text-muted);
- font-size: 0.85rem;
+ font-size: var(--font-sm);
flex-shrink: 0;
+ border: 2px solid var(--border);
}
.warmup-item.done .warmup-check {
background: var(--success);
color: white;
+ border-color: var(--success);
}
.warmup-item-icon {
- font-size: 1.1rem;
+ font-size: var(--font-lg);
flex-shrink: 0;
}
.warmup-name {
flex: 1;
- font-size: 0.95rem;
+ font-size: var(--font-sm);
}
.warmup-duration {
- font-size: 0.85rem;
+ font-size: var(--font-sm);
color: var(--text-muted);
white-space: nowrap;
}
.warmup-done-btn {
width: 100%;
- padding: 1rem;
- background: var(--bg);
+ padding: var(--space-4);
+ background: var(--bg-secondary);
border: 2px dashed var(--border);
- border-radius: 12px;
+ border-radius: var(--radius-xl);
color: var(--text-muted);
- font-size: 0.95rem;
+ font-size: var(--font-sm);
cursor: pointer;
- transition: all 0.2s;
+ transition: all var(--transition-base);
display: flex;
align-items: center;
justify-content: center;
- gap: 0.5rem;
- min-height: 44px;
+ gap: var(--space-2);
+ min-height: 48px;
}
.warmup-done-btn:hover {
@@ -1383,23 +1910,26 @@
border: none;
color: white;
font-weight: 600;
+ border: 2px solid var(--success);
}
-/* Övningssektion */
+/* ============================================
+ EXERCISES SECTION
+ ============================================ */
+
.exercises-section {
- margin-bottom: 1.5rem;
+ margin-bottom: var(--space-5);
}
.exercises-section h2 {
- font-size: 1.1rem;
+ font-size: var(--font-base);
font-weight: 600;
- margin-bottom: 1rem;
+ margin-bottom: var(--space-4);
}
-/* Exercise Card utökad */
.exercise-card.all-done {
border-color: var(--success);
- background: rgba(78, 204, 163, 0.05);
+ background: var(--success-subtle);
}
.exercise-card.all-done .exercise-info h3::after {
@@ -1410,16 +1940,17 @@
/* Avsluta pass knapp */
.finish-workout-btn {
width: 100%;
- padding: 1.25rem;
- background: var(--bg-secondary);
+ padding: var(--space-4);
+ background: var(--bg-card);
border: 1px solid var(--border);
- border-radius: 16px;
+ border-radius: var(--radius-xl);
color: var(--text-muted);
- font-size: 1rem;
+ font-size: var(--font-base);
cursor: pointer;
- transition: all 0.2s;
- margin-top: 1rem;
- min-height: 44px;
+ transition: all var(--transition-base);
+ margin-top: var(--space-4);
+ min-height: 52px;
+ box-shadow: var(--shadow-card);
}
.finish-workout-btn:hover {
@@ -1433,33 +1964,42 @@
color: white;
font-weight: 600;
animation: pulse-glow 2s infinite;
+ box-shadow: 0 8px 24px rgba(99, 102, 241, 0.3);
}
@keyframes pulse-glow {
0%, 100% {
- box-shadow: 0 0 0 0 rgba(233, 69, 96, 0.4);
+ box-shadow: 0 8px 24px rgba(99, 102, 241, 0.3);
}
50% {
- box-shadow: 0 0 20px 5px rgba(233, 69, 96, 0.2);
+ box-shadow: 0 12px 32px rgba(99, 102, 241, 0.5);
}
}
/* Mobile optimeringar för WorkoutPage */
@media (max-width: 480px) {
.workout-page .page-header {
- padding: 0.75rem 1rem;
+ padding: var(--space-3) var(--space-4);
}
.workout-page .header-center h1 {
- font-size: 1rem;
+ font-size: var(--font-sm);
}
.warmup-item {
- padding: 0.6rem;
+ padding: var(--space-3);
}
.warmup-name {
- font-size: 0.9rem;
+ font-size: var(--font-sm);
+ }
+
+ .rest-timer-actions {
+ grid-template-columns: 1fr;
+ }
+
+ .set-controls {
+ grid-template-columns: 1fr;
}
}
@@ -1470,153 +2010,430 @@
.workout-list {
display: flex;
flex-direction: column;
- gap: 0.75rem;
+ gap: var(--space-3);
}
.workout-card.compact {
- padding: 1rem;
+ padding: var(--space-4);
}
.workout-card.compact .workout-card-header {
- margin-bottom: 0.5rem;
+ margin-bottom: var(--space-2);
}
.workout-card.compact .workout-card-header h3 {
- font-size: 1.1rem;
+ font-size: var(--font-base);
}
.workout-day {
- font-size: 0.8rem;
+ font-size: var(--font-xs);
color: var(--text-muted);
- background: var(--bg);
- padding: 0.25rem 0.5rem;
- border-radius: 4px;
+ background: var(--bg-secondary);
+ padding: var(--space-1) var(--space-2);
+ border-radius: var(--radius-sm);
+ border: 1px solid var(--border);
}
.workout-exercises.compact {
display: flex;
flex-wrap: wrap;
- gap: 0.5rem;
+ gap: var(--space-2);
margin-bottom: 0;
}
-.exercise-tag {
- background: var(--bg);
- padding: 0.25rem 0.5rem;
- border-radius: 4px;
- font-size: 0.75rem;
- color: var(--text-muted);
+/* ============================================
+ STEPPER INPUT COMPONENT
+ ============================================ */
+
+.stepper-wrapper {
+ display: flex;
+ flex-direction: column;
+ gap: var(--space-1);
+ width: 100%;
}
-.exercise-tag.more {
+.stepper-label {
+ font-size: var(--font-xs);
+ color: var(--text-muted);
+ font-weight: 500;
+ text-transform: uppercase;
+ letter-spacing: 0.5px;
+}
+
+.stepper-container {
+ display: flex;
+ align-items: center;
+ gap: var(--space-1);
+ background: var(--bg-card);
+ border-radius: var(--radius-md);
+ border: 1px solid var(--border);
+ padding: var(--space-1);
+ height: 52px;
+}
+
+.stepper-btn {
+ width: 44px;
+ height: 44px;
+ min-width: 44px;
+ min-height: 44px;
+ background: var(--bg-secondary);
+ border: none;
+ border-radius: var(--radius-sm);
+ color: var(--text-primary);
+ font-size: 1.4rem;
+ font-weight: 300;
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ transition: all var(--transition-base);
+ flex-shrink: 0;
+ line-height: 1;
+}
+
+.stepper-btn:hover:not(:disabled) {
background: var(--accent);
color: white;
+ box-shadow: 0 4px 12px rgba(255, 107, 74, 0.25);
+}
+
+.stepper-btn:active:not(:disabled) {
+ transform: scale(0.94);
+}
+
+.stepper-btn:disabled {
+ opacity: 0.35;
+ cursor: not-allowed;
+}
+
+.stepper-input-wrapper {
+ flex: 1;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: var(--space-1);
+ min-width: 0;
+}
+
+.stepper-input {
+ flex: 1;
+ min-width: 0;
+ background: transparent;
+ border: none;
+ color: var(--text-primary);
+ font-size: 16px;
+ font-weight: 600;
+ text-align: center;
+ padding: var(--space-2);
+ outline: none;
+ font-family: inherit;
+}
+
+.stepper-input:disabled {
+ opacity: 0.6;
+ cursor: not-allowed;
+}
+
+/* Remove browser native number spinners */
+.stepper-input::-webkit-outer-spin-button,
+.stepper-input::-webkit-inner-spin-button {
+ -webkit-appearance: none;
+ margin: 0;
+}
+
+.stepper-input[type='number'] {
+ -moz-appearance: textfield;
+}
+
+.input-suffix {
+ color: var(--text-muted);
+ font-size: var(--font-sm);
+ font-weight: 500;
+ white-space: nowrap;
+ flex-shrink: 0;
+}
+
+/* Mobile: slightly larger touch targets */
+@media (max-width: 480px) {
+ .stepper-container {
+ height: 56px;
+ }
+
+ .stepper-btn {
+ width: 48px;
+ height: 48px;
+ min-width: 48px;
+ min-height: 48px;
+ }
+}
+
+/* Add set button */
+.add-set-btn {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 100%;
+ min-height: 48px;
+ margin-top: var(--space-2);
+ padding: var(--space-3) var(--space-4);
+ background: transparent;
+ border: 1px dashed var(--border);
+ border-radius: var(--radius-md);
+ color: var(--text-secondary);
+ font-size: var(--font-sm);
+ font-weight: 500;
+ cursor: pointer;
+ transition: all var(--transition-base);
+}
+
+.add-set-btn:hover {
+ border-color: var(--accent);
+ color: var(--accent);
+}
+
+/* Delete set button */
+.delete-set-btn {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 36px;
+ min-height: 44px;
+ background: transparent;
+ border: none;
+ color: var(--text-secondary);
+ cursor: pointer;
+ opacity: 0.6;
+ transition: all var(--transition-base);
+ flex-shrink: 0;
+}
+
+.delete-set-btn:hover:not(:disabled) {
+ color: #e53e3e;
+ opacity: 1;
+}
+
+.delete-set-btn:disabled,
+.delete-set-btn.disabled {
+ opacity: 0.2;
+ cursor: not-allowed;
}
/* ============================================
- DASHBOARD COACH SECTION (redesigned)
+ SET TYPE MODAL
============================================ */
-.coach-section {
+.set-type-modal-overlay {
+ position: fixed;
+ inset: 0;
+ background: rgba(0, 0, 0, 0.6);
+ backdrop-filter: blur(4px);
display: flex;
- flex-direction: column;
- gap: 1rem;
-}
-
-.today-action {
- /* Container for workout card or rest tips */
-}
-
-.today-workout-card {
- display: flex;
- align-items: center;
- justify-content: space-between;
- background: linear-gradient(135deg, var(--accent) 0%, #6366f1 100%);
- border-radius: 16px;
- padding: 1.25rem;
- cursor: pointer;
- transition: all 0.2s;
- color: white;
-}
-
-.today-workout-card:hover {
- transform: translateY(-2px);
- box-shadow: 0 8px 20px rgba(99, 102, 241, 0.3);
-}
-
-.workout-info h3 {
- font-size: 1.25rem;
- font-weight: 600;
- margin-bottom: 0.25rem;
-}
-
-.workout-meta {
- font-size: 0.85rem;
- opacity: 0.9;
-}
-
-.workout-action {
- background: rgba(255,255,255,0.2);
- width: 48px;
- height: 48px;
- border-radius: 50%;
- display: flex;
- align-items: center;
+ align-items: flex-end;
justify-content: center;
+ z-index: 200;
+ padding-bottom: env(safe-area-inset-bottom, 0);
}
-.action-arrow {
- font-size: 1.5rem;
-}
-
-/* Rest Day Section */
-.rest-day-section {
+.set-type-modal {
+ background: var(--bg-card);
+ border-radius: var(--radius-2xl) var(--radius-2xl) 0 0;
+ padding: var(--space-6) var(--space-4) var(--space-8);
+ width: 100%;
+ max-width: 600px;
display: flex;
flex-direction: column;
- gap: 1rem;
+ gap: var(--space-3);
+ box-shadow: var(--shadow-xl);
}
-.rest-tips {
- display: flex;
- flex-wrap: wrap;
- gap: 0.5rem;
+.set-type-modal h3 {
+ font-size: var(--font-base);
+ font-weight: 600;
+ color: var(--text-primary);
+ margin: 0 0 var(--space-1);
+ text-align: center;
}
-.tip-badge {
+.set-type-option {
display: flex;
- align-items: center;
- gap: 0.4rem;
+ flex-direction: column;
+ align-items: flex-start;
+ gap: var(--space-1);
+ width: 100%;
+ min-height: 56px;
+ padding: var(--space-3) var(--space-4);
background: var(--bg-secondary);
border: 1px solid var(--border);
- padding: 0.5rem 0.75rem;
- border-radius: 20px;
- font-size: 0.85rem;
+ border-radius: var(--radius-md);
+ cursor: pointer;
+ text-align: left;
+ transition: all var(--transition-base);
}
-.add-workout-btn {
+.set-type-option strong {
+ font-size: var(--font-base);
+ color: var(--text-primary);
+}
+
+.set-type-option span {
+ font-size: var(--font-sm);
+ color: var(--text-secondary);
+}
+
+.set-type-option:hover {
+ border-color: var(--accent);
+ background: var(--bg-tertiary);
+}
+
+.set-type-option.dropset strong {
+ color: var(--accent);
+}
+
+.set-type-cancel {
+ width: 100%;
+ min-height: 48px;
+ padding: var(--space-3);
+ background: transparent;
+ border: none;
+ color: var(--text-secondary);
+ font-size: var(--font-sm);
+ cursor: pointer;
+ margin-top: var(--space-1);
+ transition: color var(--transition-base);
+}
+
+.set-type-cancel:hover {
+ color: var(--text-primary);
+}
+
+/* ============================================
+ ALTERNATIVE EXERCISES MODAL
+ ============================================ */
+
+.alternative-modal-overlay {
+ position: fixed;
+ inset: 0;
+ background: rgba(0, 0, 0, 0.55);
+ backdrop-filter: blur(4px);
display: flex;
+ align-items: flex-end;
+ justify-content: center;
+ z-index: 220;
+ padding-bottom: env(safe-area-inset-bottom, 0);
+}
+
+.alternative-modal {
+ background: var(--bg-card);
+ border-radius: var(--radius-2xl) var(--radius-2xl) 0 0;
+ padding: var(--space-5) var(--space-4) var(--space-7);
+ width: 100%;
+ max-width: 640px;
+ display: flex;
+ flex-direction: column;
+ gap: var(--space-3);
+ box-shadow: var(--shadow-xl);
+}
+
+.alternative-modal-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: flex-start;
+ gap: var(--space-3);
+}
+
+.alternative-modal-header h3 {
+ font-size: var(--font-base);
+ margin: 0 0 var(--space-1);
+ color: var(--text-primary);
+}
+
+.alternative-modal-header p {
+ margin: 0;
+ color: var(--text-secondary);
+ font-size: var(--font-sm);
+}
+
+.alternative-modal-close {
+ border: none;
+ background: var(--bg-secondary);
+ color: var(--text-secondary);
+ width: 36px;
+ height: 36px;
+ border-radius: var(--radius-full);
+ display: inline-flex;
align-items: center;
justify-content: center;
- gap: 0.5rem;
- background: var(--bg-secondary);
- border: 2px dashed var(--border);
- border-radius: 16px;
- padding: 1.25rem;
cursor: pointer;
- color: var(--text-muted);
- transition: all 0.2s;
- font-size: 1rem;
+ transition: all var(--transition-base);
}
-.add-workout-btn:hover {
- border-color: var(--accent);
- color: var(--accent);
- background: var(--bg);
+.alternative-modal-close:hover {
+ color: var(--text-primary);
+ background: var(--bg-tertiary);
}
-.add-icon {
- font-size: 1.5rem;
- font-weight: 300;
+.alternative-modal-state {
+ padding: var(--space-4);
+ text-align: center;
+ color: var(--text-secondary);
+ font-size: var(--font-sm);
+ background: var(--bg-secondary);
+ border-radius: var(--radius-md);
+ border: 1px solid var(--border);
+}
+
+.alternative-modal-state.error {
+ color: #e53e3e;
+}
+
+.alternative-list {
+ display: flex;
+ flex-direction: column;
+ gap: var(--space-3);
+}
+
+.alternative-item {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ gap: var(--space-3);
+ padding: var(--space-3) var(--space-4);
+ border: 1px solid var(--border);
+ border-radius: var(--radius-md);
+ background: var(--bg-secondary);
+}
+
+.alternative-info {
+ display: flex;
+ flex-direction: column;
+ gap: var(--space-1);
+}
+
+.alternative-info strong {
+ font-size: var(--font-sm);
+ color: var(--text-primary);
+}
+
+.alternative-info span {
+ font-size: var(--font-xs);
+ color: var(--text-secondary);
+}
+
+.alternative-select-btn {
+ min-width: 72px;
+ padding: var(--space-2) var(--space-3);
+ border: none;
+ border-radius: var(--radius-md);
+ background: var(--accent);
+ color: white;
+ font-size: var(--font-sm);
+ cursor: pointer;
+ transition: transform var(--transition-base), box-shadow var(--transition-base);
+}
+
+.alternative-select-btn:hover {
+ transform: translateY(-1px);
+ box-shadow: 0 4px 12px rgba(255, 107, 74, 0.25);
}
/* ============================================
@@ -1633,11 +2450,11 @@
flex-direction: column;
justify-content: center;
align-items: center;
- gap: 1rem;
+ gap: var(--space-4);
}
.select-main {
- padding: 1rem;
+ padding: var(--space-4);
max-width: 600px;
margin: 0 auto;
}
@@ -1645,47 +2462,51 @@
.select-intro {
text-align: center;
color: var(--text-muted);
- margin-bottom: 1.5rem;
- font-size: 1rem;
+ margin-bottom: var(--space-6);
+ font-size: var(--font-base);
}
.workout-grid {
display: flex;
flex-direction: column;
- gap: 1rem;
+ gap: var(--space-4);
}
.workout-select-card {
display: flex;
align-items: center;
- gap: 1rem;
- background: var(--bg-secondary);
+ gap: var(--space-4);
+ background: var(--bg-card);
border: 2px solid var(--border);
- border-radius: 16px;
- padding: 1rem;
+ border-radius: var(--radius-xl);
+ padding: var(--space-4);
cursor: pointer;
- transition: all 0.2s;
+ transition: all var(--transition-base);
position: relative;
+ box-shadow: var(--shadow-card);
}
.workout-select-card:hover {
border-color: var(--workout-color, var(--accent));
transform: translateX(4px);
+ box-shadow: var(--shadow-md);
}
.workout-select-card.selected {
border-color: var(--workout-color, var(--accent));
background: var(--bg);
+ box-shadow: 0 4px 16px rgba(255, 107, 74, 0.15);
}
.workout-icon {
width: 56px;
height: 56px;
- border-radius: 14px;
+ min-width: 56px;
+ border-radius: var(--radius-xl);
display: flex;
align-items: center;
justify-content: center;
- font-size: 1.5rem;
+ font-size: var(--font-xl);
flex-shrink: 0;
}
@@ -1694,33 +2515,34 @@
}
.workout-details h3 {
- font-size: 1.1rem;
+ font-size: var(--font-base);
font-weight: 600;
- margin-bottom: 0.25rem;
+ margin-bottom: var(--space-1);
}
.workout-exercises-count {
- font-size: 0.85rem;
+ font-size: var(--font-sm);
color: var(--text-muted);
- margin-bottom: 0.5rem;
+ margin-bottom: var(--space-2);
}
.workout-preview {
display: flex;
flex-wrap: wrap;
- gap: 0.25rem;
+ gap: var(--space-1);
}
.preview-exercise {
- font-size: 0.75rem;
+ font-size: var(--font-xs);
color: var(--text-muted);
- background: var(--bg);
- padding: 0.2rem 0.5rem;
- border-radius: 4px;
+ background: var(--bg-secondary);
+ padding: var(--space-1) var(--space-2);
+ border-radius: var(--radius-sm);
+ border: 1px solid var(--border);
}
.preview-more {
- font-size: 0.75rem;
+ font-size: var(--font-xs);
color: var(--accent);
}
@@ -1745,9 +2567,11 @@
bottom: 0;
left: 0;
right: 0;
- padding: 1rem;
+ padding: var(--space-4);
background: var(--bg);
border-top: 1px solid var(--border);
+ backdrop-filter: blur(12px);
+ -webkit-backdrop-filter: blur(12px);
}
.start-btn {
@@ -1755,287 +2579,382 @@
max-width: 600px;
margin: 0 auto;
display: block;
- padding: 1rem;
+ padding: var(--space-4);
background: var(--accent);
color: white;
border: none;
- border-radius: 12px;
- font-size: 1.1rem;
+ border-radius: var(--radius-xl);
+ font-size: var(--font-lg);
font-weight: 600;
cursor: pointer;
- transition: all 0.2s;
- min-height: 44px;
+ transition: all var(--transition-base);
+ min-height: 52px;
+ box-shadow: 0 4px 12px rgba(255, 107, 74, 0.3);
}
.start-btn:hover {
background: var(--accent-hover);
- transform: scale(1.02);
+ transform: translateY(-1px);
+ box-shadow: 0 6px 20px rgba(255, 107, 74, 0.4);
}
-/* ============================================
- GLOBAL INPUT ACCESSIBILITY
- Ensure all inputs have font-size >= 16px to prevent iOS auto-zoom
- ============================================ */
-
-input[type="text"],
-input[type="email"],
-input[type="password"],
-input[type="number"],
-input[type="tel"],
-select,
-textarea {
- font-size: 16px;
+.start-btn:active {
+ transform: translateY(0);
}
-/* ============================================
- STEPPER INPUT COMPONENT
- ============================================ */
+/* ============================================================
+ AUTH PAGES — Login / Register
+ ============================================================ */
-.stepper-wrapper {
+@keyframes authFadeIn {
+ from { opacity: 0; transform: translateY(16px); }
+ to { opacity: 1; transform: translateY(0); }
+}
+
+@keyframes errorShake {
+ 0%, 100% { transform: translateX(0); }
+ 20% { transform: translateX(-6px); }
+ 40% { transform: translateX(6px); }
+ 60% { transform: translateX(-4px); }
+ 80% { transform: translateX(4px); }
+}
+
+@keyframes errorFadeIn {
+ from { opacity: 0; transform: translateY(-4px); }
+ to { opacity: 1; transform: translateY(0); }
+}
+
+.auth-page {
+ min-height: 100vh;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: var(--space-6);
+ background:
+ radial-gradient(ellipse 80% 50% at 50% -10%, rgba(255, 107, 74, 0.12) 0%, transparent 60%),
+ var(--bg-primary);
+ animation: authFadeIn var(--transition-slow) ease both;
+}
+
+.auth-card {
+ width: 100%;
+ max-width: 400px;
+ background: var(--bg-card);
+ border: 1px solid var(--border-hover);
+ border-radius: var(--radius-2xl);
+ padding: var(--space-10) var(--space-8);
+ box-shadow: var(--shadow-xl), 0 0 40px rgba(255, 107, 74, 0.06);
display: flex;
flex-direction: column;
- gap: 0.4rem;
- width: 100%;
-}
-
-.stepper-label {
- font-size: 0.75rem;
- color: var(--text-muted);
- font-weight: 500;
- text-transform: uppercase;
- letter-spacing: 0.5px;
-}
-
-.stepper-container {
- display: flex;
align-items: center;
- gap: 0.25rem;
- background: var(--bg-card);
- border-radius: 8px;
- border: 1px solid var(--border);
- padding: 0.2rem;
- height: 48px;
+ gap: var(--space-4);
}
-.stepper-btn {
- width: 44px;
- height: 44px;
- min-width: 44px;
- min-height: 44px;
- background: var(--bg-secondary);
- border: none;
- border-radius: 6px;
- color: var(--text-primary);
- font-size: 1.4rem;
- font-weight: 300;
- cursor: pointer;
- display: flex;
- align-items: center;
- justify-content: center;
- transition: background 0.15s, color 0.15s;
+.logo-mark {
+ width: 56px;
+ height: 56px;
+ color: var(--accent);
+ filter: drop-shadow(0 0 10px var(--accent-glow));
flex-shrink: 0;
- line-height: 1;
}
-.stepper-btn:hover:not(:disabled) {
- background: var(--accent);
- color: white;
-}
-
-.stepper-btn:active:not(:disabled) {
- transform: scale(0.94);
-}
-
-.stepper-btn:disabled {
- opacity: 0.35;
- cursor: not-allowed;
-}
-
-.stepper-input-wrapper {
- flex: 1;
- display: flex;
- align-items: center;
- justify-content: center;
- gap: 0.25rem;
- min-width: 0;
-}
-
-.stepper-input {
- flex: 1;
- min-width: 0;
- background: transparent;
- border: none;
+.auth-title {
+ font-size: var(--font-2xl);
+ font-weight: 700;
color: var(--text-primary);
- font-size: 16px; /* >= 16px prevents iOS auto-zoom */
- font-weight: 600;
text-align: center;
- padding: 0.4rem 0.25rem;
- outline: none;
- font-family: inherit;
-}
-
-.stepper-input:disabled {
- opacity: 0.6;
- cursor: not-allowed;
-}
-
-/* Remove browser native number spinners */
-.stepper-input::-webkit-outer-spin-button,
-.stepper-input::-webkit-inner-spin-button {
- -webkit-appearance: none;
margin: 0;
}
-.stepper-input[type='number'] {
- -moz-appearance: textfield;
-}
-
-.input-suffix {
+.auth-tagline {
+ font-size: var(--font-sm);
color: var(--text-muted);
- font-size: 0.8rem;
- font-weight: 500;
- white-space: nowrap;
- flex-shrink: 0;
+ text-align: center;
+ margin: 0;
+ letter-spacing: 0.02em;
}
-/* Mobile: slightly larger touch targets */
-@media (max-width: 480px) {
- .stepper-container {
- height: 52px;
- }
-
- .stepper-btn {
- width: 48px;
- height: 48px;
- min-width: 48px;
- min-height: 48px;
- }
-}
-
-/* Add set button */
-.add-set-btn {
- display: flex;
- align-items: center;
- justify-content: center;
+.auth-card form {
width: 100%;
- min-height: 44px;
- margin-top: 0.5rem;
- padding: 0.5rem 1rem;
- background: transparent;
- border: 1px dashed var(--border);
- border-radius: 8px;
- color: var(--text-secondary);
- font-size: 0.875rem;
- font-weight: 500;
- cursor: pointer;
- transition: border-color 0.15s, color 0.15s;
-}
-
-.add-set-btn:hover {
- border-color: var(--accent);
- color: var(--accent);
-}
-
-/* Delete set button */
-.delete-set-btn {
display: flex;
- align-items: center;
- justify-content: center;
- width: 36px;
- min-height: 44px;
- background: transparent;
+ flex-direction: column;
+ gap: var(--space-3);
+ margin-top: var(--space-2);
+}
+
+.auth-card input[type="email"],
+.auth-card input[type="password"] {
+ width: 100%;
+ background: var(--bg-elevated);
+ border: 1.5px solid var(--border);
+ border-radius: var(--radius-xl);
+ padding: var(--space-4) var(--space-5);
+ color: var(--text-primary);
+ font-size: 16px; /* prevents iOS auto-zoom */
+ transition: border-color var(--transition-base), box-shadow var(--transition-base);
+}
+
+.auth-card input[type="email"]:focus,
+.auth-card input[type="password"]:focus {
+ border-color: var(--accent);
+ box-shadow: 0 0 0 3px var(--accent-subtle);
+ outline: none;
+}
+
+.auth-card input::placeholder {
+ color: var(--text-tertiary);
+}
+
+.auth-card button[type="submit"] {
+ width: 100%;
+ padding: var(--space-4);
+ background: var(--accent);
+ color: white;
border: none;
- color: var(--text-secondary);
+ border-radius: var(--radius-xl);
+ font-size: var(--font-base);
+ font-weight: 600;
cursor: pointer;
+ min-height: 52px;
+ margin-top: var(--space-2);
+ transition: background var(--transition-base), transform var(--transition-fast), box-shadow var(--transition-base);
+ box-shadow: 0 4px 14px rgba(255, 107, 74, 0.3);
+}
+
+.auth-card button[type="submit"]:hover:not(:disabled) {
+ background: var(--accent-hover);
+ transform: translateY(-1px);
+ box-shadow: 0 6px 20px rgba(255, 107, 74, 0.45);
+}
+
+.auth-card button[type="submit"]:active:not(:disabled) {
+ transform: translateY(0);
+ box-shadow: 0 2px 8px rgba(255, 107, 74, 0.3);
+}
+
+.auth-card button[type="submit"]:disabled {
opacity: 0.6;
- transition: opacity 0.15s, color 0.15s;
- flex-shrink: 0;
-}
-
-.delete-set-btn:hover:not(:disabled) {
- color: #e53e3e;
- opacity: 1;
-}
-
-.delete-set-btn:disabled,
-.delete-set-btn.disabled {
- opacity: 0.2;
cursor: not-allowed;
}
-/* Set type modal */
-.set-type-modal-overlay {
- position: fixed;
- inset: 0;
- background: rgba(0, 0, 0, 0.6);
- display: flex;
- align-items: flex-end;
- justify-content: center;
- z-index: 200;
- padding-bottom: env(safe-area-inset-bottom, 0);
-}
-
-.set-type-modal {
- background: var(--bg-card);
- border-radius: 16px 16px 0 0;
- padding: 1.5rem 1rem 2rem;
+.auth-error {
width: 100%;
- max-width: 600px;
- display: flex;
- flex-direction: column;
- gap: 0.75rem;
+ background: var(--error-subtle);
+ border: 1px solid rgba(239, 68, 68, 0.3);
+ border-radius: var(--radius-md);
+ padding: var(--space-3) var(--space-4);
+ color: #f87171;
+ font-size: var(--font-sm);
+ text-align: center;
+ animation: errorFadeIn var(--transition-base) ease both,
+ errorShake 400ms ease 100ms both;
}
-.set-type-modal h3 {
- font-size: 1rem;
- font-weight: 600;
- color: var(--text-primary);
- margin: 0 0 0.25rem;
+.auth-link {
+ font-size: var(--font-sm);
+ color: var(--text-muted);
text-align: center;
}
-.set-type-option {
- display: flex;
- flex-direction: column;
- align-items: flex-start;
- gap: 0.2rem;
- width: 100%;
- min-height: 56px;
- padding: 0.75rem 1rem;
- background: var(--bg-secondary);
- border: 1px solid var(--border);
- border-radius: 10px;
- cursor: pointer;
- text-align: left;
- transition: border-color 0.15s;
+.auth-link a {
+ color: var(--accent);
+ text-decoration: none;
+ font-weight: 500;
+ transition: color var(--transition-fast);
}
-.set-type-option strong {
- font-size: 1rem;
+.auth-link a:hover {
+ color: var(--accent-hover);
+ text-decoration: underline;
+}
+
+/* ============================================================
+ DASHBOARD ENHANCEMENTS — 03-02 Polish
+ ============================================================ */
+
+/* ── Header logo (smaller than auth page, no glow) ────────── */
+.brand-title .logo-mark {
+ width: 26px;
+ height: 26px;
+ color: var(--accent);
+ filter: none;
+}
+
+.brand-name {
+ font-size: var(--font-xl);
+ font-weight: 700;
+ letter-spacing: -0.4px;
color: var(--text-primary);
}
-.set-type-option span {
- font-size: 0.8rem;
- color: var(--text-secondary);
-}
-
-.set-type-option:hover {
- border-color: var(--accent);
-}
-
-.set-type-option.dropset strong {
+/* ── Nav active: subtle accent pill ──────────────────────── */
+.nav-btn.active {
+ background: var(--accent-subtle);
color: var(--accent);
}
-.set-type-cancel {
- width: 100%;
- min-height: 44px;
- padding: 0.75rem;
- background: transparent;
- border: none;
- color: var(--text-secondary);
- font-size: 0.9rem;
- cursor: pointer;
- margin-top: 0.25rem;
+/* ── Stat cards: gradient depth + per-card colour accent ── */
+.stat-card {
+ background: linear-gradient(160deg, var(--bg-card) 0%, var(--bg-tertiary) 100%);
+ border-top: 2px solid var(--border);
}
+
+.quick-stats .stat-card:nth-child(1) {
+ border-top-color: rgba(255, 107, 74, 0.5); /* accent/orange */
+}
+
+.quick-stats .stat-card:nth-child(2) {
+ border-top-color: rgba(34, 197, 94, 0.5); /* success/green */
+}
+
+.quick-stats .stat-card:nth-child(3) {
+ border-top-color: rgba(245, 158, 11, 0.5); /* warning/amber */
+}
+
+.stat-card:hover {
+ transform: translateY(-2px);
+ box-shadow: var(--shadow-md);
+ border-color: var(--border-hover);
+}
+
+/* ── Stat value: slightly larger for premium feel ──────── */
+.stat-value {
+ font-size: var(--font-3xl);
+ letter-spacing: -1px;
+}
+
+/* ── Calendar: pulsing glow on today cell ───────────────── */
+@keyframes todayGlow {
+ 0%, 100% { box-shadow: 0 4px 12px rgba(255, 107, 74, 0.30); }
+ 50% { box-shadow: 0 4px 22px rgba(255, 107, 74, 0.55),
+ 0 0 0 3px rgba(255, 107, 74, 0.12); }
+}
+
+.calendar-day.today {
+ animation: todayGlow 2.5s ease-in-out infinite;
+}
+
+/* ── Workout days (non-today): subtle brand tint ─────────── */
+.calendar-day.has-workout:not(.today) {
+ background: rgba(255, 107, 74, 0.06);
+ border: 1px solid rgba(255, 107, 74, 0.18);
+}
+
+.calendar-day.has-workout:not(.today):hover {
+ background: rgba(255, 107, 74, 0.12);
+ border-color: rgba(255, 107, 74, 0.35);
+}
+
+/* ── Day-dot: more visible ──────────────────────────────── */
+.day-dot {
+ width: 6px;
+ height: 6px;
+ background: var(--accent);
+ box-shadow: 0 0 6px rgba(255, 107, 74, 0.6);
+}
+
+.calendar-day.today .day-dot {
+ background: white;
+ box-shadow: 0 0 6px rgba(255,255,255,0.5);
+}
+
+/* ── Calendar day cells: tighter spacing, better font ────── */
+.calendar-day {
+ border-radius: var(--radius-xl);
+ gap: var(--space-1);
+ min-height: 64px;
+}
+
+.day-name {
+ letter-spacing: 0.6px;
+}
+
+/* ── Coach greeting: stronger shimmer on card ───────────── */
+.coach-greeting {
+ box-shadow: 0 8px 28px rgba(99, 102, 241, 0.28),
+ 0 2px 8px rgba(0,0,0,0.3);
+}
+
+/* ── Today workout card: arrow bounce on hover ──────────── */
+@keyframes arrowNudge {
+ 0%, 100% { transform: translateX(0); }
+ 50% { transform: translateX(4px); }
+}
+
+.today-workout-card:hover .workout-action {
+ animation: arrowNudge 0.6s ease infinite;
+}
+
+/* ── Workout card: stronger accent glow on hover ─────────── */
+.today-workout-card:hover {
+ box-shadow: 0 14px 36px rgba(99, 102, 241, 0.35),
+ 0 4px 12px rgba(0,0,0,0.3);
+}
+
+/* ── Dashboard main: slightly more generous spacing ──────── */
+.dashboard-main {
+ gap: var(--space-6);
+}
+
+/* ── Add-workout button: accent border on hover ──────────── */
+.add-workout-btn:hover {
+ border-color: var(--accent);
+ color: var(--accent);
+ background: var(--accent-subtle);
+}
+
+/* ── Section fade-in stagger on load ─────────────────────── */
+@keyframes sectionIn {
+ from { opacity: 0; transform: translateY(10px); }
+ to { opacity: 1; transform: translateY(0); }
+}
+
+.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; }
diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx
index dc089a6..3bf5f5f 100644
--- a/frontend/src/App.jsx
+++ b/frontend/src/App.jsx
@@ -5,6 +5,7 @@ import ProfilePage from './pages/ProfilePage'
import ProgressPage from './pages/ProgressPage'
import WorkoutPage from './pages/WorkoutPage'
import WorkoutSelectPage from './pages/WorkoutSelectPage'
+import ChatOnboarding from './pages/ChatOnboarding'
import './App.css'
const API_URL = '/api'
@@ -21,6 +22,10 @@ function App() {
const userId = user?.id || 1
const today = new Date().toISOString().split('T')[0]
+ if (user && !user.onboarding_complete) {
+ return
För {exercise.name}
+