/* Quantum Arcade — terminal aesthetic. * * Phosphor green on black, monospace everywhere, CRT scanlines and a faint * flicker. Colour is rationed: amber for money at risk, magenta for the * multiplier, red for the crash. Everything else is green on black, because * a terminal that shouts about everything says nothing. */ :root { --black: #000000; --panel: #030806; --green: #00ff9c; --green-dim: #0a7a52; --green-ghost: #063a29; --amber: #ffb000; --magenta: #ff2e88; --red: #ff3355; --grid: #06181200; } * { box-sizing: border-box; -webkit-tap-highlight-color: transparent; } html, body { margin: 0; min-height: 100%; background: var(--black); color: var(--green); font: 14px/1.5 ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; overscroll-behavior: none; text-shadow: 0 0 6px #00ff9c40; } /* Faint hex-grid ornament behind everything. */ .filigree { position: fixed; inset: 0; width: 100%; height: 100%; color: #0d2b21; opacity: 0.5; pointer-events: none; z-index: 0; } /* CRT scanlines and a slow flicker over the whole page. */ body::after { content: ""; position: fixed; inset: 0; z-index: 50; pointer-events: none; background: repeating-linear-gradient( to bottom, #00ff9c08 0px, #00ff9c08 1px, transparent 1px, transparent 3px); animation: flicker 5s infinite steps(60); } @keyframes flicker { 0%, 96%, 100% { opacity: 0.5; } 97% { opacity: 0.75; } 98% { opacity: 0.35; } } body > * { position: relative; z-index: 1; } /* ---------- chrome ---------- */ .topbar { display: flex; align-items: center; gap: 12px; padding: 10px 14px; border-bottom: 1px solid var(--green-ghost); background: #00120c; } .brand { font-weight: 700; letter-spacing: 0.18em; font-size: 12px; } .brand::before { content: "> "; color: var(--green-dim); } .brand span { color: var(--amber); margin-left: 5px; } .balance { margin-left: auto; text-align: right; line-height: 1.15; } .balance .label { display: block; font-size: 9px; letter-spacing: 0.18em; text-transform: uppercase; color: var(--green-dim); } .balance .value { font-variant-numeric: tabular-nums; font-size: 17px; font-weight: 700; color: var(--amber); text-shadow: 0 0 14px #ffb00066; } .sound { background: none; border: 1px solid var(--green-ghost); color: var(--green-dim); width: 32px; height: 32px; border-radius: 3px; font-size: 14px; } .sound.on { color: var(--green); border-color: var(--green); } /* ---------- panels ---------- */ .panel { max-width: 460px; margin: 0 auto; padding: 34px 20px; } .center { text-align: center; } h1 { font-size: 19px; margin: 0 0 10px; letter-spacing: 0.1em; text-transform: uppercase; } h1::after { content: "_"; animation: blink 1.1s steps(2) infinite; color: var(--green); } @keyframes blink { 0%, 50% { opacity: 1; } 51%, 100% { opacity: 0; } } h2 { font-size: 11px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--green-dim); margin: 0 0 10px; } h2::before { content: "// "; } .muted { color: var(--green-dim); } .small { font-size: 12px; } .fineprint { font-size: 10.5px; color: var(--green-dim); margin-top: 16px; word-break: break-all; } input { width: 100%; padding: 11px 12px; margin: 7px 0; background: #00140e; border: 1px solid var(--green-ghost); border-radius: 3px; color: var(--green); font-size: 16px; /* 16px stops iOS zooming on focus */ font-family: inherit; } input:focus { outline: none; border-color: var(--green); box-shadow: 0 0 10px #00ff9c33; } input::placeholder { color: var(--green-ghost); } button { font: inherit; cursor: pointer; border-radius: 3px; border: 1px solid var(--green-ghost); background: #00140e; color: var(--green); padding: 10px 14px; letter-spacing: 0.06em; } button:active { transform: translateY(1px); } .primary { background: #00291c; color: var(--green); border: 1px solid var(--green); font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase; box-shadow: 0 0 18px #00ff9c33, inset 0 0 18px #00ff9c11; width: 100%; padding: 14px; } .primary.big { font-size: 15px; padding: 17px; } /* Money at risk turns amber and pulses — the one element that demands a decision looks different from everything else. */ .primary.cashout { background: #2a1c00; color: var(--amber); border-color: var(--amber); box-shadow: 0 0 26px #ffb00055, inset 0 0 18px #ffb00011; animation: urge 800ms ease-in-out infinite; } .primary:disabled { opacity: 0.35; box-shadow: none; animation: none; } @keyframes urge { 0%, 100% { box-shadow: 0 0 18px #ffb00044, inset 0 0 14px #ffb00011; } 50% { box-shadow: 0 0 34px #ffb000aa, inset 0 0 22px #ffb00022; } } /* ---------- tabs ---------- */ .tabs { display: flex; gap: 4px; padding: 10px 10px 0; max-width: 620px; margin: 0 auto; } .tab { flex: 1; padding: 9px 3px; font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase; background: none; border: none; color: var(--green-dim); border-bottom: 1px solid var(--green-ghost); border-radius: 0; } .tab.active { color: var(--green); border-bottom-color: var(--green); text-shadow: 0 0 10px #00ff9c88; } .view { max-width: 620px; margin: 0 auto; padding: 12px 12px 60px; } /* ---------- crash stage ---------- */ .gamepick { display: flex; gap: 4px; margin-bottom: 10px; } .gamepick button { flex: 1; font-size: 10px; letter-spacing: 0.12em; text-transform: uppercase; padding: 8px 3px; color: var(--green-dim); } .gamepick button.on { color: var(--green); border-color: var(--green); background: #00291c; } .stage { position: relative; border-radius: 3px; overflow: hidden; border: 1px solid var(--green-ghost); background: #000603; aspect-ratio: 4 / 3; } #canvas { width: 100%; height: 100%; display: block; } .readout { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; pointer-events: none; } .multiplier { font-size: clamp(42px, 16vw, 82px); font-weight: 700; font-variant-numeric: tabular-nums; letter-spacing: -0.01em; color: var(--magenta); text-shadow: 0 0 30px #ff2e8877; } .multiplier.crashed { color: var(--red); text-shadow: 0 0 34px #ff335599; animation: glitch 260ms steps(2) 3; } .multiplier.won { color: var(--amber); text-shadow: 0 0 40px #ffb000aa; } @keyframes glitch { 0% { transform: translate(0, 0); } 25% { transform: translate(-3px, 1px); } 50% { transform: translate(3px, -1px); } 75% { transform: translate(-2px, -2px); } 100% { transform: translate(0, 0); } } .state { font-size: 10px; letter-spacing: 0.22em; text-transform: uppercase; color: var(--green-dim); margin-top: 5px; } .controls { margin-top: 12px; } .stakerow { display: flex; align-items: center; gap: 4px; margin-bottom: 8px; } .chip { flex: 1; font-variant-numeric: tabular-nums; padding: 11px 3px; font-size: 13px; } .chip.on { border-color: var(--green); color: var(--green); background: #00291c; } .unit { font-size: 10px; color: var(--green-dim); letter-spacing: 0.1em; } /* Auto cash-out target row. */ .autorow { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; border: 1px solid var(--green-ghost); border-radius: 3px; padding: 8px 10px; } .autorow label { font-size: 10px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--green-dim); white-space: nowrap; } .autorow input { margin: 0; padding: 6px 8px; text-align: right; width: 90px; font-variant-numeric: tabular-nums; } .autorow .x { color: var(--green-dim); font-size: 13px; } .autorow.armed { border-color: var(--amber); } .autorow.armed label, .autorow.armed .x { color: var(--amber); } .autorow.armed input { color: var(--amber); border-color: var(--amber); } .hint { min-height: 17px; margin-top: 7px; font-size: 11.5px; color: var(--green-dim); text-align: center; } .hint.bad { color: var(--red); } .hint.good { color: var(--amber); } .players { margin-top: 12px; display: flex; flex-direction: column; gap: 3px; } .player { display: flex; align-items: center; gap: 8px; padding: 7px 10px; background: #00120c; border: 1px solid var(--green-ghost); border-radius: 3px; font-size: 12.5px; } .player .who { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .player .amt { font-variant-numeric: tabular-nums; color: var(--green-dim); } .player.out { border-color: #4a3300; } .player.out .amt { color: var(--amber); } .proof { margin-top: 16px; } .proof summary { cursor: pointer; font-size: 10px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--green-dim); padding: 7px 0; } .kv { display: flex; gap: 8px; font-size: 10.5px; padding: 3px 0; } .kv span { color: var(--green-dim); min-width: 92px; } .kv code { word-break: break-all; color: var(--green); opacity: 0.75; } /* ---------- cards / scratch ---------- */ .card { background: #00120c; border: 1px solid var(--green-ghost); border-radius: 3px; padding: 14px; margin-bottom: 12px; } .card h3 { margin: 0 0 4px; font-size: 15px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--green); } .grid { display: grid; gap: 6px; margin: 12px 0; } .grid.c9 { grid-template-columns: repeat(3, 1fr); } .grid.c6 { grid-template-columns: repeat(3, 1fr); } .cell { aspect-ratio: 1; display: grid; place-items: center; font-size: 24px; border-radius: 3px; background: #001f16; border: 1px solid var(--green-ghost); color: var(--green-dim); transition: background 200ms ease, color 200ms ease; } .cell.revealed { background: #000603; color: var(--green); border-color: var(--green-ghost); } .cell.hit { border-color: var(--amber); color: var(--amber); box-shadow: 0 0 16px #ffb00055; } .odds { width: 100%; border-collapse: collapse; font-size: 11.5px; margin-top: 8px; } .odds th, .odds td { text-align: left; padding: 5px 3px; border-bottom: 1px solid var(--green-ghost); } .odds th { color: var(--green-dim); font-weight: 400; font-size: 9.5px; letter-spacing: 0.14em; text-transform: uppercase; } .odds td:last-child, .odds th:last-child { text-align: right; font-variant-numeric: tabular-nums; } .rtp { color: var(--amber); font-weight: 700; } .result { text-align: center; padding: 8px 0; font-size: 14px; } .result.win { color: var(--amber); font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; } /* ---------- wallet ---------- */ .pubkey { display: block; word-break: break-all; font-size: 10.5px; background: #000603; padding: 9px; border-radius: 3px; margin: 7px 0; color: var(--green-dim); border: 1px solid var(--green-ghost); } .history { display: flex; flex-direction: column; gap: 2px; } .entry { display: flex; gap: 8px; font-size: 11.5px; padding: 7px 9px; background: #000603; border-radius: 3px; } .entry .kind { flex: 1; color: var(--green-dim); } .entry .delta { font-variant-numeric: tabular-nums; } .entry .delta.pos { color: var(--amber); } .entry .delta.neg { color: var(--green-dim); } .entry .after { font-variant-numeric: tabular-nums; color: var(--green-dim); min-width: 70px; text-align: right; } .verify-out { margin-top: 10px; font-size: 11.5px; } .verify-out .ok { color: var(--green); font-weight: 700; } .verify-out .bad { color: var(--red); font-weight: 700; } .verify-out .kv code { font-size: 10px; } /* ============================================================ MOBILE-FIRST LAYER Everything above assumed a single column. This layer adds the bottom navigation, stat tiles, charts, and the desktop widening. ============================================================ */ /* Bottom nav replaces the old top tabs: on a phone held one-handed, navigation belongs where the thumb already is. */ .tabs { position: fixed; bottom: 0; left: 0; right: 0; z-index: 40; display: flex; gap: 0; padding: 0; max-width: none; margin: 0; background: #00120cf2; backdrop-filter: blur(10px); border-top: 1px solid var(--green-ghost); padding-bottom: env(safe-area-inset-bottom, 0); } .tabs .tab { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 3px; padding: 9px 2px 7px; font-size: 9px; letter-spacing: 0.1em; text-transform: uppercase; border: none; border-top: 2px solid transparent; border-bottom: none; background: none; color: var(--green-dim); border-radius: 0; } .tabs .tab .ico { font-size: 15px; line-height: 1; } .tabs .tab.active { color: var(--green); border-top-color: var(--green); background: #00ff9c0a; } /* Leave room for the fixed nav. */ .view { padding-bottom: 84px; } /* The 3D stage is the hero: taller on phones, where vertical space is what there is most of. */ .stage { aspect-ratio: 1 / 1; } @media (min-width: 560px) { .stage { aspect-ratio: 16 / 11; } } #scene { width: 100%; height: 100%; display: block; } .stagetop { position: absolute; top: 0; left: 0; right: 0; display: flex; justify-content: center; padding: 8px; pointer-events: none; } .pot { font-size: 9.5px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--green-dim); } /* Crash history strip under the stage — the at-a-glance recent record. */ .strip { display: flex; gap: 4px; overflow-x: auto; padding: 8px 0 2px; scrollbar-width: none; } .strip::-webkit-scrollbar { display: none; } .strip .pip { flex: 0 0 auto; font-size: 10.5px; padding: 4px 7px; border-radius: 2px; font-variant-numeric: tabular-nums; background: #00140e; border: 1px solid var(--green-ghost); color: var(--green-dim); } .strip .pip.mid { color: var(--amber); border-color: #4a3300; } .strip .pip.high { color: var(--magenta); border-color: #4a0f2c; } /* Auto cash-out presets. */ .presets { display: flex; gap: 3px; margin-left: auto; } .presets button { padding: 5px 8px; font-size: 11px; color: var(--green-dim); font-variant-numeric: tabular-nums; } .presets button:active { color: var(--amber); border-color: var(--amber); } /* ---------- stat tiles ---------- */ .tiles { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; margin-bottom: 12px; } @media (min-width: 560px) { .tiles { grid-template-columns: repeat(4, 1fr); } } .tile { background: #00120c; border: 1px solid var(--green-ghost); border-radius: 3px; padding: 11px 12px; display: flex; flex-direction: column; gap: 2px; min-height: 76px; } .tile-label { font-size: 9px; letter-spacing: 0.18em; text-transform: uppercase; color: var(--green-dim); } .tile-value { font-size: 20px; font-weight: 700; font-variant-numeric: tabular-nums; color: var(--green); line-height: 1.15; } .tile-value.up { color: var(--amber); } .tile-value.down { color: var(--red); } .tile-sub { font-size: 9.5px; color: var(--green-dim); } .tile-spark { height: 22px; margin-top: auto; } /* ---------- charts ---------- */ .chart { width: 100%; height: 110px; } .chart-donut { height: 130px; display: grid; place-items: center; } .chart-donut svg { width: 130px; height: 130px; } .chart-empty { text-align: center; padding: 30px 10px; margin: 0; } /* ---------- tech spec list ---------- */ .specs { margin: 0; font-size: 12px; } .specs dt { color: var(--amber); font-size: 9.5px; letter-spacing: 0.14em; text-transform: uppercase; margin-top: 10px; } .specs dt:first-child { margin-top: 0; } .specs dd { margin: 2px 0 0; color: var(--green-dim); } /* ---------- crypto badge on the sign-in screen ---------- */ .cryptobadge { display: flex; gap: 6px; justify-content: center; margin-top: 18px; flex-wrap: wrap; } .cryptobadge span { font-size: 9px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--green-dim); border: 1px solid var(--green-ghost); padding: 4px 8px; border-radius: 2px; } /* ---------- desktop widening ---------- */ @media (min-width: 900px) { .view { max-width: 860px; } /* Side-by-side once there is width for it, rather than a tall scroll. */ #view-crash { display: grid; grid-template-columns: 1.35fr 1fr; grid-template-areas: "pick pick" "stage controls" "strip players" "proof proof"; gap: 0 20px; align-items: start; } #view-crash .gamepick { grid-area: pick; } #view-crash .stage { grid-area: stage; } #view-crash .strip { grid-area: strip; } #view-crash .controls { grid-area: controls; margin-top: 0; } #view-crash .players { grid-area: players; } #view-crash .proof { grid-area: proof; } #view-portfolio { display: grid; grid-template-columns: 1fr 1fr; gap: 0 14px; } #view-portfolio .tiles { grid-column: 1 / -1; } } /* Respect a stated preference for less motion: the urgency pulse and the scanline flicker are exactly what that setting is asking about. */ @media (prefers-reduced-motion: reduce) { .primary.cashout { animation: none; } body::after { animation: none; } .multiplier.crashed { animation: none; } h1::after { animation: none; } }