Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Training Load</title> | |
| <link rel="icon" type="image/webp" href="/icon.webp"> | |
| <link rel="stylesheet" href="/src/style.css"> | |
| </head> | |
| <body> | |
| <div id="app"> | |
| <header> | |
| <div class="header-title"> | |
| <img src="/icon.webp" alt="Training Load Icon" class="header-icon" /> | |
| <h1>Training Load</h1> | |
| </div> | |
| <div class="header-controls"> | |
| <div class="ftp-input-container"> | |
| <label for="ftp-input">FTP</label> | |
| <input type="number" id="ftp-input" value="343" min="0" step="1" placeholder="343" /> | |
| <span class="ftp-unit">W</span> | |
| </div> | |
| <div class="ftp-input-container"> | |
| <label for="target-acwr-input">Target ACWR</label> | |
| <input type="number" id="target-acwr-input" value="1.2" min="0.5" max="3" step="0.1" | |
| placeholder="1.2" /> | |
| </div> | |
| <div class="ftp-input-container"> | |
| <label for="predict-today-input" | |
| style="display: flex; align-items: center; gap: 0.5rem; cursor: pointer;"> | |
| <input type="checkbox" id="predict-today-input" style="width: auto; margin: 0;" /> | |
| <span>Predict today</span> | |
| </label> | |
| </div> | |
| <div class="ftp-input-container"> | |
| <label for="threshold-hr-input">Threshold HR</label> | |
| <input type="number" id="threshold-hr-input" value="190" min="100" max="220" step="1" | |
| placeholder="170" /> | |
| <span class="ftp-unit">bpm</span> | |
| </div> | |
| <div class="ftp-input-container"> | |
| <label for="resting-hr-input">Resting HR</label> | |
| <input type="number" id="resting-hr-input" value="53" min="30" max="100" step="1" | |
| placeholder="50" /> | |
| <span class="ftp-unit">bpm</span> | |
| </div> | |
| <input type="file" id="csv-upload" accept=".csv" /> | |
| <label for="csv-upload" class="upload-label"> | |
| π Upload CSV | |
| </label> | |
| <button id="help-button" class="help-button" title="Help"> | |
| <span>?</span> | |
| </button> | |
| </div> | |
| </header> | |
| <section id="filter-section" class="hidden"> | |
| <div class="filter-container" id="filter-container"> | |
| <!-- Activity type filters will be dynamically generated here --> | |
| </div> | |
| </section> | |
| <main> | |
| <div id="upload-status"></div> | |
| <section id="charts-section" class="hidden"> | |
| <div class="chart-container"> | |
| <h2>πΊοΈ Distance-based ACWR <span id="distance-acwr-display" class="acwr-display"></span></h2> | |
| <div id="distance-target" class="target-info"></div> | |
| <canvas id="distance-chart"></canvas> | |
| </div> | |
| <div class="chart-container"> | |
| <h2>β±οΈ Duration-based ACWR <span id="duration-acwr-display" class="acwr-display"></span></h2> | |
| <div id="duration-target" class="target-info"></div> | |
| <canvas id="duration-chart"></canvas> | |
| </div> | |
| <div class="chart-container"> | |
| <h2>π₯΅ TSS-based ACWR <span id="tss-acwr-display" class="acwr-display"></span></h2> | |
| <div id="tss-target" class="target-info"></div> | |
| <canvas id="tss-chart"></canvas> | |
| </div> | |
| <div class="chart-container"> | |
| <h2>π Calories-based ACWR <span id="calories-acwr-display" class="acwr-display"></span></h2> | |
| <div id="calories-target" class="target-info"></div> | |
| <canvas id="calories-chart"></canvas> | |
| </div> | |
| <div class="legend"> | |
| <div class="legend-item"> | |
| <span class="legend-color low"></span> | |
| <span>ACWR < 0.8 - Detraining risk</span> | |
| </div> | |
| <div class="legend-item"> | |
| <span class="legend-color optimal"></span> | |
| <span>ACWR 0.8 - 1.3 - Optimal</span> | |
| </div> | |
| <div class="legend-item"> | |
| <span class="legend-color warning"></span> | |
| <span>ACWR 1.3 - 1.5 - Warning</span> | |
| </div> | |
| <div class="legend-item"> | |
| <span class="legend-color high"></span> | |
| <span>ACWR > 1.5 - Injury risk</span> | |
| </div> | |
| </div> | |
| </section> | |
| </main> | |
| </div> | |
| <div id="help-popover" class="help-popover hidden"> | |
| <div class="help-popover-content"> | |
| <button id="help-close" class="help-close">×</button> | |
| <h2>π Glossary</h2> | |
| <div class="help-section"> | |
| <h3>ACWR - Acute:Chronic Workload Ratio</h3> | |
| <p>The ratio between your recent training load (acute: last 7 days) and your longer-term training load | |
| (chronic: last 28 days). Used to manage training progression and injury risk.</p> | |
| <ul> | |
| <li><strong>< 0.8 (Blue):</strong> Detraining risk - you may be losing fitness</li> | |
| <li><strong>0.8 - 1.3 (Green):</strong> Optimal zone - ideal training progression</li> | |
| <li><strong>1.3 - 1.5 (Orange):</strong> Warning - pushing the limits</li> | |
| <li><strong>> 1.5 (Red):</strong> Injury risk - training load may be too high</li> | |
| </ul> | |
| </div> | |
| <div class="help-section"> | |
| <h3>TSS - Training Stress Score</h3> | |
| <p>A composite metric that quantifies the overall training stress of a workout, taking into account both | |
| intensity (Normalized Power) and duration.</p> | |
| <p><strong>Formula:</strong> TSS = (Duration Γ NP Γ IF) / (FTP Γ 3600) Γ 100</p> | |
| </div> | |
| <div class="help-section"> | |
| <h3>FTP - Functional Threshold Power</h3> | |
| <p>The highest average power you can sustain for approximately one hour, measured in watts. Used as a | |
| baseline for calculating training intensity and TSS.</p> | |
| </div> | |
| <div class="help-section"> | |
| <h3>NP - Normalized Power</h3> | |
| <p>A power measurement that accounts for the variable nature of your effort during a workout, providing | |
| a more accurate representation of the physiological cost than average power.</p> | |
| </div> | |
| <div class="help-section"> | |
| <h3>IF - Intensity Factor</h3> | |
| <p>The ratio of Normalized Power to FTP (IF = NP / FTP). Indicates how hard a workout was relative to | |
| your threshold.</p> | |
| </div> | |
| </div> | |
| </div> | |
| <div id="activity-popover" class="activity-popover hidden"> | |
| <div class="activity-popover-content"> | |
| <button id="activity-close" class="help-close">×</button> | |
| <h2 id="activity-date-title"></h2> | |
| <div id="activity-list"></div> | |
| </div> | |
| </div> | |
| <script type="module" src="/src/main.ts"></script> | |
| </body> | |
| </html> |