anna-brown-workshop-tools/spindle-swap.html

115 lines
6.2 KiB
HTML
Raw Permalink Normal View History

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>
<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>