/* GhostLog — app-shell HUD, mounted once alongside HauntingLayer so it sits above every page. "Hacker witch": Transcript.tsx's terminal vocabulary (monospace log rows, phosphor glow, flicker) fused with occult framing (sigil corners, rune bullets, pentagram divider, crescent evil-meter). Palette borrowed from App.css's --qm-* tokens / SeancePage.css — no new colors introduced. */ .ghost-log { position: fixed; left: calc(14px + var(--qm-safe-left, 0px)); /* Clears the iPhone home indicator instead of sitting under it. */ bottom: calc(14px + var(--qm-safe-bottom, 0px)); z-index: 500; /* above page content, below the global CRT glass (9999) and haunting layer (9998) */ width: 300px; max-width: calc(100vw - 28px - var(--qm-safe-left, 0px) - var(--qm-safe-right, 0px)); max-height: 46vh; max-height: 46dvh; display: flex; flex-direction: column; background: var(--qm-panel, rgba(16, 16, 26, 0.85)); border: 1px solid var(--qm-border, rgba(124, 255, 178, 0.18)); border-radius: 6px; box-shadow: 0 6px 28px rgba(0, 0, 0, 0.55), 0 0 18px rgba(178, 107, 255, 0.08), inset 0 0 24px rgba(124, 255, 178, 0.03); backdrop-filter: blur(4px); font-family: var(--qm-font-ui, 'IBM Plex Mono', monospace); overflow: hidden; pointer-events: auto; } /* candle-flicker glow instead of a flat terminal green */ .ghost-log--active { animation: ghostLogCandle 5.5s ease-in-out infinite; } .ghost-log-corner { position: absolute; top: 4px; font-size: 0.7rem; color: rgba(178, 107, 255, 0.55); text-shadow: 0 0 8px rgba(178, 107, 255, 0.5); pointer-events: none; } .ghost-log-corner--tl { left: 6px; } .ghost-log-corner--tr { right: 6px; } .ghost-log-header { display: flex; align-items: center; gap: 0.45rem; padding: 0.55rem 0.5rem 0.35rem 1rem; } .ghost-log-glyph { color: var(--qm-violet, #b26bff); text-shadow: 0 0 10px rgba(178, 107, 255, 0.7); font-size: 0.95rem; } .ghost-log-title { font-family: var(--qm-font-display, 'Cinzel', serif); font-weight: 700; font-size: 0.72rem; letter-spacing: 0.28em; color: var(--qm-green, #7cffb2); text-shadow: 0 0 10px rgba(124, 255, 178, 0.4); } .ghost-log-divider { display: flex; align-items: center; justify-content: center; gap: 0.4rem; padding: 0.1rem 0 0.3rem; color: rgba(178, 107, 255, 0.4); font-size: 0.6rem; letter-spacing: 0.3em; } .ghost-log-divider-sigil { color: var(--qm-blood, #ff3b5c); text-shadow: 0 0 8px rgba(255, 59, 92, 0.5); font-size: 0.75rem; } .ghost-log-status { margin: 0; padding: 0.3rem 1rem 0.8rem; font-size: 0.74rem; font-style: italic; letter-spacing: 0.04em; color: rgba(211, 228, 220, 0.55); } .ghost-log-status.dim { opacity: 0.6; } .ghost-log-body { flex: 1 1 auto; overflow-y: auto; padding: 0.15rem 1rem 0.8rem; display: flex; flex-direction: column; gap: 0.32rem; font-size: 0.74rem; line-height: 1.4; scrollbar-width: thin; scrollbar-color: rgba(124, 255, 178, 0.3) transparent; } .ghost-log-body::-webkit-scrollbar { width: 5px; } .ghost-log-body::-webkit-scrollbar-thumb { background: rgba(124, 255, 178, 0.25); border-radius: 3px; } .ghost-log-line { display: flex; align-items: baseline; gap: 0.4rem; } .ghost-log-rune { flex: 0 0 auto; color: var(--qm-violet, #b26bff); text-shadow: 0 0 6px rgba(178, 107, 255, 0.6); font-size: 0.72rem; } .ghost-log-line--system .ghost-log-rune { color: var(--qm-green, #7cffb2); text-shadow: 0 0 6px rgba(124, 255, 178, 0.6); } .ghost-log-text { color: rgba(211, 228, 220, 0.9); } .ghost-log-entity-name { font-family: var(--qm-font-display, 'Cinzel', serif); letter-spacing: 0.08em; color: var(--qm-green, #7cffb2); } /* ---------- evil meter gauge ---------- */ .evil-meter { display: flex; flex-direction: column; align-items: center; padding: 0 0.6rem; } .evil-meter-svg { width: 100%; height: auto; overflow: visible; } .evil-meter-track { fill: none; stroke: rgba(124, 255, 178, 0.14); stroke-width: 12; stroke-linecap: round; } .evil-meter-band { fill: rgba(178, 107, 255, 0.4); filter: drop-shadow(0 0 6px rgba(178, 107, 255, 0.55)); transition: d 200ms ease; } .evil-meter-band--certain { fill: rgba(124, 255, 178, 0.5); filter: drop-shadow(0 0 10px rgba(124, 255, 178, 0.7)); } /* CRT-scanline texture cut through the belief band — the gauge belongs to both worlds at once: occult crescent shape, hacker scanline fill. */ .evil-meter-scanline { stroke: rgba(7, 7, 13, 0.55); stroke-width: 1.4; } .evil-meter-band-texture { opacity: 0.6; mix-blend-mode: multiply; pointer-events: none; } .evil-meter-needle { stroke: #d9f5e4; stroke-width: 2; stroke-linecap: round; filter: drop-shadow(0 0 4px rgba(217, 245, 228, 0.8)); } .evil-meter-hub { fill: #d9f5e4; } .evil-meter--certain .evil-meter-needle { stroke: var(--qm-green, #7cffb2); } .evil-meter-readout { display: flex; align-items: center; justify-content: center; gap: 0.5rem; margin-top: -0.35rem; font-size: 0.66rem; letter-spacing: 0.1em; text-transform: uppercase; } .evil-meter-glyph { font-size: 0.7rem; opacity: 0.65; } .evil-meter-glyph--malevolent { color: var(--qm-blood, #ff3b5c); text-shadow: 0 0 6px rgba(255, 59, 92, 0.5); } .evil-meter-glyph--benevolent { color: var(--qm-green, #7cffb2); text-shadow: 0 0 6px rgba(124, 255, 178, 0.5); } .evil-meter-label { color: rgba(211, 228, 220, 0.85); font-style: italic; } @keyframes ghostLogCandle { 0%, 100% { box-shadow: 0 6px 28px rgba(0, 0, 0, 0.55), 0 0 18px rgba(178, 107, 255, 0.08), inset 0 0 24px rgba(124, 255, 178, 0.03); } 35% { box-shadow: 0 6px 28px rgba(0, 0, 0, 0.55), 0 0 24px rgba(178, 107, 255, 0.16), inset 0 0 28px rgba(124, 255, 178, 0.05); } 60% { box-shadow: 0 6px 28px rgba(0, 0, 0, 0.55), 0 0 14px rgba(178, 107, 255, 0.06), inset 0 0 20px rgba(124, 255, 178, 0.02); } 80% { box-shadow: 0 6px 28px rgba(0, 0, 0, 0.55), 0 0 22px rgba(178, 107, 255, 0.14), inset 0 0 26px rgba(124, 255, 178, 0.04); } } @media (prefers-reduced-motion: reduce) { .ghost-log--active { animation: none; } } /* --- collapse control --------------------------------------------------- The HUD is fixed over the bottom-left of every page. On a desktop that is dead space; on a 390px phone it lands squarely on top of the séance ask-field, so there has to be a touch-reachable way to get it out of the way. */ .ghost-log-toggle { margin-left: auto; flex: 0 0 auto; /* 44x44 — Apple's HIG floor. The glyph is small; the target is not. */ min-width: 44px; min-height: 44px; display: inline-flex; align-items: center; justify-content: center; background: none; border: none; color: rgba(124, 255, 178, 0.7); font-size: 0.9rem; line-height: 1; cursor: pointer; } .ghost-log-toggle:active { color: var(--qm-green, #7cffb2); } /* Collapsed: header only, so the log is a small tab rather than a panel. */ .ghost-log--collapsed { max-height: none; } /* --- phones ------------------------------------------------------------- A 300px panel on a 390px screen covers most of the width. Span the full width instead (minus the same gutter), cap the height lower so it never eats the screen, and keep every row readable. */ @media (max-width: 560px) { .ghost-log { left: calc(8px + var(--qm-safe-left, 0px)); right: calc(8px + var(--qm-safe-right, 0px)); bottom: calc(8px + var(--qm-safe-bottom, 0px)); width: auto; max-width: none; max-height: 32vh; max-height: 32dvh; } .ghost-log-status, .ghost-log-body { font-size: 0.85rem; } }