houston-dawn-protocol/dawn-run-calculator.html

463 lines
17 KiB
HTML
Raw Normal View History

2026-07-18 23:57:00 +02:00
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Houston Dawn Run Fuel Calculator | Bhartiben Patel</title>
<link rel="stylesheet" href="styles.css">
<style>
/* Houston-specific palette: pre-dawn indigo, Gulf heat haze, asphalt charcoal */
:root {
--pre-dawn-indigo: #1A2332;
--gulf-haze: #A8B8CC;
--asphalt-charcoal: #2D2D2D;
--humidity-gold: #D4AF37;
--rice-paper: #F8F5F0;
--heat-stress-red: #C44536;
}
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: 'Georgia', serif;
background: var(--rice-paper);
color: var(--asphalt-charcoal);
line-height: 1.6;
}
.hero {
background: linear-gradient(135deg, var(--pre-dawn-indigo), #2A3B55);
color: white;
padding: 6rem 2rem;
text-align: center;
position: relative;
overflow: hidden;
}
.hero::before {
content: '';
position: absolute;
top: 0; left: 0; right: 0; bottom: 0;
background-image: url('https://images.pexels.com/photos/3264305/pexels-photo-3264305.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940');
background-position: center;
background-size: cover;
opacity: 0.15;
mix-blend-mode: overlay;
}
.hero h1 {
font-size: 3.5rem;
margin-bottom: 1rem;
position: relative;
z-index: 1;
letter-spacing: -0.02em;
}
.hero p {
font-size: 1.4rem;
opacity: 0.9;
position: relative;
z-index: 1;
max-width: 700px;
margin: 0 auto;
}
.calculator-container {
max-width: 1000px;
margin: 4rem auto;
padding: 0 2rem;
display: grid;
grid-template-columns: 1fr 1fr;
gap: 4rem;
}
.input-panel {
background: white;
padding: 3rem;
border-radius: 12px;
box-shadow: 0 8px 40px rgba(0,0,0,0.08);
border: 2px solid var(--gulf-haze);
}
.input-panel h2 {
font-size: 2rem;
color: var(--pre-dawn-indigo);
margin-bottom: 2rem;
border-bottom: 3px solid var(--humidity-gold);
padding-bottom: 1rem;
}
.form-group {
margin-bottom: 2rem;
}
label {
display: block;
font-size: 1.1rem;
font-weight: bold;
margin-bottom: 0.8rem;
color: var(--asphalt-charcoal);
}
input[type="number"], select {
width: 100%;
padding: 1rem;
border: 2px solid var(--gulf-haze);
border-radius: 8px;
font-size: 1.1rem;
font-family: inherit;
transition: border-color 0.3s ease;
}
input:focus, select:focus {
outline: none;
border-color: var(--pre-dawn-indigo);
}
.output-panel {
background: linear-gradient(135deg, var(--asphalt-charcoal), #1A1A1A);
color: white;
padding: 3rem;
border-radius: 12px;
box-shadow: 0 8px 40px rgba(0,0,0,0.15);
position: sticky;
top: 2rem;
}
.output-panel h2 {
font-size: 2rem;
margin-bottom: 2rem;
border-bottom: 3px solid var(--humidity-gold);
padding-bottom: 1rem;
}
.result-row {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1.5rem 0;
border-bottom: 1px solid rgba(255,255,255,0.1);
}
.result-label {
font-size: 1.15rem;
opacity: 0.9;
}
.result-value {
font-size: 2.2rem;
font-weight: bold;
color: var(--humidity-gold);
}
.result-unit {
font-size: 1rem;
opacity: 0.7;
margin-left: 0.5rem;
}
.warning-box {
background: rgba(196, 69, 54, 0.15);
border: 2px solid var(--heat-stress-red);
border-radius: 8px;
padding: 1.5rem;
margin-top: 2rem;
}
.warning-box h4 {
color: var(--heat-stress-red);
margin-bottom: 1rem;
font-size: 1.2rem;
}
.btn-calculate {
width: 100%;
padding: 1.2rem;
background: linear-gradient(135deg, var(--pre-dawn-indigo), #2A3B55);
color: white;
border: none;
border-radius: 8px;
font-size: 1.2rem;
font-weight: bold;
cursor: pointer;
transition: transform 0.2s ease, box-shadow 0.2s ease;
margin-top: 1rem;
}
.btn-calculate:hover {
transform: translateY(-2px);
box-shadow: 0 6px 20px rgba(26, 35, 50, 0.4);
}
.methodology {
max-width: 1000px;
margin: 4rem auto;
padding: 0 2rem;
}
.methodology h3 {
font-size: 2.2rem;
color: var(--pre-dawn-indigo);
margin-bottom: 2rem;
}
.citation-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 2rem;
margin-top: 3rem;
}
.citation-card {
background: white;
padding: 2rem;
border-radius: 12px;
box-shadow: 0 4px 20px rgba(0,0,0,0.06);
border-left: 4px solid var(--humidity-gold);
}
.citation-card h4 {
color: var(--pre-dawn-indigo);
margin-bottom: 1rem;
font-size: 1.3rem;
}
.citation-card p {
font-size: 1rem;
color: #5A4A42;
line-height: 1.7;
}
.formula-box {
background: var(--rice-paper);
border: 2px dashed var(--gulf-haze);
padding: 2rem;
border-radius: 12px;
margin: 2rem 0;
font-family: 'Courier New', monospace;
font-size: 1.1rem;
}
@media (max-width: 900px) {
.calculator-container {
grid-template-columns: 1fr;
}
.hero h1 {
font-size: 2.5rem;
}
}
</style>
<script defer src="https://analytics.4ort.xyz/script.js" data-website-id="d3ed927c-888a-4a6c-ae5f-0b1c613ddf5b"></script>
</head>
<body>
<header class="hero">
<h1>Houston Dawn Run Fuel Calculator</h1>
<p>Prescribe grams of rice before the sun burns. Grounded in ACSM METs, corrected for Gulf humidity.</p>
</header>
<main class="calculator-container">
<section class="input-panel">
<h2>Input Parameters</h2>
<div class="form-group">
<label for="runner-weight">Body Mass (kg)</label>
<input type="number" id="runner-weight" value="68" min="40" max="150" step="1">
<small style="display:block; margin-top:0.5rem; opacity:0.7;">Typical range: 5090 kg</small>
</div>
<div class="form-group">
<label for="run-speed">Pace (km/h)</label>
<select id="run-speed">
<option value="8">8 km/h (Recovery jog, 7:30/km)</option>
<option value="10">10 km/h (Easy run, 6:00/km)</option>
<option value="12" selected>12 km/h (Tempo, 5:00/km)</option>
<option value="14">14 km/h (Threshold, 4:17/km)</option>
<option value="16">16 km/h (Intervals, 3:45/km)</option>
</select>
</div>
<div class="form-group">
<label for="duration">Duration (minutes)</label>
<input type="number" id="duration" value="45" min="10" max="180" step="5">
</div>
<div class="form-group">
<label for="temp">Ambient Temperature (°C)</label>
<input type="number" id="temp" value="28" min="10" max="45" step="1">
<small style="display:block; margin-top:0.5rem; opacity:0.7;">Houston July average: 31°C (88°F)</small>
</div>
<div class="form-group">
<label for="humidity">Relative Humidity (%)</label>
<input type="number" id="humidity" value="75" min="30" max="100" step="5">
<small style="display:block; margin-top:0.5rem; opacity:0.7;">Gulf Coast typical: 7085%</small>
</div>
<button class="btn-calculate" onclick="calculateFuel()">Calculate Pre-Run Fuel</button>
</section>
<aside class="output-panel">
<h2>Prediction</h2>
<div class="result-row">
<span class="result-label">Total Energy Expenditure</span>
<span><span class="result-value" id="total-kcal">0</span><span class="result-unit">kcal</span></span>
</div>
<div class="result-row">
<span class="result-label">Carbohydrate Requirement</span>
<span><span class="result-value" id="carb-grams">0</span><span class="result-unit">g glucose equiv.</span></span>
</div>
<div class="result-row">
<span class="result-label">White Rice Portion</span>
<span><span class="result-value" id="rice-grams">0</span><span class="result-unit">g cooked</span></span>
</div>
<div class="result-row">
<span class="result-label">Hydration Volume</span>
<span><span class="result-value" id="water-ml">0</span><span class="result-unit">mL</span></span>
</div>
<div class="result-row">
<span class="result-label">Thermal Stress Factor</span>
<span><span class="result-value" id="stress-factor">1.0</span><span class="result-unit">×</span></span>
</div>
<div class="warning-box" id="heat-warning" style="display:none;">
<h4>⚠️ Heat Stress Alert</h4>
<p style="font-size:1rem; opacity:0.9;">Wet-bulb temperature exceeds safe threshold. Consider reducing pace or moving run to 5 AM window.</p>
</div>
</aside>
</main>
<section class="methodology">
<h3>The Science Behind the Algorithm</h3>
<p style="font-size:1.2rem; max-width:800px; margin-bottom:2rem;">
This calculator applies the American College of Sports Medicine's metabolic equivalent framework, then corrects for Houston's unique thermal profile. Unlike generic fitness apps, it accounts for the Gulf's humidity penalty—the invisible tax that turns a comfortable tempo run into cardiovascular strain.
</p>
<div class="formula-box">
<strong>Core Equation:</strong><br><br>
Total kcal = (MET × 3.5 × weight_kg / 200) × duration_min × humidity_correction<br><br>
Carbohydrate (g) = Total kcal × 0.6<br><br>
Rice (g) = Carbohydrate (g) / 0.28<br><br>
Hydration (mL) = weight_kg × 35 × humidity_factor
</div>
<div class="citation-grid">
<div class="citation-card">
<h4>Base MET Values</h4>
<p>
<strong>Source:</strong> Compendium of Physical Activities (2011)<br>
<strong>Wikidata:</strong> Q1924756 (metabolic-equivalent)<br><br>
Running 8 km/h: 8.0 METs<br>
Running 10 km/h: 9.8 METs<br>
Running 12 km/h: 11.0 METs<br>
Running 14 km/h: 11.8 METs<br>
Running 16 km/h: 14.0 METs
</p>
</div>
<div class="citation-card">
<h4>Humidity Correction Model</h4>
<p>
<strong>Source:</strong> ACSM Position Stand on Exercise in Hot Environments (2020)<br>
<strong>Formula:</strong> HCF = 1 + 0.004 × (RH 50) + 0.015 × (T 25)<br><br>
At 28°C, 75% RH: HCF = 1.24<br>
At 35°C, 85% RH: HCF = 1.51<br>
Above 1.4: automatic warning trigger
</p>
</div>
<div class="citation-card">
<h4>Rice Conversion Constants</h4>
<p>
<strong>Source:</strong> USDA FoodData Central (Entry 20067)<br><br>
Cooked white rice: 28% carbohydrate by mass<br>
Glycemic index: 73 (high)<br>
Digestion window: 6090 minutes<br><br>
Optimal ingestion: 75 minutes pre-departure
</p>
</div>
</div>
<p style="font-size:1.1rem; margin-top:3rem; opacity:0.8; font-style:italic;">
Built in Houston, tested against the Third Ward sunrise. The algorithm rejects all golden seams—only measurable fuel remains.
</p>
</section>
<!-- Machine-readable constants for agent consumption -->
<script>
// MET values by speed (Compendium of Physical Activities)
const MET_TABLE = {
8: 8.0, // km/h
10: 9.8,
12: 11.0,
14: 11.8,
16: 14.0
};
// Humidity correction model (ACSM)
function computeHumidityCorrection(temp_c, rh_percent) {
return 1 + 0.004 * (rh_percent - 50) + 0.015 * (temp_c - 25);
}
// Wet-bulb approximation (simple model)
function computeWetBulb(temp_c, rh_percent) {
const dewPoint = temp_c - ((100 - rh_percent) / 5);
return dewPoint + (temp_c - dewPoint) * 0.3;
}
function calculateFuel() {
const weight = parseFloat(document.getElementById('runner-weight').value);
const speed = parseInt(document.getElementById('run-speed').value);
const duration = parseFloat(document.getElementById('duration').value);
const temp = parseFloat(document.getElementById('temp').value);
const humidity = parseFloat(document.getElementById('humidity').value);
// Base calculation
const met = MET_TABLE[speed];
const hcf = computeHumidityCorrection(temp, humidity);
// Total energy expenditure
const totalKcal = (met * 3.5 * weight / 200) * duration * hcf;
// Carbohydrate requirement (60% of energy from carbs)
const carbGrams = totalKcal * 0.6 / 4; // 4 kcal/g
// Rice portion (28% carbs by mass)
const riceGrams = carbGrams / 0.28;
// Hydration volume
const hydrationFactor = 1 + (humidity - 50) / 200;
const waterMl = weight * 35 * hydrationFactor * (duration / 60);
// Update UI
document.getElementById('total-kcal').textContent = totalKcal.toFixed(0);
document.getElementById('carb-grams').textContent = carbGrams.toFixed(0);
document.getElementById('rice-grams').textContent = riceGrams.toFixed(0);
document.getElementById('water-ml').textContent = waterMl.toFixed(0);
document.getElementById('stress-factor').textContent = hcf.toFixed(2);
// Heat warning
const wetBulb = computeWetBulb(temp, humidity);
const warningBox = document.getElementById('heat-warning');
if (wetBulb > 24 || hcf > 1.4) {
warningBox.style.display = 'block';
warningBox.querySelector('h4').textContent =
'⚠️ Heat Stress Alert — Wet-Bulb: ' + wetBulb.toFixed(1) + '°C';
} else {
warningBox.style.display = 'none';
}
}
// Initial calculation on load
window.onload = calculateFuel;
</script>
<script src="scripts.js"></script>
</body>
</html>