{% if offset == 0 %}

{{ title }}

{% if best_fit_formula and not forecast_enabled %}

{{ best_fit_formula.kg_per_week }} kg/week, {{ best_fit_formula.kg_per_month }} kg/month

{% else %}
{% endif %} {% if forecast_enabled and forecast.available %}
Upcoming sessions

Approximate dates, every {{ forecast.profile.cadence_days }} days. These are scenarios based on your recent routine.

{% if forecast.stale %}

Historical projection from {{ forecast.last_date.strftime('%d %b %Y') }}. Log recent workouts to update.

{% endif %}
{% for point in forecast.session_points %} {% endfor %}
AroundTop-set scenarioEst. 1RME1RM range
{{ point.date.strftime('%d %b %Y') }} {{ point.set_display }} {{ point.value }} kg{{ point.lower }}–{{ point.upper }} range {{ point.lower }}–{{ point.upper }} kg
{% if not forecast.session_points %}

No session expected inside this horizon at your recent cadence.

{% endif %}
Why this forecast?
{{ forecast.observed_points }} sessions since {{ forecast.training_start.strftime('%d %b %Y') }} {{ forecast.training_blocks - 1 }} earlier training blocks excluded

At the current load: {{ forecast.profile.block_sessions }} sessions, from {{ forecast.profile.block_start_reps }} to a best of {{ forecast.profile.block_best_reps }} reps. {{ forecast.profile.block_stalls }} sessions did not improve that rep best.

{% if forecast.profile.increment and forecast.profile.ceiling_evidence >= 2 %}

Your recent load increases usually follow {{ forecast.profile.ceiling }} reps. The most common step is {{ '%g'|format(forecast.profile.increment) }} kg; forecasts use the recorded mix of steps. The model learns repeats, rep gains, difficult sessions and rep resets from this exercise.

{% else %}

There is not enough repeated loading history to infer a reliable rep threshold. Repeated sets remain a possible outcome.

{% endif %} {% if forecast.validation %} {% set validation = forecast.validation.transitions %}

Checked against {{ validation.count }} past next-session outcomes, each predicted using only earlier data: average error {{ validation.weight_mae }} kg load, {{ validation.reps_mae }} reps, {{ validation.e1rm_mae }} kg E1RM. Repeating the last set scored {{ forecast.validation.repeat.e1rm_mae }} kg E1RM error.

{% else %}

Too few sessions for a useful accuracy check yet.

{% endif %}

Ranges combine simulated outcomes with past forecast errors. They are not guaranteed limits. Each row is a representative outcome at that date; the rows are not a prescribed training plan. Longer horizons are less certain.

Equivalent loads at other rep counts · {{ forecast.end_date.strftime('%d %b %Y') }}

These are formula equivalents of {{ forecast.projected_value }} kg E1RM, not predictions that you will choose these sets. Rep range: {{ forecast.observed_rep_min }}–{{ forecast.observed_rep_max }} in view, expanded by ±{{ forecast.rep_buffer }}.

{% for top_set in forecast.top_sets %} {% endfor %}
RepsEquivalent loadLoad range
{{ top_set.repetitions }}{{ top_set.weight_display }} kg{{ top_set.lower_weight_display }}–{{ top_set.upper_weight_display }} kg

Rounded to {{ forecast.target_weight_increment_display }} kg display increments. Equivalents at rep counts far from your usual range are less reliable.

{% elif forecast_enabled %}

{{ forecast.reason }}

{% endif %} {% endif %} {% for topset in topsets %} {% endfor %} {% if topsets|length == limit %} {% elif topsets|length == 0 and offset == 0 %} {% endif %} {% if offset == 0 %}
Date Set & Achievements
{{ topset.start_date | strftime }}
{{ topset.repetitions }} x {{ topset.weight }}kg
No history found.
{% endif %}