MotorSignal-App/docs/stitch-designs/code/29_touring_cockpit_hud.html

425 lines
23 KiB
HTML

<!DOCTYPE html>
<html class="dark" lang="en"><head>
<meta charset="utf-8"/>
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" name="viewport"/>
<title>MotorSignal Cockpit HUD</title>
<!-- Fonts -->
<link href="https://fonts.googleapis.com" rel="preconnect"/>
<link crossorigin="" href="https://fonts.gstatic.com" rel="preconnect"/>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&amp;family=JetBrains+Mono:wght@400;500;600;700;800&amp;family=Space+Grotesk:wght@500;600;700&amp;display=swap" rel="stylesheet"/>
<!-- Material Symbols Outlined -->
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&amp;display=swap" rel="stylesheet"/>
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&amp;display=swap" rel="stylesheet"/>
<!-- Tailwind CSS CDN -->
<script src="https://cdn.tailwindcss.com?plugins=forms,container-queries"></script>
<script id="tailwind-config">
tailwind.config = {
darkMode: "class",
theme: {
extend: {
"colors": {
"on-error-container": "#ffdad6",
"secondary-fixed": "#dbe1ff",
"on-background": "#e0e2ea",
"on-tertiary-fixed": "#23005c",
"inverse-surface": "#e0e2ea",
"secondary-fixed-dim": "#b4c5ff",
"background": "#101419",
"tertiary-fixed-dim": "#d0bcff",
"primary-fixed-dim": "#00daf3",
"primary-container": "#00e5ff",
"surface-container-low": "#181c21",
"secondary": "#b4c5ff",
"surface-container-lowest": "#0b0e13",
"on-primary-fixed-variant": "#004f58",
"on-primary-container": "#00626e",
"surface-tint": "#00daf3",
"surface-dim": "#101419",
"on-surface": "#e0e2ea",
"on-secondary-container": "#cdd7ff",
"outline": "#849396",
"on-primary": "#00363d",
"tertiary-fixed": "#e9ddff",
"error-container": "#93000a",
"primary-fixed": "#9cf0ff",
"inverse-on-surface": "#2d3036",
"error": "#ffb4ab",
"surface-variant": "#32353b",
"secondary-container": "#0053db",
"primary": "#c3f5ff",
"on-secondary": "#002a78",
"tertiary": "#f2e9ff",
"on-surface-variant": "#bac9cc",
"on-secondary-fixed": "#00174b",
"surface-container-highest": "#32353b",
"surface": "#101419",
"surface-container": "#1d2025",
"on-tertiary": "#3c0091",
"outline-variant": "#3b494c",
"on-tertiary-fixed-variant": "#5516be",
"surface-container-high": "#272a30",
"on-error": "#690005",
"tertiary-container": "#d9c8ff",
"on-tertiary-container": "#6834d1",
"on-primary-fixed": "#001f24",
"surface-bright": "#36393f",
"on-secondary-fixed-variant": "#003ea8",
"inverse-primary": "#006875"
},
"borderRadius": {
"DEFAULT": "0.25rem",
"lg": "0.5rem",
"xl": "0.75rem",
"full": "9999px"
},
"spacing": {
"gutter": "1rem",
"space-xl": "2rem",
"space-sm": "0.5rem",
"space-md": "1rem",
"gutter-lg": "1.5rem",
"space-xs": "0.25rem",
"margin": "1rem",
"space-lg": "1.5rem",
"margin-lg": "2rem"
},
"fontFamily": {
"headline-sm": ["Space Grotesk"],
"headline-md": ["Space Grotesk"],
"telemetry-metric-lg-mobile": ["JetBrains Mono"],
"display-hero-mobile": ["Space Grotesk"],
"body-md": ["Inter"],
"body-lg": ["Inter"],
"telemetry-metric-md": ["JetBrains Mono"],
"display-hero": ["Space Grotesk"],
"telemetry-metric-lg": ["JetBrains Mono"],
"headline-lg": ["Space Grotesk"],
"label-caption": ["Inter"],
"label-data": ["JetBrains Mono"]
},
"fontSize": {
"headline-sm": ["20px", { "lineHeight": "28px", "fontWeight": "600" }],
"headline-md": ["24px", { "lineHeight": "32px", "letterSpacing": "-0.01em", "fontWeight": "600" }],
"telemetry-metric-lg-mobile": ["36px", { "lineHeight": "36px", "letterSpacing": "-0.03em", "fontWeight": "700" }],
"display-hero-mobile": ["40px", { "lineHeight": "44px", "letterSpacing": "-0.02em", "fontWeight": "700" }],
"body-md": ["14px", { "lineHeight": "20px", "fontWeight": "400" }],
"body-lg": ["16px", { "lineHeight": "24px", "fontWeight": "500" }],
"telemetry-metric-md": ["28px", { "lineHeight": "32px", "letterSpacing": "-0.02em", "fontWeight": "600" }],
"display-hero": ["56px", { "lineHeight": "60px", "letterSpacing": "-0.03em", "fontWeight": "700" }],
"telemetry-metric-lg": ["48px", { "lineHeight": "48px", "letterSpacing": "-0.04em", "fontWeight": "700" }],
"headline-lg": ["32px", { "lineHeight": "40px", "letterSpacing": "-0.02em", "fontWeight": "700" }],
"label-caption": ["11px", { "lineHeight": "14px", "letterSpacing": "0.05em", "fontWeight": "600" }],
"label-data": ["12px", { "lineHeight": "16px", "letterSpacing": "0.08em", "fontWeight": "600" }]
}
}
}
}
</script>
<style>
.tactical-glow-cyan {
box-shadow: 0 0 16px rgba(0, 229, 255, 0.25), inset 0 0 8px rgba(0, 229, 255, 0.15);
}
.tactical-glow-alert {
box-shadow: 0 0 20px rgba(245, 158, 11, 0.25), inset 0 0 10px rgba(239, 68, 68, 0.15);
}
.hud-scanner {
background: linear-gradient(180deg, rgba(0, 229, 255, 0.04) 0%, rgba(0, 229, 255, 0) 100%);
}
</style>
<style>
body {
min-height: max(884px, 100dvh);
}
</style>
</head>
<body class="bg-surface-container-lowest text-on-surface antialiased select-none min-h-screen pb-24 overflow-x-hidden">
<!-- TopAppBar Anchor from Shared Components -->
<header class="fixed top-0 left-0 w-full z-50 flex justify-between items-center px-gutter h-14 bg-surface-container-lowest border-b border-outline-variant">
<div class="flex items-center space-x-2">
<span class="material-symbols-outlined text-primary-container text-[20px]" data-icon="sensors">sensors</span>
<span class="text-headline-sm font-headline-sm font-bold tracking-wider text-primary-container">MOTORSIGNAL HUD</span>
</div>
<div class="flex items-center space-x-3">
<span class="flex h-2.5 w-2.5 relative">
<span class="animate-ping absolute inline-flex h-full w-full rounded-full bg-primary-container opacity-75"></span>
<span class="relative inline-flex rounded-full h-2.5 w-2.5 bg-primary-container"></span>
</span>
<span class="material-symbols-outlined text-on-surface-variant hover:text-primary-container cursor-pointer transition-colors" data-icon="warning">warning</span>
</div>
</header>
<!-- Main HUD Content Area -->
<main class="pt-16 px-space-md space-y-space-md max-w-xl mx-auto">
<!-- Diagnostic Kalman & Mode Selector Strip -->
<section class="bg-surface-container-low border border-outline-variant rounded-xl p-space-sm space-y-2">
<!-- Status Meta Bar -->
<div class="grid grid-cols-4 gap-1 text-center font-label-data text-label-data">
<div class="bg-surface-container-lowest py-1 px-1 rounded border border-outline-variant text-primary-container flex items-center justify-center space-x-1">
<span class="material-symbols-outlined text-[13px]" data-icon="sync">sync</span>
<span class="truncate">20HZ KALMAN</span>
</div>
<div class="bg-surface-container-lowest py-1 px-1 rounded border border-outline-variant text-on-surface-variant flex items-center justify-center space-x-1">
<span class="material-symbols-outlined text-[13px] text-primary" data-icon="satellite_alt">satellite_alt</span>
<span class="truncate">18 SVs</span>
</div>
<div class="bg-surface-container-lowest py-1 px-1 rounded border border-outline-variant text-on-surface-variant flex items-center justify-center space-x-1">
<span class="material-symbols-outlined text-[13px] text-primary-container" data-icon="battery_charging_full">battery_charging_full</span>
<span>98%</span>
</div>
<div class="bg-surface-container-lowest py-1 px-1 rounded border border-outline-variant text-on-surface flex items-center justify-center space-x-1">
<span class="material-symbols-outlined text-[13px] text-secondary" data-icon="thermostat">thermostat</span>
<span>72°F</span>
</div>
</div>
<!-- Mode Selector Pills -->
<div class="grid grid-cols-3 gap-1.5 p-1 bg-surface-container-lowest rounded-lg border border-outline-variant">
<button class="h-10 rounded-md font-headline-sm text-xs font-bold bg-primary-container text-on-primary-container tactical-glow-cyan transition-all">
TOURING HUD
</button>
<button class="h-10 rounded-md font-headline-sm text-xs text-on-surface-variant hover:text-on-surface hover:bg-surface-container transition-all">
SPORT
</button>
<button class="h-10 rounded-md font-headline-sm text-xs text-on-surface-variant hover:text-on-surface hover:bg-surface-container transition-all">
MINIMAL
</button>
</div>
</section>
<!-- Primary Speed & Altimetry Telemetry Cockpit Block -->
<section class="grid grid-cols-12 gap-space-sm items-stretch">
<!-- Heading Compass Tile -->
<div class="col-span-3 bg-surface-container-low border border-outline-variant rounded-xl p-space-sm flex flex-col justify-between items-center text-center">
<span class="text-label-data font-label-data text-outline">BEARING</span>
<div class="relative w-12 h-12 flex items-center justify-center my-1">
<div class="absolute inset-0 rounded-full border border-dashed border-outline-variant animate-spin" style="animation-duration: 40s;"></div>
<span class="material-symbols-outlined text-primary-container text-2xl rotate-45" data-icon="explore">explore</span>
</div>
<div>
<div class="font-headline-sm text-headline-sm font-bold text-on-surface">NW</div>
<div class="font-label-data text-label-data text-primary-container">315°</div>
</div>
</div>
<!-- Main Glowing Speed Gauge -->
<div class="col-span-6 bg-surface-container-low border border-primary-container/40 rounded-xl p-space-sm flex flex-col items-center justify-center relative overflow-hidden tactical-glow-cyan hud-scanner">
<div class="absolute top-2 left-3 flex items-center space-x-1">
<span class="w-1.5 h-1.5 rounded-full bg-primary-container animate-pulse"></span>
<span class="text-[10px] font-label-data tracking-widest text-primary-container">SPEED RTK</span>
</div>
<div class="text-[76px] leading-[72px] font-telemetry-metric-lg font-extrabold text-on-surface tracking-tighter mt-3 mb-1">
68
</div>
<span class="font-label-data text-sm font-bold text-primary-container tracking-widest px-2.5 py-0.5 rounded bg-surface-container-lowest border border-primary-container/30">
MPH
</span>
<div class="w-full bg-surface-container-highest h-1 mt-3 rounded-full overflow-hidden">
<div class="bg-primary-container h-full w-[68%]"></div>
</div>
</div>
<!-- Elevation & Barometric Tile -->
<div class="col-span-3 bg-surface-container-low border border-outline-variant rounded-xl p-space-sm flex flex-col justify-between items-center text-center">
<span class="text-label-data font-label-data text-outline">ALTITUDE</span>
<div class="my-1">
<span class="material-symbols-outlined text-secondary text-xl" data-icon="landscape">landscape</span>
<div class="font-label-data text-xs text-primary-container font-semibold flex items-center justify-center mt-1">
<span class="material-symbols-outlined text-xs" data-icon="arrow_upward">arrow_upward</span>
+120
</div>
<div class="text-[9px] font-label-data text-outline">FT/MIN</div>
</div>
<div>
<div class="font-headline-sm text-headline-sm font-bold text-on-surface">3,420</div>
<div class="font-label-data text-label-data text-outline">FT BARO</div>
</div>
</div>
</section>
<!-- High-Visibility Tactical Police / Radar Alert Banner -->
<section class="bg-error-container/30 border border-error/50 rounded-xl p-space-sm relative overflow-hidden tactical-glow-alert">
<div class="flex items-start justify-between gap-2">
<div class="flex items-start space-x-2.5">
<div class="min-w-[42px] h-[42px] rounded-lg bg-error flex items-center justify-center text-on-error">
<span class="material-symbols-outlined text-2xl animate-pulse" data-icon="radar">radar</span>
</div>
<div class="space-y-0.5">
<div class="flex items-center space-x-2">
<span class="font-headline-sm text-xs font-bold text-error tracking-wider uppercase">POLICE TRAP AHEAD</span>
<span class="px-1.5 py-0.2 bg-error/20 text-error text-[10px] font-label-data rounded border border-error/40">WAZE MESH</span>
</div>
<div class="font-body-lg text-body-md font-bold text-on-surface">
Police reported 2.4 mi ahead on US-101
</div>
<div class="font-label-data text-[11px] text-on-surface-variant flex items-center space-x-1.5 pt-0.5">
<span>Verified by 8 riders</span>
<span>•</span>
<span>2 min ago</span>
<span>•</span>
<span class="text-primary-container">Auto-mute interlock armed</span>
</div>
</div>
</div>
<!-- Glove ACK Button -->
<button class="min-h-[48px] min-w-[58px] px-3 bg-surface-container-high hover:bg-error hover:text-on-error border border-error/60 rounded-lg font-label-data font-bold text-sm text-error transition-all active:scale-95 flex items-center justify-center">
ACK
</button>
</div>
</section>
<!-- Turn-by-Turn Touring Navigation Tile -->
<section class="bg-surface-container-low border border-outline-variant rounded-xl p-space-md relative">
<div class="flex items-center justify-between pb-2 border-b border-outline-variant/60 mb-3">
<div class="flex items-center space-x-1.5">
<span class="material-symbols-outlined text-primary-container text-lg" data-icon="near_me">near_me</span>
<span class="font-label-data text-xs text-primary-container tracking-wider font-semibold">NAVIGATION MESH ROUTE</span>
</div>
<span class="font-label-data text-xs text-on-surface-variant">ETA 4:28 PM • 54 mi rem</span>
</div>
<div class="flex items-center space-x-3.5">
<div class="w-12 h-12 rounded-xl bg-surface-container-highest flex items-center justify-center border border-outline-variant text-primary-container">
<span class="material-symbols-outlined text-3xl" data-icon="turn_right">turn_right</span>
</div>
<div class="flex-1">
<div class="font-label-data text-sm font-bold text-primary-container uppercase">In 1.8 mi</div>
<div class="font-headline-md text-headline-sm font-bold text-on-surface leading-tight">Turn right onto CA-84 W / La Honda Rd</div>
</div>
</div>
<!-- Distance Progress Indicator -->
<div class="mt-3.5 space-y-1">
<div class="w-full bg-surface-container-highest h-1.5 rounded-full overflow-hidden">
<div class="bg-primary-container h-full w-[45%]"></div>
</div>
<div class="flex justify-between font-label-data text-[11px] text-outline">
<span>Leg: 1.4 mi completed</span>
<span>Next: Skyline Blvd junction</span>
</div>
</div>
</section>
<!-- Touring Odometer & Range Telemetry Bento -->
<section class="grid grid-cols-2 gap-space-sm">
<!-- Trip A Card -->
<div class="bg-surface-container-low border border-outline-variant rounded-xl p-space-sm space-y-1">
<div class="flex justify-between items-center text-outline">
<span class="font-label-data text-label-data">TRIP METRICS</span>
<span class="material-symbols-outlined text-base" data-icon="route">route</span>
</div>
<div class="font-headline-md text-headline-sm font-bold text-on-surface">142.6 <span class="text-xs font-label-data text-primary-container">MI</span></div>
<div class="font-label-data text-xs text-on-surface-variant flex items-center justify-between pt-1">
<span>Avg Speed</span>
<span class="text-on-surface font-semibold">54.2 mph</span>
</div>
</div>
<!-- Fuel Range Card -->
<div class="bg-surface-container-low border border-outline-variant rounded-xl p-space-sm space-y-1">
<div class="flex justify-between items-center text-outline">
<span class="font-label-data text-label-data">FUEL RANGE</span>
<span class="material-symbols-outlined text-base text-primary-container" data-icon="local_gas_station">local_gas_station</span>
</div>
<div class="font-headline-md text-headline-sm font-bold text-on-surface">84 <span class="text-xs font-label-data text-primary-container">MI REM</span></div>
<div class="w-full bg-surface-container-highest h-1.5 rounded-full overflow-hidden mt-1.5">
<div class="bg-primary-container h-full w-[38%]"></div>
</div>
<div class="font-label-data text-[10px] text-outline flex justify-between pt-0.5">
<span>Tank Level</span>
<span class="text-primary-container font-semibold">38%</span>
</div>
</div>
<!-- Ride Time Card -->
<div class="bg-surface-container-low border border-outline-variant rounded-xl p-space-sm space-y-1">
<div class="flex justify-between items-center text-outline">
<span class="font-label-data text-label-data">RIDE DURATION</span>
<span class="material-symbols-outlined text-base" data-icon="timer">timer</span>
</div>
<div class="font-headline-md text-headline-sm font-bold text-on-surface">2h 15m</div>
<div class="font-label-data text-[11px] text-on-surface-variant flex justify-between pt-1">
<span>Moving: <span class="text-on-surface">2h 04m</span></span>
<span>Stop: <span class="text-on-surface">11m</span></span>
</div>
</div>
<!-- Grip & Road State Card -->
<div class="bg-surface-container-low border border-outline-variant rounded-xl p-space-sm space-y-1">
<div class="flex justify-between items-center text-outline">
<span class="font-label-data text-label-data">PAVEMENT GRIP</span>
<span class="material-symbols-outlined text-base text-primary-container" data-icon="speed">speed</span>
</div>
<div class="font-headline-md text-headline-sm font-bold text-primary-container">98% <span class="text-xs font-label-data text-on-surface">OPTIMAL</span></div>
<div class="font-label-data text-[11px] text-on-surface-variant flex items-center space-x-1 pt-1">
<span class="w-1.5 h-1.5 rounded-full bg-primary-container"></span>
<span>Dry asphalt profile</span>
</div>
</div>
</section>
<!-- Weather Alert Tile -->
<section class="bg-surface-container-low border border-outline-variant rounded-xl px-space-md py-space-sm flex items-center justify-between">
<div class="flex items-center space-x-2.5">
<span class="material-symbols-outlined text-primary-container" data-icon="wb_sunny">wb_sunny</span>
<div class="font-body-md text-xs text-on-surface font-medium">
Weather: Clear Sky 72°F • Wind Gusts 18 MPH NW
</div>
</div>
<span class="font-label-data text-[10px] text-primary-container px-2 py-0.5 rounded bg-surface-container-highest border border-primary-container/30">
SAFE
</span>
</section>
<!-- Quick Action Glove Bar (48px+ Targets) -->
<section class="grid grid-cols-3 gap-space-sm pt-1">
<button class="min-h-[52px] rounded-xl bg-surface-container-high border border-outline-variant text-on-surface hover:border-primary-container active:scale-95 transition-all flex flex-col items-center justify-center space-y-1 p-2">
<span class="material-symbols-outlined text-xl" data-icon="pause_circle">pause_circle</span>
<span class="font-label-data text-[11px] tracking-wider uppercase font-bold">PAUSE RIDE</span>
</button>
<button class="min-h-[52px] rounded-xl bg-primary-container text-on-primary-container tactical-glow-cyan active:scale-95 transition-all flex flex-col items-center justify-center space-y-1 p-2 font-bold">
<span class="material-symbols-outlined text-xl" data-icon="add_location_alt">add_location_alt</span>
<span class="font-label-data text-[11px] tracking-wider uppercase">MARK HAZARD</span>
</button>
<button class="min-h-[52px] rounded-xl bg-surface-container-high border border-outline-variant text-on-surface hover:border-primary-container active:scale-95 transition-all flex flex-col items-center justify-center space-y-1 p-2">
<span class="material-symbols-outlined text-xl" data-icon="map">map</span>
<span class="font-label-data text-[11px] tracking-wider uppercase font-bold">OVERVIEW</span>
</button>
</section>
</main>
<!-- Persistent 6-icon Bottom Navigation Dock -->
<!-- Matches BottomNavBar Component Definition with Dash Active -->
<nav class="fixed bottom-0 left-0 w-full z-50 flex justify-around items-center px-space-xs py-space-xs bg-surface-container-lowest border-t border-outline-variant">
<!-- Dash (Active Item) -->
<button class="flex flex-col items-center justify-center bg-surface-container-high text-primary-container rounded-lg px-2 py-1 min-h-[48px] flex-1 active:scale-95 duration-100 ease-out">
<span class="material-symbols-outlined text-xl" data-icon="speed" style="font-variation-settings: 'FILL' 1;">speed</span>
<span class="text-label-caption font-label-caption mt-0.5 font-bold">Dash</span>
</button>
<!-- Map -->
<button class="flex flex-col items-center justify-center text-on-surface-variant hover:bg-surface-container-low hover:text-primary-fixed px-2 py-1 min-h-[48px] flex-1 active:scale-95 duration-100 ease-out">
<span class="material-symbols-outlined text-xl" data-icon="navigation">navigation</span>
<span class="text-label-caption font-label-caption mt-0.5">Map</span>
</button>
<!-- Activity -->
<button class="flex flex-col items-center justify-center text-on-surface-variant hover:bg-surface-container-low hover:text-primary-fixed px-2 py-1 min-h-[48px] flex-1 active:scale-95 duration-100 ease-out">
<span class="material-symbols-outlined text-xl" data-icon="analytics">analytics</span>
<span class="text-label-caption font-label-caption mt-0.5">Activity</span>
</button>
<!-- Garage -->
<button class="flex flex-col items-center justify-center text-on-surface-variant hover:bg-surface-container-low hover:text-primary-fixed px-2 py-1 min-h-[48px] flex-1 active:scale-95 duration-100 ease-out">
<span class="material-symbols-outlined text-xl" data-icon="two_wheeler">two_wheeler</span>
<span class="text-label-caption font-label-caption mt-0.5">Garage</span>
</button>
<!-- Social -->
<button class="flex flex-col items-center justify-center text-on-surface-variant hover:bg-surface-container-low hover:text-primary-fixed px-2 py-1 min-h-[48px] flex-1 active:scale-95 duration-100 ease-out">
<span class="material-symbols-outlined text-xl" data-icon="group">group</span>
<span class="text-label-caption font-label-caption mt-0.5">Social</span>
</button>
<!-- Settings -->
<button class="flex flex-col items-center justify-center text-on-surface-variant hover:bg-surface-container-low hover:text-primary-fixed px-2 py-1 min-h-[48px] flex-1 active:scale-95 duration-100 ease-out">
<span class="material-symbols-outlined text-xl" data-icon="settings">settings</span>
<span class="text-label-caption font-label-caption mt-0.5">Settings</span>
</button>
</nav>
<!-- Interactive HUD Micro-Interactions -->
<script>
document.addEventListener('DOMContentLoaded', () => {
// Dynamic tactile feedback for ACK button
const ackButton = document.querySelector('button:has(span:contains("ACK")), button:contains("ACK")') || document.querySelector('section.bg-error-container\\/30 button');
if (ackButton) {
ackButton.addEventListener('click', () => {
const banner = ackButton.closest('section');
banner.style.transition = 'all 0.3s ease';
banner.style.opacity = '0.4';
ackButton.textContent = 'MUTED';
ackButton.classList.add('bg-outline-variant', 'text-on-surface');
});
}
});
</script>
</body></html>