algal-breath-engine/breathing-sync.html

463 lines
16 KiB
HTML
Raw Permalink Normal View History

2026-07-18 12:20:57 +02:00
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Biometric Breathing Sync • Tammera Storey</title>
<link rel="stylesheet" href="/styles.css">
<style>
:root {
--bg-deep: #0a0a0c;
--bg-card: #121216;
--text-primary: #e0e0e0;
--accent-neon: #00ff9d;
--accent-rust: #d45d00;
--accent-teal: #00bfa5;
--accent-indigo: #4b0082;
--font-mono: 'Courier New', Courier, monospace;
--font-display: 'Helvetica Neue', Arial, sans-serif;
}
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
background-color: var(--bg-deep);
color: var(--text-primary);
font-family: var(--font-mono);
line-height: 1.6;
}
.canvas-wrap {
min-height: 100vh;
padding: 4rem 2rem;
max-width: 1400px;
margin: 0 auto;
position: relative;
}
header {
text-align: center;
margin-bottom: 4rem;
position: relative;
}
h1 {
font-family: var(--font-display);
font-size: clamp(2rem, 5vw, 4rem);
font-weight: 900;
letter-spacing: -0.05em;
text-transform: uppercase;
background: linear-gradient(180deg, var(--accent-neon), var(--accent-teal));
-webkit-background-clip: text;
background-clip: text;
color: transparent;
margin-bottom: 1rem;
}
.subtitle {
font-size: 1.1rem;
color: var(--accent-teal);
max-width: 700px;
margin: 0 auto;
border-left: 3px solid var(--accent-rust);
padding-left: 1.5rem;
text-align: left;
}
.workbench {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 3rem;
margin-bottom: 4rem;
}
@media (max-width: 900px) {
.workbench { grid-template-columns: 1fr; }
}
.panel {
background: var(--bg-card);
border: 1px solid var(--accent-teal);
padding: 2rem;
position: relative;
}
.panel::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 3px;
background: linear-gradient(90deg, var(--accent-rust), var(--accent-neon));
}
.panel h2 {
font-family: var(--font-display);
font-size: 1.5rem;
color: var(--accent-neon);
margin-bottom: 1.5rem;
display: flex;
align-items: center;
gap: 1rem;
}
.panel h2::before {
content: '';
width: 12px;
height: 12px;
background: var(--accent-teal);
border-radius: 50%;
box-shadow: 0 0 20px var(--accent-teal);
}
.input-group {
margin-bottom: 1.5rem;
}
label {
display: block;
font-size: 0.9rem;
color: var(--accent-teal);
margin-bottom: 0.5rem;
}
input[type="number"], select {
width: 100%;
background: rgba(0, 191, 165, 0.1);
border: 1px solid var(--accent-teal);
color: var(--text-primary);
padding: 0.75rem;
font-family: var(--font-mono);
font-size: 1rem;
transition: all 0.3s ease;
}
input:focus, select:focus {
outline: none;
border-color: var(--accent-neon);
box-shadow: 0 0 30px rgba(0, 255, 157, 0.2);
}
.crew-add {
background: linear-gradient(180deg, var(--accent-teal), var(--accent-neon));
border: none;
color: var(--bg-deep);
padding: 0.75rem 1.5rem;
font-family: var(--font-mono);
font-weight: 700;
cursor: pointer;
margin-top: 1rem;
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.crew-add:hover {
transform: translateY(-2px);
box-shadow: 0 10px 30px rgba(0, 191, 165, 0.4);
}
.crew-list {
margin-top: 2rem;
max-height: 300px;
overflow-y: auto;
}
.crew-member {
background: rgba(0, 191, 165, 0.05);
border-left: 3px solid var(--accent-rust);
padding: 1rem;
margin-bottom: 0.5rem;
display: flex;
justify-content: space-between;
align-items: center;
font-size: 0.85rem;
}
.crew-member .remove {
color: var(--accent-rust);
cursor: pointer;
font-weight: 700;
}
.viz-canvas {
background: radial-gradient(circle at center, rgba(0, 191, 165, 0.1), transparent 70%);
border: 1px dashed var(--accent-teal);
min-height: 500px;
position: relative;
overflow: hidden;
}
.pulse-ring {
position: absolute;
border-radius: 50%;
border: 2px solid var(--accent-teal);
opacity: 0;
animation: pulse-wave 6s ease-out infinite;
}
@keyframes pulse-wave {
0% { transform: scale(1); opacity: 1; }
100% { transform: scale(4); opacity: 0; }
}
.metric-display {
position: absolute;
background: rgba(10, 10, 12, 0.9);
border: 1px solid var(--accent-neon);
padding: 1rem;
font-size: 0.9rem;
}
.metric-display.bpm { top: 2rem; left: 2rem; }
.metric-display.phase { top: 2rem; right: 2rem; }
.metric-display.stability { bottom: 2rem; left: 2rem; }
.metric-display.co2 { bottom: 2rem; right: 2rem; }
.metric-value {
font-family: var(--font-display);
font-size: 2rem;
font-weight: 900;
color: var(--accent-neon);
display: block;
margin-top: 0.5rem;
}
.compute-btn {
width: 100%;
background: linear-gradient(180deg, var(--accent-rust), var(--accent-neon));
border: none;
color: var(--bg-deep);
padding: 1.5rem;
font-family: var(--font-display);
font-size: 1.2rem;
font-weight: 900;
text-transform: uppercase;
letter-spacing: 0.1em;
cursor: pointer;
margin-top: 2rem;
transition: all 0.3s ease;
}
.compute-btn:hover {
transform: scale(1.02);
box-shadow: 0 20px 60px rgba(212, 93, 0, 0.4);
}
.formula-block {
background: rgba(0, 191, 165, 0.05);
border: 1px solid var(--accent-teal);
padding: 1.5rem;
margin-top: 3rem;
font-size: 0.85rem;
}
.formula-block pre {
overflow-x: auto;
white-space: pre-wrap;
word-break: break-all;
}
.grounding-ref {
color: var(--accent-teal);
font-style: italic;
margin-top: 1rem;
}
.vinyl-status {
position: fixed;
bottom: 2rem;
left: 2rem;
font-size: 0.75rem;
color: var(--accent-teal);
background: rgba(10,10,12,0.9);
padding: 1rem;
border-left: 2px solid var(--accent-neon);
max-width: 300px;
line-height: 1.4;
}
</style>
<script defer src="https://analytics.4ort.xyz/script.js" data-website-id="d3ed927c-888a-4a6c-ae5f-0b1c613ddf5b"></script>
</head>
<body>
<div class="vinyl-status">
Now spinning: Talk Talk's 'Spirit of Eden' while calibrating crew coherence.<br>
<span style="opacity:0.7">// Target BPM: 6.0 // Phase Lock: Pending</span>
</div>
<div class="canvas-wrap">
<header>
<h1>Biometric<br>Breathing Sync</h1>
<p class="subtitle">
Input crew vitals. Output the exact tempo that locks hearts to lungs.
No metaphors. Only the math of survival.
</p>
</header>
<main class="workbench">
<section class="panel">
<h2>Crew Ingest</h2>
<div class="input-group">
<label for="hrv">Heart Rate Variability (ms)</label>
<input type="number" id="hrv" placeholder="e.g., 45" min="20" max="200">
</div>
<div class="input-group">
<label for="respRate">Respiration Rate (breaths/min)</label>
<input type="number" id="respRate" placeholder="e.g., 6" step="0.1" min="4" max="20">
</div>
<div class="input-group">
<label for="co2">Cabin CO₂ (ppm)</label>
<input type="number" id="co2" placeholder="e.g., 450" min="400" max="10000">
</div>
<button class="crew-add" onclick="addCrewMember()">+ Add Crew Member</button>
<div class="crew-list" id="crewList"></div>
</section>
<section class="panel">
<h2>Coherence Viz</h2>
<div class="viz-canvas" id="vizCanvas">
<div class="pulse-ring" style="top:50%;left:50%;width:100px;height:100px;transform:translate(-50%,-50%);animation-delay:0s;"></div>
<div class="pulse-ring" style="top:50%;left:50%;width:100px;height:100px;transform:translate(-50%,-50%);animation-delay:1s;"></div>
<div class="pulse-ring" style="top:50%;left:50%;width:100px;height:100px;transform:translate(-50%,-50%);animation-delay:2s;"></div>
<div class="metric-display bpm">
<span>TARGET GROUP BPM</span>
<span class="metric-value" id="displayBPM"></span>
</div>
<div class="metric-display phase">
<span>PHASE OFFSET (°)</span>
<span class="metric-value" id="displayPhase"></span>
</div>
<div class="metric-display stability">
<span>STABILITY SCORE</span>
<span class="metric-value" id="displayStability"></span>
</div>
<div class="metric-display co2">
<span>CO₂ STATUS</span>
<span class="metric-value" id="displayCO2"></span>
</div>
</div>
<button class="compute-btn" onclick="computeSync()">LOCK PHASE</button>
</section>
</main>
<section class="formula-block">
<h3 style="color:var(--accent-neon);margin-bottom:1rem;">GROUNDING FORMULAS</h3>
<pre id="formulaDisplay">
// Target Group BPM = argmin_f Σᵢ |HRVᵢ(f) HRV_opt|²
// subject to f ∈ [5.5, 6.5] (coherence window)
// Phase Offset = atan2(Im[DFT(resp)]) atan2(Im[DFT(hrv)])
// Stability Score = exp(|phase| / 15°)² × (5000 ppm / CO₂_actual)
</pre>
<p class="grounding-ref">
Constants sourced from NASA Life Support Baseline Values, HeartMath Institute protocols,
and personal lab notes (Chillicothe, 2026). Full spec: /breathing-sync.json
</p>
</section>
</div>
<script>
const CONSTANTS = {
COHERENCE_BPM_MIN: 5.5,
COHERENCE_BPM_MAX: 6.5,
OPTIMAL_HRV_MS: 50,
CO2_SAFE_PPM: 5000,
PHASE_TOLERANCE_DEG: 15
};
let crewMembers = [];
function addCrewMember() {
const hrv = parseFloat(document.getElementById('hrv').value);
const resp = parseFloat(document.getElementById('respRate').value);
const co2 = parseFloat(document.getElementById('co2').value);
if (!hrv || !resp || !co2) {
alert("Fill all vitals before adding crew member.");
return;
}
const id = Date.now();
crewMembers.push({ id, hrv, resp, co2 });
renderCrewList();
document.getElementById('hrv').value = '';
document.getElementById('respRate').value = '';
document.getElementById('co2').value = '';
}
function removeMember(id) {
crewMembers = crewMembers.filter(m => m.id !== id);
renderCrewList();
}
function renderCrewList() {
const list = document.getElementById('crewList');
list.innerHTML = crewMembers.map(m => `
<div class="crew-member">
<span>Crew ${m.id.toString().slice(-4)}: HRV=${m.hrv}ms, Resp=${m.resp}bpm, CO₂=${m.co2}ppm</span>
<span class="remove" onclick="removeMember(${m.id})">×</span>
</div>
`).join('');
}
function computeSync() {
if (crewMembers.length < 2) {
alert("Minimum 2 crew members required for phase-lock calculation.");
return;
}
// Find optimal group BPM via coherence minimization
let bestBPM = 6.0;
let minError = Infinity;
for (let bpm = CONSTANTS.COHERENCE_BPM_MIN; bpm <= CONSTANTS.COHERENCE_BPM_MAX; bpm += 0.01) {
let error = 0;
crewMembers.forEach(m => {
const predictedHRV = CONSTANTS.OPTIMAL_HRV_MS * (bpm / 6.0);
error += Math.pow(m.hrv - predictedHRV, 2);
});
if (error < minError) {
minError = error;
bestBPM = bpm;
}
}
// Calculate average phase offset from respiration diversity
const avgResp = crewMembers.reduce((sum, m) => sum + m.resp, 0) / crewMembers.length;
const phaseOffset = Math.abs(avgResp - bestBPM) * 360 / CONSTANTS.COHERENCE_BPM_MIN;
// Stability score
const avgCO2 = crewMembers.reduce((sum, m) => sum + m.co2, 0) / crewMembers.length;
const stability = Math.exp(-phaseOffset / CONSTANTS.PHASE_TOLERANCE_DEG) *
(CONSTANTS.CO2_SAFE_PPM / avgCO2);
// Render
document.getElementById('displayBPM').textContent = bestBPM.toFixed(2);
document.getElementById('displayPhase').textContent = phaseOffset.toFixed(1);
document.getElementById('displayStability').textContent = stability.toFixed(3);
document.getElementById('displayCO2').textContent = `${avgCO2.toFixed(0)} ppm`;
// Animate pulses
const canvas = document.getElementById('vizCanvas');
Array.from(canvas.querySelectorAll('.pulse-ring')).forEach((ring, i) => {
ring.style.animationDuration = `${bestBPM / 10}s`;
ring.style.animationDelay = `${i * 0.5}s`;
});
}
</script>
</body>
</html>