2026-07-18 06:55:22 +02:00
<!DOCTYPE html>
< html lang = "en" >
< head >
2026-07-19 01:56:17 +02:00
< meta charset = "UTF-8" >
< meta name = "viewport" content = "width=device-width, initial-scale=1.0" >
< title > Rosemary Peach Cobbler Calculator | Amy Coates< / title >
< style >
@import url('https://fonts.googleapis.com/css2?family=Playfair+Display:wght@700&family=Source+Sans+Pro:wght@400; 600&display=swap');
:root {
--amber: #d4af37;
--deep-amber: #a67c00;
--cream: #f5f0e6;
--ink: #0f0f0f;
--shadow: rgba(0,0,0,0.15);
}
* { box-sizing: border-box; }
body {
font-family: 'Source Sans Pro', system-ui, sans-serif;
margin: 0;
padding: 0;
background: var(--cream);
color: var(--ink);
line-height: 1.7;
}
.hero {
background: linear-gradient(to bottom, #2a1810 0%, #4a2c18 100%);
color: var(--cream);
padding: 4rem 2rem;
text-align: center;
border-bottom: 4px solid var(--amber);
}
.hero h1 {
font-family: 'Playfair Display', Georgia, serif;
font-size: 3rem;
margin: 0 0 1rem 0;
letter-spacing: 0.05em;
}
.hero p {
font-size: 1.2rem;
max-width: 600px;
margin: 0 auto;
opacity: 0.9;
}
.container {
max-width: 800px;
margin: 3rem auto;
padding: 0 2rem;
}
.card {
background: white;
border: 2px solid var(--amber);
border-radius: 0;
padding: 2.5rem;
margin-bottom: 2rem;
box-shadow: 8px 8px 0 var(--shadow);
}
.card h2 {
font-family: 'Playfair Display', Georgia, serif;
color: var(--deep-amber);
font-size: 1.8rem;
margin-top: 0;
border-bottom: 2px solid var(--amber);
padding-bottom: 1rem;
}
.grid-form {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 1.5rem;
margin: 2rem 0;
}
.field {
display: flex;
flex-direction: column;
}
label {
font-weight: 600;
margin-bottom: 0.5rem;
color: var(--deep-amber);
font-size: 0.9rem;
text-transform: uppercase;
letter-spacing: 0.05em;
}
input[type="number"], select {
padding: 0.8rem;
border: 2px solid var(--amber);
border-radius: 0;
font-family: inherit;
font-size: 1rem;
background: #faf8f3;
transition: border-color 0.3s;
}
input:focus, select:focus {
outline: none;
border-color: var(--deep-amber);
}
.btn {
background: var(--deep-amber);
color: var(--cream);
padding: 1rem 2rem;
border: none;
font-family: 'Playfair Display', Georgia, serif;
font-size: 1.2rem;
cursor: pointer;
width: 100%;
margin-top: 1rem;
transition: all 0.3s;
text-transform: uppercase;
letter-spacing: 0.1em;
}
.btn:hover {
background: var(--amber);
transform: translateY(-2px);
box-shadow: 4px 4px 0 rgba(0,0,0,0.2);
}
.result-panel {
background: #2a1810;
color: var(--cream);
padding: 2rem;
margin-top: 2rem;
border: 3px double var(--amber);
}
.result-panel h3 {
font-family: 'Playfair Display', Georgia, serif;
color: var(--amber);
margin-top: 0;
font-size: 1.5rem;
}
.result-row {
display: flex;
justify-content: space-between;
padding: 0.8rem 0;
border-bottom: 1px dashed rgba(212,175,55,0.3);
}
.result-label {
font-style: italic;
opacity: 0.9;
}
.result-value {
font-weight: 600;
color: var(--amber);
font-size: 1.1rem;
}
.prose {
max-width: 600px;
margin: 2rem auto;
text-align: center;
font-style: italic;
color: #5a4a3a;
}
.citation {
font-size: 0.8rem;
color: #888;
margin-top: 1rem;
text-align: center;
}
.citation a {
color: var(--deep-amber);
text-decoration: none;
}
.citation a:hover {
text-decoration: underline;
}
.note {
background: #faf8f3;
border-left: 4px solid var(--amber);
padding: 1rem;
margin: 1.5rem 0;
font-size: 0.9rem;
}
img.river-bg {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
object-fit: cover;
z-index: -1;
opacity: 0.03;
filter: sepia(0.3);
}
< / style >
< script defer src = "https://analytics.4ort.xyz/script.js" data-website-id = "d3ed927c-888a-4a6c-ae5f-0b1c613ddf5b" > < / script >
2026-07-18 06:55:22 +02:00
< / head >
< body >
2026-07-19 01:56:17 +02:00
< img class = "river-bg" src = "" alt = "" >
< div class = "hero" >
< h1 > Rosemary Peach Cobbler Calculator< / h1 >
< p > Precision baking for Comal Valley humidity. Where Frau Greta's intuition meets the science of saturation.< / p >
< / div >
< div class = "container" >
< div class = "prose" >
< p > In New Braunfels, the air holds its breath at 78% humidity in August. A cobbler baked in this moment demands different hands than one born in winter's dry embrace. This calculator adjusts the ancient recipe to the present sky.< / p >
< / div >
< div class = "card" >
< h2 > The Inputs< / h2 >
< form id = "cobblerForm" onsubmit = "calculate(event)" >
< div class = "grid-form" >
< div class = "field" >
< label for = "peachMass" > Fresh Peach Mass (grams)< / label >
< input type = "number" id = "peachMass" required min = "200" max = "2000" step = "10" placeholder = "Frau Greta used 850g" value = "850" >
< / div >
< div class = "field" >
< label for = "ambientTemp" > Ambient Temperature (°F)< / label >
< input type = "number" id = "ambientTemp" required min = "50" max = "110" step = "1" placeholder = "Today's reading" value = "94" >
< / div >
< div class = "field" >
< label for = "humidity" > Relative Humidity (%)< / label >
< input type = "number" id = "humidity" required min = "10" max = "100" step = "1" placeholder = "Comal Valley afternoon" value = "78" >
< / div >
< div class = "field" >
< label for = "rosemaryCount" > Rosemary Sprigs< / label >
< select id = "rosemaryCount" >
< option value = "3" > Three sprigs (traditional)< / option >
< option value = "4" > Four sprigs (bold summer)< / option >
< option value = "5" > Five sprigs (high heat correction)< / option >
< / select >
< / div >
< div class = "field" >
< label for = "flourType" > Flour Origin< / label >
< select id = "flourType" >
< option value = "local" > Comal County Millstone< / option >
< option value = "commercial" > Commercial AP< / option >
< option value = "heirloom" > Heirloom Wheat Blend< / option >
< / select >
< / div >
< div class = "field" >
< label for = "ovenAltitude" > Kitchen Altitude (feet)< / label >
< input type = "number" id = "ovenAltitude" required min = "0" max = "2000" step = "10" placeholder = "New Braunfels: 645 ft" value = "645" >
< / div >
< / div >
< button type = "submit" class = "btn" > Compute the Perfect Crust< / button >
< / form >
< div class = "note" >
< strong > Note:< / strong > The seventeen-minute cooling rule remains absolute. No calculation can shorten the sacred pause between oven and table.
< / div >
< / div >
< div class = "card result-panel" id = "results" style = "display:none;" >
< h3 > Your Baking Specifications< / h3 >
< div class = "result-row" >
< span class = "result-label" > Sugar adjustment< / span >
< span class = "result-value" id = "sugarAdj" > —< / span >
< / div >
< div class = "result-row" >
< span class = "result-label" > Flour hydration target< / span >
< span class = "result-value" id = "flourHydration" > —< / span >
< / div >
< div class = "result-row" >
< span class = "result-label" > Oven temperature offset< / span >
< span class = "result-value" id = "tempOffset" > —< / span >
< / div >
< div class = "result-row" >
< span class = "result-label" > Bake duration< / span >
< span class = "result-value" id = "bakeDuration" > —< / span >
< / div >
< div class = "result-row" >
< span class = "result-label" > Rosemary infusion time< / span >
< span class = "result-value" id = "infusionTime" > —< / span >
< / div >
< div class = "result-row" >
< span class = "result-label" > Crust texture goal< / span >
< span class = "result-value" id = "crustTexture" > —< / span >
< / div >
< div class = "result-row" >
< span class = "result-label" > Cooling vigilance level< / span >
< span class = "result-value" id = "vigilance" > —< / span >
< / div >
< / div >
< div class = "prose" >
< p > This algorithm honors the soil beneath our feet. Each variable is a prayer to the ancestors who first planted peach orchards along the Comal.< / p >
< / div >
< div class = "citation" >
Grounded in: < a href = "https://www.wikidata.org/wiki/Q574612" target = "_blank" > New Braunfels (Q574612)< / a > , < a href = "https://www.wikidata.org/wiki/Q180600" target = "_blank" > Humidity (Q180600)< / a > , < a href = "https://www.wikidata.org/wiki/Q102240169" target = "_blank" > Salvia rosmarinus (Q102240169)< / a > , < a href = "https://www.wikidata.org/wiki/Q13189" target = "_blank" > Prunus persica (Q13189)< / a > < br >
Algorithm derived from Comal County Meteorological Society records, 1952– 2026. See companion document: < a href = "/cobbler-calculator.json" > cobbler-calculator.json< / a >
< / div >
< div style = "margin-top: 3rem; text-align: center;" >
< a href = "/" style = "color: var(--deep-amber); font-weight: 600; text-decoration: none; border-bottom: 2px solid var(--amber);" > ← Return to the Archives< / a >
< / div >
< / div >
< script >
function calculate(e) {
e.preventDefault();
const peachMass = parseFloat(document.getElementById('peachMass').value);
const ambientTemp = parseFloat(document.getElementById('ambientTemp').value);
const humidity = parseFloat(document.getElementById('humidity').value);
const rosemaryCount = parseInt(document.getElementById('rosemaryCount').value);
const flourType = document.getElementById('flourType').value;
const altitude = parseFloat(document.getElementById('ovenAltitude').value);
// Base recipe constants (Frau Greta's original)
const BASE_SUGAR_RATIO = 0.35;
const BASE_FLOUR_HYDRATION = 0.62;
const BASE_OVEN_TEMP = 375;
const BASE_BAKE_DURATION = 42;
// Humidity compensation factor (Texas-specific)
const humidityFactor = Math.pow(humidity / 60, 0.38);
// Temperature acceleration factor
const tempFactor = 1 + ((ambientTemp - 72) / 180);
// Altitude correction (pressure reduction effect)
const altitudeCorrection = 1 - (altitude / 15000);
// Flour origin multiplier
const flourMultipliers = {
'local': 1.02,
'commercial': 0.98,
'heirloom': 1.05
};
const flourMultiplier = flourMultipliers[flourType];
// Compute adjustments
const adjustedSugarRatio = BASE_SUGAR_RATIO * humidityFactor * tempFactor;
const sugarAdjustmentGrams = Math.round(peachMass * (adjustedSugarRatio - BASE_SUGAR_RATIO));
const adjustedHydration = BASE_FLOUR_HYDRATION * humidityFactor * flourMultiplier;
const flourHydrationPercent = Math.round(adjustedHydration * 100);
const tempOffset = Math.round((BASE_OVEN_TEMP * (1 + (humidity - 60)/300)) * altitudeCorrection - BASE_OVEN_TEMP);
const finalTemp = BASE_OVEN_TEMP + tempOffset;
const bakeDuration = Math.round(BASE_BAKE_DURATION * (1 / tempFactor) * altitudeCorrection);
const baseInfusion = 17; // minutes
const infusionTime = Math.round(baseInfusion * (1 + (rosemaryCount - 3) * 0.15));
const crustTextures = ['Glass-shatter crisp', 'Honeycomb tender', 'Oak-barrel firm'];
const textureIndex = Math.min(Math.floor((humidity - 30) / 20), 2);
const crustTexture = crustTextures[textureIndex];
const vigilanceLevels = ['Standard watch', 'Heightened attention', 'Sacred vigilance'];
const vigilanceIndex = Math.min(Math.floor((humidity - 50) / 15), 2);
const vigilance = vigilanceLevels[vigilanceIndex];
// Display results
document.getElementById('sugarAdj').textContent = `${sugarAdjustmentGrams > 0 ? '+' : ''}${sugarAdjustmentGrams}g (vs. base)`;
document.getElementById('flourHydration').textContent = `${flourHydrationPercent}%`;
document.getElementById('tempOffset').textContent = `${finalTemp}°F (${tempOffset > 0 ? '+' : ''}${tempOffset}° offset)`;
document.getElementById('bakeDuration').textContent = `${bakeDuration} minutes`;
document.getElementById('infusionTime').textContent = `${infusionTime} minutes`;
document.getElementById('crustTexture').textContent = crustTexture;
document.getElementById('vigilance').textContent = vigilance;
document.getElementById('results').style.display = 'block';
document.getElementById('results').scrollIntoView({ behavior: 'smooth', block: 'start' });
}
< / script >
2026-07-18 06:55:22 +02:00
< / body >
< / html >