endurance-coach 0.1.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/README.md +3 -0
  2. package/dist/cli.js +318 -35
  3. package/dist/expander/expander.d.ts +20 -0
  4. package/dist/expander/expander.js +339 -0
  5. package/dist/expander/index.d.ts +8 -0
  6. package/dist/expander/index.js +9 -0
  7. package/dist/expander/types.d.ts +169 -0
  8. package/dist/expander/types.js +6 -0
  9. package/dist/expander/zones.d.ts +50 -0
  10. package/dist/expander/zones.js +159 -0
  11. package/dist/index.d.ts +4 -0
  12. package/dist/index.js +9 -1
  13. package/dist/schema/compact-plan.d.ts +175 -0
  14. package/dist/schema/compact-plan.js +64 -0
  15. package/dist/schema/compact-plan.schema.d.ts +277 -0
  16. package/dist/schema/compact-plan.schema.js +205 -0
  17. package/dist/templates/index.d.ts +10 -0
  18. package/dist/templates/index.js +13 -0
  19. package/dist/templates/interpolate.d.ts +51 -0
  20. package/dist/templates/interpolate.js +204 -0
  21. package/dist/templates/loader.d.ts +19 -0
  22. package/dist/templates/loader.js +129 -0
  23. package/dist/templates/template.schema.d.ts +401 -0
  24. package/dist/templates/template.schema.js +101 -0
  25. package/dist/templates/template.types.d.ts +155 -0
  26. package/dist/templates/template.types.js +7 -0
  27. package/dist/templates/yaml-parser.d.ts +15 -0
  28. package/dist/templates/yaml-parser.js +18 -0
  29. package/package.json +2 -1
  30. package/templates/bike/CLAUDE.md +7 -0
  31. package/templates/bike/easy.yaml +38 -0
  32. package/templates/bike/endurance.yaml +42 -0
  33. package/templates/bike/hills.yaml +80 -0
  34. package/templates/bike/overunders.yaml +81 -0
  35. package/templates/bike/rest.yaml +16 -0
  36. package/templates/bike/sweetspot.yaml +80 -0
  37. package/templates/bike/tempo.yaml +79 -0
  38. package/templates/bike/threshold.yaml +83 -0
  39. package/templates/bike/vo2max.yaml +84 -0
  40. package/templates/brick/CLAUDE.md +7 -0
  41. package/templates/brick/halfironman.yaml +72 -0
  42. package/templates/brick/ironman.yaml +72 -0
  43. package/templates/brick/olympic.yaml +70 -0
  44. package/templates/brick/sprint.yaml +70 -0
  45. package/templates/plan-viewer.html +22 -22
  46. package/templates/run/CLAUDE.md +7 -0
  47. package/templates/run/easy.yaml +36 -0
  48. package/templates/run/fartlek.yaml +40 -0
  49. package/templates/run/hills.yaml +36 -0
  50. package/templates/run/intervals.1k.yaml +63 -0
  51. package/templates/run/intervals.400.yaml +63 -0
  52. package/templates/run/intervals.800.yaml +63 -0
  53. package/templates/run/intervals.mile.yaml +64 -0
  54. package/templates/run/long.yaml +41 -0
  55. package/templates/run/progression.yaml +49 -0
  56. package/templates/run/race.5k.yaml +36 -0
  57. package/templates/run/recovery.yaml +36 -0
  58. package/templates/run/rest.yaml +16 -0
  59. package/templates/run/strides.yaml +49 -0
  60. package/templates/run/tempo.yaml +56 -0
  61. package/templates/run/threshold.yaml +56 -0
  62. package/templates/strength/CLAUDE.md +7 -0
  63. package/templates/strength/core.yaml +56 -0
  64. package/templates/strength/foundation.yaml +65 -0
  65. package/templates/strength/full.yaml +73 -0
  66. package/templates/strength/maintenance.yaml +62 -0
  67. package/templates/swim/CLAUDE.md +7 -0
  68. package/templates/swim/aerobic.yaml +67 -0
  69. package/templates/swim/easy.yaml +51 -0
  70. package/templates/swim/openwater.yaml +60 -0
  71. package/templates/swim/rest.yaml +16 -0
  72. package/templates/swim/technique.yaml +67 -0
  73. package/templates/swim/threshold.yaml +75 -0
  74. package/templates/swim/vo2max.yaml +88 -0
  75. /package/bin/{claude-coach.js → endurance-coach.js} +0 -0
@@ -0,0 +1,56 @@
1
+ id: threshold
2
+ name: Threshold Run
3
+ sport: run
4
+ type: threshold
5
+ category: threshold
6
+
7
+ params:
8
+ threshold_mins:
9
+ type: int
10
+ required: true
11
+ default: 20
12
+ min: 10
13
+ max: 40
14
+ description: Duration of threshold section in minutes
15
+ warmup_mins:
16
+ type: int
17
+ default: 15
18
+ description: Warmup duration in minutes
19
+ cooldown_mins:
20
+ type: int
21
+ default: 10
22
+ description: Cooldown duration in minutes
23
+
24
+ structure:
25
+ warmup:
26
+ - type: warmup
27
+ name: Easy warmup
28
+ duration: "${warmup_mins}min"
29
+ pace: "${paces.easy}"
30
+ main:
31
+ - type: work
32
+ name: Threshold
33
+ duration: "${threshold_mins}min"
34
+ pace: "${paces.threshold}"
35
+ intensity: Zone 4
36
+ cooldown:
37
+ - type: cooldown
38
+ name: Easy cooldown
39
+ duration: "${cooldown_mins}min"
40
+ pace: "${paces.easy}"
41
+
42
+ humanReadable: |
43
+ THRESHOLD RUN
44
+
45
+ WARM-UP: ${warmup_mins} min easy @ ${paces.easy}
46
+
47
+ MAIN SET:
48
+ ${threshold_mins} min @ threshold pace (${paces.threshold})
49
+ This is your ~1 hour race pace. Hard but sustainable.
50
+
51
+ COOL-DOWN: ${cooldown_mins} min easy
52
+
53
+ estimatedDuration: "${warmup_mins + threshold_mins + cooldown_mins}"
54
+ targetZone: Z4
55
+ rpe: "7-8"
56
+ notes: Improves lactate threshold
@@ -0,0 +1,7 @@
1
+ <claude-mem-context>
2
+ # Recent Activity
3
+
4
+ <!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
5
+
6
+ _No recent activity_
7
+ </claude-mem-context>
@@ -0,0 +1,56 @@
1
+ id: strength.core
2
+ name: Core Session
3
+ sport: strength
4
+ type: core
5
+ category: strength
6
+
7
+ params:
8
+ duration:
9
+ type: int
10
+ required: true
11
+ default: 15
12
+ min: 10
13
+ max: 25
14
+ description: Duration in minutes
15
+
16
+ structure:
17
+ main:
18
+ - type: work
19
+ name: Core circuit
20
+ duration: "${duration}min"
21
+ description: "2-3 rounds through all exercises"
22
+ exercises:
23
+ - "Plank x 45-60s"
24
+ - "Side plank x 30s each side"
25
+ - "Dead bug x 12 each side"
26
+ - "Bird dog x 10 each side"
27
+ - "Bicycle crunches x 20"
28
+ - "Hollow hold x 30s"
29
+
30
+ humanReadable: |
31
+ CORE SESSION - ${duration} minutes
32
+
33
+ CIRCUIT (2-3 rounds):
34
+ - Plank x 45-60 seconds
35
+ - Side plank x 30s each side
36
+ - Dead bug x 12 each side
37
+ - Bird dog x 10 each side
38
+ - Bicycle crunches x 20
39
+ - Hollow hold x 30 seconds
40
+
41
+ Minimal rest between exercises.
42
+ 90s rest between rounds.
43
+
44
+ Focus on quality:
45
+ - Neutral spine in planks
46
+ - Controlled movement in dead bugs
47
+ - No rocking in bird dogs
48
+ - Full extension in hollow holds
49
+
50
+ Can be done after any easy workout
51
+ or as a standalone session.
52
+
53
+ estimatedDuration: "${duration}"
54
+ targetZone: "-"
55
+ rpe: "5"
56
+ notes: Core stability and injury prevention
@@ -0,0 +1,65 @@
1
+ id: strength.foundation
2
+ name: Foundation Strength
3
+ sport: strength
4
+ type: strength
5
+ category: strength
6
+
7
+ params:
8
+ duration:
9
+ type: int
10
+ required: true
11
+ default: 30
12
+ min: 20
13
+ max: 45
14
+ description: Duration in minutes
15
+
16
+ structure:
17
+ warmup:
18
+ - type: warmup
19
+ name: Light cardio + dynamic stretches
20
+ duration: 5min
21
+ description: "Jump rope, high knees, arm circles"
22
+ main:
23
+ - type: work
24
+ name: Bodyweight circuit
25
+ duration: "${duration - 10}min"
26
+ description: "2-3 sets x 12-15 reps"
27
+ exercises:
28
+ - "Squats x 15"
29
+ - "Push-ups x 12"
30
+ - "Lunges x 10 each leg"
31
+ - "Plank x 45s"
32
+ - "Glute bridges x 15"
33
+ - "Bird dogs x 10 each side"
34
+ cooldown:
35
+ - type: cooldown
36
+ name: Stretching
37
+ duration: 5min
38
+
39
+ humanReadable: |
40
+ FOUNDATION STRENGTH - ${duration} minutes
41
+
42
+ WARM-UP: 5 min light cardio + dynamic stretches
43
+ - Jump rope or jumping jacks
44
+ - High knees, butt kicks
45
+ - Arm circles, leg swings
46
+
47
+ MAIN CIRCUIT (2-3 rounds):
48
+ - Squats x 15
49
+ - Push-ups x 12 (modify as needed)
50
+ - Lunges x 10 each leg
51
+ - Plank x 45 seconds
52
+ - Glute bridges x 15
53
+ - Bird dogs x 10 each side
54
+
55
+ Rest 30-60s between rounds.
56
+
57
+ COOL-DOWN: 5 min static stretching
58
+
59
+ Focus on movement quality over speed.
60
+ Perfect for beginners or base phase training.
61
+
62
+ estimatedDuration: "${duration}"
63
+ targetZone: "-"
64
+ rpe: "4-5"
65
+ notes: Base phase - bodyweight, movement patterns
@@ -0,0 +1,73 @@
1
+ id: strength.full
2
+ name: Full Strength Session
3
+ sport: strength
4
+ type: strength
5
+ category: strength
6
+
7
+ params:
8
+ duration:
9
+ type: int
10
+ required: true
11
+ default: 45
12
+ min: 35
13
+ max: 60
14
+ description: Duration in minutes
15
+
16
+ structure:
17
+ warmup:
18
+ - type: warmup
19
+ name: Light cardio + activation
20
+ duration: 5min
21
+ description: "Light cardio, dynamic stretches, band activation"
22
+ main:
23
+ - type: work
24
+ name: Strength circuit 1
25
+ duration: 15min
26
+ description: "3-4 sets x 6-8 reps, moderate load"
27
+ exercises:
28
+ - "Goblet squats x 10"
29
+ - "Push-ups x 12"
30
+ - "Single-leg Romanian deadlift x 8 each"
31
+ - type: work
32
+ name: Strength circuit 2
33
+ duration: 15min
34
+ exercises:
35
+ - "Lat pulldown x 10"
36
+ - "Step-ups x 10 each leg"
37
+ - "Plank x 45s"
38
+ cooldown:
39
+ - type: cooldown
40
+ name: Stretching
41
+ duration: 5min
42
+
43
+ humanReadable: |
44
+ FULL STRENGTH SESSION - ${duration} minutes
45
+
46
+ WARM-UP: 5 min light cardio + activation
47
+ - 2 min easy cardio (bike, row, or skip)
48
+ - Dynamic stretches
49
+ - Band activation (glutes, shoulders)
50
+
51
+ CIRCUIT 1 (3 rounds):
52
+ - Goblet squats x 10
53
+ - Push-ups x 12
54
+ - Single-leg Romanian deadlift x 8 each
55
+
56
+ Rest 60s between rounds.
57
+
58
+ CIRCUIT 2 (3 rounds):
59
+ - Lat pulldown x 10 (or band pull-aparts x 15)
60
+ - Step-ups x 10 each leg
61
+ - Plank x 45s
62
+
63
+ Rest 60s between rounds.
64
+
65
+ COOL-DOWN: 5 min stretching
66
+
67
+ Use moderate weight - last 2 reps should be challenging
68
+ but form should remain solid.
69
+
70
+ estimatedDuration: "${duration}"
71
+ targetZone: "-"
72
+ rpe: "6-7"
73
+ notes: Build phase - moderate load, compound movements
@@ -0,0 +1,62 @@
1
+ id: strength.maintenance
2
+ name: Maintenance Strength
3
+ sport: strength
4
+ type: strength
5
+ category: strength
6
+
7
+ params:
8
+ duration:
9
+ type: int
10
+ required: true
11
+ default: 20
12
+ min: 15
13
+ max: 30
14
+ description: Duration in minutes
15
+
16
+ structure:
17
+ warmup:
18
+ - type: warmup
19
+ name: Quick activation
20
+ duration: 3min
21
+ description: "Light movement, band work"
22
+ main:
23
+ - type: work
24
+ name: Maintenance circuit
25
+ duration: "${duration - 6}min"
26
+ description: "2 sets x 8-10 reps, light weight"
27
+ exercises:
28
+ - "Squats x 10 (bodyweight or light)"
29
+ - "Push-ups x 10"
30
+ - "Lunges x 8 each"
31
+ - "Plank x 30s"
32
+ - "Glute bridges x 12"
33
+ cooldown:
34
+ - type: cooldown
35
+ name: Light stretching
36
+ duration: 3min
37
+
38
+ humanReadable: |
39
+ MAINTENANCE STRENGTH - ${duration} minutes
40
+
41
+ WARM-UP: 3 min quick activation
42
+
43
+ CIRCUIT (2 rounds only):
44
+ - Squats x 10 (bodyweight or light)
45
+ - Push-ups x 10
46
+ - Lunges x 8 each leg
47
+ - Plank x 30 seconds
48
+ - Glute bridges x 12
49
+
50
+ Minimal rest between exercises.
51
+ 2-3 min rest between rounds.
52
+
53
+ COOL-DOWN: 3 min light stretching
54
+
55
+ This is about maintaining strength, not building.
56
+ Perfect for race week or taper periods.
57
+ Keep it light and short.
58
+
59
+ estimatedDuration: "${duration}"
60
+ targetZone: "-"
61
+ rpe: "3-4"
62
+ notes: Taper/race week - maintain without fatigue
@@ -0,0 +1,7 @@
1
+ <claude-mem-context>
2
+ # Recent Activity
3
+
4
+ <!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
5
+
6
+ _No recent activity_
7
+ </claude-mem-context>
@@ -0,0 +1,67 @@
1
+ id: swim.aerobic
2
+ name: Aerobic Endurance Swim
3
+ sport: swim
4
+ type: endurance
5
+ category: threshold
6
+
7
+ params:
8
+ reps:
9
+ type: int
10
+ required: true
11
+ default: 5
12
+ min: 3
13
+ max: 8
14
+ description: Number of 400m repeats
15
+ rest_secs:
16
+ type: int
17
+ default: 20
18
+ description: Rest between 400m repeats in seconds
19
+
20
+ structure:
21
+ warmup:
22
+ - type: warmup
23
+ name: Easy swim with drills
24
+ description: "300m easy, 4x50m drills"
25
+ duration: 10min
26
+ intensity: Zone 1-2
27
+ main:
28
+ - type: intervals
29
+ repeats: "${reps}"
30
+ work:
31
+ type: work
32
+ name: 400m @ CSS+10s
33
+ distance: 400m
34
+ pace: "${paces.css} + 10s/100m"
35
+ intensity: Zone 2
36
+ recovery:
37
+ type: recovery
38
+ name: Rest
39
+ duration: "${rest_secs}s"
40
+ cooldown:
41
+ - type: cooldown
42
+ name: Easy pull
43
+ distance: 200m
44
+ pace: Very easy
45
+ intensity: Zone 1
46
+
47
+ humanReadable: |
48
+ AEROBIC ENDURANCE SWIM
49
+
50
+ WARM-UP: 300m easy, 4x50m drills (catch-up, fingertip drag)
51
+
52
+ MAIN SET:
53
+ ${reps} x 400m @ CSS+10s/100m
54
+ Pace: ${paces.css} + 10 seconds per 100m
55
+ Rest: ${rest_secs}s between each 400m
56
+
57
+ Hold a steady, sustainable pace.
58
+ Focus on stroke consistency and breathing rhythm.
59
+
60
+ COOL-DOWN: 200m easy pull
61
+
62
+ Total: ~${300 + (reps * 400) + 200}m
63
+
64
+ estimatedDuration: "${10 + (reps * 8) + 5}"
65
+ targetZone: Z2
66
+ rpe: "5-6"
67
+ notes: Builds aerobic capacity with longer intervals
@@ -0,0 +1,51 @@
1
+ id: swim.easy
2
+ name: Easy Swim
3
+ sport: swim
4
+ type: endurance
5
+ category: endurance
6
+
7
+ params:
8
+ duration:
9
+ type: int
10
+ required: true
11
+ default: 30
12
+ min: 15
13
+ max: 90
14
+ description: Duration in minutes
15
+
16
+ structure:
17
+ warmup:
18
+ - type: warmup
19
+ name: Easy freestyle
20
+ duration: 5min
21
+ pace: Easy
22
+ intensity: Zone 1
23
+ main:
24
+ - type: work
25
+ name: Continuous swim
26
+ duration: "${duration - 10}min"
27
+ pace: "${paces.swim_easy}"
28
+ intensity: Zone 2
29
+ cooldown:
30
+ - type: cooldown
31
+ name: Easy cooldown
32
+ duration: 5min
33
+ pace: Very easy
34
+ intensity: Zone 1
35
+
36
+ humanReadable: |
37
+ EASY SWIM - ${duration} minutes
38
+
39
+ WARM-UP: 5 min easy freestyle
40
+
41
+ MAIN SET:
42
+ ${duration - 10} min continuous swimming @ Zone 2
43
+ Pace: ${paces.swim_easy}
44
+ Focus on smooth, relaxed technique.
45
+
46
+ COOL-DOWN: 5 min very easy
47
+
48
+ estimatedDuration: "${duration}"
49
+ targetZone: Z2
50
+ rpe: "3-4"
51
+ notes: Aerobic base building, technique focus
@@ -0,0 +1,60 @@
1
+ id: swim.openwater
2
+ name: Open Water Swim
3
+ sport: swim
4
+ type: endurance
5
+ category: endurance
6
+
7
+ params:
8
+ duration:
9
+ type: int
10
+ required: true
11
+ default: 45
12
+ min: 20
13
+ max: 120
14
+ description: Duration in minutes
15
+
16
+ structure:
17
+ warmup:
18
+ - type: warmup
19
+ name: Pool warm-up
20
+ description: "If starting in pool: 200m easy with sighting drills"
21
+ duration: 5min
22
+ intensity: Zone 1
23
+ main:
24
+ - type: work
25
+ name: Continuous open water swim
26
+ duration: "${duration - 10}min"
27
+ pace: "${paces.swim_easy}"
28
+ intensity: Zone 2-3
29
+ description: "Include sighting every 8-10 strokes, bilateral breathing"
30
+ cooldown:
31
+ - type: cooldown
32
+ name: Easy finish
33
+ duration: 5min
34
+ pace: Very easy
35
+ intensity: Zone 1
36
+
37
+ humanReadable: |
38
+ OPEN WATER SWIM - ${duration} minutes
39
+
40
+ WARM-UP: 5 min easy (pool or gentle OW entry)
41
+
42
+ MAIN SET:
43
+ ${duration - 10} min continuous open water swimming
44
+ Pace: ${paces.swim_easy} (Zone 2-3)
45
+
46
+ Focus areas:
47
+ - Sight every 8-10 strokes (head up, quick look)
48
+ - Practice bilateral breathing
49
+ - Navigate to fixed landmarks
50
+ - Adjust for currents/conditions
51
+
52
+ COOL-DOWN: 5 min easy
53
+
54
+ Safety: Always swim with a buddy or in supervised areas.
55
+ Consider using a swim buoy for visibility.
56
+
57
+ estimatedDuration: "${duration}"
58
+ targetZone: Z2-Z3
59
+ rpe: "5-6"
60
+ notes: Open water skills - sighting, navigation, conditions
@@ -0,0 +1,16 @@
1
+ id: swim.rest
2
+ name: Rest Day
3
+ sport: swim
4
+ type: rest
5
+ category: rest
6
+
7
+ humanReadable: |
8
+ REST DAY
9
+
10
+ Take the day off from swimming. Focus on recovery, sleep, and nutrition.
11
+ Light stretching or foam rolling optional.
12
+
13
+ estimatedDuration: 0
14
+ targetZone: "-"
15
+ rpe: "1"
16
+ notes: Complete rest from structured training
@@ -0,0 +1,67 @@
1
+ id: swim.technique
2
+ name: Technique Swim
3
+ sport: swim
4
+ type: technique
5
+ category: technique
6
+
7
+ params:
8
+ duration:
9
+ type: int
10
+ required: true
11
+ default: 45
12
+ min: 30
13
+ max: 75
14
+ description: Duration in minutes
15
+
16
+ structure:
17
+ warmup:
18
+ - type: warmup
19
+ name: Easy swim
20
+ duration: 5min
21
+ pace: Easy
22
+ intensity: Zone 1
23
+ main:
24
+ - type: work
25
+ name: Drill set
26
+ description: "6-8 x 50m drill/swim alternating, 15s rest"
27
+ duration: "${(duration - 15) / 2}min"
28
+ intensity: Zone 1-2
29
+ - type: work
30
+ name: Technique focus
31
+ description: "Focus on catch, pull, rotation"
32
+ duration: "${(duration - 15) / 2}min"
33
+ pace: "${paces.swim_easy}"
34
+ intensity: Zone 2
35
+ cooldown:
36
+ - type: cooldown
37
+ name: Easy swim
38
+ duration: 5min
39
+ pace: Very easy
40
+ intensity: Zone 1
41
+
42
+ humanReadable: |
43
+ TECHNIQUE SWIM - ${duration} minutes
44
+
45
+ WARM-UP: 5 min easy
46
+
47
+ MAIN SET:
48
+ Drill/Swim Alternating (6-8 x 50m, 15s rest):
49
+ - Catch-up drill
50
+ - Fingertip drag
51
+ - Single-arm freestyle
52
+ - Full stroke with focus
53
+
54
+ Focus on:
55
+ - High elbow catch
56
+ - Hip rotation
57
+ - Relaxed recovery
58
+
59
+ COOL-DOWN: 5 min easy
60
+
61
+ This is a quality-over-quantity session.
62
+ Keep effort low, focus on form improvements.
63
+
64
+ estimatedDuration: "${duration}"
65
+ targetZone: Z1-Z2
66
+ rpe: "3-4"
67
+ notes: Drill-focused session for form improvement
@@ -0,0 +1,75 @@
1
+ id: swim.threshold
2
+ name: Threshold Swim
3
+ sport: swim
4
+ type: threshold
5
+ category: threshold
6
+
7
+ params:
8
+ reps:
9
+ type: int
10
+ required: true
11
+ default: 10
12
+ min: 6
13
+ max: 16
14
+ description: Number of 100m repeats at CSS pace
15
+ rest_secs:
16
+ type: int
17
+ default: 10
18
+ description: Rest between 100m repeats in seconds
19
+
20
+ structure:
21
+ warmup:
22
+ - type: warmup
23
+ name: Easy swim
24
+ distance: 400m
25
+ duration: 8min
26
+ pace: Easy
27
+ intensity: Zone 1
28
+ - type: warmup
29
+ name: Build set
30
+ description: "4x50m build 1-4"
31
+ duration: 5min
32
+ intensity: Zone 1-3
33
+ main:
34
+ - type: intervals
35
+ repeats: "${reps}"
36
+ work:
37
+ type: work
38
+ name: 100m @ CSS
39
+ distance: 100m
40
+ pace: "${paces.css}"
41
+ intensity: Zone 4
42
+ recovery:
43
+ type: recovery
44
+ name: Rest
45
+ duration: "${rest_secs}s"
46
+ cooldown:
47
+ - type: cooldown
48
+ name: Easy swim
49
+ distance: 200m
50
+ pace: Very easy
51
+ intensity: Zone 1
52
+
53
+ humanReadable: |
54
+ THRESHOLD SWIM
55
+
56
+ WARM-UP:
57
+ - 400m easy
58
+ - 4 x 50m build (1-4)
59
+
60
+ MAIN SET:
61
+ ${reps} x 100m @ CSS pace
62
+ Pace: ${paces.css}/100m
63
+ Rest: ${rest_secs}s between each
64
+
65
+ Maintain consistent pace throughout.
66
+ This is "comfortably hard" - sustainable but challenging.
67
+
68
+ COOL-DOWN: 200m easy
69
+
70
+ Total: ~${400 + 200 + (reps * 100) + 200}m
71
+
72
+ estimatedDuration: "${13 + (reps * 2) + 4}"
73
+ targetZone: Z4
74
+ rpe: "7"
75
+ notes: Develops lactate threshold at CSS pace