@import url("https://fonts.googleapis.com/css2?family=Press+Start+2P&family=VT323&display=swap"); /* Minimal CSS for the EV Grid Oracle Phaser demo. (Replaces the Vite starter template styles.) */ * { box-sizing: border-box; } html, body { height: 100%; } body { margin: 0; font-family: "VT323", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; background: radial-gradient(900px 540px at 18% 8%, rgba(255, 0, 245, 0.18), rgba(0,0,0,0) 55%), radial-gradient(900px 540px at 82% 18%, rgba(0, 255, 224, 0.16), rgba(0,0,0,0) 58%), radial-gradient(1200px 600px at 30% 10%, #121629, #070911 70%); color: #e8ecff; text-shadow: 0 0 12px rgba(122, 167, 255, 0.12); } :root{ --hud-bg: rgba(9, 9, 22, 0.78); --hud-bg2: rgba(18, 16, 42, 0.62); --hud-stroke: rgba(142, 110, 255, 0.35); --hud-stroke2: rgba(90, 120, 255, 0.26); --hud-glow: rgba(172, 88, 255, 0.25); --hud-cyan: #23e7ff; --hud-green: #47ff9a; --hud-amber: #ffbf3c; --hud-pink: #ff5a8a; } .title, .pill, .btn, .kpiLabel, .panelTitle { font-family: "Press Start 2P", "VT323", ui-monospace, monospace; letter-spacing: 0.4px; } /* HEAVY RETRO CRT: scanlines + noise + flicker */ body::before { content: ""; pointer-events: none; position: fixed; inset: 0; background: repeating-linear-gradient( to bottom, rgba(0, 0, 0, 0.00) 0px, rgba(0, 0, 0, 0.00) 2px, rgba(0, 0, 0, 0.18) 3px, rgba(0, 0, 0, 0.18) 4px ); mix-blend-mode: multiply; opacity: 0.35; animation: crt-scan 6s linear infinite; z-index: 99998; } body::after { content: ""; pointer-events: none; position: fixed; inset: 0; background-image: radial-gradient(circle at 20% 30%, rgba(255,255,255,0.06), rgba(255,255,255,0) 40%), radial-gradient(circle at 80% 60%, rgba(255,255,255,0.05), rgba(255,255,255,0) 42%), url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='120' height='120' filter='url(%23n)' opacity='.25'/%3E%3C/svg%3E"); opacity: 0.18; mix-blend-mode: overlay; animation: crt-noise 1.1s steps(2) infinite, crt-flicker 3.4s infinite; z-index: 99999; } @media (prefers-reduced-motion: reduce) { body::before, body::after { animation: none !important; } } @keyframes crt-scan { 0% { transform: translateY(0); } 100% { transform: translateY(12px); } } @keyframes crt-noise { 0% { transform: translate(0, 0); } 25% { transform: translate(-2px, 1px); } 50% { transform: translate(1px, -1px); } 75% { transform: translate(2px, 1px); } 100% { transform: translate(0, 0); } } @keyframes crt-flicker { 0%, 100% { opacity: 0.30; } 40% { opacity: 0.38; } 55% { opacity: 0.26; } 70% { opacity: 0.42; } } #app { height: 100%; } .shell { height: 100vh; display: grid; grid-template-rows: auto 1fr; } .topbar { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 14px 16px; border-bottom: 1px solid rgba(120, 140, 200, 0.25); background: rgba(7, 9, 17, 0.6); backdrop-filter: blur(10px); } .topbar { box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.04) inset, 0 16px 50px rgba(0,0,0,0.45); } .brand { display: flex; gap: 12px; align-items: center; } .dot { width: 12px; height: 12px; border-radius: 999px; background: #47ff9a; box-shadow: 0 0 18px rgba(71, 255, 154, 0.45); } /* (moved further down; see .game.baselineGame / .game.oracleGame overrides) */ .title { font-weight: 900; letter-spacing: 0.3px; text-transform: uppercase; } .glitch { position: relative; display: inline-block; animation: boot-in 520ms ease-out both; } .glitch::before, .glitch::after { content: attr(data-text); position: absolute; inset: 0; pointer-events: none; opacity: 0.0; } .glitch::before { color: rgba(255, 0, 245, 0.85); transform: translate(0, 0); mix-blend-mode: screen; } .glitch::after { color: rgba(0, 255, 224, 0.85); transform: translate(0, 0); mix-blend-mode: screen; } .glitch { animation: boot-in 520ms ease-out both, glitch-pop 1400ms 220ms steps(10) 1; } .glitch::before, .glitch::after { animation: glitch-echo 1400ms 220ms steps(10) 1; } @keyframes boot-in { 0% { opacity: 0; transform: translateY(-8px) scale(0.98); filter: blur(2px); } 100% { opacity: 1; transform: translateY(0) scale(1); filter: blur(0); } } @keyframes glitch-pop { 0% { letter-spacing: 1.8px; } 12% { letter-spacing: 0.3px; } 22% { letter-spacing: 1.2px; } 100% { letter-spacing: 0.3px; } } @keyframes glitch-echo { 0% { opacity: 0; transform: translate(0, 0); } 6% { opacity: 0.55; transform: translate(-2px, 0); } 12% { opacity: 0.35; transform: translate(2px, 0); } 18% { opacity: 0.45; transform: translate(-1px, 1px); } 24% { opacity: 0.0; transform: translate(0, 0); } 100% { opacity: 0.0; transform: translate(0, 0); } } .subtitle { font-size: 12px; opacity: 0.8; } .controls { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; justify-content: flex-end; } .btn { background: linear-gradient(180deg, rgba(120, 102, 255, 0.34), rgba(20, 18, 46, 0.55)); border: 1px solid var(--hud-stroke); color: #e8ecff; padding: 8px 10px; border-radius: 10px; cursor: pointer; font-weight: 700; text-transform: uppercase; letter-spacing: 0.6px; box-shadow: 0 0 0 1px rgba(255,255,255,0.05) inset, 0 10px 30px rgba(0,0,0,0.35); } .btn.primary { background: linear-gradient(180deg, rgba(255, 191, 60, 0.75), rgba(160, 88, 255, 0.22)); border-color: rgba(255, 191, 60, 0.65); box-shadow: 0 0 0 1px rgba(255,255,255,0.08) inset, 0 0 28px rgba(255, 191, 60, 0.16); } .btn.glow { background: linear-gradient(180deg, rgba(35, 231, 255, 0.24), rgba(172, 88, 255, 0.10)); border-color: rgba(35, 231, 255, 0.45); box-shadow: 0 0 0 1px rgba(255,255,255,0.06) inset, 0 0 34px rgba(35, 231, 255, 0.12), 0 14px 40px rgba(172, 88, 255, 0.12); } .btn.ghost { background: rgba(9, 9, 22, 0.45); } .btn:hover { border-color: rgba(35, 231, 255, 0.55); } .controlCluster.primary { display: flex; gap: 10px; padding: 6px; border-radius: 12px; border: 1px solid rgba(120, 140, 200, 0.18); background: rgba(255, 255, 255, 0.03); } .advanced { position: relative; } .advanced > summary { list-style: none; } .advanced > summary::-webkit-details-marker { display: none; } .advanced[open] > summary { border-color: rgba(182, 124, 255, 0.55); } .advancedGrid { position: absolute; right: 0; top: calc(100% + 10px); width: min(560px, calc(100vw - 24px)); padding: 12px; display: grid; gap: 10px; grid-template-columns: 1fr 1fr; border: 1px solid rgba(120, 140, 200, 0.22); border-radius: 16px; background: rgba(7, 9, 17, 0.82); backdrop-filter: blur(12px); box-shadow: 0 20px 60px rgba(0,0,0,0.55); z-index: 100000; } .advancedGrid .label.wide { grid-column: 1 / -1; min-width: unset; } .heroStrip { display: grid; grid-template-columns: 1fr auto; gap: 16px; align-items: center; padding: 14px 16px; border-bottom: 1px solid rgba(120, 140, 200, 0.22); background: radial-gradient(700px 140px at 25% 20%, rgba(182, 124, 255, 0.20), rgba(0,0,0,0) 70%), radial-gradient(700px 140px at 80% 30%, rgba(0, 255, 224, 0.14), rgba(0,0,0,0) 68%), rgba(7, 9, 17, 0.55); backdrop-filter: blur(12px); } .heroEyebrow { font-family: "Press Start 2P", "VT323", ui-monospace, monospace; font-size: 10px; letter-spacing: 0.8px; opacity: 0.9; text-transform: uppercase; } .heroHeadline { display: flex; align-items: baseline; gap: 10px; margin-top: 6px; } .heroMain { font-family: "Press Start 2P", "VT323", ui-monospace, monospace; font-size: 26px; letter-spacing: 0.6px; text-shadow: 0 0 24px rgba(182, 124, 255, 0.22); } .heroUnit { font-size: 12px; opacity: 0.78; } .heroSub { margin-top: 6px; font-size: 12px; opacity: 0.78; } .heroRight { display: flex; align-items: center; gap: 10px; } .heroMini { min-width: 84px; padding: 10px 10px; border-radius: 14px; border: 1px solid rgba(120, 140, 200, 0.18); background: rgba(255, 255, 255, 0.03); } .miniLabel { font-family: "Press Start 2P", "VT323", ui-monospace, monospace; font-size: 9px; letter-spacing: 0.7px; opacity: 0.8; text-transform: uppercase; } .miniVal { margin-top: 6px; font-size: 14px; } .heroVerdict { margin-left: 6px; font-family: "Press Start 2P", "VT323", ui-monospace, monospace; font-size: 10px; letter-spacing: 0.8px; padding: 10px 12px; border-radius: 999px; border: 1px solid rgba(120, 140, 200, 0.25); background: rgba(7, 9, 17, 0.55); } .heroVerdict.win { border-color: rgba(71, 255, 154, 0.45); box-shadow: 0 0 28px rgba(71, 255, 154, 0.12); } .heroVerdict.risk { border-color: rgba(255, 90, 138, 0.45); box-shadow: 0 0 28px rgba(255, 90, 138, 0.14); } .heroVerdict.ready { border-color: rgba(182, 124, 255, 0.45); box-shadow: 0 0 28px rgba(182, 124, 255, 0.12); } .heroStrip { border-top: 1px solid rgba(255,255,255,0.05); box-shadow: 0 0 0 1px rgba(255,255,255,0.03) inset; } .pulse { animation: pulse 520ms ease-out; } @keyframes pulse { 0% { transform: translateZ(0) scale(1); } 35% { transform: translateZ(0) scale(1.012); } 100% { transform: translateZ(0) scale(1); } } .shake { animation: shake 420ms ease-out; } @keyframes shake { 0% { transform: translateX(0); } 25% { transform: translateX(-6px); } 55% { transform: translateX(4px); } 100% { transform: translateX(0); } } .label { display: flex; align-items: center; gap: 8px; font-size: 12px; opacity: 0.95; padding: 6px 8px; border: 1px solid rgba(120, 140, 200, 0.22); border-radius: 10px; background: rgba(255, 255, 255, 0.04); } .label.wide { min-width: 340px; } .select, .input { background: rgba(7, 9, 17, 0.7); border: 1px solid rgba(120, 140, 200, 0.25); color: #e8ecff; padding: 7px 10px; border-radius: 10px; outline: none; } .input { width: 100%; } .input.narrow { width: 140px; } .btn.small { padding: 6px 8px; letter-spacing: 0.4px; } .replayBar { border-bottom: 1px solid rgba(120, 140, 200, 0.22); background: rgba(7, 9, 17, 0.55); backdrop-filter: blur(10px); padding: 10px 16px 12px; } .replayTitle { font-family: "Press Start 2P", "VT323", ui-monospace, monospace; font-size: 10px; letter-spacing: 0.6px; opacity: 0.92; margin-bottom: 8px; } .replayRow { display: flex; align-items: center; gap: 12px; } .replayMeta { display: grid; gap: 6px; justify-items: end; min-width: 170px; font-size: 12px; opacity: 0.9; } .replayHint { margin-top: 8px; font-size: 12px; opacity: 0.72; } .range { width: 100%; accent-color: #7aa7ff; } .main { display: grid; grid-template-columns: 1fr 1fr 380px; gap: 14px; padding: 14px; height: 100%; align-items: start; } .game { border: 1px solid rgba(120, 140, 200, 0.22); border-radius: 16px; overflow: hidden; background: linear-gradient(180deg, rgba(10, 12, 24, 0.9), rgba(6, 7, 14, 0.9)); min-height: 520px; width: 100%; aspect-ratio: 16 / 9; height: fit-content; } .hudHeader { background: linear-gradient(180deg, rgba(18, 16, 42, 0.75), rgba(9, 9, 22, 0.55)); } .hudTag { display: inline-flex; gap: 8px; align-items: center; } .hudIcon { display: inline-flex; width: 18px; height: 18px; align-items: center; justify-content: center; font-size: 12px; border-radius: 6px; border: 1px solid rgba(255,255,255,0.10); background: rgba(0,0,0,0.25); box-shadow: 0 0 18px rgba(172, 88, 255, 0.16); } .hudIcon.good { border-color: rgba(71,255,154,0.35); box-shadow: 0 0 16px rgba(71,255,154,0.12); } .hudIcon.danger { border-color: rgba(255,90,138,0.35); box-shadow: 0 0 16px rgba(255,90,138,0.12); } .hudIcon.info { border-color: rgba(35,231,255,0.35); box-shadow: 0 0 16px rgba(35,231,255,0.12); } .hudIcon.oracle { border-color: rgba(182,124,255,0.45); box-shadow: 0 0 16px rgba(182,124,255,0.14); } .hudPill { background: rgba(0,0,0,0.22); } .hudCard { background: linear-gradient(180deg, rgba(18, 16, 42, 0.62), rgba(9, 9, 22, 0.62)); border: 1px solid var(--hud-stroke); box-shadow: 0 0 0 1px rgba(255,255,255,0.03) inset, 0 0 34px rgba(172, 88, 255, 0.10); } .hudTitle { font-family: "Press Start 2P", "VT323", ui-monospace, monospace; font-size: 10px; letter-spacing: 0.9px; text-transform: uppercase; display: flex; align-items: center; gap: 10px; } .hudKpiRow { align-items: center; } .kpiLeft { display: inline-flex; gap: 10px; align-items: center; } .kpiIcon { width: 18px; height: 18px; display: inline-flex; align-items: center; justify-content: center; border-radius: 6px; border: 1px solid rgba(255,255,255,0.10); background: rgba(0,0,0,0.22); font-size: 12px; } .kpiRight { display: grid; grid-template-columns: 92px auto; gap: 10px; align-items: center; } .kpiBar { height: 10px; border-radius: 999px; background: rgba(0,0,0,0.28); border: 1px solid rgba(255,255,255,0.08); box-shadow: 0 0 0 1px rgba(255,255,255,0.02) inset; overflow: hidden; } .kpiBarFill { height: 100%; width: 0%; border-radius: 999px; background: linear-gradient(90deg, rgba(35,231,255,0.85), rgba(182,124,255,0.85)); box-shadow: 0 0 16px rgba(35,231,255,0.10); transition: width 420ms ease; } .kpiVal.deltaPos + .kpiBar .kpiBarFill {} .kpiVal.deltaPos { color: var(--hud-green); } .kpiVal.deltaNeg { color: var(--hud-pink); } .game.baselineGame { border: 1px solid rgba(255, 88, 88, 0.40); box-shadow: 0 0 0 1px rgba(255, 88, 88, 0.10) inset, 0 0 36px rgba(255, 88, 88, 0.16); } .game.oracleGame { border: 1px solid rgba(120, 102, 255, 0.48); box-shadow: 0 0 0 1px rgba(120, 102, 255, 0.14) inset, 0 0 42px rgba(160, 88, 255, 0.22); } #gameBaseline, #gameOracle { width: 100%; height: 100%; } #gameBaseline canvas, #gameOracle canvas { width: 100% !important; height: 100% !important; image-rendering: pixelated; display: block; } /* MapLibre canvas in the same mount div */ #gameBaseline .maplibregl-canvas, #gameOracle .maplibregl-canvas { width: 100% !important; height: 100% !important; display: block; } .gameHeader { display: flex; align-items: center; justify-content: space-between; padding: 10px 12px; border-bottom: 1px solid rgba(120, 140, 200, 0.18); background: rgba(255, 255, 255, 0.03); } .tag { font-weight: 900; letter-spacing: 0.4px; font-size: 12px; opacity: 0.9; } .tag.oracle { color: #b67cff; text-shadow: 0 0 16px rgba(182, 124, 255, 0.40); } .tag.baseline { color: rgba(232, 236, 255, 0.78); } .pill { font-size: 11px; padding: 4px 8px; border-radius: 999px; border: 1px solid rgba(120, 140, 200, 0.22); background: rgba(7, 9, 17, 0.55); opacity: 0.9; } .pill.good { border-color: rgba(71, 255, 154, 0.4); } .pill.warn { border-color: rgba(255, 165, 0, 0.35); } .pill.bad { border-color: rgba(255, 90, 138, 0.4); } .rail { display: grid; gap: 14px; grid-template-rows: auto auto auto 1fr; } .kpis { display: grid; gap: 10px; } .kpiRow { display: flex; justify-content: space-between; gap: 10px; font-size: 12px; } .kpiVal { font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; opacity: 0.95; } .deltaPos { color: #47ff9a; } .deltaNeg { color: #ff5a8a; } @media (max-width: 1280px) { .main { grid-template-columns: 1fr; } } .side { display: grid; grid-template-rows: auto 1fr; gap: 14px; } .card { border: 1px solid rgba(120, 140, 200, 0.22); border-radius: 16px; padding: 12px; background: linear-gradient(180deg, rgba(255, 255, 255, 0.06), rgba(255, 255, 255, 0.03)); } .card.collapsible { padding: 0; overflow: hidden; } .card.collapsible > summary.cardTitle { cursor: pointer; user-select: none; padding: 12px; margin: 0; list-style: none; } .card.collapsible > summary.cardTitle::-webkit-details-marker { display: none; } .card.collapsible[open] > summary.cardTitle { border-bottom: 1px solid rgba(120, 140, 200, 0.18); background: rgba(255, 255, 255, 0.02); } .card.collapsible > .mono { border: 0; border-radius: 0; margin: 0; } .cardTitle { font-weight: 900; letter-spacing: 0.2px; margin-bottom: 10px; } .mono { margin: 0; font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; font-size: 12px; line-height: 1.35; white-space: pre-wrap; padding: 10px; border-radius: 12px; border: 1px solid rgba(120, 140, 200, 0.16); background: linear-gradient(180deg, rgba(0, 0, 0, 0.24), rgba(0, 0, 0, 0.08)), repeating-linear-gradient(to bottom, rgba(255,255,255,0.04) 0px, rgba(255,255,255,0.04) 1px, rgba(255,255,255,0) 18px); } @media (max-width: 1100px) { .main { grid-template-columns: 1fr; } .label.wide { min-width: 240px; } .advancedGrid { position: static; width: 100%; } } /* Old Vite starter tail removed — demo CSS is now intentional and focused. */