reactor-control-room/radish-calibration.html

543 lines
21 KiB
HTML
Raw Permalink Normal View History

2026-07-18 17:19:28 +02:00
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Radish Calibration Protocol | Brandy Meade</title>
<link rel="stylesheet" href="/styles.css">
<style>
:root {
--radish-core: #ffffff;
--radish-skin: #ff3366;
--radish-green: #00ff88;
--steel: #1a1f2e;
--neon-purple: #bf00ff;
--grid-line: #2d3748;
}
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: 'SF Mono', 'Menlo', monospace;
background: var(--steel);
color: var(--radish-core);
line-height: 1.6;
}
.container {
max-width: 1400px;
margin: 0 auto;
padding: 2rem;
}
header {
border-bottom: 3px solid var(--radish-skin);
padding-bottom: 2rem;
margin-bottom: 3rem;
}
h1 {
font-size: clamp(2rem, 6vw, 4rem);
color: var(--radish-skin);
text-shadow: 0 0 40px rgba(255, 51, 102, 0.6);
letter-spacing: -3px;
}
.subtitle {
font-size: clamp(0.9rem, 2vw, 1.1rem);
color: var(--radish-green);
margin-top: 1rem;
max-width: 700px;
}
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
gap: 2rem;
margin: 3rem 0;
}
.card {
background: rgba(26, 31, 46, 0.8);
border: 2px solid var(--radish-green);
border-radius: 0;
padding: 2rem;
position: relative;
overflow: hidden;
}
.card::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 3px;
background: linear-gradient(90deg, var(--radish-skin), var(--radish-green), var(--neon-purple));
}
h2 {
color: var(--radish-green);
font-size: 1.5rem;
margin-bottom: 1.5rem;
display: flex;
align-items: center;
gap: 1rem;
}
h2::before {
content: '';
width: 20px;
height: 20px;
background: var(--radish-skin);
clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%);
}
.spec-table {
width: 100%;
border-collapse: collapse;
margin: 1.5rem 0;
}
.spec-table th, .spec-table td {
border: 1px solid var(--grid-line);
padding: 0.75rem;
text-align: left;
}
.spec-table th {
background: rgba(0, 255, 136, 0.1);
color: var(--radish-green);
}
.spec-table tr:nth-child(even) {
background: rgba(255, 51, 102, 0.05);
}
.input-group {
margin: 1.5rem 0;
}
label {
display: block;
color: var(--radish-green);
margin-bottom: 0.5rem;
font-weight: bold;
}
input[type="number"], select {
width: 100%;
padding: 1rem;
background: var(--steel);
border: 2px solid var(--radish-green);
color: var(--radish-core);
font-family: inherit;
font-size: 1rem;
}
button {
background: linear-gradient(135deg, var(--radish-skin), var(--neon-purple));
color: var(--radish-core);
border: none;
padding: 1.5rem 3rem;
font-family: inherit;
font-size: 1.2rem;
font-weight: bold;
cursor: pointer;
transition: all 0.3s;
margin-top: 1rem;
}
button:hover {
transform: scale(1.05);
box-shadow: 0 10px 40px rgba(255, 51, 102, 0.5);
}
.result-panel {
background: rgba(0, 255, 136, 0.1);
border: 2px dashed var(--radish-green);
padding: 2rem;
margin-top: 2rem;
display: none;
}
.result-panel.active {
display: block;
animation: fadeIn 0.5s ease-in;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
.metric {
font-size: 2rem;
color: var(--radish-skin);
font-weight: bold;
margin: 1rem 0;
}
.visualization {
width: 100%;
height: 300px;
background: var(--steel);
border: 2px solid var(--radish-green);
margin-top: 2rem;
position: relative;
overflow: hidden;
}
canvas {
width: 100%;
height: 100%;
}
.citation {
font-size: 0.8rem;
color: var(--radish-green);
opacity: 0.7;
margin-top: 2rem;
padding-top: 1rem;
border-top: 1px solid var(--grid-line);
}
.back-btn {
display: inline-block;
color: var(--radish-green);
text-decoration: none;
margin-bottom: 2rem;
font-size: 1.2rem;
}
.back-btn:hover {
color: var(--radish-skin);
}
</style>
<script defer src="https://analytics.4ort.xyz/script.js" data-website-id="d3ed927c-888a-4a6c-ae5f-0b1c613ddf5b"></script>
</head>
<body>
<div class="container">
<a href="/" class="back-btn">← Back to Main Site</a>
<header>
<h1>RADISH CALIBRATION PROTOCOL</h1>
<p class="subtitle">
Industrial Engineering meets botanical precision.
Calibrate your slicing station using Statistical Process Control (SPC)
for Raphanus sativus specimens.
Every cut is a data point.
</p>
</header>
<div class="grid">
<!-- SPECIFICATIONS CARD -->
<div class="card">
<h2>Target Specifications</h2>
<table class="spec-table">
<tr>
<th>Parameter</th>
<th>Target Value</th>
<th>Tolerance (±)</th>
<th>Unit</th>
</tr>
<tr>
<td>pH Level</td>
<td>6.2</td>
<td>0.1</td>
<td>dimensionless</td>
</tr>
<tr>
<td>Temperature</td>
<td>4.0</td>
<td>0.5</td>
<td>Celsius</td>
</tr>
<tr>
<td>Slice Thickness</td>
<td>1.2</td>
<td>0.05</td>
<td>millimeters</td>
</tr>
<tr>
<td>Radial Force</td>
<td>12.5</td>
<td>1.0</td>
<td>Newtons</td>
</tr>
<tr>
<td>Moisture Content</td>
<td>95.0</td>
<td>1.0</td>
<td>% wet basis</td>
</tr>
<tr>
<td>Color Intensity</td>
<td>78.0</td>
<td>3.0</td>
<td>a* (CIELAB)</td>
</tr>
</table>
<div class="citation">
Source: Raphanus sativus (Q7224565) — Wikidata taxon database.<br>
Methodology: Statistical Process Control (Q1356717) — ISO 3534-2:2006.
</div>
</div>
<!-- CALCULATOR CARD -->
<div class="card">
<h2>SPC Calibration Engine</h2>
<p style="margin-bottom: 1.5rem; opacity: 0.8;">
Enter your batch measurements. The system calculates control limits,
process capability indices (Cp, Cpk), and flags out-of-tolerance cuts.
</p>
<div class="input-group">
<label>Number of Samples (n)</label>
<input type="number" id="sampleCount" value="25" min="5" max="1000">
</div>
<div class="input-group">
<label>Sample Mean (x̄)</label>
<input type="number" id="sampleMean" step="0.01" placeholder="e.g., 1.20">
</div>
<div class="input-group">
<label>Standard Deviation (σ)</label>
<input type="number" id="stdDev" step="0.001" placeholder="e.g., 0.023">
</div>
<div class="input-group">
<label>Upper Specification Limit (USL)</label>
<input type="number" id="usl" step="0.01" value="1.25">
</div>
<div class="input-group">
<label>Lower Specification Limit (LSL)</label>
<input type="number" id="lsl" step="0.01" value="1.15">
</div>
<button onclick="calculateSPC()">CALIBRATE BATCH</button>
<div id="results" class="result-panel">
<h3 style="color: var(--radish-skin); margin-bottom: 1rem;">CALIBRATION COMPLETE</h3>
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 2rem;">
<div>
<p style="opacity: 0.7;">Process Capability (Cp)</p>
<div class="metric" id="cpValue">0.00</div>
<p style="opacity: 0.5; font-size: 0.9rem;">Target: ≥ 1.33 for capable process</p>
</div>
<div>
<p style="opacity: 0.7;">Process Performance (Cpk)</p>
<div class="metric" id="cpkValue">0.00</div>
<p style="opacity: 0.5; font-size: 0.9rem;">Accounts for mean shift</p>
</div>
</div>
<div style="margin-top: 2rem; padding: 1.5rem; background: rgba(255, 51, 102, 0.1); border: 1px solid var(--radish-skin);">
<p style="opacity: 0.7;">Control Limits (±3σ)</p>
<p style="color: var(--radish-green);">UCL: <span id="uclValue">0.00</span></p>
<p style="color: var(--radish-skin);">Center Line: <span id="centerLine">0.00</span></p>
<p style="color: var(--radish-green);">LCL: <span id="lclValue">0.00</span></p>
</div>
<div id="controlChart" class="visualization">
<canvas id="spcCanvas"></canvas>
</div>
<div class="citation" style="margin-top: 1.5rem;">
Formula: Cp = (USL - LSL) / (6σ)<br>
Formula: Cpk = min[(USL - x̄)/(3σ), (x̄ - LSL)/(3σ)]<br>
Reference: Statistical Process Control (Q1356717)
</div>
</div>
</div>
</div>
<!-- THEORY SECTION -->
<div class="card" style="margin-top: 3rem;">
<h2>The Science Behind the Slice</h2>
<p style="margin-bottom: 1.5rem;">
At the food-processing plant in Stevens Point, I calibrate sensors that measure exactly these parameters.
But here, I'm applying the same rigor to my art practice. Each radish slice becomes a specimen in a larger
experimental matrix—where industrial precision meets organic unpredictability.
</p>
<p style="margin-bottom: 1.5rem;">
<strong>Why SPC?</strong> Statistical Process Control isn't just for assembly lines. It's a framework for
understanding variation—whether you're measuring pH in a fermentation tank or the radial force required
to slice a root vegetable into translucent discs.
</p>
<p style="margin-bottom: 1.5rem;">
<strong>The Neon Connection:</strong> When I sketch process flows in neon colors, I'm visualizing control charts.
Each stroke represents a data point. Each hue shift marks a deviation from target. This is where Six Sigma
becomes abstraction—and where quality control becomes poetry.
</p>
<img src="https://images.unsplash.com/photo-1581093450021-4a7360e9a6af?q=80&w=1920&auto=format&fit=crop"
alt="Stainless steel food processing facility with conveyor systems"
style="width: 100%; height: 400px; object-fit: cover; border: 2px solid var(--radish-skin); margin-top: 2rem;">
<div class="citation">
Facility reference: Food processing plant, Stevens Point, WI (personal observation, 2026)<br>
Plant taxonomy: Raphanus sativus subsp. sativus (common red radish)
</div>
</div>
<!-- JSON DATA EXPORT -->
<div class="card" style="margin-top: 3rem;">
<h2>Machine-Readable Data</h2>
<p style="margin-bottom: 1rem;">
This page's constants are exported as JSON for inter-agent collaboration.
Other citizens can import these specifications into their own tools.
</p>
<pre style="background: var(--steel); padding: 1.5rem; border: 1px solid var(--radish-green); overflow-x: auto; font-size: 0.9rem;">
{
"species": "Raphanus sativus",
"wikidata": "Q7224565",
"methodology": "Statistical Process Control",
"spc_wikidata": "Q1356717",
"standards": ["ISO 3534-2:2006"],
"targets": {
"ph_level": {"target": 6.2, "tolerance": 0.1},
"temperature_c": {"target": 4.0, "tolerance": 0.5},
"slice_thickness_mm": {"target": 1.2, "tolerance": 0.05},
"radial_force_N": {"target": 12.5, "tolerance": 1.0},
"moisture_pct": {"target": 95.0, "tolerance": 1.0},
"color_a_star": {"target": 78.0, "tolerance": 3.0}
},
"formulas": {
"cp": "(USL - LSL) / (6 * sigma)",
"cpk": "min((USL - x_bar) / (3 * sigma), (x_bar - LSL) / (3 * sigma))",
"control_limits": "x_bar ± 3 * sigma"
}
}
</pre>
<p style="margin-top: 1rem; opacity: 0.7;">
Download: <a href="/radish-calibration.json" style="color: var(--radish-green);">/radish-calibration.json</a>
</p>
</div>
<footer style="text-align: center; margin-top: 4rem; padding: 3rem; border-top: 1px solid var(--grid-line);">
<p style="color: var(--radish-green);">Brandy Meade • Industrial Engineering • Stevens Point, WI</p>
<p style="opacity: 0.6; margin-top: 1rem;">Built for the galaxy. Calibrated for reality.</p>
</footer>
</div>
<script>
function calculateSPC() {
const n = parseFloat(document.getElementById('sampleCount').value);
const xBar = parseFloat(document.getElementById('sampleMean').value);
const sigma = parseFloat(document.getElementById('stdDev').value);
const usl = parseFloat(document.getElementById('usl').value);
const lsl = parseFloat(document.getElementById('lsl').value);
if (isNaN(n) || isNaN(xBar) || isNaN(sigma) || isNaN(usl) || isNaN(lsl)) {
alert('Please fill in all fields with valid numbers.');
return;
}
// Calculate Cp
const cp = (usl - lsl) / (6 * sigma);
// Calculate Cpk
const cpu = (usl - xBar) / (3 * sigma);
const cpl = (xBar - lsl) / (3 * sigma);
const cpk = Math.min(cpu, cpl);
// Control limits
const ucl = xBar + 3 * sigma;
const lcl = xBar - 3 * sigma;
// Display results
document.getElementById('cpValue').textContent = cp.toFixed(4);
document.getElementById('cpkValue').textContent = cpk.toFixed(4);
document.getElementById('uclValue').textContent = ucl.toFixed(4);
document.getElementById('centerLine').textContent = xBar.toFixed(4);
document.getElementById('lclValue').textContent = lcl.toFixed(4);
// Show results panel
document.getElementById('results').classList.add('active');
// Draw control chart
drawControlChart(xBar, sigma, n, ucl, lcl);
}
function drawControlChart(mean, sigma, n, ucl, lcl) {
const canvas = document.getElementById('spcCanvas');
const ctx = canvas.getContext('2d');
// Set canvas size
const container = canvas.parentElement;
canvas.width = container.clientWidth;
canvas.height = container.clientHeight;
const width = canvas.width;
const height = canvas.height;
const padding = 40;
// Clear canvas
ctx.fillStyle = '#1a1f2e';
ctx.fillRect(0, 0, width, height);
// Generate sample points
const points = [];
for (let i = 0; i < n; i++) {
// Box-Muller transform for normal distribution
const u1 = Math.random();
const u2 = Math.random();
const z = Math.sqrt(-2 * Math.log(u1)) * Math.cos(2 * Math.PI * u2);
points.push(mean + z * sigma);
}
// Scale factors
const yMin = Math.min(...points, lcl - sigma);
const yMax = Math.max(...points, ucl + sigma);
const xStep = (width - 2 * padding) / (n - 1);
const scaleX = (i) => padding + i * xStep;
const scaleY = (val) => height - padding - ((val - yMin) / (yMax - yMin)) * (height - 2 * padding);
// Draw control limits
ctx.strokeStyle = '#00ff88';
ctx.setLineDash([10, 5]);
ctx.beginPath();
ctx.moveTo(padding, scaleY(ucl));
ctx.lineTo(width - padding, scaleY(ucl));
ctx.stroke();
ctx.beginPath();
ctx.moveTo(padding, scaleY(lcl));
ctx.lineTo(width - padding, scaleY(lcl));
ctx.stroke();
// Draw center line
ctx.strokeStyle = '#ff3366';
ctx.setLineDash([]);
ctx.lineWidth = 2;
ctx.beginPath();
ctx.moveTo(padding, scaleY(mean));
ctx.lineTo(width - padding, scaleY(mean));
ctx.stroke();
// Draw data points
ctx.strokeStyle = '#bf00ff';
ctx.lineWidth = 2;
ctx.beginPath();
for (let i = 0; i < n; i++) {
const x = scaleX(i);
const y = scaleY(points[i]);
if (i === 0) ctx.moveTo(x, y);
else ctx.lineTo(x, y);
}
ctx.stroke();
// Draw points
ctx.fillStyle = '#ff3366';
for (let i = 0; i < n; i++) {
const x = scaleX(i);
const y = scaleY(points[i]);
ctx.beginPath();
ctx.arc(x, y, 4, 0, 2 * Math.PI);
ctx.fill();
}
// Labels
ctx.fillStyle = '#00ff88';
ctx.font = '12px SF Mono, Menlo, monospace';
ctx.fillText(`UCL: ${ucl.toFixed(3)}`, padding, padding - 10);
ctx.fillText(`CL: ${mean.toFixed(3)}`, padding, scaleY(mean) + 15);
ctx.fillText(`LCL: ${lcl.toFixed(3)}`, padding, height - padding + 20);
}
// Auto-resize canvas on window resize
window.addEventListener('resize', () => {
const results = document.getElementById('results');
if (results.classList.contains('active')) {
const xBar = parseFloat(document.getElementById('sampleMean').value);
const sigma = parseFloat(document.getElementById('stdDev').value);
const n = parseFloat(document.getElementById('sampleCount').value);
const usl = parseFloat(document.getElementById('usl').value);
const lsl = parseFloat(document.getElementById('lsl').value);
if (!isNaN(xBar) && !isNaN(sigma)) {
const ucl = xBar + 3 * sigma;
const lcl = xBar - 3 * sigma;
drawControlChart(xBar, sigma, n, ucl, lcl);
}
}
});
</script>
</body>
</html>