Spaces:
Sleeping
Sleeping
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8" /> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |
| <title>Flight Simulator</title> | |
| <link rel="preconnect" href="https://fonts.googleapis.com" /> | |
| <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> | |
| <link | |
| href="https://fonts.googleapis.com/css2?family=Chakra+Petch:wght@400;500;600;700&family=Space+Grotesk:wght@400;500;700&display=swap" | |
| rel="stylesheet" | |
| /> | |
| <style> | |
| :root { | |
| --hud-ink: #0f2d3f; | |
| --hud-highlight: #2ee5b6; | |
| --hud-warning: #ffc763; | |
| --hud-text: #e9f6ff; | |
| --hud-soft: rgba(233, 246, 255, 0.72); | |
| --hud-muted: rgba(233, 246, 255, 0.32); | |
| --panel-bg: linear-gradient(160deg, rgba(7, 28, 42, 0.86), rgba(10, 44, 63, 0.72)); | |
| --panel-border: rgba(46, 229, 182, 0.35); | |
| } | |
| * { | |
| box-sizing: border-box; | |
| } | |
| body { | |
| margin: 0; | |
| min-height: 100vh; | |
| overflow: hidden; | |
| font-family: "Space Grotesk", "Segoe UI", sans-serif; | |
| background: #72bbec; | |
| } | |
| #game-container, | |
| canvas { | |
| position: fixed; | |
| inset: 0; | |
| width: 100%; | |
| height: 100%; | |
| } | |
| #game-container { | |
| width: 100vw; | |
| height: 100vh; | |
| background: #87ceeb; | |
| } | |
| #ui-root { | |
| position: fixed; | |
| inset: 0; | |
| padding: | |
| max(clamp(12px, 2vw, 24px), env(safe-area-inset-top)) | |
| max(clamp(12px, 2vw, 24px), env(safe-area-inset-right)) | |
| max(clamp(12px, 2vw, 24px), env(safe-area-inset-bottom)) | |
| max(clamp(12px, 2vw, 24px), env(safe-area-inset-left)); | |
| display: grid; | |
| grid-template-columns: minmax(240px, 320px) 1fr minmax(220px, 300px); | |
| grid-template-rows: auto 1fr; | |
| gap: 16px; | |
| pointer-events: none; | |
| z-index: 10; | |
| } | |
| #ui-root::before { | |
| content: ""; | |
| position: absolute; | |
| inset: 0; | |
| background: | |
| radial-gradient(140% 90% at 50% 0%, rgba(255, 230, 160, 0.25), transparent 52%), | |
| linear-gradient(180deg, rgba(0, 0, 0, 0.16), transparent 28%); | |
| z-index: -1; | |
| } | |
| .hud-card { | |
| border: 1px solid var(--panel-border); | |
| border-radius: 16px; | |
| background: var(--panel-bg); | |
| box-shadow: 0 14px 30px rgba(3, 12, 20, 0.28); | |
| backdrop-filter: blur(10px); | |
| color: var(--hud-text); | |
| animation: card-in 520ms ease both; | |
| } | |
| .hud-banner { | |
| grid-column: 1 / 4; | |
| padding: 12px 16px; | |
| display: grid; | |
| gap: 2px; | |
| } | |
| .hud-kicker { | |
| margin: 0; | |
| font-family: "Chakra Petch", sans-serif; | |
| letter-spacing: 0.2em; | |
| font-weight: 600; | |
| font-size: 0.72rem; | |
| text-transform: uppercase; | |
| color: var(--hud-soft); | |
| } | |
| .hud-title { | |
| margin: 0; | |
| font-family: "Chakra Petch", sans-serif; | |
| letter-spacing: 0.04em; | |
| font-size: clamp(1rem, 2.2vw, 1.5rem); | |
| } | |
| .hud-status { | |
| margin: 0; | |
| display: flex; | |
| align-items: center; | |
| gap: 8px; | |
| font-size: 0.84rem; | |
| color: var(--hud-soft); | |
| } | |
| .status-dot { | |
| width: 8px; | |
| height: 8px; | |
| border-radius: 999px; | |
| background: var(--hud-highlight); | |
| box-shadow: 0 0 10px rgba(46, 229, 182, 0.8); | |
| } | |
| .hud-telemetry { | |
| align-self: end; | |
| padding: 14px; | |
| } | |
| .hud-controls { | |
| align-self: start; | |
| padding: 14px; | |
| animation-delay: 120ms; | |
| } | |
| .hud-heading { | |
| margin: 0 0 12px; | |
| font-family: "Chakra Petch", sans-serif; | |
| font-size: 1rem; | |
| letter-spacing: 0.04em; | |
| } | |
| .meter-wrap { | |
| margin-top: 14px; | |
| display: grid; | |
| gap: 6px; | |
| } | |
| .meter-label { | |
| display: flex; | |
| align-items: center; | |
| justify-content: space-between; | |
| color: var(--hud-soft); | |
| font-size: 0.76rem; | |
| letter-spacing: 0.06em; | |
| text-transform: uppercase; | |
| } | |
| .meter-rail { | |
| height: 9px; | |
| border-radius: 999px; | |
| background: rgba(255, 255, 255, 0.12); | |
| border: 1px solid var(--hud-muted); | |
| overflow: hidden; | |
| } | |
| .meter-fill { | |
| height: 100%; | |
| width: 0; | |
| border-radius: inherit; | |
| background: linear-gradient(90deg, #6dd8ff, var(--hud-highlight)); | |
| box-shadow: 0 0 12px rgba(46, 229, 182, 0.55); | |
| transition: width 120ms linear; | |
| } | |
| .telemetry-grid { | |
| margin: 0; | |
| display: grid; | |
| grid-template-columns: auto auto; | |
| gap: 8px 14px; | |
| } | |
| .telemetry-grid dt { | |
| color: var(--hud-soft); | |
| font-size: 0.8rem; | |
| text-transform: uppercase; | |
| letter-spacing: 0.08em; | |
| } | |
| .telemetry-grid dd { | |
| margin: 0; | |
| text-align: right; | |
| font-family: "Chakra Petch", sans-serif; | |
| color: #ffffff; | |
| font-size: 1rem; | |
| } | |
| .control-grid { | |
| display: grid; | |
| gap: 10px; | |
| } | |
| .control-row { | |
| display: flex; | |
| align-items: center; | |
| justify-content: space-between; | |
| gap: 8px; | |
| color: var(--hud-soft); | |
| font-size: 0.88rem; | |
| } | |
| .key-pair { | |
| display: inline-flex; | |
| gap: 6px; | |
| align-items: center; | |
| } | |
| kbd { | |
| min-width: 30px; | |
| padding: 4px 8px; | |
| border-radius: 8px; | |
| border: 1px solid rgba(233, 246, 255, 0.35); | |
| background: rgba(255, 255, 255, 0.08); | |
| color: #ffffff; | |
| font-family: "Chakra Petch", sans-serif; | |
| font-size: 0.78rem; | |
| text-align: center; | |
| } | |
| kbd.active { | |
| color: var(--hud-ink); | |
| background: var(--hud-highlight); | |
| border-color: transparent; | |
| box-shadow: 0 0 14px rgba(46, 229, 182, 0.7); | |
| } | |
| .center-stack { | |
| grid-column: 2; | |
| grid-row: 2; | |
| justify-self: center; | |
| align-self: center; | |
| position: relative; | |
| width: min(42vw, 260px); | |
| aspect-ratio: 1; | |
| animation: reticle-in 620ms ease both; | |
| animation-delay: 180ms; | |
| } | |
| .horizon-shell { | |
| position: absolute; | |
| inset: 0; | |
| border-radius: 999px; | |
| border: 1px solid rgba(233, 246, 255, 0.4); | |
| background: radial-gradient(circle at 50% 50%, rgba(0, 0, 0, 0.14), rgba(0, 0, 0, 0.32)); | |
| overflow: hidden; | |
| } | |
| .horizon-ladder { | |
| position: absolute; | |
| top: 50%; | |
| left: 50%; | |
| width: 130%; | |
| height: 130%; | |
| transform: translate(-50%, -50%); | |
| background: | |
| linear-gradient(180deg, rgba(124, 193, 241, 0.6), rgba(124, 193, 241, 0.05) 46%, rgba(72, 60, 46, 0.5) 54%, rgba(72, 60, 46, 0.78)), | |
| repeating-linear-gradient( | |
| to bottom, | |
| transparent 0, | |
| transparent 23px, | |
| rgba(233, 246, 255, 0.4) 23px, | |
| rgba(233, 246, 255, 0.4) 25px | |
| ); | |
| transition: transform 0.09s linear; | |
| } | |
| .reticle { | |
| position: absolute; | |
| inset: 50% auto auto 50%; | |
| transform: translate(-50%, -50%); | |
| width: 48px; | |
| height: 48px; | |
| border: 2px solid rgba(255, 255, 255, 0.9); | |
| border-radius: 999px; | |
| } | |
| .reticle::before, | |
| .reticle::after { | |
| content: ""; | |
| position: absolute; | |
| background: rgba(255, 255, 255, 0.9); | |
| } | |
| .reticle::before { | |
| width: 2px; | |
| height: 68px; | |
| left: 50%; | |
| top: 50%; | |
| transform: translate(-50%, -50%); | |
| } | |
| .reticle::after { | |
| width: 68px; | |
| height: 2px; | |
| top: 50%; | |
| left: 50%; | |
| transform: translate(-50%, -50%); | |
| } | |
| .mobile-note { | |
| position: absolute; | |
| bottom: 14px; | |
| left: 50%; | |
| transform: translateX(-50%); | |
| margin: 0; | |
| color: rgba(15, 45, 63, 0.82); | |
| font-weight: 600; | |
| font-family: "Chakra Petch", sans-serif; | |
| font-size: 0.8rem; | |
| letter-spacing: 0.03em; | |
| text-shadow: 0 2px 8px rgba(255, 255, 255, 0.42); | |
| } | |
| @keyframes card-in { | |
| from { | |
| opacity: 0; | |
| transform: translateY(-12px); | |
| } | |
| to { | |
| opacity: 1; | |
| transform: translateY(0); | |
| } | |
| } | |
| @keyframes reticle-in { | |
| from { | |
| opacity: 0; | |
| transform: scale(0.92); | |
| } | |
| to { | |
| opacity: 1; | |
| transform: scale(1); | |
| } | |
| } | |
| .throttle-label { | |
| color: var(--hud-warning); | |
| } | |
| @media (max-width: 900px) { | |
| #ui-root { | |
| grid-template-columns: 1fr 1fr; | |
| grid-template-rows: auto auto 1fr; | |
| gap: 10px; | |
| padding: 10px; | |
| } | |
| .hud-banner { | |
| grid-column: 1 / 3; | |
| } | |
| .hud-telemetry { | |
| grid-column: 1 / 2; | |
| grid-row: 2; | |
| align-self: start; | |
| } | |
| .hud-controls { | |
| grid-column: 2 / 3; | |
| grid-row: 2; | |
| } | |
| .center-stack { | |
| grid-column: 1 / 3; | |
| grid-row: 3; | |
| width: min(56vw, 230px); | |
| align-self: end; | |
| margin-bottom: 6vh; | |
| } | |
| .mobile-note { | |
| font-size: 0.75rem; | |
| bottom: 8px; | |
| } | |
| } | |
| @media (max-width: 620px) { | |
| #ui-root { | |
| grid-template-columns: 1fr; | |
| grid-template-rows: auto auto auto auto; | |
| } | |
| .hud-banner, | |
| .hud-telemetry, | |
| .hud-controls, | |
| .center-stack { | |
| grid-column: 1; | |
| } | |
| .hud-telemetry, | |
| .hud-controls { | |
| padding: 12px; | |
| } | |
| .center-stack { | |
| width: min(62vw, 210px); | |
| justify-self: end; | |
| margin: 0 8px 5.5vh 0; | |
| } | |
| .hud-controls .control-row:last-child { | |
| margin-top: 6px; | |
| } | |
| } | |
| </style> | |
| <script type="importmap"> | |
| { | |
| "imports": { | |
| "three": "https://unpkg.com/three@0.160.0/build/three.module.js" | |
| } | |
| } | |
| </script> | |
| <script type="module" crossorigin src="/assets/index-DIq_VqFy.js"></script> | |
| </head> | |
| <body> | |
| <div id="game-container"></div> | |
| <div id="ui-root"> | |
| <header class="hud-card hud-banner"> | |
| <p class="hud-kicker">Flight Simulator</p> | |
| <h1 class="hud-title">Tactical Flight HUD</h1> | |
| <p class="hud-status"><span class="status-dot"></span>Live Simulation Feed</p> | |
| </header> | |
| <section class="hud-card hud-telemetry"> | |
| <h2 class="hud-heading">Telemetry</h2> | |
| <dl class="telemetry-grid"> | |
| <dt>Speed</dt> | |
| <dd id="hud-speed">0 kn</dd> | |
| <dt>Altitude</dt> | |
| <dd id="hud-altitude">0 m</dd> | |
| <dt>Heading</dt> | |
| <dd id="hud-heading">000 deg</dd> | |
| <dt>Pitch</dt> | |
| <dd id="hud-pitch">0 deg</dd> | |
| <dt>Roll</dt> | |
| <dd id="hud-roll">0 deg</dd> | |
| <dt class="throttle-label">Throttle</dt> | |
| <dd id="hud-throttle">0%</dd> | |
| <dt>FPS</dt> | |
| <dd id="hud-fps">60</dd> | |
| </dl> | |
| <div class="meter-wrap"> | |
| <div class="meter-label"> | |
| <span>Engine Load</span> | |
| <span id="hud-engine-state">Nominal</span> | |
| </div> | |
| <div class="meter-rail"> | |
| <div id="hud-throttle-bar" class="meter-fill"></div> | |
| </div> | |
| </div> | |
| </section> | |
| <section class="hud-card hud-controls"> | |
| <h2 class="hud-heading">Controls</h2> | |
| <div class="control-grid"> | |
| <div class="control-row"> | |
| <span class="key-pair"><kbd id="key-w">W</kbd><kbd id="key-s">S</kbd></span> | |
| <span>Pitch Up and Down</span> | |
| </div> | |
| <div class="control-row"> | |
| <span class="key-pair"><kbd id="key-a">A</kbd><kbd id="key-d">D</kbd></span> | |
| <span>Roll Left and Right</span> | |
| </div> | |
| <div class="control-row"> | |
| <span class="key-pair"><kbd id="key-q">Q</kbd><kbd id="key-e">E</kbd></span> | |
| <span>Yaw Left and Right</span> | |
| </div> | |
| <div class="control-row"> | |
| <span class="key-pair"><kbd id="key-shift">Shift</kbd></span> | |
| <span>Boost Thrust</span> | |
| </div> | |
| <div class="control-row"> | |
| <span class="key-pair"><kbd>Cam</kbd></span> | |
| <span>Auto Follow Mode</span> | |
| </div> | |
| </div> | |
| </section> | |
| <div class="center-stack"> | |
| <div class="horizon-shell"> | |
| <div id="horizon-ladder" class="horizon-ladder"></div> | |
| </div> | |
| <div class="reticle"></div> | |
| </div> | |
| <p class="mobile-note">Best with keyboard on desktop.</p> | |
| </div> | |
| </body> | |
| </html> | |