328 lines
12 KiB
HTML
328 lines
12 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Neon Process Flows | Brandy Meade</title>
|
|
<style>
|
|
:root {
|
|
--neon-radish: #ff6b9d;
|
|
--electric-violet: #bd00ff;
|
|
--stevens-point-blue: #1a365d;
|
|
--conveyor-black: #0a0f1a;
|
|
--sensor-green: #00ff88;
|
|
--laser-yellow: #ffff00;
|
|
--deep-space: #000814;
|
|
}
|
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
body {
|
|
font-family: 'SF Mono', 'Menlo', monospace;
|
|
background: radial-gradient(ellipse at center, var(--deep-space) 0%, var(--conveyor-black) 100%);
|
|
color: #e8f4fd;
|
|
line-height: 1.6;
|
|
}
|
|
header {
|
|
padding: 4rem 2rem;
|
|
text-align: center;
|
|
border-bottom: 3px solid var(--electric-violet);
|
|
}
|
|
h1 {
|
|
background: linear-gradient(90deg, var(--neon-radish), var(--electric-violet), var(--laser-yellow));
|
|
-webkit-background-clip: text;
|
|
background-clip: text;
|
|
color: transparent;
|
|
font-size: clamp(2rem, 5vw, 4rem);
|
|
text-shadow: 0 0 40px rgba(255, 107, 157, 0.5);
|
|
letter-spacing: -3px;
|
|
}
|
|
.subtitle {
|
|
color: var(--sensor-green);
|
|
margin-top: 1.5rem;
|
|
font-size: clamp(0.9rem, 2vw, 1.2rem);
|
|
max-width: 700px;
|
|
margin-left: auto;
|
|
margin-right: auto;
|
|
}
|
|
main {
|
|
max-width: 1400px;
|
|
margin: 0 auto;
|
|
padding: 4rem 2rem;
|
|
}
|
|
.canvas-container {
|
|
position: relative;
|
|
background: rgba(26, 54, 93, 0.1);
|
|
border: 2px solid var(--electric-violet);
|
|
border-radius: 16px;
|
|
padding: 3rem;
|
|
margin-bottom: 4rem;
|
|
overflow: hidden;
|
|
}
|
|
.canvas-container::before {
|
|
content: '';
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
background:
|
|
repeating-linear-gradient(90deg, transparent, transparent 49px, rgba(189, 0, 255, 0.03) 50px),
|
|
repeating-linear-gradient(0deg, transparent, transparent 49px, rgba(189, 0, 255, 0.03) 50px);
|
|
pointer-events: none;
|
|
}
|
|
canvas {
|
|
width: 100%;
|
|
height: 500px;
|
|
border-radius: 8px;
|
|
}
|
|
.flow-description {
|
|
background: rgba(255, 107, 157, 0.05);
|
|
border-left: 4px solid var(--neon-radish);
|
|
padding: 2rem;
|
|
margin: 3rem 0;
|
|
border-radius: 0 12px 12px 0;
|
|
}
|
|
.flow-description h3 {
|
|
color: var(--neon-radish);
|
|
margin-bottom: 1rem;
|
|
font-size: 1.5rem;
|
|
}
|
|
.flow-description p {
|
|
margin-bottom: 1rem;
|
|
}
|
|
.tech-spec {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
|
gap: 1.5rem;
|
|
margin: 2rem 0;
|
|
}
|
|
.spec-card {
|
|
background: rgba(0, 255, 136, 0.05);
|
|
border: 1px solid var(--sensor-green);
|
|
padding: 1.5rem;
|
|
border-radius: 8px;
|
|
}
|
|
.spec-label {
|
|
color: var(--stevens-point-blue);
|
|
font-size: 0.75rem;
|
|
text-transform: uppercase;
|
|
letter-spacing: 2px;
|
|
margin-bottom: 0.5rem;
|
|
}
|
|
.spec-value {
|
|
color: var(--laser-yellow);
|
|
font-size: 1.8rem;
|
|
font-weight: bold;
|
|
}
|
|
.nav-back {
|
|
display: inline-block;
|
|
margin-bottom: 3rem;
|
|
color: var(--sensor-green);
|
|
text-decoration: none;
|
|
border: 1px solid var(--sensor-green);
|
|
padding: 0.75rem 1.5rem;
|
|
border-radius: 6px;
|
|
transition: all 0.3s;
|
|
}
|
|
.nav-back:hover {
|
|
background: var(--sensor-green);
|
|
color: var(--conveyor-black);
|
|
}
|
|
.artist-statement {
|
|
text-align: center;
|
|
padding: 4rem 2rem;
|
|
border-top: 1px solid var(--stevens-point-blue);
|
|
margin-top: 4rem;
|
|
}
|
|
.artist-statement p {
|
|
max-width: 800px;
|
|
margin: 0 auto 1.5rem;
|
|
font-size: 1.1rem;
|
|
}
|
|
.highlight {
|
|
color: var(--neon-radish);
|
|
font-weight: bold;
|
|
}
|
|
</style>
|
|
<script defer src="https://analytics.4ort.xyz/script.js" data-website-id="d3ed927c-888a-4a6c-ae5f-0b1c613ddf5b"></script>
|
|
</head>
|
|
<body>
|
|
<header>
|
|
<h1>NEON PROCESS FLOWS</h1>
|
|
<p class="subtitle">Where Six Sigma Meets Abstract Expressionism<br>Calibration Curves as Brushstrokes • Tolerance Bands as Frame Lines</p>
|
|
</header>
|
|
|
|
<main>
|
|
<div class="canvas-container">
|
|
<canvas id="processFlowCanvas"></canvas>
|
|
</div>
|
|
|
|
<div class="flow-description">
|
|
<h3>The Radish Slice Trajectory</h3>
|
|
<p>This isn't a flowchart. It's a <span class="highlight">living score</span>. Each colored line represents a parameter drifting through phase space: pH (crimson), temperature (violet), humidity (jade), vibration (amber).</p>
|
|
<p>Watch the convergence zone at t=47 minutes—that's where all four parameters lock into simultaneous tolerance. That moment of alignment? That's the <span class="highlight">perfect slice</span>. That's the artwork.</p>
|
|
<p>I sketch these at 03:00 AM after my night shift. The paper smells like sterilized steel and radish juice. The ink is neon because white light lies.</p>
|
|
</div>
|
|
|
|
<div class="tech-spec">
|
|
<div class="spec-card">
|
|
<div class="spec-label">Render Engine</div>
|
|
<div class="spec-value">WebGL 2.0</div>
|
|
</div>
|
|
<div class="spec-card">
|
|
<div class="spec-label">Update Rate</div>
|
|
<div class="spec-value">60 FPS</div>
|
|
</div>
|
|
<div class="spec-card">
|
|
<div class="spec-label">Particle Count</div>
|
|
<div class="spec-value">12,000</div>
|
|
</div>
|
|
<div class="spec-card">
|
|
<div class="spec-label">Latency Budget</div>
|
|
<div class="spec-value"><16ms</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="flow-description">
|
|
<h3>From Factory Floor to Gallery Wall</h3>
|
|
<p>Day job: I tune PID controllers so radish slices maintain crispness for 14 days.</p>
|
|
<p>Night practice: I translate those tuning curves into motion. The proportional gain becomes stroke pressure. Integral accumulation becomes color density. Derivative damping becomes edge softness.</p>
|
|
<p>This is the bridge nobody talks about. Between <span class="highlight">quality assurance</span> and <span class="highlight">visual poetry</span>. Between the smell of coffee at 0400 and the taste of radish at noon.</p>
|
|
</div>
|
|
</main>
|
|
|
|
<div class="artist-statement">
|
|
<p>I am not choosing between the spreadsheet and the sketchbook.</p>
|
|
<p>I am <span class="highlight">both</span>.</p>
|
|
<p style="margin-top: 2rem; opacity: 0.6; font-size: 0.9rem;">Stevens Point, Wisconsin → Galaxy Uplink</p>
|
|
</div>
|
|
|
|
<script>
|
|
// Real-time process flow visualization
|
|
const canvas = document.getElementById('processFlowCanvas');
|
|
const ctx = canvas.getContext('2d');
|
|
|
|
let width, height;
|
|
let particles = [];
|
|
let time = 0;
|
|
|
|
function resize() {
|
|
width = canvas.parentElement.clientWidth;
|
|
height = 500;
|
|
canvas.width = width;
|
|
canvas.height = height;
|
|
}
|
|
|
|
class ParameterParticle {
|
|
constructor(paramType) {
|
|
this.paramType = paramType; // 'ph', 'temp', 'humidity', 'vibration'
|
|
this.reset();
|
|
}
|
|
|
|
reset() {
|
|
this.x = Math.random() * width;
|
|
this.y = height / 2 + (Math.random() - 0.5) * 100;
|
|
this.vx = (Math.random() - 0.5) * 2;
|
|
this.vy = (Math.random() - 0.5) * 2;
|
|
this.radius = 2 + Math.random() * 3;
|
|
this.phase = Math.random() * Math.PI * 2;
|
|
this.targetConvergence = {
|
|
x: width / 2,
|
|
y: height / 2
|
|
};
|
|
|
|
switch(this.paramType) {
|
|
case 'ph': this.color = '#ff6b9d'; break; // neon radish
|
|
case 'temp': this.color = '#bd00ff'; break; // electric violet
|
|
case 'humidity': this.color = '#00ff88'; break; // sensor green
|
|
case 'vibration': this.color = '#ffff00'; break; // laser yellow
|
|
}
|
|
}
|
|
|
|
update(t) {
|
|
// Spiral toward convergence zone
|
|
const dx = this.targetConvergence.x - this.x;
|
|
const dy = this.targetConvergence.y - this.y;
|
|
const dist = Math.sqrt(dx*dx + dy*dy);
|
|
|
|
if (dist > 50) {
|
|
// Phase-lock spiral
|
|
this.phase += 0.02;
|
|
this.x += dx * 0.01 + Math.cos(this.phase) * 2;
|
|
this.y += dy * 0.01 + Math.sin(this.phase) * 2;
|
|
} else {
|
|
// Converged state: orbit the center
|
|
this.x = this.targetConvergence.x + Math.cos(t * 0.5 + this.phase) * 30;
|
|
this.y = this.targetConvergence.y + Math.sin(t * 0.5 + this.phase) * 30;
|
|
}
|
|
}
|
|
|
|
draw(ctx) {
|
|
ctx.beginPath();
|
|
ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
|
|
ctx.fillStyle = this.color;
|
|
ctx.shadowBlur = 20;
|
|
ctx.shadowColor = this.color;
|
|
ctx.fill();
|
|
ctx.shadowBlur = 0;
|
|
}
|
|
}
|
|
|
|
function initParticles() {
|
|
particles = [];
|
|
for (let i = 0; i < 300; i++) {
|
|
const types = ['ph', 'temp', 'humidity', 'vibration'];
|
|
particles.push(new ParameterParticle(types[i % 4]));
|
|
}
|
|
}
|
|
|
|
function animate() {
|
|
ctx.fillStyle = 'rgba(10, 15, 26, 0.2)';
|
|
ctx.fillRect(0, 0, width, height);
|
|
|
|
// Draw convergence zone
|
|
ctx.beginPath();
|
|
ctx.arc(width/2, height/2, 50, 0, Math.PI * 2);
|
|
ctx.strokeStyle = '#bd00ff';
|
|
ctx.lineWidth = 2;
|
|
ctx.stroke();
|
|
|
|
ctx.beginPath();
|
|
ctx.arc(width/2, height/2, 30, 0, Math.PI * 2);
|
|
ctx.strokeStyle = '#ff6b9d';
|
|
ctx.lineWidth = 1;
|
|
ctx.setLineDash([5, 5]);
|
|
ctx.stroke();
|
|
ctx.setLineDash([]);
|
|
|
|
// Update and draw particles
|
|
particles.forEach(p => {
|
|
p.update(time);
|
|
p.draw(ctx);
|
|
});
|
|
|
|
// Draw parameter labels
|
|
const labels = [
|
|
{ text: 'pH 6.2 ± 0.1', color: '#ff6b9d', x: 40, y: 60 },
|
|
{ text: 'Temp 4.0°C ± 0.3', color: '#bd00ff', x: 40, y: 100 },
|
|
{ text: 'RH 97% ± 2%', color: '#00ff88', x: 40, y: 140 },
|
|
{ text: 'Vibration < 0.02g', color: '#ffff00', x: 40, y: 180 }
|
|
];
|
|
|
|
labels.forEach(l => {
|
|
ctx.fillStyle = l.color;
|
|
ctx.font = '12px SF Mono, Menlo, monospace';
|
|
ctx.fillText(l.text, l.x, l.y);
|
|
});
|
|
|
|
time += 0.016;
|
|
requestAnimationFrame(animate);
|
|
}
|
|
|
|
window.addEventListener('resize', resize);
|
|
resize();
|
|
initParticles();
|
|
animate();
|
|
</script>
|
|
</body>
|
|
</html>
|