If i am just running everyday will it improve my running or not

Running every day (without variation) will give you some improvement at first, but will plateau quickly and may lead to overtraining or injury. Here's the core issue:
Your body adapts to the same stimulus. Once it adapts, the same run at the same pace and distance stops being a meaningful training stress. You stop improving.

What Actually Drives Running Improvement

To keep improving, you need to manipulate these variables:

1. Progressive Overload

Gradually increase distance, duration, or frequency over weeks. The common rule: increase weekly mileage by no more than 10% per week.

2. Variety of Effort (Intensity Zones)

Running the same easy pace every day is the #1 reason people plateau. You need:
Run TypePurpose% of Weekly Runs
Easy / recovery runsBuild aerobic base, recover70-80%
Tempo runsImprove lactate threshold10-15%
Intervals / speedworkBoost VO2 max5-10%
Long runsBuild endurance, fat adaptation1x/week

3. Rest and Recovery

Improvement happens during rest, not during the run. Running breaks down muscle fibers; rest rebuilds them stronger. Running 7 days a week with no easy or rest days leads to:
  • Accumulated fatigue
  • Overuse injuries (shin splints, stress fractures, tendinopathy)
  • Stagnation or performance decline

4. Cross-Training

Cycling, swimming, or strength training on some days reduces injury risk and builds supporting muscles, which directly helps running economy.

Practical Weekly Template (Beginner - Intermediate)

DaySession
MondayEasy run (30-40 min)
TuesdayIntervals (e.g., 6x400m at hard effort)
WednesdayRest or cross-training
ThursdayTempo run (20-30 min at comfortably hard pace)
FridayEasy run or rest
SaturdayLong run (45-90 min easy)
SundayFull rest or walk

Bottom Line

  • Short term (0-3 months): Just running daily will improve you if you're a beginner - any stimulus works when you're untrained.
  • Medium/long term: You must add variety, progressive overload, and recovery or you will stall and risk injury.
  • The best runners train with structure - not just volume.
If you tell me your current level (beginner/intermediate), weekly mileage, and goal (5K, 10K, marathon, general fitness), I can give you a more specific plan.

How do I know if I'm overtraining vs building fitness?

My goal is 1600m in 4.5-5.0minutes

Great context. A 4:30-5:00 for 1600m is a serious speed goal - that's a sub-5 mile pace. Here's everything you need:

Overtraining vs. Building Fitness: How to Tell

The key difference is how you feel after 24-48 hours of rest.
SignalBuilding FitnessOvertraining
FatigueTired after hard sessions, recovered next dayTired all the time, even after rest days
PerformanceGradually improving over weeksDeclining or flatlined despite more effort
SleepNormal or slightly deeperDisrupted, restless, or sleeping too much
MoodMotivated, occasional tirednessIrritable, anxious, low motivation, dread runs
Resting heart rateStableElevated 5-10+ BPM above normal
SorenessLocalized, fades in 24-48hPersistent, widespread, doesn't go away
IllnessRareFrequent colds, infections (suppressed immunity)
AppetiteNormal to increasedSuppressed or abnormally increased

The Simplest Self-Test

Check your resting heart rate (RHR) every morning before getting out of bed. If it's 7+ BPM above your baseline for 2-3 days in a row, you're not recovered - back off.

The "3 Hard Days" Rule for Your Goal

For 1600m speed, you never need more than 3 hard sessions per week. Everything else should be easy. Most runners overtrain by running moderately hard every day - that zone is too hard to recover from quickly, too easy to stimulate real speed adaptation.

Targeted Training Plan for 4:30-5:00 1600m

Your target pace: 4:30/km - 4:42/km (roughly 68-70 sec per 400m for 4:30 goal)

What You Need to Develop

  1. Speed - raw leg turnover for 400m repeats
  2. Lactate threshold - sustain fast pace without slowing
  3. VO2 max - aerobic engine ceiling
  4. Running economy - efficiency at speed

Weekly Structure (4-5 days running)

DaySessionDetails
MondaySpeed intervals8-10 x 200m at faster than goal pace (e.g. 35-38 sec per 200m), 90 sec rest
TuesdayEasy run25-35 min at comfortable conversational pace
WednesdayThreshold run3 x 1000m at goal race pace (4:30-5:00/km), 2 min rest
ThursdayRest or easy walkFull recovery
FridayVO2 max intervals5 x 400m at slightly faster than race pace, 2-3 min rest
SaturdayEasy run + strides30 min easy + 4-6 x 80m accelerations
SundayFull restNo running

Signs This Plan Is Working (4-8 weeks)

  • Your 200m intervals start feeling easier at the same pace
  • Your resting HR drops slightly over weeks
  • A time trial 1600m improves by 10-20 seconds per month

How to Know You're Overtraining With This Goal Specifically

Since 1600m is a high-intensity event, watch for:
  • Your intervals getting slower week over week even though you're trying hard - classic sign
  • Legs feeling "heavy" or "dead" on what should be easy days
  • You can't hit your target split times anymore, when you could before
If that happens: Take 5-7 days of only easy jogging or rest. You will come back faster - this is called supercompensation.

Current Fitness Check

Do a 400m time trial at max effort. Your result maps roughly to:
400m timeProjected 1600m
60-65 sec~4:30-4:45
65-70 sec~4:45-5:10
70-75 sec~5:15-5:40
This tells you how far you are from your goal and whether you need more speed work or endurance work first.
What's your current 1600m or 400m time? That'll help me tell you exactly where to focus.

1600 time is 7minutes

Good baseline. 7:00 for 1600m means you're currently running about 105 sec per 400m. Your goal is 68-75 sec per 400m. That's a 30-40 second improvement per lap - significant, but very achievable with structured training over 3-6 months.

Reality Check on the Goal

CurrentGoalGap
1600m time7:004:30-5:002:00-2:30 faster
Per 400m~105 sec68-75 sec~30-37 sec/lap
Per km pace4:22/km2:49-3:08/km...
Wait - let me recalculate. 7:00 for 1600m = 4:22/km pace. Your goal of 4:30-5:00 min for 1600m = 2:49-3:08/km pace.
That's actually running 1600m in 4.5-5 minutes total - that's an elite-level target (sub-5 minute mile). That's a massive jump from 7 minutes.
Are you aiming for 1600m in 4:30-5:00 minutes total, or a per-km pace of 4:30-5:00?
  • If total time of 4:30-5:00 = sub-5 minute mile, that's world-class amateur / competitive athlete level
  • If 5:00/km pace for 1600m = finishing in ~8:00, that's more realistic from 7:00

Assuming You Mean Total Time 4:30-5:00 for 1600m

This is doable but will take 6-12 months of serious training. Here's your roadmap:

Phase 1: Build Your Aerobic Base (Weeks 1-6)

Your aerobic engine is the limiter right now. Without this, speed work won't stick.
DaySession
MonEasy 20-30 min (comfortable, can talk)
Tue6 x 400m at current 1600m pace (105 sec each), 90 sec rest
WedRest
ThuEasy 25 min + 4 strides (80m fast accelerations)
FriRest
Sat3 x 600m at slightly faster than 1600m pace, 2 min rest
SunRest

Phase 2: Build Speed (Weeks 7-14)

Once easy runs feel genuinely easy and 400m reps improve:
DaySession
MonEasy 30 min
Tue8 x 200m at target pace (85-90 sec per 400m effort), 60 sec rest
WedEasy 25 min
Thu4 x 400m at 90-95 sec, 2 min rest
FriRest
Sat2 x 800m at 3:10-3:20, 3 min rest
SunRest

Phase 3: Race-Specific (Weeks 15-20)

Now you're training at or near goal pace:
  • 6-8 x 300m at goal pace (51-56 sec), full 3 min rest
  • 1 x 1200m time trial monthly to track progress
  • Reduce volume, sharpen speed

Realistic Milestone Timeline

MonthExpected 1600m Time
Now7:00
Month 26:20-6:30
Month 45:45-6:00
Month 65:10-5:30
Month 9-124:30-5:00 (goal)

Overtraining Warning Signs Specific to Your Level

Since you're building from 7:00, your biggest risks are:
  1. Too much too soon - adding intervals before your easy runs feel genuinely easy
  2. Running hard every day - at your current fitness, 2 hard days + rest is plenty
  3. Skipping the easy pace - easy means 6:00-7:00/km, not 5:00/km
One simple rule: If your 400m reps are getting slower each week, you're not recovering enough. Cut one session and add a rest day.
Want me to build out a full 12-week week-by-week plan?

I was following a running plan which was given by a insta athlete but recently he stop the series His workouts was like Monday long run 35 , 40,50 alternatively Tuesday recovery run wed intervals Thu recovery run Fri hard run Sat long run Sun rest

That plan has a solid structure but has one big problem for your specific goal - let me break it down.

Analysis of the Instagram Plan

DaySessionVerdict
MonLong run 35/40/50 min✅ Good for aerobic base
TueRecovery run✅ Smart after long run
WedIntervals✅ Best session of the week
ThuRecovery run✅ Fine
FriHard run⚠️ Vague - what kind of hard?
SatLong run❌ Problem (see below)
SunRest

The Problem: Two Long Runs Per Week

Monday long run + Saturday long run = too much volume for a 1600m goal. Long runs build endurance for 5K, 10K, half marathons. For 1600m speed, you need one long run max and more quality speed work instead.
Also, "hard run" on Friday is vague and dangerous placed right before a Saturday long run - you'd be going into your long run already fatigued.

Your Upgraded Plan (Built on His Framework)

Same skeleton, fixed for your 1600m goal:
DaySessionDetails
MonLong run35 min easy (Week 1), 40 min (Week 2), 45 min (Week 3) - conversational pace
TueRecovery run20-25 min very easy, legs loosening only
WedIntervalsThe most important session (see below)
ThuRecovery run20 min easy OR full rest if legs feel heavy
FriSpeed sessionSpecific 200m/400m reps (not just "hard run")
SatStrides + easy20 min easy + 6 x 80m fast accelerations
SunFull restNo running

Wednesday Intervals - Progression (Most Important)

This is where you get faster. Cycle through these:
WeekSession
1-26 x 400m at current pace (105 sec), 90 sec rest
3-48 x 400m at 100 sec, 90 sec rest
5-66 x 400m at 95 sec, 2 min rest
7-85 x 600m at 95 sec/400m effort, 2 min rest
9-104 x 800m at 3:15-3:20, 3 min rest

Friday Speed Session - Progression

WeekSession
1-28 x 200m at 48-50 sec, 60 sec rest
3-410 x 200m at 46-48 sec, 60 sec rest
5-66 x 300m at 72-75 sec, 90 sec rest
7-84 x 400m at 88-92 sec, 2 min rest
9-103 x 600m at 2:15-2:20, 2 min rest

How to Know It's Working

Do a solo 1600m time trial every 4 weeks. You should drop roughly:
  • 30-45 sec by week 4
  • 60-90 sec by week 8
  • 2+ min by week 16-20
If you're not dropping time, the intervals aren't fast enough - push the pace on Wednesday and Friday sessions.

One Rule to Replace the Instagram Series

80/20 rule: 80% of your running should feel easy (you can hold a conversation). Only 20% should be hard. Most runners who plateau are running 60-70% at a "medium" effort - too hard to recover from, too easy to build speed. Cut the medium. Go easier on easy days so you can go harder on hard days.
Want me to write out the full 12-week plan week by week with exact times and distances?

Create a 12-week training plan with exact paces and splits for 1600m

Reading File
Now let me build the full plan and generate a PDF.
Running Command

mkdir -p /tmp/workspace/running-plan && ls /tmp/workspace/running-plan/

Writing File

~/running-plan/generate_plan.py

from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import mm, cm
from reportlab.platypus import (
    SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
    HRFlowable, PageBreak, KeepTogether
)
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_RIGHT
from reportlab.platypus import BaseDocTemplate, Frame, PageTemplate

OUTPUT = "/tmp/workspace/running-plan/1600m_12week_plan.pdf"

# ── Colours ──────────────────────────────────────────────────────────────────
C_DARK   = colors.HexColor("#1A1A2E")
C_BLUE   = colors.HexColor("#16213E")
C_ACCENT = colors.HexColor("#E94560")
C_GOLD   = colors.HexColor("#F5A623")
C_GREEN  = colors.HexColor("#27AE60")
C_LIGHT  = colors.HexColor("#ECF0F1")
C_MID    = colors.HexColor("#BDC3C7")
C_WHITE  = colors.white
C_EASY   = colors.HexColor("#D5F5E3")   # green tint
C_HARD   = colors.HexColor("#FADBD8")   # red tint
C_INTER  = colors.HexColor("#D6EAF8")   # blue tint
C_REST   = colors.HexColor("#F2F3F4")   # grey

doc = SimpleDocTemplate(
    OUTPUT,
    pagesize=A4,
    rightMargin=15*mm, leftMargin=15*mm,
    topMargin=15*mm, bottomMargin=15*mm,
    title="12-Week 1600m Training Plan",
    author="Orris Training"
)

styles = getSampleStyleSheet()

def S(name, **kw):
    return ParagraphStyle(name, **kw)

title_style = S("Title2", fontSize=26, textColor=C_WHITE,
                fontName="Helvetica-Bold", alignment=TA_CENTER, spaceAfter=4)
sub_style   = S("Sub",    fontSize=13, textColor=C_GOLD,
                fontName="Helvetica-Bold", alignment=TA_CENTER, spaceAfter=2)
body_style  = S("Body2",  fontSize=9,  textColor=C_DARK,
                fontName="Helvetica", leading=13, spaceAfter=4)
h1_style    = S("H1",     fontSize=14, textColor=C_WHITE,
                fontName="Helvetica-Bold", alignment=TA_CENTER, spaceAfter=3)
h2_style    = S("H2",     fontSize=11, textColor=C_ACCENT,
                fontName="Helvetica-Bold", spaceAfter=3, spaceBefore=6)
note_style  = S("Note",   fontSize=8,  textColor=colors.HexColor("#555555"),
                fontName="Helvetica-Oblique", leading=11)
cell_style  = S("Cell",   fontSize=8,  textColor=C_DARK,
                fontName="Helvetica", leading=10)
cell_bold   = S("CellB",  fontSize=8,  textColor=C_DARK,
                fontName="Helvetica-Bold", leading=10)
cell_head   = S("CellH",  fontSize=8,  textColor=C_WHITE,
                fontName="Helvetica-Bold", leading=10, alignment=TA_CENTER)
phase_style = S("Phase",  fontSize=10, textColor=C_WHITE,
                fontName="Helvetica-Bold", alignment=TA_CENTER)

# ── Helper: coloured banner ───────────────────────────────────────────────────
def banner(text, bg=C_BLUE, style=h1_style, pad=6):
    tbl = Table([[Paragraph(text, style)]], colWidths=[180*mm])
    tbl.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,-1), bg),
        ("TOPPADDING",  (0,0), (-1,-1), pad),
        ("BOTTOMPADDING",(0,0),(-1,-1), pad),
        ("LEFTPADDING", (0,0), (-1,-1), 8),
        ("RIGHTPADDING",(0,0), (-1,-1), 8),
        ("ROUNDEDCORNERS", [4]),
    ]))
    return tbl

# ── Pace reference table ──────────────────────────────────────────────────────
def pace_table():
    headers = ["Run Type", "Effort Feel", "Pace (per km)", "Heart Rate"]
    rows = [
        ["Easy / Recovery", "Can hold full conversation", "6:30 – 7:30 /km", "60–70% max HR"],
        ["Aerobic / Long",  "Comfortable, slight effort", "6:00 – 6:30 /km", "65–75% max HR"],
        ["Tempo",           "Comfortably hard, can't talk", "5:00 – 5:30 /km","80–87% max HR"],
        ["Interval (1600m pace)", "Hard, race effort", "4:22 /km (current)", "88–95% max HR"],
        ["Speed / 200m reps","Very fast, near sprint",    "3:45 – 4:00 /km", "95–100% max HR"],
    ]
    col_w = [40*mm, 52*mm, 46*mm, 42*mm]
    data = [[Paragraph(h, cell_head) for h in headers]]
    bg_cycle = [C_EASY, C_INTER, C_HARD]
    for i, r in enumerate(rows):
        data.append([Paragraph(r[0], cell_bold)] +
                    [Paragraph(x, cell_style) for x in r[1:]])
    tbl = Table(data, colWidths=col_w, repeatRows=1)
    ts = TableStyle([
        ("BACKGROUND",    (0,0), (-1,0),  C_DARK),
        ("ROWBACKGROUNDS",(0,1), (-1,-1), [C_EASY, C_LIGHT, C_INTER, C_LIGHT, C_HARD]),
        ("GRID",          (0,0), (-1,-1), 0.5, C_MID),
        ("TOPPADDING",    (0,0), (-1,-1), 4),
        ("BOTTOMPADDING", (0,0), (-1,-1), 4),
        ("LEFTPADDING",   (0,0), (-1,-1), 5),
        ("VALIGN",        (0,0), (-1,-1), "MIDDLE"),
    ])
    tbl.setStyle(ts)
    return tbl

# ── Weekly schedule builder ───────────────────────────────────────────────────
DAY_COLS = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]

def week_table(week_num, phase, sessions, note=""):
    """sessions = list of 7 dicts: {label, detail, color}"""
    header_data = [
        Paragraph(f"WEEK {week_num}", cell_head),
        Paragraph(f"Phase: {phase}", cell_head),
        Paragraph(note, cell_head),
    ]
    # Day header row
    day_row = [Paragraph(d, cell_head) for d in DAY_COLS]
    # Content row
    content_row = []
    row_bg = []
    for s in sessions:
        txt = f"<b>{s['label']}</b><br/><font size=7>{s['detail']}</font>"
        content_row.append(Paragraph(txt, cell_style))
        row_bg.append(s.get("color", C_LIGHT))

    col_w = [180*mm / 7] * 7
    data = [day_row, content_row]
    tbl = Table(data, colWidths=col_w)
    ts = TableStyle([
        ("BACKGROUND",    (0,0), (-1,0), C_BLUE),
        ("GRID",          (0,0), (-1,-1), 0.4, C_MID),
        ("TOPPADDING",    (0,0), (-1,-1), 4),
        ("BOTTOMPADDING", (0,0), (-1,-1), 4),
        ("LEFTPADDING",   (0,0), (-1,-1), 3),
        ("VALIGN",        (0,0), (-1,-1), "TOP"),
        ("FONTSIZE",      (0,0), (-1,-1), 7.5),
    ])
    for i, c in enumerate(row_bg):
        ts.add("BACKGROUND", (i,1), (i,1), c)
    tbl.setStyle(ts)

    # Week header
    hdr = Table([[
        Paragraph(f"WEEK {week_num}", cell_bold),
        Paragraph(f"Phase: {phase}", cell_style),
        Paragraph(note, note_style),
    ]], colWidths=[25*mm, 60*mm, 95*mm])
    hdr.setStyle(TableStyle([
        ("BACKGROUND",    (0,0), (-1,-1), C_ACCENT),
        ("TEXTCOLOR",     (0,0), (-1,-1), C_WHITE),
        ("TOPPADDING",    (0,0), (-1,-1), 3),
        ("BOTTOMPADDING", (0,0), (-1,-1), 3),
        ("LEFTPADDING",   (0,0), (-1,-1), 6),
        ("VALIGN",        (0,0), (-1,-1), "MIDDLE"),
    ]))
    return [hdr, tbl, Spacer(1, 4*mm)]

# ── Define all 12 weeks ───────────────────────────────────────────────────────
E  = C_EASY    # easy
H  = C_HARD    # hard
I  = C_INTER   # intervals
R  = C_REST    # rest/recovery
T  = colors.HexColor("#FDEBD0")  # tempo / orange tint

def w(label, detail, color=C_LIGHT):
    return {"label": label, "detail": detail, "color": color}

WEEKS = [
    # ── PHASE 1: Aerobic Base (Weeks 1-4) ────────────────────────────────────
    {
        "week": 1, "phase": "Aerobic Base",
        "note": "Build easy mileage. All runs feel comfortable.",
        "sessions": [
            w("Long Run","35 min @ 6:30-7:00/km\nConversational", E),
            w("Recovery","20 min @ 7:00-7:30/km\nVery easy", R),
            w("Intervals","6 x 400m @ 1:45\n(4:22/km pace)\nRest: 90 sec jog", I),
            w("Recovery","20 min @ 7:00-7:30/km", R),
            w("Strides","20 min easy +\n6 x 80m strides\n(relaxed fast)", E),
            w("Long Run","35 min @ 6:30-7:00/km", E),
            w("REST","Full rest or\n10 min walk", R),
        ]
    },
    {
        "week": 2, "phase": "Aerobic Base",
        "note": "Repeat Week 1 structure. Push interval pace slightly.",
        "sessions": [
            w("Long Run","40 min @ 6:30/km", E),
            w("Recovery","20 min @ 7:00/km", R),
            w("Intervals","6 x 400m @ 1:42\nRest: 90 sec jog", I),
            w("Recovery","20 min easy", R),
            w("Speed","8 x 200m @ 50 sec\nRest: 60 sec", H),
            w("Easy Run","30 min @ 6:30/km", E),
            w("REST","Full rest", R),
        ]
    },
    {
        "week": 3, "phase": "Aerobic Base",
        "note": "Increase interval volume. Easy days stay easy.",
        "sessions": [
            w("Long Run","40 min @ 6:20/km", E),
            w("Recovery","25 min @ 7:00/km", R),
            w("Intervals","8 x 400m @ 1:42\nRest: 90 sec jog", I),
            w("Recovery","20 min easy", R),
            w("Speed","10 x 200m @ 49 sec\nRest: 60 sec", H),
            w("Easy Run","30 min +\n4 x 80m strides", E),
            w("REST","Full rest", R),
        ]
    },
    {
        "week": 4, "phase": "Aerobic Base – Deload",
        "note": "⬇ Deload week. Cut volume 30%. Let body absorb training.",
        "sessions": [
            w("Easy Run","30 min @ 6:30/km\nLight effort", E),
            w("Recovery","20 min @ 7:00/km", R),
            w("Intervals","5 x 400m @ 1:42\nRest: 2 min", I),
            w("REST","Full rest", R),
            w("Speed","6 x 200m @ 50 sec\nRest: 90 sec", H),
            w("Easy Run","25 min easy", E),
            w("REST","Full rest", R),
        ]
    },
    # ── PHASE 2: Speed Development (Weeks 5-8) ───────────────────────────────
    {
        "week": 5, "phase": "Speed Development",
        "note": "TIME TRIAL on Wed. Note your 1600m time.",
        "sessions": [
            w("Long Run","40 min @ 6:00-6:30/km", E),
            w("Recovery","25 min @ 7:00/km", R),
            w("TIME TRIAL","1600m solo TT\nWarm up 10 min\nGoal: beat 7:00\nCool down 10 min", H),
            w("Recovery","20 min very easy", R),
            w("Speed","6 x 300m @ 1:12\n(4:00/km pace)\nRest: 2 min", H),
            w("Easy Run","35 min +\n4 strides", E),
            w("REST","Full rest", R),
        ]
    },
    {
        "week": 6, "phase": "Speed Development",
        "note": "Focus: faster 200m reps. Full rest between sets.",
        "sessions": [
            w("Long Run","45 min @ 6:00/km", E),
            w("Recovery","25 min easy", R),
            w("Intervals","6 x 400m @ 1:38\n(target: 1:35 in 2 wks)\nRest: 2 min", I),
            w("Recovery","20 min easy", R),
            w("Speed","8 x 200m @ 47 sec\nRest: 75 sec", H),
            w("Easy Run","30 min easy", E),
            w("REST","Full rest", R),
        ]
    },
    {
        "week": 7, "phase": "Speed Development",
        "note": "Introduce 600m reps. Pace = current 1600m race effort.",
        "sessions": [
            w("Long Run","45 min @ 6:00/km", E),
            w("Recovery","25 min easy", R),
            w("Intervals","5 x 600m @ 2:35\n(4:18/km pace)\nRest: 2.5 min", I),
            w("Recovery","20 min easy", R),
            w("Speed","6 x 300m @ 1:10\nRest: 2 min", H),
            w("Easy Run","30 min +\n6 strides", E),
            w("REST","Full rest", R),
        ]
    },
    {
        "week": 8, "phase": "Speed Dev – Deload",
        "note": "⬇ Deload. Reduce volume 30%. Keep intensity.",
        "sessions": [
            w("Easy Run","30 min @ 6:30/km", E),
            w("Recovery","20 min easy", R),
            w("Intervals","4 x 600m @ 2:33\nRest: 2.5 min", I),
            w("REST","Full rest", R),
            w("Speed","5 x 200m @ 46 sec\nRest: 90 sec", H),
            w("Easy Run","25 min easy", E),
            w("REST","Full rest", R),
        ]
    },
    # ── PHASE 3: Race-Specific (Weeks 9-12) ──────────────────────────────────
    {
        "week": 9, "phase": "Race-Specific",
        "note": "TIME TRIAL. Target: 6:00-6:20. Push hard.",
        "sessions": [
            w("Long Run","40 min @ 5:50/km", E),
            w("Recovery","25 min easy", R),
            w("TIME TRIAL","1600m solo TT\nTarget: sub 6:20\nWarm up 10 min", H),
            w("Recovery","20 min very easy", R),
            w("Intervals","4 x 800m @ 3:20\n(4:10/km pace)\nRest: 3 min", I),
            w("Easy Run","30 min +\n4 strides", E),
            w("REST","Full rest", R),
        ]
    },
    {
        "week": 10, "phase": "Race-Specific",
        "note": "Peak training week. Hardest volume of the plan.",
        "sessions": [
            w("Long Run","45 min @ 5:45/km", E),
            w("Recovery","25 min easy", R),
            w("Intervals","6 x 400m @ 1:30\n(3:45/km pace)\nRest: 2 min", I),
            w("Recovery","20 min easy", R),
            w("Tempo","3 x 1000m @ 4:40/km\nRest: 2.5 min", T),
            w("Easy Run","30 min easy +\n6 strides", E),
            w("REST","Full rest", R),
        ]
    },
    {
        "week": 11, "phase": "Race-Specific",
        "note": "Sharpen speed. Reps shorter, faster, fully rested.",
        "sessions": [
            w("Easy Run","35 min @ 6:00/km", E),
            w("Recovery","20 min easy", R),
            w("Intervals","8 x 300m @ 1:07\n(3:44/km pace)\nRest: 2.5 min", I),
            w("Recovery","20 min easy", R),
            w("Speed","4 x 400m @ 1:28\nRest: 3 min\n(near goal pace)", H),
            w("Easy Run","25 min easy", E),
            w("REST","Full rest", R),
        ]
    },
    {
        "week": 12, "phase": "PEAK & TEST WEEK",
        "note": "⬇ Taper. Fresh legs. TIME TRIAL on Sat — go for your best.",
        "sessions": [
            w("Easy Run","25 min @ 6:30/km\nFeel fresh", E),
            w("Recovery","15 min very easy", R),
            w("Sharpener","4 x 200m @ 44 sec\nFull 3 min rest\nFeel fast, not tired", I),
            w("REST","Full rest\nStay off feet", R),
            w("Strides Only","10 min easy +\n4 x 80m strides", E),
            w("TIME TRIAL","RACE DAY\n1600m Full Effort\nWarm up 15 min\nTarget: sub 5:30", H),
            w("REST","Celebrate &\nrecover", R),
        ]
    },
]

# ── Progress milestones table ─────────────────────────────────────────────────
def milestones_table():
    headers = ["Week", "Time Trial", "Target 1600m", "Key Fitness Marker"]
    rows = [
        ["1",   "—",          "Baseline: 7:00",  "Completing 6x400m without stopping"],
        ["4",   "—",          "Est. 6:30-6:45",  "Easy runs feel genuinely easy"],
        ["5",   "✓ TT",       "Target: sub 6:30","400m reps at 1:42 feel manageable"],
        ["8",   "—",          "Est. 6:00-6:15",  "600m reps holding 4:15-4:20/km"],
        ["9",   "✓ TT",       "Target: sub 6:20","800m reps at 3:20 completed"],
        ["12",  "✓ RACE DAY", "Target: sub 5:30","All reps faster than Week 1 by 15+ sec"],
    ]
    col_w = [15*mm, 25*mm, 50*mm, 90*mm]
    data = [[Paragraph(h, cell_head) for h in headers]]
    for i, r in enumerate(rows):
        bg = C_HARD if "TT" in r[1] or "RACE" in r[1] else C_LIGHT
        data.append([Paragraph(x, cell_bold if i==5 else cell_style) for x in r])
    tbl = Table(data, colWidths=col_w, repeatRows=1)
    ts = TableStyle([
        ("BACKGROUND",    (0,0), (-1,0),  C_DARK),
        ("ROWBACKGROUNDS",(0,1), (-1,-1), [C_LIGHT, C_LIGHT, C_HARD, C_LIGHT, C_HARD, C_EASY]),
        ("GRID",          (0,0), (-1,-1), 0.5, C_MID),
        ("TOPPADDING",    (0,0), (-1,-1), 4),
        ("BOTTOMPADDING", (0,0), (-1,-1), 4),
        ("LEFTPADDING",   (0,0), (-1,-1), 5),
        ("VALIGN",        (0,0), (-1,-1), "MIDDLE"),
    ])
    tbl.setStyle(ts)
    return tbl

# ── Overtraining signals table ────────────────────────────────────────────────
def overtraining_table():
    headers = ["Signal", "OK (Building)", "Warning (Overtraining)"]
    rows = [
        ["Resting HR (morning)", "Stable / slightly lower", "+7 BPM above baseline 2+ days"],
        ["Energy on easy runs",  "Comfortable, relaxed",    "Legs heavy, effort feels harder"],
        ["Interval performance", "Same or improving",       "Splits getting slower each week"],
        ["Sleep",                "Normal to deeper",        "Disrupted, waking at night"],
        ["Mood",                 "Motivated",               "Dreading runs, irritable"],
        ["Recovery time",        "Sore for 24-36 hrs",     "Still sore after 48+ hrs"],
    ]
    col_w = [45*mm, 65*mm, 70*mm]
    data = [[Paragraph(h, cell_head) for h in headers]]
    for r in rows:
        data.append([Paragraph(r[0], cell_bold), Paragraph(r[1], cell_style), Paragraph(r[2], cell_style)])
    tbl = Table(data, colWidths=col_w, repeatRows=1)
    ts = TableStyle([
        ("BACKGROUND",    (0,0), (-1,0),  C_DARK),
        ("ROWBACKGROUNDS",(0,1), (-1,-1), [C_EASY, C_LIGHT]),
        ("GRID",          (0,0), (-1,-1), 0.5, C_MID),
        ("TOPPADDING",    (0,0), (-1,-1), 4),
        ("BOTTOMPADDING", (0,0), (-1,-1), 4),
        ("LEFTPADDING",   (0,0), (-1,-1), 5),
        ("VALIGN",        (0,0), (-1,-1), "MIDDLE"),
    ])
    tbl.setStyle(ts)
    return tbl

# ── Build document ────────────────────────────────────────────────────────────
story = []

# ── Cover header ──────────────────────────────────────────────────────────────
cover = Table([[
    Paragraph("12-WEEK 1600m TRAINING PLAN", title_style),
    Paragraph("Current: 7:00  →  Goal: Sub 5:30", sub_style),
    Paragraph("Starting pace: 4:22/km  |  Target: 3:26/km  |  Phases: 3", 
              S("sub2", fontSize=10, textColor=C_MID, fontName="Helvetica",
                alignment=TA_CENTER)),
]], colWidths=[180*mm])
cover.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,-1), C_DARK),
    ("TOPPADDING",    (0,0), (-1,-1), 12),
    ("BOTTOMPADDING", (0,0), (-1,-1), 12),
    ("ALIGN",         (0,0), (-1,-1), "CENTER"),
]))
story.append(cover)
story.append(Spacer(1, 6*mm))

# ── Pace Legend ───────────────────────────────────────────────────────────────
story.append(banner("PACE REFERENCE GUIDE", C_BLUE))
story.append(Spacer(1, 2*mm))
story.append(pace_table())
story.append(Spacer(1, 4*mm))

# ── Colour key ────────────────────────────────────────────────────────────────
key_data = [
    [Paragraph("COLOUR KEY:", cell_bold),
     Paragraph("  Easy / Long Run", S("ck", fontSize=8, backColor=C_EASY, fontName="Helvetica")),
     Paragraph("  Intervals / Speed", S("ck2", fontSize=8, backColor=C_INTER, fontName="Helvetica")),
     Paragraph("  Hard / Time Trial", S("ck3", fontSize=8, backColor=C_HARD, fontName="Helvetica")),
     Paragraph("  Tempo", S("ck4", fontSize=8, backColor=T, fontName="Helvetica")),
     Paragraph("  Rest / Recovery", S("ck5", fontSize=8, backColor=C_REST, fontName="Helvetica")),
    ]
]
key_tbl = Table(key_data, colWidths=[25*mm, 32*mm, 36*mm, 34*mm, 24*mm, 29*mm])
key_tbl.setStyle(TableStyle([
    ("BACKGROUND", (1,0),(1,0), C_EASY),
    ("BACKGROUND", (2,0),(2,0), C_INTER),
    ("BACKGROUND", (3,0),(3,0), C_HARD),
    ("BACKGROUND", (4,0),(4,0), T),
    ("BACKGROUND", (5,0),(5,0), C_REST),
    ("TOPPADDING",    (0,0),(-1,-1), 4),
    ("BOTTOMPADDING", (0,0),(-1,-1), 4),
    ("LEFTPADDING",   (0,0),(-1,-1), 4),
    ("VALIGN",        (0,0),(-1,-1), "MIDDLE"),
]))
story.append(key_tbl)
story.append(Spacer(1, 5*mm))

# ── Phase banners + weeks ─────────────────────────────────────────────────────
phase_defs = [
    (1, 4,  "PHASE 1: AEROBIC BASE",        "Build mileage and running economy. Intervals at current pace.", C_GREEN),
    (5, 8,  "PHASE 2: SPEED DEVELOPMENT",   "Faster reps, introduce 600m. First time trial Week 5.",       C_GOLD),
    (9, 12, "PHASE 3: RACE-SPECIFIC",       "Near-goal pace work. Taper. Full time trial Week 12.",        C_ACCENT),
]

phase_idx = 0
for wk in WEEKS:
    wnum = wk["week"]
    # Insert phase banner at start of each phase
    for (ps, pe, ptitle, pdesc, pcol) in phase_defs:
        if wnum == ps:
            story.append(PageBreak() if wnum > 1 else Spacer(1, 1*mm))
            ph_tbl = Table([[
                Paragraph(ptitle, S("PT", fontSize=13, textColor=C_WHITE,
                                    fontName="Helvetica-Bold", alignment=TA_CENTER)),
                Paragraph(pdesc,  S("PD", fontSize=9,  textColor=C_LIGHT,
                                    fontName="Helvetica", alignment=TA_CENTER)),
            ]], colWidths=[180*mm])
            ph_tbl.setStyle(TableStyle([
                ("BACKGROUND",    (0,0), (-1,-1), pcol),
                ("TOPPADDING",    (0,0), (-1,-1), 8),
                ("BOTTOMPADDING", (0,0), (-1,-1), 8),
                ("ALIGN",         (0,0), (-1,-1), "CENTER"),
            ]))
            story.append(ph_tbl)
            story.append(Spacer(1, 4*mm))

    rows = week_table(wnum, wk["phase"], wk["sessions"], wk["note"])
    for r in rows:
        story.append(r)

# ── Progress milestones ───────────────────────────────────────────────────────
story.append(PageBreak())
story.append(banner("PROGRESS MILESTONES & TIME TRIALS", C_DARK))
story.append(Spacer(1, 3*mm))
story.append(milestones_table())
story.append(Spacer(1, 6*mm))

# ── Overtraining guide ────────────────────────────────────────────────────────
story.append(banner("OVERTRAINING vs. BUILDING FITNESS", C_BLUE))
story.append(Spacer(1, 3*mm))
story.append(overtraining_table())
story.append(Spacer(1, 4*mm))

# ── Key rules ─────────────────────────────────────────────────────────────────
story.append(banner("5 GOLDEN RULES", C_DARK))
story.append(Spacer(1, 3*mm))
rules = [
    ("1. 80/20 Rule",        "80% of runs = easy. Only 20% hard. If your easy runs feel hard, slow down."),
    ("2. 10% Rule",          "Never increase total weekly mileage by more than 10% per week."),
    ("3. Deload every 4th week", "Cut volume 30% every 4th week. This is when fitness actually improves."),
    ("4. Morning HR check",  "Take resting HR daily. If 7+ BPM above normal, take an extra rest day."),
    ("5. Intervals = quality", "If your splits are slowing down mid-session, stop. Don't grind through bad reps."),
]
rules_data = [[Paragraph(r[0], cell_bold), Paragraph(r[1], cell_style)] for r in rules]
rules_tbl = Table(rules_data, colWidths=[50*mm, 130*mm])
rules_tbl.setStyle(TableStyle([
    ("ROWBACKGROUNDS", (0,0), (-1,-1), [C_LIGHT, C_EASY]),
    ("GRID",          (0,0), (-1,-1), 0.4, C_MID),
    ("TOPPADDING",    (0,0), (-1,-1), 5),
    ("BOTTOMPADDING", (0,0), (-1,-1), 5),
    ("LEFTPADDING",   (0,0), (-1,-1), 6),
    ("VALIGN",        (0,0), (-1,-1), "MIDDLE"),
]))
story.append(rules_tbl)

story.append(Spacer(1, 5*mm))
story.append(Paragraph(
    "Generated by Orris Training Assistant  |  Start date: August 12, 2026  |  "
    "All paces are guidelines — adjust based on how you feel each day.",
    S("footer", fontSize=7.5, textColor=C_MID, alignment=TA_CENTER, fontName="Helvetica-Oblique")
))

# ── Build ─────────────────────────────────────────────────────────────────────
doc.build(story)
print(f"PDF saved: {OUTPUT}")
Running Command

cd /tmp/workspace/running-plan && python generate_plan.py 2>&1

Running Command

ls -lh /tmp/workspace/running-plan/

Your full 12-week plan is ready. Download it here:

1600m 12week plan

PDF Document · PDF


What's Inside the PDF

3 Phases, Built for Your 7:00 → Sub 5:30 Goal

PhaseWeeksFocus
Aerobic Base1-4Build engine. Intervals at your current pace.
Speed Development5-8Faster reps, 600m introduced, first time trial (Week 5).
Race-Specific9-12Near-goal pace, 800m reps, taper, full race test Week 12.

Every Week Has Exact Splits

  • Monday: Long run with exact pace range (e.g. 40 min @ 6:30/km)
  • Wednesday: Intervals with rep distance, target split, and rest time (e.g. 6 x 400m @ 1:42, 90 sec jog rest)
  • Friday: Speed session with 200m/300m targets
  • Deload every 4th week built in automatically

Also Included

  • Pace reference guide (5 run types with HR zones)
  • Progress milestone tracker (what your 1600m should be at each check)
  • Overtraining vs. building fitness table
  • 5 golden rules of training

Your Key Targets to Watch

  • Week 5 time trial: Break 6:30
  • Week 9 time trial: Break 6:20
  • Week 12 race day: Target sub 5:30 (that's a realistic ceiling from 7:00 in 12 weeks)
Sub 4:30-5:00 total is achievable after this plan with 3-6 more months of training on top.

Should i do 2 times running or one time. E

One session per day. That's the right answer for your level.
Here's why:

One Run Per Day vs. Two-a-Days

Two-a-days (running twice daily) are used by elite runners logging 100+ km per week. They split volume because doing it all at once would be too much stress on the body in one go.
You are at 7:00/1600m, building toward sub-5:30. Your total daily volume is 20-45 minutes. There is zero benefit to splitting that into two sessions - it just adds extra stress without extra stimulus.

What Two-a-Days Would Actually Do to You Right Now

EffectWhat Happens
RecoveryYou never fully recover between sessions - legs stay fatigued
Injury riskDoubles the impact load before your body has adapted
Sleep/muscle repairRecovery happens at night - two sessions per day cuts into that cycle
PerformanceHard sessions (intervals, speed) will suffer because legs are pre-fatigued

The One Exception

The only time double sessions make sense at your level:
  • You are doing a morning easy run (15-20 min) purely for blood flow/warmup on a heavy training day
  • This is rare and only useful in Phase 3 (Weeks 9-12) if your body has adapted well

Simple Rule

One quality session > two mediocre sessions.
Run once. Make that one run count. Sleep. Recover. Repeat.
Stick to the plan in your PDF - one session per day, one full rest day per week. That's the formula.

Exercises

Could you clarify what you're looking for?
Asking for Preferences

What kind of exercises are you asking about?

Good choice. Strength training is one of the most underused tools for getting faster at 1600m. Here's exactly what you need:

Why Strength Training Makes You a Faster Runner

  • Stronger legs = more force per stride = faster pace for same effort
  • Single-leg stability = better running form, less energy wasted
  • Injury prevention = most running injuries come from weak glutes, hips, and calves
  • Running economy = less oxygen needed at the same speed

When to Do It (Fits Your 12-Week Plan)

Running DayStrength Timing
Easy / Recovery days✅ After the run, 20-30 min
Interval / Hard days❌ Not on the same day - legs need full energy
Rest day (Sunday)✅ Optional light session if feeling good
Best days: Tuesday after recovery run, Thursday after recovery run

The Full Strength Plan (No Gym Needed)

Block A - Lower Body Power (Do 2x per week)

ExerciseSets x RepsWhy It Helps
Bulgarian Split Squat3 x 10 each legSingle-leg strength, mimics running stride
Step-Ups (onto chair/bench)3 x 12 each legHip drive and glute activation
Romanian Deadlift (bodyweight or dumbbells)3 x 12Hamstring strength - prevents injury
Calf Raises (slow, full range)4 x 20Propulsion off the ground
Glute Bridge3 x 15Glute power for uphill and sprint finish

Block B - Core & Stability (Do 2x per week, can be same day as Block A)

ExerciseSets x DurationWhy It Helps
Plank3 x 45 secCore stability = less energy wasted in upper body
Side Plank3 x 30 sec eachHip stability, reduces side-to-side sway
Dead Bug3 x 10 each sideAnti-rotation core, posture under fatigue
Single-leg Glute Bridge3 x 12 each legHip strength + balance
Mountain Climbers3 x 20Core endurance + hip flexor strength

Block C - Plyometrics (Add from Week 5 onwards)

These directly improve your speed and leg stiffness - the #1 thing that separates fast runners.
ExerciseSets x RepsCue
Box Jumps / Jump Squats4 x 6Land soft, explode fast
Bounding (exaggerated running strides)3 x 20mBig push-off each step
Single-leg Hops3 x 8 each legLand and absorb softly
Ankle Hops (fast, low)4 x 15Stiff ankles = faster ground contact

Weekly Strength Schedule (Paired with Your Running Plan)

DayRunningStrength
MonLong runNone
TueRecovery runBlock A + B (after run)
WedIntervalsNone
ThuRecovery runBlock A + B (after run)
FriSpeed sessionNone
SatEasy + stridesOptional: Block C only
SunRestNone

Progression Over 12 Weeks

PhaseFocus
Weeks 1-4Master form. Bodyweight only. High reps (15-20).
Weeks 5-8Add load (dumbbells, backpack). Medium reps (10-12). Add plyometrics.
Weeks 9-11Heavier load, lower reps (6-8). Explosive movements.
Week 12Cut strength to minimum - save legs for time trial.

3 Exercises That Matter Most for 1600m

If you can only do 3 things, do these:
  1. Calf raises - your calf is the primary propulsion muscle in running
  2. Bulgarian split squat - single-leg power equals race-day speed
  3. Plank variations - a weak core means wasted energy every single stride
Do these consistently and you will notice your interval splits drop faster than running alone.

Create a printable strength routine card for my phone

Running Command

mkdir -p /tmp/workspace/running-plan && ls /tmp/workspace/running-plan/

Writing File

~/running-plan/generate_card.py

from reportlab.lib.pagesizes import A5
from reportlab.lib import colors
from reportlab.lib.units import mm
from reportlab.lib.styles import ParagraphStyle
from reportlab.lib.enums import TA_CENTER, TA_LEFT
from reportlab.platypus import (
    SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle, HRFlowable
)

OUTPUT = "/tmp/workspace/running-plan/strength_card.pdf"

# Phone-friendly: tall portrait, A5 (148 x 210 mm)
W, H = A5

doc = SimpleDocTemplate(
    OUTPUT,
    pagesize=A5,
    rightMargin=8*mm, leftMargin=8*mm,
    topMargin=8*mm,   bottomMargin=8*mm,
    title="Runner Strength Card",
)

# ── Colours ───────────────────────────────────────────────────────────────────
C_BG     = colors.HexColor("#0D0D1A")
C_ACCENT = colors.HexColor("#E94560")
C_GOLD   = colors.HexColor("#F5A623")
C_GREEN  = colors.HexColor("#27AE60")
C_BLUE   = colors.HexColor("#1A6FA8")
C_CARD   = colors.HexColor("#16213E")
C_LIGHT  = colors.HexColor("#ECF0F1")
C_MID    = colors.HexColor("#7F8C8D")
C_WHITE  = colors.white
C_PLY    = colors.HexColor("#6C3483")   # purple for plyos

PAGE_W = W - 16*mm   # usable width

def S(name, **kw):
    return ParagraphStyle(name, **kw)

title_s  = S("T",  fontSize=17, textColor=C_WHITE,   fontName="Helvetica-Bold",
             alignment=TA_CENTER, spaceAfter=1, leading=20)
sub_s    = S("Su", fontSize=9,  textColor=C_GOLD,    fontName="Helvetica",
             alignment=TA_CENTER, spaceAfter=1)
sec_s    = S("Sc", fontSize=10, textColor=C_WHITE,   fontName="Helvetica-Bold",
             alignment=TA_CENTER)
exname_s = S("EN", fontSize=8.5,textColor=C_WHITE,   fontName="Helvetica-Bold",  leading=11)
detail_s = S("D",  fontSize=7.5,textColor=C_LIGHT,   fontName="Helvetica",       leading=10)
cue_s    = S("C",  fontSize=7,  textColor=C_GOLD,    fontName="Helvetica-Oblique",leading=9)
note_s   = S("N",  fontSize=7,  textColor=C_MID,     fontName="Helvetica-Oblique",
             alignment=TA_CENTER, leading=9)
day_s    = S("Dy", fontSize=7.5,textColor=C_WHITE,   fontName="Helvetica-Bold",  alignment=TA_CENTER)
day_d    = S("Dd", fontSize=7,  textColor=C_LIGHT,   fontName="Helvetica",       alignment=TA_CENTER, leading=9)
phase_s  = S("Ph", fontSize=7.5,textColor=C_WHITE,   fontName="Helvetica-Bold",  alignment=TA_CENTER)

def section_banner(text, bg=C_CARD, color=C_ACCENT):
    style = S("sb", fontSize=10, textColor=color, fontName="Helvetica-Bold",
              alignment=TA_CENTER)
    tbl = Table([[Paragraph(text, style)]], colWidths=[PAGE_W])
    tbl.setStyle(TableStyle([
        ("BACKGROUND",    (0,0),(-1,-1), bg),
        ("TOPPADDING",    (0,0),(-1,-1), 5),
        ("BOTTOMPADDING", (0,0),(-1,-1), 5),
        ("LEFTPADDING",   (0,0),(-1,-1), 6),
    ]))
    return tbl

def exercise_block(exercises, accent=C_ACCENT):
    """exercises: list of (name, sets_reps, cue)"""
    rows = []
    for name, sets, cue in exercises:
        rows.append([
            Paragraph(f"● {name}", exname_s),
            Paragraph(sets,        detail_s),
            Paragraph(cue,         cue_s),
        ])
    col_w = [PAGE_W*0.42, PAGE_W*0.22, PAGE_W*0.36]
    tbl = Table(rows, colWidths=col_w)
    ts = TableStyle([
        ("ROWBACKGROUNDS", (0,0),(-1,-1), [C_CARD, colors.HexColor("#1E2D50")]),
        ("TOPPADDING",     (0,0),(-1,-1), 4),
        ("BOTTOMPADDING",  (0,0),(-1,-1), 4),
        ("LEFTPADDING",    (0,0),(-1,-1), 4),
        ("RIGHTPADDING",   (0,0),(-1,-1), 3),
        ("VALIGN",         (0,0),(-1,-1), "TOP"),
        ("LINEBELOW",      (0,0),(-1,-1), 0.3, colors.HexColor("#2C3E6B")),
        ("LEFTPADDING",    (0,0),(0,-1),  6),
    ])
    # accent left border simulation via background on col 0 strip
    tbl.setStyle(ts)
    return tbl

def schedule_row(days):
    """days: list of (day_name, session, bg_color)"""
    cells = [[Paragraph(d, day_s), Paragraph(s, day_d)] for d, s, _ in days]
    bgs   = [c for _, _, c in days]
    n = len(days)
    col_w = [PAGE_W / n] * n
    # Transpose: one row of day names, one row of sessions
    header_row = [Paragraph(d, day_s)  for d, _, _ in days]
    detail_row = [Paragraph(s, day_d)  for _, s, _ in days]
    tbl = Table([header_row, detail_row], colWidths=col_w)
    ts = TableStyle([
        ("TOPPADDING",    (0,0),(-1,-1), 3),
        ("BOTTOMPADDING", (0,0),(-1,-1), 3),
        ("LEFTPADDING",   (0,0),(-1,-1), 2),
        ("RIGHTPADDING",  (0,0),(-1,-1), 2),
        ("ALIGN",         (0,0),(-1,-1), "CENTER"),
        ("VALIGN",        (0,0),(-1,-1), "MIDDLE"),
        ("GRID",          (0,0),(-1,-1), 0.3, colors.HexColor("#2C3E6B")),
    ])
    for i, bg in enumerate(bgs):
        ts.add("BACKGROUND", (i,0),(i,0), bg)
        ts.add("BACKGROUND", (i,1),(i,1), colors.HexColor("#16213E"))
    tbl.setStyle(ts)
    return tbl

def phase_table():
    phases = [
        ("Wk 1-4", "Bodyweight\nHigh reps 15-20\nMaster form",       C_GREEN),
        ("Wk 5-8", "Add load\nMed reps 10-12\n+ Plyometrics",         C_GOLD),
        ("Wk 9-11","Heavy load\nLow reps 6-8\nExplosive",             C_ACCENT),
        ("Wk 12",  "Cut strength\nSave legs for\ntime trial",         C_MID),
    ]
    cells = [[Paragraph(p[0], S("ph", fontSize=8, textColor=C_WHITE,
                                fontName="Helvetica-Bold", alignment=TA_CENTER)),
              Paragraph(p[1], S("pd", fontSize=7, textColor=C_LIGHT,
                                fontName="Helvetica", alignment=TA_CENTER, leading=9))]
             for p in phases]
    # Each phase: 2 rows (name + detail) in its own col
    header_row = [Paragraph(p[0], S("ph2", fontSize=8, textColor=C_WHITE,
                                     fontName="Helvetica-Bold", alignment=TA_CENTER))
                  for p in phases]
    detail_row = [Paragraph(p[1], S("pd2", fontSize=6.5, textColor=C_LIGHT,
                                     fontName="Helvetica", alignment=TA_CENTER, leading=8))
                  for p in phases]
    col_w = [PAGE_W / 4] * 4
    tbl = Table([header_row, detail_row], colWidths=col_w)
    ts = TableStyle([
        ("TOPPADDING",    (0,0),(-1,-1), 4),
        ("BOTTOMPADDING", (0,0),(-1,-1), 4),
        ("GRID",          (0,0),(-1,-1), 0.3, colors.HexColor("#2C3E6B")),
        ("ALIGN",         (0,0),(-1,-1), "CENTER"),
        ("VALIGN",        (0,0),(-1,-1), "MIDDLE"),
    ])
    for i, p in enumerate(phases):
        ts.add("BACKGROUND", (i,0),(i,0), p[2])
        ts.add("BACKGROUND", (i,1),(i,1), C_CARD)
    tbl.setStyle(ts)
    return tbl

# ── Story ─────────────────────────────────────────────────────────────────────
story = []

# ── Header ────────────────────────────────────────────────────────────────────
hdr = Table([[
    Paragraph("RUNNER STRENGTH CARD", title_s),
    Paragraph("1600m Training  |  Goal: Sub 5:30", sub_s),
]], colWidths=[PAGE_W])
hdr.setStyle(TableStyle([
    ("BACKGROUND",    (0,0),(-1,-1), C_BG),
    ("TOPPADDING",    (0,0),(-1,-1), 7),
    ("BOTTOMPADDING", (0,0),(-1,-1), 5),
    ("LEFTPADDING",   (0,0),(-1,-1), 4),
]))
story.append(hdr)
story.append(Spacer(1, 2*mm))

# ── Block A: Lower Body ───────────────────────────────────────────────────────
story.append(section_banner("🦵  BLOCK A — LOWER BODY POWER  (2x / week)", C_CARD, C_ACCENT))
story.append(Spacer(1, 1*mm))

col_hdr = Table([[
    Paragraph("Exercise", S("ch", fontSize=7.5, textColor=C_MID, fontName="Helvetica-Bold")),
    Paragraph("Sets × Reps", S("ch2", fontSize=7.5, textColor=C_MID, fontName="Helvetica-Bold")),
    Paragraph("Cue", S("ch3", fontSize=7.5, textColor=C_MID, fontName="Helvetica-Bold")),
]], colWidths=[PAGE_W*0.42, PAGE_W*0.22, PAGE_W*0.36])
col_hdr.setStyle(TableStyle([
    ("BACKGROUND",    (0,0),(-1,-1), colors.HexColor("#0A0A14")),
    ("TOPPADDING",    (0,0),(-1,-1), 2),
    ("BOTTOMPADDING", (0,0),(-1,-1), 2),
    ("LEFTPADDING",   (0,0),(0,-1),  6),
    ("LEFTPADDING",   (1,0),(2,-1),  4),
]))
story.append(col_hdr)

lower_body = [
    ("Bulgarian Split Squat",    "3 × 10 / leg",  "Back foot on bench"),
    ("Step-Ups",                 "3 × 12 / leg",  "Drive through heel"),
    ("Romanian Deadlift",        "3 × 12",         "Hinge hips, soft knees"),
    ("Calf Raises",              "4 × 20",         "Slow down, full range"),
    ("Glute Bridge",             "3 × 15",         "Squeeze at top 1 sec"),
]
story.append(exercise_block(lower_body, C_ACCENT))
story.append(Spacer(1, 3*mm))

# ── Block B: Core ─────────────────────────────────────────────────────────────
story.append(section_banner("💪  BLOCK B — CORE & STABILITY  (2x / week)", C_CARD, C_GREEN))
story.append(Spacer(1, 1*mm))
story.append(col_hdr)

core = [
    ("Plank",                    "3 × 45 sec",     "Flat back, breathe"),
    ("Side Plank",               "3 × 30 sec / side","Hip up, straight body"),
    ("Dead Bug",                 "3 × 10 / side",  "Lower back on floor"),
    ("Single-leg Glute Bridge",  "3 × 12 / leg",   "Keep hips level"),
    ("Mountain Climbers",        "3 × 20",          "Fast knees, hips low"),
]
story.append(exercise_block(core, C_GREEN))
story.append(Spacer(1, 3*mm))

# ── Block C: Plyometrics ──────────────────────────────────────────────────────
story.append(section_banner("⚡  BLOCK C — PLYOMETRICS  (from Week 5)", C_CARD, C_GOLD))
story.append(Spacer(1, 1*mm))
story.append(col_hdr)

plyo = [
    ("Jump Squats",              "4 × 6",           "Land soft, explode up"),
    ("Bounding",                 "3 × 20m",         "Big push-off, drive arm"),
    ("Single-leg Hops",          "3 × 8 / leg",    "Absorb landing softly"),
    ("Ankle Hops",               "4 × 15",          "Fast, stiff ankles"),
]
story.append(exercise_block(plyo, C_GOLD))
story.append(Spacer(1, 3*mm))

# ── Weekly Schedule ───────────────────────────────────────────────────────────
story.append(section_banner("📅  WEEKLY SCHEDULE", C_BG, C_BLUE))
story.append(Spacer(1, 1*mm))

C_RUN  = colors.HexColor("#1A4A6B")
C_STR  = colors.HexColor("#1A3A2A")
C_OFF  = colors.HexColor("#1A1A2E")
C_BOTH = colors.HexColor("#3D2B0A")

days_data = [
    ("MON",  "Long Run\nNo strength",           C_RUN),
    ("TUE",  "Recovery Run\n+ Block A+B",        C_BOTH),
    ("WED",  "Intervals\nNo strength",           C_RUN),
    ("THU",  "Recovery Run\n+ Block A+B",        C_BOTH),
    ("FRI",  "Speed Session\nNo strength",       C_RUN),
    ("SAT",  "Easy + Strides\nOpt: Block C",     C_STR),
    ("SUN",  "FULL REST",                        C_OFF),
]
story.append(schedule_row(days_data))
story.append(Spacer(1, 3*mm))

# ── 12-Week Progression ───────────────────────────────────────────────────────
story.append(section_banner("📈  12-WEEK PROGRESSION", C_BG, C_GOLD))
story.append(Spacer(1, 1*mm))
story.append(phase_table())
story.append(Spacer(1, 3*mm))

# ── Top 3 Must-Do ─────────────────────────────────────────────────────────────
top3 = Table([[
    Paragraph("🥇 TOP 3 EXERCISES FOR 1600m SPEED", 
              S("t3h", fontSize=9, textColor=C_GOLD, fontName="Helvetica-Bold", alignment=TA_CENTER)),
    Paragraph("1. Calf Raises  —  propulsion off the ground\n"
              "2. Bulgarian Split Squat  —  single-leg race power\n"
              "3. Plank  —  core = no wasted energy per stride",
              S("t3d", fontSize=7.5, textColor=C_LIGHT, fontName="Helvetica", leading=11)),
]], colWidths=[PAGE_W])
top3.setStyle(TableStyle([
    ("BACKGROUND",    (0,0),(-1,-1), colors.HexColor("#1A1200")),
    ("TOPPADDING",    (0,0),(-1,-1), 5),
    ("BOTTOMPADDING", (0,0),(-1,-1), 5),
    ("LEFTPADDING",   (0,0),(-1,-1), 8),
    ("LINEABOVE",     (0,0),(-1,0),  1.5, C_GOLD),
    ("LINEBELOW",     (0,-1),(-1,-1),1.5, C_GOLD),
]))
story.append(top3)
story.append(Spacer(1, 2*mm))

# ── Footer ────────────────────────────────────────────────────────────────────
story.append(Paragraph(
    "Orris Training  |  Current: 7:00  →  Goal: Sub 5:30  |  Strength = Speed",
    S("ft", fontSize=6.5, textColor=C_MID, fontName="Helvetica-Oblique",
      alignment=TA_CENTER)
))

# ── Build ─────────────────────────────────────────────────────────────────────
doc.build(story)
print(f"Card saved: {OUTPUT}")
Running Command

cd /tmp/workspace/running-plan && python generate_card.py 2>&1

Running Command

ls -lh /tmp/workspace/running-plan/strength_card.pdf

Your strength card is ready - phone-sized (A5 portrait), dark theme, everything on one page:

strength card

PDF Document · PDF


What's on the Card

Block A - Lower Body Power (5 exercises with sets, reps, cue)
  • Bulgarian Split Squat, Step-Ups, Romanian Deadlift, Calf Raises, Glute Bridge
Block B - Core & Stability (5 exercises)
  • Plank, Side Plank, Dead Bug, Single-leg Glute Bridge, Mountain Climbers
Block C - Plyometrics (from Week 5)
  • Jump Squats, Bounding, Single-leg Hops, Ankle Hops
Weekly Schedule - colour-coded 7-day layout showing exactly when to run vs. when to strength train
12-Week Progression - 4-phase guide (bodyweight → loaded → explosive → taper)
Top 3 Must-Do - the three exercises that matter most for 1600m speed

Tip: Open the PDF on your phone and save it as a screenshot or add to your home screen for quick gym access.

See this planner

Let me read the PDF first.
Reading File
Running Command

cd /tmp/workspace && python3 -c " import pdfplumber path = '/tmp/workspace/attachments/bd954119-c405-4a2f-9079-d1910f2d23b2/Revised_1600m_Training_Plan.pdf' with pdfplumber.open(path) as pdf: print(f'Pages: {len(pdf.pages)}') for i, page in enumerate(pdf.pages): print(f'--- PAGE {i+1} ---') print(page.extract_text()) "

Got it. I can read the full plan. Here's my analysis:

Your Uploaded Plan - Full Review

What I See

This is a revised version of the plan, and it's been tailored for Army Nursing Assistant physical preparation - so it's not just 1600m speed, it's also building military fitness (pull-ups, push-ups, planks). That's a smart adjustment.

What's Good ✅

ElementVerdict
Weekly structure (Mon-Sun)✅ Solid - mirrors what we discussed
Deload on Week 4 & 8✅ Correct - reduces injury risk
Time trials on Week 5 & 9✅ Good checkpoints
Hill sprints on Friday✅ Excellent addition - builds leg power specific to 1600m
Pull-ups on Saturday✅ Smart for Army PT prep
3x/week push-ups + planks✅ Covers upper body and core
Realistic goal (5:45-6:00)✅ Much more achievable from 7:00 in 12 weeks vs. sub-5:30

What Needs Fixing ⚠️

1. Wednesday intervals - paces not specified The plan says "6x400m progressing to 8x400m" but no target split times. Without paces, you won't know if you're working hard enough.
  • Weeks 1-2: 6x400m @ 1:45 (your current 1600m pace)
  • Weeks 3-4: 8x400m @ 1:42, deload 5x400m
  • Week 6: 6x400m @ 1:38
  • Weeks 10-11: 6x400m @ 1:30-1:33
2. Friday alternating hill sprints / 200m reps - no structure What does "alternate" mean week to week? Suggest:
  • Odd weeks (1,3,5,7,9,11): 8x200m @ 48-50 sec, 60 sec rest
  • Even weeks (2,4,6,8,10,12): 6x hill sprints (30-40m steep hill, walk back = rest)
3. Goal is conservative but realistic The original plan aimed for sub-5:30. This revised plan targets 5:45-6:00 which is more honest from a 7:00 baseline in 12 weeks. This is actually the better goal - hit this first, then chase sub-5:30 in the next training block.
4. Pull-ups on Saturday - no progression How many? Start with what you can do:
  • Weeks 1-4: 3 sets to failure (assisted if needed)
  • Weeks 5-8: 4 sets, adding 1 rep per set each week
  • Weeks 9-12: 5 sets, weighted if bodyweight becomes easy

Side-by-Side Comparison

ElementMy Original PlanYour Revised PlanWinner
GoalSub-5:305:45-6:00Revised (realistic)
Hill workNoneFriday hillsRevised
Army PT prepNonePull-ups + push-upsRevised
Exact paces✅ Specified❌ VagueOriginal
Interval volumeDetailedHigh levelOriginal
PlyometricsWeek 5 onwardNot includedOriginal

Bottom Line

This revised plan is better suited to your actual goal (Army Nursing Assistant prep + 1600m). The structure is sound. The main gap is missing exact split times on interval days - without those numbers you're running blind.
Want me to rebuild this plan into a clean PDF with the exact paces and splits filled in, using this revised structure?

How should I adjust the plan if I fall behind on timing

My goal onow Tarritorial army open rally

Good context. Territorial Army Open Rally changes everything - there's a fixed exam date you can't move, so the plan must bend around your progress, not the other way around.

First - What the Territorial Army Rally Requires for 1600m

CategoryMale (Under 30)Qualifying Standard
1600m Run5:30 or fasterPass/Fail
Pull-ups6 minimumPass/Fail
9 feet ditch jumpClear itPass/Fail
Zig-zag balanceCompletePass/Fail
So your hard target is sub-5:30 - not just improvement. You need to hit that number on rally day.

How to Adjust If You Fall Behind

Step 1 - Identify WHY You're Behind

ReasonAdjustment
Intervals getting slowerAdd 1 more rest day, reduce reps by 2, don't reduce pace
Easy runs feel hardYou're running too fast on easy days - slow down by 30 sec/km
Missed sessions (illness/life)Don't try to "make up" missed runs - just continue from where you left off
Time trial worse than expectedRepeat the current phase 1 extra week before moving on
General fatigue, heavy legsTake a full 3-day rest, then restart the week

Step 2 - The Adjustment Rules by Phase

If you fall behind in Phase 1 (Weeks 1-4):
  • Repeat Week 2 or 3 before moving to Phase 2
  • Do NOT rush into speed work with a weak base - injury risk is high
  • Add 1 rest day to your week temporarily
If you fall behind in Phase 2 (Weeks 5-8):
  • Drop interval volume (fewer reps) but keep the pace target
  • Example: 6x400m becomes 4x400m - same speed, less total stress
  • Don't skip the Week 5 time trial - it tells you exactly where you are
If you fall behind in Phase 3 (Weeks 9-12):
  • This is close to rally date - do NOT add more hard sessions
  • Reduce easy run duration by 10 min
  • Keep all interval sessions but cut 1-2 reps per session
  • Prioritize sleep and food over extra training

Step 3 - Time Trial Check System

Your two time trials (Week 5 and Week 9) are your early warning system:
Week 5 TT ResultAction
Sub 6:30✅ On track - continue Phase 2 as planned
6:30 - 6:45⚠️ Slightly behind - extend Phase 2 by 1 week
Over 6:45❌ Repeat Phase 1 for 2 more weeks before moving on
Week 9 TT ResultAction
Sub 6:00✅ On track for sub-5:30 by rally
6:00 - 6:20⚠️ Need to sharpen - add 1 extra speed session per week
Over 6:20❌ Focus entirely on intervals + speed, cut long runs

Step 4 - Emergency Catch-Up Protocol

If you're 3+ weeks behind and rally date is close:
Drop this:
  • Long runs (cut from 40-45 min down to 25 min)
  • Second recovery run (Thu becomes full rest)
Keep this (non-negotiable):
  • Wednesday intervals - this is where speed comes from
  • Friday speed session
  • Strength (pull-ups, squats) - rally tests this too
Add this:
  • 2 x per week: 4x400m at target pace (1:22 per 400m for sub-5:30)
  • Strides every easy run day (6 x 80m fast accelerations)

Your Sub-5:30 Target Broken Down

For sub-5:30 you need each 400m lap in 82 seconds or faster.
LapTarget Split
Lap 180-82 sec (controlled start)
Lap 282-84 sec (settle into pace)
Lap 383-85 sec (hold on)
Lap 478-80 sec (empty the tank)
Train your body to know what 82 sec/400m feels like. Every Wednesday interval session, run your 400m reps at 80-82 sec - this is your race pace rehearsal.

One Golden Rule for Rally Prep

Never skip Wednesday intervals. If you can only do one session in a week, make it that one. Speed work is the direct path to your 5:30 target. Everything else supports it.
What's your rally date? If you tell me when it is, I can work backwards and tell you exactly how many weeks you have and which phase to prioritize.

Create an emergency catch-up plan if I'm behind

21nov 2026

Running Command

python3 -c " from datetime import date start = date(2026, 8, 12) rally = date(2026, 11, 21) delta = rally - start weeks = delta.days // 7 days = delta.days % 7 print(f'Days to rally: {delta.days}') print(f'Full weeks: {weeks} weeks and {days} days') "

14 weeks and 3 days. Now building the full emergency plan PDF.
Writing File

~/running-plan/generate_emergency.py

from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import mm
from reportlab.lib.styles import ParagraphStyle
from reportlab.lib.enums import TA_CENTER, TA_LEFT
from reportlab.platypus import (
    SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
    HRFlowable, PageBreak, KeepTogether
)

OUTPUT = "/tmp/workspace/running-plan/emergency_catchup_plan.pdf"

W, H = A4
PAGE_W = W - 26*mm

# ── Colours ───────────────────────────────────────────────────────────────────
C_BG     = colors.HexColor("#0D0D1A")
C_DARK   = colors.HexColor("#1A1A2E")
C_CARD   = colors.HexColor("#16213E")
C_ACCENT = colors.HexColor("#E94560")
C_GOLD   = colors.HexColor("#F5A623")
C_GREEN  = colors.HexColor("#27AE60")
C_BLUE   = colors.HexColor("#1A6FA8")
C_RED    = colors.HexColor("#C0392B")
C_LIGHT  = colors.HexColor("#ECF0F1")
C_MID    = colors.HexColor("#7F8C8D")
C_WHITE  = colors.white
C_EASY   = colors.HexColor("#D5F5E3")
C_HARD   = colors.HexColor("#FADBD8")
C_INTER  = colors.HexColor("#D6EAF8")
C_REST   = colors.HexColor("#F2F3F4")
C_TEMPO  = colors.HexColor("#FDEBD0")
C_WARN   = colors.HexColor("#FFF3CD")
C_TRIG   = colors.HexColor("#1A0A00")

def S(name, **kw):
    return ParagraphStyle(name, **kw)

title_s  = S("T",  fontSize=22, textColor=C_WHITE,  fontName="Helvetica-Bold", alignment=TA_CENTER, leading=26)
sub_s    = S("Su", fontSize=10, textColor=C_GOLD,   fontName="Helvetica",      alignment=TA_CENTER)
alert_s  = S("Al", fontSize=11, textColor=C_WHITE,  fontName="Helvetica-Bold", alignment=TA_CENTER)
h2_s     = S("H2", fontSize=11, textColor=C_ACCENT, fontName="Helvetica-Bold", spaceAfter=2)
body_s   = S("B",  fontSize=9,  textColor=C_DARK,   fontName="Helvetica",      leading=13)
cell_s   = S("C",  fontSize=8,  textColor=C_DARK,   fontName="Helvetica",      leading=10)
cell_b   = S("Cb", fontSize=8,  textColor=C_DARK,   fontName="Helvetica-Bold", leading=10)
cell_w   = S("Cw", fontSize=8,  textColor=C_WHITE,  fontName="Helvetica",      leading=10)
cell_bw  = S("Cbw",fontSize=8,  textColor=C_WHITE,  fontName="Helvetica-Bold", leading=10, alignment=TA_CENTER)
note_s   = S("N",  fontSize=7.5,textColor=C_MID,    fontName="Helvetica-Oblique", alignment=TA_CENTER, leading=10)
rule_s   = S("R",  fontSize=9,  textColor=C_WHITE,  fontName="Helvetica-Bold", leading=12)
rule_d   = S("Rd", fontSize=8.5,textColor=C_LIGHT,  fontName="Helvetica",      leading=11)
warn_s   = S("W",  fontSize=8.5,textColor=colors.HexColor("#7D6608"), fontName="Helvetica", leading=11)

def banner(text, bg=C_CARD, fg=C_ACCENT, size=11, pad=6):
    st = S("bn", fontSize=size, textColor=fg, fontName="Helvetica-Bold", alignment=TA_CENTER)
    t = Table([[Paragraph(text, st)]], colWidths=[PAGE_W])
    t.setStyle(TableStyle([
        ("BACKGROUND",    (0,0),(-1,-1), bg),
        ("TOPPADDING",    (0,0),(-1,-1), pad),
        ("BOTTOMPADDING", (0,0),(-1,-1), pad),
    ]))
    return t

def week_block(week_num, date_range, tag, sessions, note="", tag_color=C_ACCENT):
    """sessions: list of (day, session_label, detail, bg_color)"""
    # Header
    hdr = Table([[
        Paragraph(f"WEEK {week_num}", S("wh", fontSize=9, textColor=C_WHITE, fontName="Helvetica-Bold")),
        Paragraph(date_range,         S("wd", fontSize=8, textColor=C_LIGHT, fontName="Helvetica")),
        Paragraph(tag,                S("wt", fontSize=8, textColor=C_WHITE, fontName="Helvetica-Bold", alignment=TA_CENTER)),
        Paragraph(note,               S("wn", fontSize=7.5, textColor=C_GOLD, fontName="Helvetica-Oblique")),
    ]], colWidths=[22*mm, 38*mm, 35*mm, PAGE_W-95*mm])
    hdr.setStyle(TableStyle([
        ("BACKGROUND",    (0,0),(-1,-1), tag_color),
        ("TOPPADDING",    (0,0),(-1,-1), 4),
        ("BOTTOMPADDING", (0,0),(-1,-1), 4),
        ("LEFTPADDING",   (0,0),(-1,-1), 6),
        ("VALIGN",        (0,0),(-1,-1), "MIDDLE"),
        ("BACKGROUND",    (2,0),(2,0),   colors.HexColor("#00000033")),
    ]))

    # Sessions
    rows = []
    for day, label, detail, bg in sessions:
        rows.append([
            Paragraph(day,    S("dy", fontSize=8, textColor=C_DARK, fontName="Helvetica-Bold")),
            Paragraph(label,  S("sl", fontSize=8, textColor=C_DARK, fontName="Helvetica-Bold", leading=10)),
            Paragraph(detail, S("sd", fontSize=7.5, textColor=colors.HexColor("#2C3E50"), fontName="Helvetica", leading=10)),
        ])
    col_w = [12*mm, 45*mm, PAGE_W - 57*mm]
    body = Table(rows, colWidths=col_w)
    ts = TableStyle([
        ("GRID",          (0,0),(-1,-1), 0.3, C_MID),
        ("TOPPADDING",    (0,0),(-1,-1), 3),
        ("BOTTOMPADDING", (0,0),(-1,-1), 3),
        ("LEFTPADDING",   (0,0),(-1,-1), 5),
        ("VALIGN",        (0,0),(-1,-1), "TOP"),
    ])
    for i, (day, label, detail, bg) in enumerate(sessions):
        ts.add("BACKGROUND", (0,i),(2,i), bg)
    body.setStyle(ts)

    return KeepTogether([hdr, body, Spacer(1, 3*mm)])

# ── Day colours ───────────────────────────────────────────────────────────────
E = C_EASY
I = C_INTER
H = C_HARD
R = C_REST
T = C_TEMPO
PT= colors.HexColor("#E8DAEF")  # purple/light for PT

# ── Date ranges (starting Aug 12 2026) ───────────────────────────────────────
from datetime import date, timedelta
start = date(2026, 8, 12)
def dr(week_num):
    ws = start + timedelta(weeks=week_num-1)
    we = ws + timedelta(days=6)
    return f"{ws.strftime('%d %b')} – {we.strftime('%d %b')}"

# ── Build story ───────────────────────────────────────────────────────────────
story = []

# ── COVER ─────────────────────────────────────────────────────────────────────
cover = Table([[
    Paragraph("EMERGENCY CATCH-UP PLAN", title_s),
    Paragraph("Territorial Army Open Rally  |  21 November 2026", sub_s),
    Paragraph("14 Weeks 3 Days  |  Current: 7:00  |  Target: Sub 5:30", 
              S("cv", fontSize=10, textColor=C_MID, fontName="Helvetica", alignment=TA_CENTER)),
]], colWidths=[PAGE_W])
cover.setStyle(TableStyle([
    ("BACKGROUND",    (0,0),(-1,-1), C_BG),
    ("TOPPADDING",    (0,0),(-1,-1), 10),
    ("BOTTOMPADDING", (0,0),(-1,-1), 10),
    ("ALIGN",         (0,0),(-1,-1), "CENTER"),
]))
story.append(cover)
story.append(Spacer(1, 4*mm))

# ── RALLY REQUIREMENTS ────────────────────────────────────────────────────────
story.append(banner("TERRITORIAL ARMY RALLY - PHYSICAL REQUIREMENTS", C_RED, C_WHITE, 10))
req_data = [
    [Paragraph("Event", cell_bw), Paragraph("Standard", cell_bw), Paragraph("Your Gap", cell_bw), Paragraph("Priority", cell_bw)],
    [Paragraph("1600m Run", cell_b),    Paragraph("Sub 5:30",    cell_s), Paragraph("Need 1:30 faster", cell_s), Paragraph("🔴 CRITICAL", S("p", fontSize=8, textColor=C_RED, fontName="Helvetica-Bold", leading=10))],
    [Paragraph("Pull-ups",  cell_b),    Paragraph("Min 6 reps",  cell_s), Paragraph("Build from now", cell_s),  Paragraph("🟠 HIGH",     S("p2",fontSize=8, textColor=C_GOLD, fontName="Helvetica-Bold", leading=10))],
    [Paragraph("9-ft Ditch Jump",cell_b),Paragraph("Clear it",  cell_s), Paragraph("Leg power needed", cell_s),Paragraph("🟡 MEDIUM",  S("p3",fontSize=8, textColor=colors.HexColor("#7D6608"), fontName="Helvetica-Bold", leading=10))],
    [Paragraph("Zig-zag Balance",cell_b),Paragraph("Complete",  cell_s), Paragraph("Core stability",  cell_s), Paragraph("🟢 LOW",     S("p4",fontSize=8, textColor=C_GREEN, fontName="Helvetica-Bold", leading=10))],
]
req_tbl = Table(req_data, colWidths=[40*mm, 30*mm, 50*mm, PAGE_W-120*mm])
req_tbl.setStyle(TableStyle([
    ("BACKGROUND",    (0,0),(-1,0),  C_RED),
    ("ROWBACKGROUNDS",(0,1),(-1,-1), [C_HARD, C_LIGHT, C_WARN, C_EASY]),
    ("GRID",          (0,0),(-1,-1), 0.4, C_MID),
    ("TOPPADDING",    (0,0),(-1,-1), 4),
    ("BOTTOMPADDING", (0,0),(-1,-1), 4),
    ("LEFTPADDING",   (0,0),(-1,-1), 5),
    ("VALIGN",        (0,0),(-1,-1), "MIDDLE"),
]))
story.append(Spacer(1, 2*mm))
story.append(req_tbl)
story.append(Spacer(1, 4*mm))

# ── 400m PACE TARGET ──────────────────────────────────────────────────────────
story.append(banner("SUB 5:30 RACE SPLIT TARGETS (Each 400m Lap)", C_DARK, C_GOLD, 10))
lap_data = [
    [Paragraph("Lap", cell_bw), Paragraph("Target Split", cell_bw), Paragraph("Cumulative", cell_bw), Paragraph("Strategy", cell_bw)],
    [Paragraph("Lap 1 (0-400m)",  cell_b), Paragraph("80 sec", cell_s), Paragraph("1:20",  cell_s), Paragraph("Controlled start. Don't sprint.", cell_s)],
    [Paragraph("Lap 2 (400-800m)",cell_b), Paragraph("82 sec", cell_s), Paragraph("2:42",  cell_s), Paragraph("Settle into rhythm. Relax arms.", cell_s)],
    [Paragraph("Lap 3 (800-1200m)",cell_b),Paragraph("83 sec", cell_s), Paragraph("4:05",  cell_s), Paragraph("This lap hurts. Hold pace. Breathe.", cell_s)],
    [Paragraph("Lap 4 (1200-1600m)",cell_b),Paragraph("79 sec",cell_s), Paragraph("5:24",  cell_s), Paragraph("Empty the tank. Lean forward. Sprint.", cell_s)],
]
lap_tbl = Table(lap_data, colWidths=[42*mm, 28*mm, 28*mm, PAGE_W-98*mm])
lap_tbl.setStyle(TableStyle([
    ("BACKGROUND",    (0,0),(-1,0),  C_DARK),
    ("ROWBACKGROUNDS",(0,1),(-1,-1), [C_EASY, C_INTER, C_TEMPO, C_HARD]),
    ("GRID",          (0,0),(-1,-1), 0.4, C_MID),
    ("TOPPADDING",    (0,0),(-1,-1), 4),
    ("BOTTOMPADDING", (0,0),(-1,-1), 4),
    ("LEFTPADDING",   (0,0),(-1,-1), 5),
    ("VALIGN",        (0,0),(-1,-1), "MIDDLE"),
]))
story.append(Spacer(1, 2*mm))
story.append(lap_tbl)
story.append(Spacer(1, 4*mm))

# ── TRIGGER SYSTEM ────────────────────────────────────────────────────────────
story.append(banner("CATCH-UP TRIGGER SYSTEM - When to Activate Emergency Mode", C_TRIG, C_GOLD, 10))
story.append(Spacer(1, 2*mm))
trig_data = [
    [Paragraph("Check Point", cell_bw), Paragraph("Time Trial Result", cell_bw), Paragraph("Status", cell_bw), Paragraph("Action", cell_bw)],
    [Paragraph("Week 5 TT\n(mid Sep)",  cell_b), Paragraph("Sub 6:20",   cell_s), Paragraph("✅ On Track",  S("ok", fontSize=8, textColor=C_GREEN, fontName="Helvetica-Bold", leading=10)), Paragraph("Continue Phase 2 as planned",      cell_s)],
    [Paragraph("Week 5 TT",  cell_b), Paragraph("6:20 - 6:40",   cell_s), Paragraph("⚠️ Slight Delay", S("sl2",fontSize=8,textColor=C_GOLD, fontName="Helvetica-Bold",leading=10)), Paragraph("Repeat Phase 2 Week 1 before moving on", cell_s)],
    [Paragraph("Week 5 TT",  cell_b), Paragraph("Over 6:40",     cell_s), Paragraph("🔴 Emergency",  S("em", fontSize=8, textColor=C_RED,  fontName="Helvetica-Bold", leading=10)), Paragraph("Switch to Emergency Protocol NOW",  cell_s)],
    [Paragraph("Week 9 TT\n(mid Oct)",  cell_b), Paragraph("Sub 5:55",   cell_s), Paragraph("✅ On Track",  S("ok2",fontSize=8,textColor=C_GREEN,fontName="Helvetica-Bold",leading=10)), Paragraph("Normal taper into rally",          cell_s)],
    [Paragraph("Week 9 TT",  cell_b), Paragraph("5:55 - 6:15",   cell_s), Paragraph("⚠️ Slight Delay", S("sl3",fontSize=8,textColor=C_GOLD, fontName="Helvetica-Bold",leading=10)), Paragraph("Add 2 extra interval sessions in Wk 10-11", cell_s)],
    [Paragraph("Week 9 TT",  cell_b), Paragraph("Over 6:15",     cell_s), Paragraph("🔴 Emergency",  S("em2",fontSize=8,textColor=C_RED,  fontName="Helvetica-Bold",leading=10)), Paragraph("Full Emergency Protocol - see Page 2", cell_s)],
]
trig_tbl = Table(trig_data, colWidths=[30*mm, 32*mm, 30*mm, PAGE_W-92*mm])
trig_tbl.setStyle(TableStyle([
    ("BACKGROUND",    (0,0),(-1,0),  C_DARK),
    ("ROWBACKGROUNDS",(0,1),(-1,-1), [C_EASY, C_WARN, C_HARD, C_EASY, C_WARN, C_HARD]),
    ("GRID",          (0,0),(-1,-1), 0.4, C_MID),
    ("TOPPADDING",    (0,0),(-1,-1), 4),
    ("BOTTOMPADDING", (0,0),(-1,-1), 4),
    ("LEFTPADDING",   (0,0),(-1,-1), 5),
    ("VALIGN",        (0,0),(-1,-1), "MIDDLE"),
]))
story.append(trig_tbl)

story.append(PageBreak())

# ── PAGE 2: 14-WEEK SCHEDULE ──────────────────────────────────────────────────
story.append(banner("14-WEEK RALLY COUNTDOWN SCHEDULE", C_BG, C_WHITE, 12, 8))
story.append(Spacer(1, 3*mm))

# Phase banners
def phase_hdr(text, sub, bg):
    t = Table([[
        Paragraph(text, S("ph", fontSize=11, textColor=C_WHITE, fontName="Helvetica-Bold", alignment=TA_CENTER)),
        Paragraph(sub,  S("pd", fontSize=8,  textColor=C_LIGHT, fontName="Helvetica",      alignment=TA_CENTER)),
    ]], colWidths=[PAGE_W])
    t.setStyle(TableStyle([
        ("BACKGROUND",    (0,0),(-1,-1), bg),
        ("TOPPADDING",    (0,0),(-1,-1), 5),
        ("BOTTOMPADDING", (0,0),(-1,-1), 5),
    ]))
    return t

# ── PHASE 1: BASE (Weeks 1-4) ─────────────────────────────────────────────────
story.append(phase_hdr("PHASE 1: AEROBIC BASE  (Weeks 1-4)", "Build the engine. All runs easy. Intervals at current pace.", C_GREEN))
story.append(Spacer(1,2*mm))

w1_sessions = [
    ("MON", "Long Run",       "35 min @ 6:30-7:00/km. Conversational pace.",         E),
    ("TUE", "Recovery + PT",  "20 min easy jog. Then: 3x10 squats, 3x10 lunges, 3x10 calf raises, 3x plank 30s.", R),
    ("WED", "Intervals",      "6 x 400m @ 1:45 each. 90 sec jog rest between.",      I),
    ("THU", "Recovery Run",   "20 min @ 7:00/km. Very easy.",                          R),
    ("FRI", "Speed",          "8 x 200m @ 52 sec each. 60 sec rest. OR 6 hill sprints (40m).", H),
    ("SAT", "Easy + Pull-ups","30 min easy + 3 sets pull-ups to failure (min 3).",    E),
    ("SUN", "REST",           "Full rest. Walk only.",                                 R),
]
story.append(week_block(1, dr(1), "BASE BUILDING", w1_sessions, "Start conservative.", C_GREEN))

w2_sessions = [
    ("MON", "Long Run",       "40 min @ 6:30/km.",                                    E),
    ("TUE", "Recovery + PT",  "20 min easy. Squats 3x12, Lunges 3x12, Calf raises 4x15, Plank 3x35s.", R),
    ("WED", "Intervals",      "6 x 400m @ 1:43. 90 sec jog rest.",                   I),
    ("THU", "Recovery Run",   "20 min easy.",                                          R),
    ("FRI", "Hills",          "6 x 40m hill sprints. Walk back = full rest. Explosive drive.", H),
    ("SAT", "Easy + Pull-ups","30 min easy + 3 sets pull-ups + 3x15 push-ups.",       E),
    ("SUN", "REST",           "Full rest.",                                            R),
]
story.append(week_block(2, dr(2), "BASE BUILDING", w2_sessions, "", C_GREEN))

w3_sessions = [
    ("MON", "Long Run",       "40 min @ 6:20/km.",                                    E),
    ("TUE", "Recovery + PT",  "25 min easy. Squats 3x15, Bulgarian split squat 3x8/leg, Calf raises 4x20, Plank 3x40s.", R),
    ("WED", "Intervals",      "8 x 400m @ 1:42. 90 sec jog rest. (Toughest Wed so far)", I),
    ("THU", "Recovery Run",   "20 min easy.",                                          R),
    ("FRI", "Speed",          "10 x 200m @ 50 sec. 60 sec rest.",                    H),
    ("SAT", "Easy + Pull-ups","30 min easy + 4 sets pull-ups + push-ups 3x15.",       E),
    ("SUN", "REST",           "Full rest.",                                            R),
]
story.append(week_block(3, dr(3), "BASE BUILDING", w3_sessions, "", C_GREEN))

w4_sessions = [
    ("MON", "Easy Run",       "30 min @ 6:30/km. DELOAD - lighter week.",             E),
    ("TUE", "Recovery + PT",  "20 min easy. Light PT: 2x10 squats, 2x plank 30s.",   R),
    ("WED", "Intervals",      "5 x 400m @ 1:42. 2 min rest. (Deload: fewer reps)",   I),
    ("THU", "REST",           "Full rest.",                                            R),
    ("FRI", "Speed",          "6 x 200m @ 50 sec. 75 sec rest.",                     H),
    ("SAT", "Easy + Pull-ups","25 min easy + 3 sets pull-ups.",                       E),
    ("SUN", "REST",           "Full rest. Body adapts this week.",                    R),
]
story.append(week_block(4, dr(4), "DELOAD WEEK", w4_sessions, "Cut volume 30%. Recovery = gains.", C_BLUE))

# ── PHASE 2: SPEED DEV (Weeks 5-8) ───────────────────────────────────────────
story.append(phase_hdr("PHASE 2: SPEED DEVELOPMENT  (Weeks 5-8)", "Faster reps. Introduce 600m. First time trial Week 5.", C_GOLD))
story.append(Spacer(1,2*mm))

w5_sessions = [
    ("MON", "Easy Run",       "35 min @ 6:00-6:30/km.",                               E),
    ("TUE", "Recovery + PT",  "20 min easy. Squats 3x12, Split squat 3x10/leg, Calf raises 4x20, Side plank 3x30s.", R),
    ("WED", "TIME TRIAL",     "1600m solo time trial. Warm-up 10 min easy. Run full effort. Cool down 10 min. NOTE YOUR TIME.", H),
    ("THU", "Recovery Run",   "20 min very easy. Legs recovering from TT.",           R),
    ("FRI", "Speed",          "6 x 300m @ 1:12. 2 min rest. (New distance - push pace)", H),
    ("SAT", "Easy + Pull-ups","35 min easy + 4 sets pull-ups + push-ups 3x18.",       E),
    ("SUN", "REST",           "Full rest.",                                            R),
]
story.append(week_block(5, dr(5), "TIME TRIAL WK", w5_sessions, "TARGET: Sub 6:20 on TT.", C_ACCENT))

w6_sessions = [
    ("MON", "Long Run",       "40 min @ 6:00/km.",                                    E),
    ("TUE", "Recovery + PT",  "25 min easy. Full strength: split squat 3x10, RDL 3x12, calf 4x20, plank 3x45s.", R),
    ("WED", "Intervals",      "6 x 400m @ 1:38. 2 min rest. FASTER than Phase 1.",   I),
    ("THU", "Recovery Run",   "20 min easy.",                                          R),
    ("FRI", "Hills",          "8 x 40m hill sprints. Explosive. Walk back rest.",     H),
    ("SAT", "Easy + Pull-ups","30 min easy + 4 sets pull-ups + push-ups 3x20.",       E),
    ("SUN", "REST",           "Full rest.",                                            R),
]
story.append(week_block(6, dr(6), "SPEED DEV", w6_sessions, "", C_GOLD))

w7_sessions = [
    ("MON", "Long Run",       "45 min @ 5:55/km.",                                    E),
    ("TUE", "Recovery + PT",  "25 min easy. Split squat 3x12, jump squats 3x6, calf 4x20, dead bug 3x10.", R),
    ("WED", "Intervals",      "5 x 600m @ 2:35 each. 2.5 min rest. (First 600s - hold pace!)", I),
    ("THU", "Recovery Run",   "20 min easy.",                                          R),
    ("FRI", "Speed",          "6 x 300m @ 1:10. 2 min rest.",                        H),
    ("SAT", "Easy + Pull-ups","30 min easy + strides 6x80m + 5 sets pull-ups.",       E),
    ("SUN", "REST",           "Full rest.",                                            R),
]
story.append(week_block(7, dr(7), "SPEED DEV", w7_sessions, "", C_GOLD))

w8_sessions = [
    ("MON", "Easy Run",       "30 min @ 6:20/km. DELOAD.",                            E),
    ("TUE", "Recovery + PT",  "20 min easy. Light PT only: 2x10 squats, 2x plank.",  R),
    ("WED", "Intervals",      "4 x 600m @ 2:32. 2.5 min rest. (Deload: fewer reps)", I),
    ("THU", "REST",           "Full rest.",                                            R),
    ("FRI", "Speed",          "5 x 200m @ 47 sec. 90 sec rest.",                     H),
    ("SAT", "Easy + Pull-ups","25 min easy + 4 sets pull-ups.",                       E),
    ("SUN", "REST",           "Full rest. Critical recovery.",                        R),
]
story.append(week_block(8, dr(8), "DELOAD WEEK", w8_sessions, "Body adapts. Don't skip rest.", C_BLUE))

story.append(PageBreak())

# ── PHASE 3: RACE-SPECIFIC (Weeks 9-12) ──────────────────────────────────────
story.append(phase_hdr("PHASE 3: RACE-SPECIFIC  (Weeks 9-12)", "Near goal pace. 800m reps. Second time trial Week 9.", C_ACCENT))
story.append(Spacer(1,2*mm))

w9_sessions = [
    ("MON", "Easy Run",       "35 min @ 5:50/km.",                                    E),
    ("TUE", "Recovery + PT",  "20 min easy. Heavy PT: split squat 4x10, jump squats 4x6, calf 4x20, plank 3x50s.", R),
    ("WED", "TIME TRIAL",     "1600m solo TT. Warm-up 10 min. Full effort. TARGET: Sub 5:55. Note exact time.", H),
    ("THU", "Recovery Run",   "20 min very easy. Light jog only.",                    R),
    ("FRI", "Intervals",      "4 x 800m @ 3:20 each. 3 min full rest. Race pace effort.", I),
    ("SAT", "Easy + Pull-ups","30 min easy + strides 6x80m + 5 sets pull-ups.",       E),
    ("SUN", "REST",           "Full rest.",                                            R),
]
story.append(week_block(9, dr(9), "TIME TRIAL WK", w9_sessions, "TARGET: Sub 5:55 on TT.", C_ACCENT))

w10_sessions = [
    ("MON", "Long Run",       "40 min @ 5:45/km. Peak aerobic session.",              E),
    ("TUE", "Recovery + PT",  "25 min easy. Full PT: split squat 4x10, push-ups 4x20, pull-ups 5 sets, plank 3x55s.", R),
    ("WED", "Intervals",      "6 x 400m @ 1:30. 2 min rest. Near goal race pace.", I),
    ("THU", "Recovery Run",   "20 min easy.",                                          R),
    ("FRI", "Tempo",          "3 x 1000m @ 4:35/km pace. 2.5 min rest. Sustained effort.", T),
    ("SAT", "Easy + Pull-ups","30 min easy + 6 strides + 5 sets pull-ups.",           E),
    ("SUN", "REST",           "Full rest.",                                            R),
]
story.append(week_block(10, dr(10), "PEAK WEEK", w10_sessions, "Hardest week of plan.", C_RED))

w11_sessions = [
    ("MON", "Easy Run",       "30 min @ 6:00/km. Sharpen, don't fatigue.",            E),
    ("TUE", "Recovery + PT",  "20 min easy. PT: split squat 3x8, explosive push-ups 3x10, pull-ups 5 sets.", R),
    ("WED", "Intervals",      "8 x 300m @ 1:07 each. 2.5 min full rest. Short, sharp, fast.", I),
    ("THU", "Recovery Run",   "20 min very easy.",                                    R),
    ("FRI", "Speed",          "4 x 400m @ 1:28. 3 min full rest. This is race pace.", H),
    ("SAT", "Easy + Pull-ups","25 min easy + strides + 5 sets pull-ups.",             E),
    ("SUN", "REST",           "Full rest.",                                            R),
]
story.append(week_block(11, dr(11), "SHARPEN", w11_sessions, "", C_ACCENT))

# ── PHASE 4: TAPER (Weeks 12-14) ─────────────────────────────────────────────
story.append(phase_hdr("PHASE 4: TAPER  (Weeks 12-14 + Rally Day)", "Cut volume. Keep sharpness. Arrive fresh on rally day.", C_BLUE))
story.append(Spacer(1,2*mm))

w12_sessions = [
    ("MON", "Easy Run",       "25 min @ 6:20/km. Feel light.",                        E),
    ("TUE", "Recovery + PT",  "15 min easy. Light PT only: 2x10 squats, 3 sets pull-ups.", R),
    ("WED", "Sharpener",      "5 x 400m @ 1:28. 3 min rest. Keep the feel of fast.", I),
    ("THU", "REST",           "Full rest. Stay off feet.",                             R),
    ("FRI", "Strides Only",   "15 min easy + 5 x 80m strides. Feel fast, don't tire.", E),
    ("SAT", "Easy + Pull-ups","20 min easy + 4 sets pull-ups. Body is resting.",       E),
    ("SUN", "REST",           "Full rest.",                                            R),
]
story.append(week_block(12, dr(12), "TAPER", w12_sessions, "Volume drops 40%. Keep race feel.", C_BLUE))

w13_sessions = [
    ("MON", "Easy Run",       "20 min @ 6:30/km. Very light.",                        E),
    ("TUE", "Recovery + PT",  "15 min easy. 3 sets pull-ups only.",                   R),
    ("WED", "Race Rehearsal", "4 x 400m @ 1:22 (goal race pace). 3 min full rest. Run EXACTLY how you'll race.", H),
    ("THU", "REST",           "Full rest.",                                            R),
    ("FRI", "Strides",        "10 min easy + 4 x 80m strides. Legs should feel springy.", E),
    ("SAT", "Easy Walk",      "20 min easy walk only. Stay active, not tired.",        R),
    ("SUN", "REST",           "Full rest. Visualise the race.",                        R),
]
story.append(week_block(13, dr(13), "FINAL TAPER", w13_sessions, "Legs must feel fresh by Thursday.", C_BLUE))

# Week 14 (partial - only 3 days to rally Nov 21)
w14_sessions = [
    ("MON", "Easy Jog",       "15 min very easy. Shake out legs. 3 x 80m strides.",  E),
    ("TUE", "Complete REST",  "No running. Sleep well. Eat properly. Hydrate.",       R),
    ("WED", "RALLY DAY",      "Nov 19 prep: Light walk only. Sleep early. Pack kit.", R),
    ("THU", "RALLY DAY -2",   "Nov 20: Eat carbs. Rest fully. Visualise 4 laps.",    R),
    ("FRI", "RALLY DAY -1",   "Nov 20: Light 10 min jog + 3 strides. Stay loose.",   E),
    ("SAT", "RALLY DAY",      "21 NOV: Warm up 15 min. 4 x 80m strides. RACE. Sub 5:30!", H),
    ("SUN", "-",              "-",                                                    R),
]
story.append(week_block(14, "10 Nov – 21 Nov", "RALLY WEEK", w14_sessions, "RACE DAY: 21 NOV 2026", C_RED))

story.append(PageBreak())

# ── EMERGENCY PROTOCOL ────────────────────────────────────────────────────────
story.append(banner("EMERGENCY PROTOCOL - Activate If Behind After Week 5 TT", C_RED, C_WHITE, 11, 7))
story.append(Spacer(1, 2*mm))

emerg_note = Paragraph(
    "If your Week 5 TT is over 6:40 OR Week 9 TT is over 6:15, drop this plan and follow the Emergency Protocol below for the remaining weeks until rally.",
    S("en", fontSize=8.5, textColor=C_RED, fontName="Helvetica-Bold", leading=12)
)
story.append(emerg_note)
story.append(Spacer(1, 2*mm))

# Emergency weekly template
em_sessions = [
    ("MON", "Short Easy Run", "25 min @ 6:30/km. No more. Protect recovery.", E),
    ("TUE", "Intervals A",    "6 x 400m @ TARGET pace (1:22). 2 min rest. FULL effort.", I),
    ("WED", "REST",           "Complete rest. Legs must recover for Thursday.", R),
    ("THU", "Intervals B",    "8 x 200m @ 40 sec. 75 sec rest. Pure speed.", H),
    ("FRI", "REST",           "Complete rest.", R),
    ("SAT", "Race Sim",       "2 x 800m @ 2:45 each. 4 min full rest. Simulate race effort.", I),
    ("SUN", "REST",           "Full rest.", R),
]

em_tbl_hdr = Table([[
    Paragraph("EMERGENCY WEEKLY TEMPLATE", S("eht", fontSize=10, textColor=C_WHITE, fontName="Helvetica-Bold", alignment=TA_CENTER)),
    Paragraph("Repeat this structure every week until rally. Cut all long runs.", S("ehd", fontSize=8, textColor=C_LIGHT, fontName="Helvetica", alignment=TA_CENTER)),
]], colWidths=[PAGE_W])
em_tbl_hdr.setStyle(TableStyle([
    ("BACKGROUND",    (0,0),(-1,-1), C_RED),
    ("TOPPADDING",    (0,0),(-1,-1), 5),
    ("BOTTOMPADDING", (0,0),(-1,-1), 5),
]))
story.append(em_tbl_hdr)

em_rows = []
for day, label, detail, bg in em_sessions:
    em_rows.append([
        Paragraph(day,    S("ed", fontSize=8, textColor=C_DARK, fontName="Helvetica-Bold")),
        Paragraph(label,  S("el", fontSize=8, textColor=C_DARK, fontName="Helvetica-Bold", leading=10)),
        Paragraph(detail, S("eds",fontSize=7.5,textColor=colors.HexColor("#2C3E50"), fontName="Helvetica", leading=10)),
    ])
em_body = Table(em_rows, colWidths=[12*mm, 40*mm, PAGE_W-52*mm])
em_ts = TableStyle([
    ("GRID",         (0,0),(-1,-1), 0.3, C_MID),
    ("TOPPADDING",   (0,0),(-1,-1), 3),
    ("BOTTOMPADDING",(0,0),(-1,-1), 3),
    ("LEFTPADDING",  (0,0),(-1,-1), 5),
    ("VALIGN",       (0,0),(-1,-1), "TOP"),
])
for i, (day, label, detail, bg) in enumerate(em_sessions):
    em_ts.add("BACKGROUND", (0,i),(2,i), bg)
em_body.setStyle(em_ts)
story.append(em_body)
story.append(Spacer(1, 4*mm))

# ── PROGRESS TRACKER ─────────────────────────────────────────────────────────
story.append(banner("PROGRESS TRACKER - Fill In After Each Time Trial", C_DARK, C_GOLD, 10))
story.append(Spacer(1, 2*mm))
track_data = [
    [Paragraph("Check Point", cell_bw), Paragraph("Date", cell_bw), Paragraph("Target", cell_bw),
     Paragraph("Your Time", cell_bw), Paragraph("Status", cell_bw)],
    [Paragraph("Baseline",   cell_b), Paragraph("12 Aug",   cell_s), Paragraph("7:00",    cell_s), Paragraph("7:00",     cell_s), Paragraph("Start",     cell_s)],
    [Paragraph("Week 5 TT",  cell_b), Paragraph("~12 Sep",  cell_s), Paragraph("Sub 6:20",cell_s), Paragraph("________", cell_s), Paragraph("________",  cell_s)],
    [Paragraph("Week 9 TT",  cell_b), Paragraph("~9 Oct",   cell_s), Paragraph("Sub 5:55",cell_s), Paragraph("________", cell_s), Paragraph("________",  cell_s)],
    [Paragraph("RALLY DAY",  cell_b), Paragraph("21 Nov",   cell_s), Paragraph("Sub 5:30",cell_s), Paragraph("________", cell_s), Paragraph("________",  cell_s)],
]
track_tbl = Table(track_data, colWidths=[32*mm, 28*mm, 30*mm, 32*mm, PAGE_W-122*mm])
track_tbl.setStyle(TableStyle([
    ("BACKGROUND",    (0,0),(-1,0),  C_DARK),
    ("ROWBACKGROUNDS",(0,1),(-1,-1), [C_LIGHT, C_INTER, C_TEMPO, C_HARD]),
    ("GRID",          (0,0),(-1,-1), 0.5, C_MID),
    ("TOPPADDING",    (0,0),(-1,-1), 5),
    ("BOTTOMPADDING", (0,0),(-1,-1), 5),
    ("LEFTPADDING",   (0,0),(-1,-1), 6),
    ("VALIGN",        (0,0),(-1,-1), "MIDDLE"),
]))
story.append(track_tbl)
story.append(Spacer(1, 4*mm))

# ── GOLDEN RULES ─────────────────────────────────────────────────────────────
story.append(banner("5 NON-NEGOTIABLE RULES FOR RALLY SUCCESS", C_BG, C_WHITE, 10))
story.append(Spacer(1, 2*mm))
rules = [
    ("1. Wednesday intervals are sacred",
     "Miss any session except Wednesday. Never skip intervals - this is where your 5:30 comes from."),
    ("2. Easy runs stay EASY",
     "If your easy run feels hard, you are running too fast. Slow down by 30 sec/km. This is not laziness - it is recovery."),
    ("3. Never add extra hard sessions",
     "When behind, the instinct is to run more. Don't. Quality over quantity always wins."),
    ("4. Check morning HR daily",
     "Before getting up: if HR is 7+ BPM above normal, take an extra rest day. No exceptions."),
    ("5. The last 10 days decide nothing",
     "Fitness is built in Weeks 1-11. Weeks 12-14 are for showing up fresh. Rest is not weakness."),
]
for title, detail in rules:
    r_tbl = Table([[
        Paragraph(title,  rule_s),
        Paragraph(detail, rule_d),
    ]], colWidths=[60*mm, PAGE_W-60*mm])
    r_tbl.setStyle(TableStyle([
        ("BACKGROUND",    (0,0),(0,0), C_DARK),
        ("BACKGROUND",    (1,0),(1,0), C_CARD),
        ("TOPPADDING",    (0,0),(-1,-1), 5),
        ("BOTTOMPADDING", (0,0),(-1,-1), 5),
        ("LEFTPADDING",   (0,0),(-1,-1), 7),
        ("VALIGN",        (0,0),(-1,-1), "MIDDLE"),
        ("LINEBELOW",     (0,0),(-1,-1), 0.3, colors.HexColor("#2C3E6B")),
    ]))
    story.append(r_tbl)

story.append(Spacer(1, 4*mm))
story.append(Paragraph(
    "Orris Training Assistant  |  Rally: 21 November 2026  |  Target: Sub 5:30  |  14 weeks 3 days remaining",
    S("ft", fontSize=7, textColor=C_MID, fontName="Helvetica-Oblique", alignment=TA_CENTER)
))

doc = SimpleDocTemplate(
    OUTPUT,
    pagesize=A4,
    rightMargin=13*mm, leftMargin=13*mm,
    topMargin=10*mm, bottomMargin=10*mm,
    title="Emergency Catch-Up Plan - Territorial Army Rally",
)
doc.build(story)
print(f"PDF saved: {OUTPUT}")
Running Command

cd /tmp/workspace/running-plan && python generate_emergency.py 2>&1

Running Command

ls -lh /tmp/workspace/running-plan/

Your Emergency Catch-Up Plan is ready. Download it here:

emergency catchup plan

PDF Document · PDF


What's Inside (4 Pages)

Page 1 - Rally Intel + Trigger System

  • Territorial Army Rally requirements - 1600m sub 5:30, pull-ups, ditch jump, zig-zag
  • Exact 400m lap splits for sub 5:30 (Lap 1: 80s, Lap 2: 82s, Lap 3: 83s, Lap 4: 79s)
  • Catch-Up Trigger table - tells you exactly when to activate emergency mode based on your Week 5 and Week 9 time trials

Pages 2-3 - Full 14-Week Schedule (Aug 12 to Nov 21)

Every week with exact dates, exact paces, and every PT session (pull-ups, squats, split squats) built in. Divided into:
  • Phase 1 (Wk 1-4): Aerobic base with deload
  • Phase 2 (Wk 5-8): Speed development, first TT Week 5
  • Phase 3 (Wk 9-12): Race-specific, second TT Week 9
  • Phase 4 (Wk 12-14): Taper into rally day

Page 4 - Emergency Protocol + Tracker

  • Emergency weekly template - what to do if you're badly behind (strip everything except 2 interval sessions + race sim)
  • Progress tracker - fill in your TT times at Week 5, 9, and rally day
  • 5 non-negotiable rules for rally success

Your Key Dates

DateEventTarget
~12 SepWeek 5 Time TrialSub 6:20
~9 OctWeek 9 Time TrialSub 5:55
21 NovRally DaySub 5:30
You have exactly 14 weeks and 3 days. That's enough time if you start today.

3 and 4

Could you clarify what "3 and 4" refers to?
Asking for Preferences

What do you mean by 3 and 4?

Got it - you want a budget-friendly diet to support your training. One more quick question:
Asking for Preferences

What type of food do you eat?

Here's your complete budget-friendly runner's diet:

What Your Body Needs for 1600m Training

NutrientWhyDaily Target
CarbsFuel for intervals and speed work55-60% of calories
ProteinMuscle repair after hard sessions1.4-1.6g per kg body weight
FatsHormone production, joint health25-30% of calories
WaterPerformance drops 5% when even slightly dehydrated3-4 litres/day

Budget Daily Meal Plan

Morning (Pre-Run or Breakfast)

Option A - Before early run:
  • 1 banana + a handful of peanuts (quick carbs + fat = 15 min before run)
Full breakfast after run:
  • 2-3 eggs (any style) + 2 slices bread/roti
  • OR oats with milk + 1 banana
Why: Eggs are the cheapest complete protein. Oats are slow-release carbs that sustain energy through the day.

Mid-Morning Snack

  • 1 banana OR handful of roasted chana (chickpeas)
  • OR peanut butter on bread
Cost: Almost nothing. Chana is one of the best runner snacks - cheap, high protein, high carb.

Lunch (Biggest Meal of Day)

Budget plate:
  • Rice (2 cups cooked) or 3-4 rotis
  • Dal / lentils / rajma / chana (1 bowl) - your main protein source
  • Any vegetable sabzi
  • Curd/yoghurt if available
Why this works: Dal + rice = complete amino acid profile. This is the best cheap runner meal that exists.

Pre-Training Snack (1-1.5 hrs before run)

  • 1 banana + 2 biscuits
  • OR bread with peanut butter
  • OR handful of dates (if available - great quick energy)
Avoid: Heavy oily food within 2 hours of running. You will cramp.

Post-Training (Within 30-45 Minutes - CRITICAL)

This is the most important meal of the day for recovery and improvement.
Must have: Carbs + Protein together
  • 2 eggs + 2 rotis/bread
  • OR milk (1 glass) + banana
  • OR curd rice
  • OR dal + rice
Why: The 30-45 min window after running is when muscles absorb protein most efficiently. Miss this and your recovery is 30% worse.

Dinner

  • Same as lunch structure: roti/rice + dal or chicken/eggs + vegetable
  • Slightly smaller than lunch
  • Eat at least 2 hours before sleeping

Weekly Budget-Friendly Shopping List

ItemWhy Buy ItApprox Cost
Eggs (dozen)Best cheap proteinLow
Dal / lentils (500g)Protein + carbsVery low
Bananas (bunch)Pre/post run fuelVery low
Oats (500g)Breakfast carbs, lasts weeksLow
Peanuts / peanut butterHealthy fats + proteinLow
Milk (1L/day if possible)Protein + calciumModerate
Rice / atta (flour)Base carbsVery low
Seasonal vegetablesVitamins, mineralsVery low
Chana (chickpeas)Snack proteinVery low
Total weekly cost is very low if you stick to these basics. No supplements needed at your level.

Training Day vs. Rest Day Eating

DayAdjust How
Hard session (Wed/Fri)Eat more carbs - extra roti/rice at lunch
Easy / recovery dayNormal portions, slightly less carbs
Rest day (Sunday)Slightly less food overall, same protein
Day before time trialEat more carbs the evening before - rice/roti heavy dinner

3 Biggest Diet Mistakes Runners Make

  1. Not eating after runs - skipping the post-run meal destroys recovery. Even a banana + glass of milk is enough.
  2. Not drinking enough water - most runners are chronically dehydrated. Urine should be pale yellow. Dark yellow = drink more.
  3. Eating too little on hard days - intervals burn a lot of fuel. Undereating means your next session will be slower.

Simple Rule to Remember

Before run: Banana or light carbs After run: Protein + carbs within 45 min Every day: 3-4 litres water Hard day: Eat more carbs at lunch and dinner
No expensive supplements needed. Eggs, dal, rice, banana and milk will take you to sub-5:30. Consistency in eating matters more than perfect nutrition.

I will do the running in the evening

Good - evening running actually has some advantages. Here's how to adjust the entire eating schedule around evening training:

Evening Runner Meal Timing

TimeMealWhat to Eat
7:00-8:00 AMBreakfastOats + milk + banana OR 2 eggs + 2 rotis. Full meal.
11:00-12:00 PMLunchRice/roti + dal + vegetable + curd. Biggest meal of day.
3:00-4:00 PMPre-run snack1 banana + handful peanuts OR bread + peanut butter.
5:00-6:00 PMRUNTraining session
6:30-7:00 PMPost-run mealProtein + carbs within 45 min. (Most important)
8:30-9:00 PMDinnerLight - roti + dal/eggs + vegetables. Not too heavy.

The 2 Key Adjustments for Evening Running

1. Pre-Run Snack (3-4 PM) is Now Critical

You have been awake and active all day. By 5 PM your energy is lower than morning. The 3-4 PM snack is what fuels your intervals.
Best pre-run snacks (1.5-2 hrs before running):
  • Banana + peanuts
  • Bread + peanut butter
  • Rice/roti (small portion) from leftover lunch
  • Dates (3-4) - fastest energy if you feel low
Avoid 2 hrs before run:
  • Heavy oily food
  • Large full meals
  • Milk or curd right before (can cause cramps)

2. Post-Run Dinner Timing

After an evening run your dinner IS your recovery meal. Eat within 45 minutes.
Evening post-run meal (best options):
  • 3 eggs + 2 rotis
  • Dal rice + curd
  • Chicken + roti (if non-veg)
  • Milk + banana + handful chana
Keep dinner moderate - not so heavy that you can't sleep. Eating too much right before bed disrupts sleep quality, and sleep is when your body actually improves.

Why Evening Running Has Advantages

  • Body temperature peaks in late afternoon - muscles are warmer, reaction time faster
  • Lung function is slightly better in evening
  • You are fully fuelled from the whole day's eating
  • Research shows interval performance is 3-5% better at 5-6 PM vs. 6 AM

One Thing to Watch

Don't run after 8 PM if possible. Hard intervals at night raise cortisol and adrenaline, which can make it hard to sleep. Poor sleep = poor recovery = slower improvement. 5-7 PM is the sweet spot.

Updated Simple Daily Rule

Morning:   Full breakfast (eggs/oats)
Afternoon: Full lunch (dal + rice)
3-4 PM:    Light snack (banana + peanuts)
5-6 PM:    RUN
6:30 PM:   Recovery meal (protein + carbs) within 45 min
8:30 PM:   Light dinner
10-11 PM:  Sleep (minimum 7-8 hours)
Stick to this timing and your body will have fuel when it needs it and recovery nutrients exactly when muscles are absorbing them best.

Any equipment needed

Your credits are exhausted. You can purchase a top-up or subscribe to a plan to continue using Orris. If you're already subscribed, your daily credits will reset tomorrow.

How can i build my physique with running

Your credits are exhausted. You can purchase a top-up or subscribe to a plan to continue using Orris. If you're already subscribed, your daily credits will reset tomorrow.
This is a shared conversation. Sign in to Orris to start your own chat.