Add EMF field mode, Armory shop/waitlist, and ambient haunting layer
Three self-contained features, verified complete and cross-wired end-to-end (audited: backend 54/54 tests, frontend 110/110 tests, tsc --noEmit clean, i18n coverage script clean): - EMF mode: DeviceMotion/DeviceOrientation-based field-meter sensing, a fifth séance channel alongside Wire/EVP/Radio/Ouija, with its own fragment prompt persona and full frontend gauge UI. - Armory (shop/waitlist): pre-order capture page for the future Ultimate Quantum Box hardware line, rate-limited public endpoint, explicitly no payment collection. - Haunting layer: ambient possession effects (dread-bed audio, title glitching, idle-paced whispers/manifests), respects prefers-reduced-motion, mounted once at the app root. Plus WebUSB robustness fixes in lib/sdr.ts (Terratec vendor ID, explicit selectConfiguration, isSecureContext gate). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013PphXq1s43DNRj1uWKGXof
This commit is contained in:
@@ -749,14 +749,16 @@
|
||||
.evp-panel,
|
||||
.radio-panel,
|
||||
.ouija-panel,
|
||||
.wire-panel {
|
||||
.wire-panel,
|
||||
.emf-panel {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.55rem;
|
||||
}
|
||||
|
||||
.evp-scope,
|
||||
.radio-waterfall {
|
||||
.radio-waterfall,
|
||||
.emf-gauge {
|
||||
width: 100%;
|
||||
border: 1px solid rgba(124, 255, 178, 0.18);
|
||||
border-radius: 4px;
|
||||
@@ -772,8 +774,13 @@
|
||||
height: 110px;
|
||||
}
|
||||
|
||||
.emf-gauge {
|
||||
height: 140px;
|
||||
}
|
||||
|
||||
.evp-readout,
|
||||
.radio-readout {
|
||||
.radio-readout,
|
||||
.emf-readout {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: baseline;
|
||||
@@ -798,6 +805,70 @@
|
||||
color: rgba(211, 233, 219, 0.75);
|
||||
}
|
||||
|
||||
/* emf */
|
||||
.emf-level {
|
||||
color: #7cffb2;
|
||||
font-size: 1.5rem;
|
||||
text-shadow: 0 0 14px rgba(124, 255, 178, 0.65);
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
.emf-baseline {
|
||||
font-size: 0.72rem;
|
||||
letter-spacing: 0.08em;
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
.emf-listening {
|
||||
margin: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
font-size: 0.76rem;
|
||||
color: rgba(211, 233, 219, 0.75);
|
||||
}
|
||||
|
||||
.emf-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.6rem;
|
||||
margin-top: 0.7rem;
|
||||
}
|
||||
|
||||
.emf-actions .panel-action {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
/* smaller secondary control (calibrate, try again) */
|
||||
.panel-subaction {
|
||||
align-self: flex-start;
|
||||
background: transparent;
|
||||
border: 1px solid rgba(124, 255, 178, 0.3);
|
||||
border-radius: 3px;
|
||||
color: rgba(124, 255, 178, 0.75);
|
||||
font-family: 'IBM Plex Mono', monospace;
|
||||
font-size: 0.7rem;
|
||||
letter-spacing: 0.12em;
|
||||
text-transform: uppercase;
|
||||
padding: 0.32rem 0.7rem;
|
||||
cursor: pointer;
|
||||
transition: box-shadow 150ms ease, color 150ms ease;
|
||||
}
|
||||
|
||||
.panel-subaction:hover:not(:disabled) {
|
||||
color: #7cffb2;
|
||||
box-shadow: 0 0 10px rgba(124, 255, 178, 0.25);
|
||||
}
|
||||
|
||||
.panel-subaction:disabled {
|
||||
opacity: 0.35;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.panel-notice .panel-subaction {
|
||||
margin-top: 0.2rem;
|
||||
}
|
||||
|
||||
.rec-dot {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
|
||||
Reference in New Issue
Block a user