.zwift-hr-calculator-wrapper {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
max-width: 800px;
margin: 0 auto;
color: #333;
line-height: 1.6;
}
.zwift-calc-container {
background: #f0f3f5;
padding: 30px;
border-radius: 8px;
box-shadow: 0 4px 15px rgba(0,0,0,0.1);
margin-bottom: 40px;
border-left: 5px solid #fc6100; /* Zwift Orange */
}
.zwift-calc-title {
text-align: center;
color: #2c3e50;
margin-bottom: 25px;
font-size: 24px;
font-weight: 700;
}
.form-group {
margin-bottom: 20px;
}
.form-group label {
display: block;
margin-bottom: 8px;
font-weight: 600;
color: #444;
}
.form-group input {
width: 100%;
padding: 12px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 16px;
box-sizing: border-box;
}
.form-group input:focus {
border-color: #fc6100;
outline: none;
box-shadow: 0 0 0 2px rgba(252, 97, 0, 0.2);
}
.calc-btn {
background-color: #fc6100;
color: white;
border: none;
padding: 15px 30px;
font-size: 18px;
font-weight: bold;
border-radius: 4px;
cursor: pointer;
width: 100%;
transition: background-color 0.2s;
text-transform: uppercase;
letter-spacing: 1px;
}
.calc-btn:hover {
background-color: #e55800;
}
.results-section {
display: none;
margin-top: 30px;
background: white;
padding: 20px;
border-radius: 6px;
}
.zone-table {
width: 100%;
border-collapse: collapse;
margin-top: 15px;
}
.zone-table th, .zone-table td {
padding: 12px;
text-align: left;
border-bottom: 1px solid #eee;
}
.zone-table th {
background-color: #f8f9fa;
font-weight: 700;
}
/* Zwift Zone Colors */
.z1-row { border-left: 6px solid #7e8083; } /* Gray */
.z2-row { border-left: 6px solid #3284c4; } /* Blue */
.z3-row { border-left: 6px solid #5ac05a; } /* Green */
.z4-row { border-left: 6px solid #ffd800; } /* Yellow */
.z5-row { border-left: 6px solid #ff420e; } /* Orange/Red */
.zone-badge {
padding: 4px 8px;
border-radius: 4px;
color: white;
font-weight: bold;
font-size: 12px;
display: inline-block;
width: 60px;
text-align: center;
}
.bg-z1 { background-color: #7e8083; }
.bg-z2 { background-color: #3284c4; }
.bg-z3 { background-color: #5ac05a; }
.bg-z4 { background-color: #ffd800; color: #333; }
.bg-z5 { background-color: #ff420e; }
.helper-text {
font-size: 13px;
color: #666;
margin-top: 5px;
}
/* Content Styling */
.content-section h2 {
color: #2c3e50;
margin-top: 40px;
border-bottom: 2px solid #fc6100;
padding-bottom: 10px;
display: inline-block;
}
.content-section h3 {
color: #444;
margin-top: 30px;
}
.content-section p {
margin-bottom: 15px;
}
.content-section ul {
margin-bottom: 20px;
padding-left: 20px;
}
.content-section li {
margin-bottom: 10px;
}
How Does Zwift Calculate Heart Rate Zones?
Understanding your heart rate zones is critical for effective training on Zwift. While power (measured in watts) is the primary metric for structured workouts, heart rate remains a vital bio-feedback mechanism to gauge internal stress and recovery.
By default, Zwift utilizes a traditional 5-zone model derived from your Maximum Heart Rate (Max HR). When you first set up your profile, Zwift estimates this using the standard formula: 220 - Age. However, you can (and should) manually update this number in your user profile settings if you have performed a max effort test or a ramp test.
The 5 Zwift Heart Rate Zones Explained
Zwift uses a distinct color-coded system displayed on the HUD (Heads-Up Display) during your ride. Each color corresponds to a specific physiological state:
- Zone 1 (Gray) – Recovery: (50-59% Max HR). Very light effort, used for warm-ups, cool-downs, and active recovery between hard intervals. You should be able to hold a conversation easily.
- Zone 2 (Blue) – Endurance: (60-69% Max HR). The "bread and butter" zone for building aerobic base. You can ride here for hours. It builds fat-burning efficiency and mitochondrial density.
- Zone 3 (Green) – Tempo: (70-79% Max HR). Often called "Sweet Spot" in power terms, though HR Zone 3 is slightly lower. This requires concentration to maintain but is sustainable for 60-90 minutes.
- Zone 4 (Yellow) – Threshold: (80-89% Max HR). This is riding at or near your FTP (Functional Threshold Power). Your muscles start burning lactate. Sustainable for 10 to 60 minutes depending on fitness.
- Zone 5 (Orange/Red) – Anaerobic/Max: (90-100% Max HR). Maximum exertion. Used for sprints, steep climbs, or attacks. This zone is sustainable for only very short durations (seconds to a few minutes).
Heart Rate vs. Power Zones
It is important to note that Zwift calculates Power Zones (based on FTP) differently than Heart Rate Zones (based on Max HR). Power is instantaneous, whereas heart rate has a "lag." When you start a sprint, your power spikes instantly, but your heart rate may take 30 seconds to climb into Zone 5.
For the most accurate training, ensure your Max HR is set correctly in the "My Profile" section of the Zwift menu. Using the calculator above will help you identify exactly where your BPM boundaries lie so you can pace your efforts effectively during events like the Tour de Zwift or Zwift Academy.
function calculateZwiftZones() {
var ageInput = document.getElementById('riderAge').value;
var maxHRInput = document.getElementById('riderMaxHR').value;
var resultContainer = document.getElementById('resultContainer');
var displayMaxHR = document.getElementById('displayMaxHR');
var tableBody = document.getElementById('zoneTableBody');
var maxHR = 0;
// Logic: Use manual Max HR if available, otherwise calculate from age
if (maxHRInput && parseFloat(maxHRInput) > 0) {
maxHR = parseFloat(maxHRInput);
} else if (ageInput && parseFloat(ageInput) > 0) {
maxHR = 220 – parseFloat(ageInput);
} else {
alert("Please enter your Age or a known Max Heart Rate.");
return;
}
// Calculations based on standard Zwift/Standard 5-zone model
// Z1: 50-59%
// Z2: 60-69%
// Z3: 70-79%
// Z4: 80-89%
// Z5: 90-100%
var z1_min = Math.round(maxHR * 0.50);
var z1_max = Math.round(maxHR * 0.59);
var z2_min = Math.round(maxHR * 0.60);
var z2_max = Math.round(maxHR * 0.69);
var z3_min = Math.round(maxHR * 0.70);
var z3_max = Math.round(maxHR * 0.79);
var z4_min = Math.round(maxHR * 0.80);
var z4_max = Math.round(maxHR * 0.89);
var z5_min = Math.round(maxHR * 0.90);
var z5_max = maxHR;
// Generate HTML for Table Rows
var html = ";
// Zone 5 (Red/Orange) – Reverse order typically good for tables, but standard is 1-5
// Let's do 1 to 5 for clarity
// Zone 1
html += '
';
// Update DOM
displayMaxHR.innerText = Math.round(maxHR);
tableBody.innerHTML = html;
resultContainer.style.display = 'block';
}