MotorSignal-App/docs/stitch-designs/code/28_minimal_cockpit_hud.html

437 lines
14 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>MotorSignal Minimal HUD Dashboard</title>
<!-- Bootstrap 5.3.3 CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<!-- Google Fonts: Space Grotesk & JetBrains Mono -->
<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=JetBrains+Mono:wght@400;500;700;800&family=Space+Grotesk:wght@400;500;600;700&display=swap" rel="stylesheet">
<style>
:root {
--bg-pitch-black: #000000;
--cyan-telemetry: #00e5ff;
--cyan-glow: rgba(0, 229, 255, 0.28);
--green-status: #00e676;
--green-glow: rgba(0, 230, 118, 0.4);
--navy-blue-btn: #0d2847;
--navy-blue-btn-hover: #133966;
--navy-blue-border: #1e4976;
--gray-dock-border: #1a1e24;
--dock-bg: rgba(6, 8, 11, 0.95);
}
* {
box-sizing: border-box;
-webkit-font-smoothing: antialiased;
user-select: none;
}
body {
background-color: var(--bg-pitch-black);
color: #ffffff;
font-family: 'Space Grotesk', -apple-system, BlinkMacSystemFont, sans-serif;
margin: 0;
padding: 0;
width: 100%;
min-height: 100vh;
overflow-x: hidden;
display: flex;
justify-content: center;
align-items: center;
}
/* Container constrained strictly to 375px mobile portrait viewport */
.mobile-viewport {
width: 375px;
height: 812px;
max-height: 812px;
background-color: var(--bg-pitch-black);
position: relative;
overflow: hidden;
display: flex;
flex-direction: column;
box-shadow: 0 0 50px rgba(0, 0, 0, 0.9), 0 0 0 1px #11151a;
}
.font-mono {
font-family: 'JetBrains Mono', monospace;
}
/* Top Status Bar */
.top-status-header {
padding: 16px 20px 8px 20px;
z-index: 10;
}
.status-pill {
background: rgba(18, 24, 32, 0.85);
border: 1px solid rgba(255, 255, 255, 0.08);
border-radius: 9999px;
padding: 6px 14px;
font-size: 11px;
font-weight: 600;
letter-spacing: 0.06em;
text-transform: uppercase;
color: #cbd5e1;
display: inline-flex;
align-items: center;
gap: 6px;
}
.status-dot-green {
width: 7px;
height: 7px;
border-radius: 50%;
background-color: var(--green-status);
box-shadow: 0 0 10px var(--green-glow), 0 0 4px var(--green-status);
animation: pulse-green 2s infinite ease-in-out;
}
@keyframes pulse-green {
0%, 100% { opacity: 1; transform: scale(1); }
50% { opacity: 0.6; transform: scale(0.9); }
}
/* Speedometer Central Display */
.speedo-container {
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
position: relative;
margin-top: -16px;
}
/* Ambient Subtle Grid Backing */
.speedo-grid-ambient {
position: absolute;
width: 280px;
height: 280px;
border-radius: 50%;
background: radial-gradient(circle, rgba(0, 229, 255, 0.04) 0%, rgba(0, 0, 0, 0) 70%);
pointer-events: none;
z-index: 1;
}
.speed-number {
font-family: 'JetBrains Mono', monospace;
font-size: 108px;
line-height: 0.9;
font-weight: 800;
color: #ffffff;
letter-spacing: -0.04em;
text-shadow: 0 0 24px var(--cyan-glow), 0 0 45px rgba(0, 229, 255, 0.15);
position: relative;
z-index: 2;
}
.speed-unit {
font-family: 'Space Grotesk', sans-serif;
font-size: 16px;
font-weight: 700;
letter-spacing: 0.28em;
color: var(--cyan-telemetry);
margin-top: 6px;
text-shadow: 0 0 12px var(--cyan-glow);
position: relative;
z-index: 2;
}
/* Secondary Lean Arc Indicator (Subtle Tactical MotorSignal Accent) */
.mini-telemetry-indicator {
display: flex;
align-items: center;
gap: 12px;
margin-top: 24px;
font-size: 11px;
font-family: 'JetBrains Mono', monospace;
color: #64748b;
letter-spacing: 0.05em;
z-index: 2;
}
.mini-telemetry-indicator span.val {
color: #94a3b8;
font-weight: 600;
}
/* Bottom Action & Odometer Section */
.bottom-action-section {
padding: 0 20px 18px 20px;
z-index: 10;
}
.odometer-card {
background: rgba(14, 18, 24, 0.6);
border: 1px solid rgba(255, 255, 255, 0.06);
border-radius: 12px;
padding: 10px 16px;
margin-bottom: 14px;
display: flex;
justify-content: space-between;
align-items: center;
}
.odometer-label {
font-size: 11px;
text-transform: uppercase;
letter-spacing: 0.12em;
color: #64748b;
font-weight: 600;
}
.odometer-val {
font-family: 'JetBrains Mono', monospace;
font-size: 18px;
font-weight: 700;
color: #f1f5f9;
letter-spacing: 0.02em;
}
.btn-start-session {
background: var(--navy-blue-btn);
border: 1px solid var(--navy-blue-border);
color: #38bdf8;
font-size: 15px;
font-weight: 700;
letter-spacing: 0.08em;
text-transform: uppercase;
padding: 14px 20px;
border-radius: 14px;
width: 100%;
height: 54px;
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
box-shadow: 0 4px 20px rgba(13, 40, 71, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.1);
transition: all 0.2s ease;
cursor: pointer;
}
.btn-start-session:hover, .btn-start-session:active {
background: var(--navy-blue-btn-hover);
border-color: #38bdf8;
color: #ffffff;
box-shadow: 0 6px 24px rgba(56, 189, 248, 0.25);
transform: translateY(-1px);
}
/* 6-Icon MotorSignal Bottom Dock */
.bottom-dock {
background: var(--dock-bg);
backdrop-filter: blur(16px);
-webkit-backdrop-filter: blur(16px);
border-top: 1px solid var(--gray-dock-border);
height: 68px;
display: flex;
align-items: center;
justify-content: space-around;
padding: 0 4px 6px 4px;
z-index: 20;
}
.dock-tab {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
text-decoration: none;
color: #64748b;
font-size: 9.5px;
font-weight: 600;
letter-spacing: 0.04em;
padding: 6px 8px;
width: 54px;
height: 100%;
transition: color 0.15s ease;
border-radius: 8px;
}
.dock-tab svg {
width: 20px;
height: 20px;
stroke-width: 1.8;
margin-bottom: 3px;
transition: transform 0.15s ease, stroke 0.15s ease;
}
.dock-tab.active {
color: var(--cyan-telemetry);
}
.dock-tab.active svg {
stroke: var(--cyan-telemetry);
filter: drop-shadow(0 0 6px rgba(0, 229, 255, 0.5));
}
.dock-tab:hover {
color: #e2e8f0;
}
/* Telemetry subtle header bar */
.telemetry-channel-meta {
display: flex;
justify-content: space-between;
align-items: center;
font-size: 10px;
color: #475569;
font-family: 'JetBrains Mono', monospace;
padding: 0 4px 10px 4px;
}
</style>
</head>
<body>
<!-- 375x812 Mobile Viewport Frame -->
<div class="mobile-viewport">
<!-- Top Status Row -->
<header class="top-status-header">
<!-- Device/Telemetry metadata row -->
<div class="telemetry-channel-meta">
<span>MOTORSIGNAL // HUD</span>
<span class="d-inline-flex align-items-center gap-1">
<svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="#00e5ff" stroke-width="2.5"><path d="M13 2L3 14h9l-1 8 10-12h-9l1-8z"/></svg>
20HZ KALMAN
</span>
</div>
<!-- Requested Status Row: 'GPS 2D FIX', '79 F', and green 'STANDBY' dot -->
<div class="d-flex justify-content-between align-items-center">
<!-- GPS Status Pill -->
<div class="status-pill font-mono">
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="#00e5ff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<polygon points="12 2 19 21 12 17 5 21 12 2"/>
</svg>
<span>GPS 2D FIX</span>
</div>
<!-- Ambient Temperature Pill -->
<div class="status-pill font-mono">
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="#cbd5e1" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M14 14.76V3.5a2.5 2.5 0 0 0-5 0v11.26a4.5 4.5 0 1 0 5 0z"/>
</svg>
<span>79°F</span>
</div>
<!-- System State Pill with Green Dot -->
<div class="status-pill">
<span class="status-dot-green"></span>
<span style="color: #4ade80; font-weight: 700;">STANDBY</span>
</div>
</div>
</header>
<!-- Speedometer Centerpiece -->
<main class="speedo-container">
<div class="speedo-grid-ambient"></div>
<!-- 96pt+ Immense Digital Speedometer in crisp monospace with subtle cyan glow -->
<div class="speed-number">0</div>
<div class="speed-unit">MPH</div>
<!-- Subtle telemetry micro-indicators for pitch, roll, and latency -->
<div class="mini-telemetry-indicator">
<div>ROLL <span class="val">0.0°</span></div>
<div>•</div>
<div>PITCH <span class="val">+0.2°</span></div>
<div>•</div>
<div>RTT <span class="val" style="color: #00e5ff;">12ms</span></div>
</div>
</main>
<!-- Bottom Data & Primary Action Button -->
<div class="bottom-action-section">
<!-- Trip Odometer Row -->
<div class="odometer-card">
<div class="d-flex align-items-center gap-2">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#64748b" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="10"/>
<polyline points="12 6 12 12 16 14"/>
</svg>
<span class="odometer-label">Trip Odometer</span>
</div>
<div class="odometer-val">0.00 <span style="font-size: 13px; color: #64748b; font-weight: 500;">MI</span></div>
</div>
<!-- Prominent Dark Blue 'Start Session' Button (Glove-Friendly Touch Target) -->
<button class="btn-start-session" type="button" aria-label="Start Ride Telemetry Session">
<svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor">
<polygon points="5 3 19 12 5 21 5 3"/>
</svg>
<span>Start Session</span>
</button>
</div>
<!-- Persistent 6-Icon Bottom Dock: Dash, Map, Activity, Garage, Social, Settings -->
<nav class="bottom-dock" aria-label="Primary Navigation">
<!-- 1. Dash (Active) -->
<a href="#" class="dock-tab active" aria-current="page">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="9"/>
<path d="M12 7v5l3 3"/>
</svg>
<span>Dash</span>
</a>
<!-- 2. Map -->
<a href="#" class="dock-tab">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round">
<polygon points="1 6 1 22 8 18 16 22 23 18 23 2 16 6 8 2 1 6"/>
<line x1="8" y1="2" x2="8" y2="18"/>
<line x1="16" y1="6" x2="16" y2="22"/>
</svg>
<span>Map</span>
</a>
<!-- 3. Activity -->
<a href="#" class="dock-tab">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round">
<polyline points="22 12 18 12 15 21 9 3 6 12 2 12"/>
</svg>
<span>Activity</span>
</a>
<!-- 4. Garage -->
<a href="#" class="dock-tab">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round">
<circle cx="5.5" cy="17.5" r="3.5"/>
<circle cx="18.5" cy="17.5" r="3.5"/>
<path d="M15 6h-5l-3 6.5h11z"/>
<path d="M9 17.5h6"/>
</svg>
<span>Garage</span>
</a>
<!-- 5. Social -->
<a href="#" class="dock-tab">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round">
<path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/>
<circle cx="9" cy="7" r="4"/>
<path d="M23 21v-2a4 4 0 0 0-3-3.87"/>
<path d="M16 3.13a4 4 0 0 1 0 7.75"/>
</svg>
<span>Social</span>
</a>
<!-- 6. Settings -->
<a href="#" class="dock-tab">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="3"/>
<path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"/>
</svg>
<span>Settings</span>
</a>
</nav>
</div>
</body>
</html>