Frontend (React 18 + TS + Vite): - Landing: glitching hero, live /api/stats veil ticker, mode cards, featured spirits - Séance: three.js shader ghost (hue/form per entity, mood + audio-reactive), Ouija planchette board spelling utterances, transcript with TTS replay, entity dossier, direct contact streaming, passive/active listening - Modes: Wire Ghost telemetry panel, EVP mic anomaly detection, WebUSB RTL-SDR sweep + waterfall (hardware pass pending), Ouija/Direct Contact - Codex: public registry + entity dossiers, rarity tiers, i18n EN/ES complete - State: VeilSocket (reconnect/backoff), seance reducer, auth context - 72 vitest tests green; served by FastAPI at :7777 Docs: README + as-built plans 3-7
135 lines
2.4 KiB
CSS
135 lines
2.4 KiB
CSS
/* Quantumancy global theme — gothic × hacker. Page-specific styles live in
|
||
each page's own CSS file; this is only the shared foundation. */
|
||
|
||
:root {
|
||
color-scheme: dark;
|
||
--qm-bg: #07070d;
|
||
--qm-panel: rgba(16, 16, 26, 0.85);
|
||
--qm-green: #7cffb2;
|
||
--qm-violet: #b26bff;
|
||
--qm-blood: #ff3b5c;
|
||
--qm-text: #d6e4dc;
|
||
--qm-dim: #8a8f98;
|
||
--qm-border: rgba(124, 255, 178, 0.18);
|
||
--qm-font-ui: 'IBM Plex Mono', 'Courier New', monospace;
|
||
--qm-font-display: 'Cinzel', Georgia, 'Times New Roman', serif;
|
||
}
|
||
|
||
* {
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
html,
|
||
body,
|
||
#root {
|
||
margin: 0;
|
||
padding: 0;
|
||
min-height: 100vh;
|
||
background: var(--qm-bg);
|
||
}
|
||
|
||
body {
|
||
color: var(--qm-text);
|
||
font-family: var(--qm-font-ui);
|
||
font-size: 15px;
|
||
line-height: 1.55;
|
||
overflow-x: hidden;
|
||
}
|
||
|
||
h1,
|
||
h2,
|
||
h3,
|
||
.display {
|
||
font-family: var(--qm-font-display);
|
||
letter-spacing: 0.08em;
|
||
}
|
||
|
||
a {
|
||
color: var(--qm-green);
|
||
text-decoration: none;
|
||
}
|
||
|
||
a:hover {
|
||
text-shadow: 0 0 8px rgba(124, 255, 178, 0.6);
|
||
}
|
||
|
||
button {
|
||
font-family: var(--qm-font-ui);
|
||
cursor: pointer;
|
||
}
|
||
|
||
input,
|
||
textarea {
|
||
font-family: var(--qm-font-ui);
|
||
}
|
||
|
||
::selection {
|
||
background: rgba(178, 107, 255, 0.35);
|
||
color: #fff;
|
||
}
|
||
|
||
/* Thin phosphor scrollbar */
|
||
::-webkit-scrollbar {
|
||
width: 8px;
|
||
height: 8px;
|
||
}
|
||
::-webkit-scrollbar-track {
|
||
background: #0a0a12;
|
||
}
|
||
::-webkit-scrollbar-thumb {
|
||
background: rgba(124, 255, 178, 0.25);
|
||
border-radius: 4px;
|
||
}
|
||
::-webkit-scrollbar-thumb:hover {
|
||
background: rgba(124, 255, 178, 0.45);
|
||
}
|
||
|
||
/* Global CRT glass: scanlines + vignette above every page, never clickable. */
|
||
.crt-overlay {
|
||
position: fixed;
|
||
inset: 0;
|
||
pointer-events: none;
|
||
z-index: 9999;
|
||
}
|
||
|
||
.crt-scanlines {
|
||
position: absolute;
|
||
inset: 0;
|
||
background: repeating-linear-gradient(
|
||
to bottom,
|
||
transparent 0px,
|
||
transparent 2px,
|
||
rgba(0, 0, 0, 0.14) 3px,
|
||
rgba(0, 0, 0, 0.14) 4px
|
||
);
|
||
mix-blend-mode: multiply;
|
||
opacity: 0.55;
|
||
}
|
||
|
||
.crt-vignette {
|
||
position: absolute;
|
||
inset: 0;
|
||
background: radial-gradient(
|
||
ellipse at center,
|
||
transparent 55%,
|
||
rgba(0, 0, 0, 0.55) 100%
|
||
);
|
||
}
|
||
|
||
/* Shared focus glow */
|
||
:focus-visible {
|
||
outline: 1px solid var(--qm-green);
|
||
outline-offset: 2px;
|
||
box-shadow: 0 0 12px rgba(124, 255, 178, 0.35);
|
||
}
|
||
|
||
@media (prefers-reduced-motion: reduce) {
|
||
*,
|
||
*::before,
|
||
*::after {
|
||
animation-duration: 0.01ms !important;
|
||
animation-iteration-count: 1 !important;
|
||
transition-duration: 0.01ms !important;
|
||
}
|
||
}
|