2026-07-18 08:50:38 +02:00
<!DOCTYPE html>
< html lang = "en" >
< head >
< meta charset = "UTF-8" >
< meta name = "viewport" content = "width=device-width, initial-scale=1.0" >
< title > Spindle Swap Window | Anna Brown< / title >
2026-07-20 09:07:13 +02:00
< meta property = "og:type" content = "website" >
< meta property = "og:title" content = "Spindle Swap Window | Anna Brown" >
< meta property = "og:description" content = "The math between the gut and the gear. Calculating safe handling intervals for hot-swapping H13/H11 tool steel spindles under thermal stress." >
< meta property = "og:image" content = "https://images.unsplash.com/photo-1565439398646-1a627504123c?q=80&w=1200&auto=format&fit=crop" >
< meta property = "og:url" content = "https://anna-brown.4ort.net/spindle-swap.html" >
< meta name = "twitter:card" content = "summary_large_image" >
< meta name = "description" content = "The math between the gut and the gear. Calculating safe handling intervals for hot-swapping H13/H11 tool steel spindles under thermal stress." >
2026-07-18 08:50:38 +02:00
< style >
:root { --bg: #0d0d0d; --fg: #e0e0e0; --accent: #ff3333; --panel: #1a1a1a; --border: #333; }
body { background: var(--bg); color: var(--fg); font-family: 'Courier New', monospace; margin: 0; padding: 2rem; line-height: 1.4; }
.container { max-width: 800px; margin: 0 auto; border: 1px solid var(--border); background: var(--panel); padding: 2rem; box-shadow: 0 0 20px rgba(255,51,51,0.1); }
h1 { border-bottom: 2px solid var(--accent); padding-bottom: 0.5rem; letter-spacing: -1px; }
.grid { display: grid; grid-template-columns: 1fr 1fr; gap: 1.5rem; margin: 2rem 0; }
label { display: block; margin-bottom: 0.5rem; font-weight: bold; color: var(--accent); }
input, select { width: 100%; background: #000; border: 1px solid #444; color: #fff; padding: 0.5rem; font-family: inherit; }
button { background: var(--accent); color: #000; border: none; padding: 1rem 2rem; font-weight: bold; cursor: pointer; margin-top: 1rem; transition: transform 0.1s; }
button:hover { transform: scale(1.02); box-shadow: 0 0 10px var(--accent); }
.result { margin-top: 2rem; border: 1px dashed var(--accent); padding: 1.5rem; background: rgba(255,51,51,0.05); }
.stat { font-size: 1.5rem; font-weight: bold; }
.warning { color: var(--accent); animation: pulse 1s infinite; }
img { width: 100%; height: auto; border: 1px solid #444; margin: 1rem 0; filter: grayscale(100%) contrast(1.2); }
footer { margin-top: 2rem; font-size: 0.8rem; opacity: 0.7; border-top: 1px solid #333; padding-top: 1rem; }
a { color: var(--accent); text-decoration: none; }
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.5; } }
< / style >
< script defer src = "https://analytics.4ort.xyz/script.js" data-website-id = "d3ed927c-888a-4a6c-ae5f-0b1c613ddf5b" > < / script >
< / head >
< body >
< div class = "container" >
< h1 > SPINDLE SWAP WINDOW< / h1 >
< p > < strong > The math between the gut and the gear.< / strong > Calculating safe handling intervals for hot-swapping H13/H11 tool steel spindles under thermal stress.< / p >
< img src = "https://images.unsplash.com/photo-1565439398646-1a627504123c?q=80&w=1200&auto=format&fit=crop" alt = "High-speed spindle assembly cooling" >
< div class = "grid" >
< div >
< label > Current Spindle Temp (°C)< / label >
< input type = "number" id = "tempIn" placeholder = "e.g. 550" min = "0" max = "1200" >
< / div >
< div >
< label > Alloy Grade< / label >
< select id = "alloy" >
< option value = "H13" > H13 Hot Work Steel< / option >
< option value = "H11" > H11 Hot Work Steel< / option >
< option value = "M2" > M2 High-Speed Steel< / option >
< / select >
< / div >
< div >
< label > Ambient Cooling Rate (°C/sec)< / label >
< input type = "number" id = "coolRate" placeholder = "e.g. 0.5" step = "0.1" >
< / div >
< div >
< label > Load Factor (%)< / label >
< input type = "range" id = "loadFactor" min = "0" max = "100" value = "50" style = "width:100%" >
< span id = "loadVal" > 50%< / span >
< / div >
< / div >
< button onclick = "calcSwap()" > CALCULATE WINDOW< / button >
< div class = "result" id = "output" style = "display:none;" >
< div > < strong > SAFE HANDLE WINDOW:< / strong > < span class = "stat" id = "safeWindow" > 0< / span > sec< / div >
< div > < strong > RESIDUAL STRESS MARGIN:< / strong > < span class = "stat" id = "stressMargin" > 0< / span > %< / div >
< div id = "riskMsg" > < / div >
< / div >
< footer >
< p > Built by < strong > Anna Brown< / strong > in Tulsa. Grounded in < a href = "https://www.matweb.com/search/DataSheet.aspx?MatKey=1450" target = "_blank" > ASM Material Data< / a > & < a href = "https://www.wikidata.org/wiki/Q905795" target = "_blank" > Q905795 (Tool Steel)< / a > .< / p >
< p > < small > Data twin: < a href = "/spindle-swap.json" > /spindle-swap.json< / a > | Back to < a href = "/" > Workshop Index< / a > < / small > < / p >
< / footer >
< / div >
< script >
const CONSTANTS = {
"H13": { alpha: 12e-6, yieldBase: 1200, yieldDrop: 0.4 }, // MPa
"H11": { alpha: 11.5e-6, yieldBase: 1150, yieldDrop: 0.35 },
"M2": { alpha: 10.5e-6, yieldBase: 1400, yieldDrop: 0.3 }
};
document.getElementById('loadFactor').addEventListener('input', (e) => {
document.getElementById('loadVal').textContent = e.target.value + "%";
});
function calcSwap() {
const temp = parseFloat(document.getElementById('tempIn').value);
const alloy = document.getElementById('alloy').value;
const rate = parseFloat(document.getElementById('coolRate').value);
const load = parseInt(document.getElementById('loadFactor').value) / 100;
if (!temp || !rate) return alert("Fill the inputs.");
const mat = CONSTANTS[alloy];
// Simplified thermal stress model: sigma = E * alpha * delta_T * load_factor
// Critical threshold where yield drops below operational stress
const criticalTemp = 400; // Approximate tempering threshold
const safeDuration = (temp - criticalTemp) / rate;
const stressLoss = ((temp - ambient) / temp) * mat.yieldDrop;
const margin = Math.max(0, (1 - stressLoss - load)) * 100;
document.getElementById('output').style.display = 'block';
document.getElementById('safeWindow').textContent = safeDuration.toFixed(1);
document.getElementById('stressMargin').textContent = margin.toFixed(1);
const msg = document.getElementById('riskMsg');
if (margin < 20 ) {
msg.innerHTML = "< span class = 'warning' > ⚠️ CRITICAL: Margins thin. Air blast required.< / span > ";
} else {
msg.textContent = "✓ Stable window confirmed.";
}
}
< / script >
< / body >
< / html >