feat(mobile): add community social feed, tactical layers, club wall, launch curves, and curvy routes (v1.0.2+102)
|
|
@ -74,3 +74,5 @@ website/build_failures.log
|
|||
scratch_*.py
|
||||
*.scratch.*
|
||||
1.29
|
||||
graphify-out/
|
||||
devtools_options.yaml
|
||||
|
|
|
|||
|
|
@ -33,6 +33,13 @@
|
|||
<action android:name="android.intent.action.MAIN"/>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
<!-- MotorSignal Deep Link Intent Filters -->
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data android:scheme="motorsignal" />
|
||||
</intent-filter>
|
||||
<!-- OAuth2 Deep Link Intent Filter -->
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
|
|
|
|||
|
|
@ -0,0 +1,177 @@
|
|||
# MotorSignal — Missing & Unimplemented Features Report
|
||||
## Comprehensive Platform Audit: Mobile App, Web Portal, Backend API & Infrastructure
|
||||
**Audit Updated:** September 29, 2026
|
||||
**Audited Against:** Master Stitch Design Specification (56 Screens), Production Codebase (`lib/`, `website/`, `backend/`), and Architecture Rules (`AGENTS.md`)
|
||||
**Deployment Head:** `9bc1632` (Production Live at `https://motorsignal.app`)
|
||||
**Physical Hardware Target:** Google Pixel 8a (`app.motorsignal.motorcycle`)
|
||||
|
||||
---
|
||||
|
||||
## 1. Executive Summary & Audit Scorecard
|
||||
|
||||
This audit provides an exhaustive, evidence-backed evaluation of every feature and screen specified in the MotorSignal platform design catalog (32 Mobile App screens, 24 Web routes, and associated Backend/Cloud subsystems).
|
||||
|
||||
Every item has been classified into one of three strict categories following Rule 9 (Testing & Validation Truthfulness):
|
||||
1. **Fully Implemented & Verified**: Production-ready, backed by real data persistence/services, and verified by automated tests.
|
||||
2. **Partially Implemented / UI-Only**: Screen or component exists in code, but lacks key interactive features, backend integration, or relies on simplified/mock presentation.
|
||||
3. **Completely Missing / Unimplemented**: Specified in the Stitch design catalog or product roadmaps, but no code or route exists.
|
||||
|
||||
### Platform Scorecard Matrix (Updated Post-Sprint)
|
||||
|
||||
| Subsystem | Total Items | Fully Implemented | Partially Implemented | Completely Missing | Implementation Rate |
|
||||
|---|:---:|:---:|:---:|:---:|:---:|
|
||||
| **Mobile App Screens** (`lib/`) | 32 | **30** (+5) | **1** (-1) | **1** (-1) | **93.8% Full / 3.1% Part** |
|
||||
| **Website Pages & Routes** (`website/`) | 24 | **21** (+3) | **3** (-3) | 0 | **87.5% Full / 12.5% Part** |
|
||||
| **Backend & Cloud Services** (`backend/`) | 12 | 8 | 1 | 3 | **66.7% Full / 8.3% Part** |
|
||||
| **Hardware & Peripheral Links** | 3 | 0 | 0 | 3 | **0.0% (Future Roadmap)** |
|
||||
| **Total Platform** | **71** | **59** (+8) | **4** (-1) | **8** (-1) | **83.1% Fully Verified** |
|
||||
|
||||
---
|
||||
|
||||
## 2. Mobile App (32 Stitch Screens)
|
||||
|
||||
### A. Fully Implemented & Production-Ready (30 Screens)
|
||||
|
||||
| ID | Route / Screen | Key Components & Implementation Details | Verified Status |
|
||||
|---|---|---|:---:|
|
||||
| **MOB-01** | `DASH-01` (`/` Minimal) | `ResponsiveDashboardLayout`, `SpeedReadout(size: hero)`, `EvolutionPortraitDashboard`. 96pt digital speed, trip odometer, elapsed timer, 2D/3D GPS fix badge, Standby/Recording badge. | **VERIFIED** |
|
||||
| **MOB-02** | `DASH-02` (`/` Sport) | `GForceIndicator` (0.5G/1.0G friction circle), `LeanAngleIndicator` (motorcycle banking silhouette, peak MAX L/R memory), `PerformanceSummary`, `PerformanceLaunchShortcut`. | **VERIFIED** |
|
||||
| **MOB-03** | `DASH-03` (`/` Touring) | `DashboardMapPanel`, digital compass heading, elevation gain, moving time, trip A odometer, average speed, road alert ticker strip. | **VERIFIED** |
|
||||
| **MOB-04** | `DASH-04` (Recording State) | `RideStateMachine` (`RideState.riding`), 20 Hz Kalman acquisition, pulsing status indicator, `RideActionButton` stop session controller. | **VERIFIED** |
|
||||
| **MOB-05** | `MAP-01` (`/map` Tactical Map) | `MapScreen`, `UnifiedMapView`, real-time GPS location tracking, motorcycle heading vector, road hazard & speed trap overlay markers. | **VERIFIED** |
|
||||
| **MOB-06** | `MAP-02` (Tactical Layer Overrides Drawer) | `TacticalLayersBottomSheet`, `MapLayerSettingsNotifier`, `MapConfig.tacticalDark`, `MapConfig.satellite4K`, `MapConfig.elevation3D`, `UnifiedMapView`, `MapScreen`. **Stitch MAP-02 bottom sheet drawer** with 3 selectable base map style cards (`Tactical Dark`, `Satellite 4K`, `3D Topo Elevation`), 4 tactical HUD overlay toggles (`Police & Radar Traps`, `Group Ride Pack Blips`, `Twisty Road Curvature`, `Offline Cached Only Mode`), Right Vertical HUD controls dock (Layers, Compass Orient, Zoom In/Out, Recenter on Rider), Top Floating Search Card with quick-filter chips (`Gas & Fuel`, `Twisty Passes`, `Scenic Rest`, `Repair/Moto`), and persistent `SharedPreferences` state. | **VERIFIED (NEW)** |
|
||||
| **MOB-07** | `ALERT-01` (Road Alert Overlay) | `DashboardAlertRegion`, `RoadAlertService`, `SwarmRoadAlertService`, `WazeRoadAlertProvider`, `QuickSwarmReportModal`. Flashing red/amber alert card, distance countdown, confirmation count, audio mute & dismiss actions. | **VERIFIED** |
|
||||
| **MOB-08** | `PERF-01` (`/launch` Performance Mode) | `PerformanceLaunchScreen`, `PerformanceTimerService`, `PerformanceLaunchStateMachine`. Pre-launch GPS accuracy check ($\le \pm 2$ ft), slope validation ($\le \pm 1\%$), 0–60, 0–100, 1/4 mile, and 60–130 timing splits. | **VERIFIED** |
|
||||
| **MOB-09** | `PERF-02` (Draggy-Style Launch Curve & DA) | `LaunchCurveChart`, `DensityAltitudeCard`, `DensityAltitudeCalculator`. **Interactive Speed vs Time curve chart**, longitudinal G-force acceleration trace graph, touch scrubber, peak G readout, and **barometric Density Altitude (DA) calculation** with relative air density % and horsepower impact advisory. | **VERIFIED (NEW)** |
|
||||
| **MOB-10** | `ACT-01` (`/activity?tab=rides`) | `ActivityScreen`, `HistoryScreen`. Ride feed cards, dark route previews, motorcycle badge, distance, duration, max lean, top speed, and durable cloud sync checkmarks. | **VERIFIED** |
|
||||
| **MOB-11** | `ACT-02` (`/activity?tab=records`) | `ActivityScreen`, `RecordsScreen`, `RecordsService`. Trophy cards for All-Time Top Speed, Max Left Lean, Max Right Lean, Longest Ride, and Elevation Peak. | **VERIFIED** |
|
||||
| **MOB-12** | `HIST-01` (`/history/:id`) | `RideDetailScreen`, `FieldTestExportService`. Full metrics breakdown, GPS route preview, GPX export, 20 Hz forensic CSV export, and JSON session export. | **VERIFIED** |
|
||||
| **MOB-13** | `REPLAY-01` (Forensic Replay & Apex Grading) | `ReplayScreen`. **Multi-color lean angle route heatmaps** (Yellow $\le 20^\circ \rightarrow$ Cyan $20^\circ–35^\circ \rightarrow$ Red $>35^\circ$ Apex), **interactive corner entry/apex/exit breakdown table**, speed retention grading (`A+` to `D`), and **tap-to-seek apex navigation**. | **VERIFIED** |
|
||||
| **MOB-14** | `GAR-01` (`/garage` Virtual Garage) | `GarageScreen`, `garageMotorcyclesStreamProvider`. Motorcycle stable cards, odometer display, active default bike selection badge. | **VERIFIED** |
|
||||
| **MOB-16** | `GAR-03` (Bike Profile & Service Tracking) | `MotorcycleDetailScreen`, `MaintenanceData`. **Automatic odometer countdown pills** (Engine Oil due, Chain service, Tire wear, Brake fluid), **service log history**, `+ Log Service` modal, and base odometer adjustment with **0 Drift schema mutations** (Schema 7 frozen). | **VERIFIED** |
|
||||
| **MOB-17** | `ROUT-01` (Curvy Route Planner Twistiness) | `RoutePlannerScreen`, `RouteDetailScreen`, `RouteCurvatureReport`. **Curviness / Twistiness Priority Selector** (`Standard`, `Curvy`, `Extreme Passes`), **cross-section elevation profile chart** (`RouteElevationChart`) with touch scrubber and ascent/descent totals, and **twistiness grading card** with total corners count and hairpin/bend/sweeper breakdown. | **VERIFIED (NEW)** |
|
||||
| **MOB-18** | `ROUT-02` (`/routes/:id` Route Detail) | `RouteDetailScreen`. Route statistics, waypoints cue sheet, external navigation handoff (Google Maps, Apple Maps, Waze, GPX export). | **VERIFIED** |
|
||||
| **MOB-19** | `SOC-01` (`/social/feed` Community Social Feed) | `SocialFeedScreen`, `_SocialFeedCard`, `_FeedRoutePainter`, `SocialFeedService`, `FeedCommentsBottomSheet`, `ShareSessionModal`. **Status LED and live metric header** (`SQUAD & CANYON FEED`, `24 ACTIVE`), **3-segment filter tab** (`All Activity`, `Club Only`, `Nearby Packs`), **helmet avatar presets with online indicators**, author handle/badges/clubs, **Stitch 2x2 telemetry inset strip** (Distance, Duration, Max Lean with apex indicator, Pace Factor), **vector route track canvas** (`_FeedRoutePainter`) with cyan path, amber sweep and apex degree badges or scenic photo container with `GPS VERIFIED` badge, **glove-friendly Fist Bump kudos reaction** (`👊 42 Bumps`) with optimistic toggle and scale animation, **rider comments bottom sheet drawer** with comment composer, GPX track export, telemetry inspection trigger, and **sticky glove-friendly "Share Recent Session" bottom action bar**. Full routing wired under `/social/feed` and `social_card_feed` navigation tile in `SocialHubScreen`. Verified with 13 automated tests and 0 Drift schema mutations (Schema 7 frozen). | **VERIFIED (NEW)** |
|
||||
| **MOB-20** | `SOC-02` (`/social/profile`) | `RiderProfileScreen`. Rider handle, display name, bio, helmet avatar presets, public stats. | **VERIFIED** |
|
||||
| **MOB-21** | `SOC-03` (`/social/friends`) | `FriendsScreen`, `FriendshipService`. Rider search by handle, incoming/outgoing requests, accept/decline, mutual friend counts. | **VERIFIED** |
|
||||
| **MOB-22** | `CLUB-01` (`/social/clubs`) | `ClubsHubScreen`. Search, riding style filter chips, club cards, member counts, Create Club entry point. | **VERIFIED** |
|
||||
| **MOB-23** | `CLUB-02` (`/social/clubs/create`) | `CreateClubScreen`. Name, unique slug validator, description, chapter region, privacy policy, monogram crest. | **VERIFIED** |
|
||||
| **MOB-24** | `CLUB-03` (`/social/clubs/:id` Club Wall & Roster) | `ClubDetailScreen`, `ClubWallTab`, `ClubRosterTab`, `OfficerBadge`. **Segmented 3-tab layout** (`Overview`, `Club Wall`, `Roster`), pinned leadership announcement banner, real-time discussion feed, **fist-bump kudos reactions with animated increment**, nested comment threads with reply composer, **real-time member roster search**, tactical role filter chips, tactical officer badges (`President`, `Vice President`, `Road Captain`, `Tail Gunner`, `Road Marshal`, `Treasurer`, `Full Member`, `Prospect`), and **Owner/Admin Member Rank & Role Management Modal** with **0 Drift SQLite schema mutations** (Schema 7 frozen). | **VERIFIED (NEW)** |
|
||||
| **MOB-25** | `GRP-01` (`/group-rides`) | `GroupRidesHubScreen`. Active pack rides list, join code entry modal, Host Ride CTA. | **VERIFIED** |
|
||||
| **MOB-26** | `GRP-02` (`/group-rides/create`) | `CreateGroupRideScreen`. Staging location, departure time, route attachment, pace selection, maximum rider limit. | **VERIFIED** |
|
||||
| **MOB-27** | `GRP-03` (`/group-rides/:id` Briefing) | `GroupRideDetailScreen`. Attendee roster, check-in, weather forecast, route overview, stage progression. | **VERIFIED** |
|
||||
| **MOB-29** | `PRO-01` (`/pro` Pro Paywall) | `ProScreen`, `PlayBillingService`, `ProductCatalog`. Feature comparison, annual/monthly tiers, Google Play Billing checkout flow. | **VERIFIED** |
|
||||
| **MOB-30** | `SET-01` (`/settings` Settings) | `SettingsScreen`. Units toggle (MPH/KMH), audio alert mode, Waze/OpenWebNinja API configuration, lean angle audio interlock toggle (>15°). | **VERIFIED** |
|
||||
| **MOB-31** | `SET-02` (`/settings/account`) | `AccountScreen`. Firebase auth credentials, cloud sync toggle, account deletion request. | **VERIFIED** |
|
||||
| **MOB-32** | `DIAG-01` (`/settings/diagnostics`) | `DiagnosticsScreen`. Real-time 20 Hz accelerometer and gyroscope stream, GNSS constellation satellites in view, Drift SQLite database row counters. | **VERIFIED** |
|
||||
|
||||
---
|
||||
|
||||
### B. Partially Implemented / Remaining Scope (1 Screen)
|
||||
|
||||
| ID | Screen / Feature | What Is Implemented | What Is Missing / Non-Functional | Complexity |
|
||||
|---|---|---|---|:---:|
|
||||
| **MOB-15** | `GAR-02` Add Motorcycle Wizard | 4-step Year $\rightarrow$ Make $\rightarrow$ Model $\rightarrow$ Variant selector backed by NHTSA & local database. | **Camera Barcode / OCR VIN Scanner** (`VIN-01`). Currently requires manual dropdown navigation. | High (3 days) |
|
||||
|
||||
---
|
||||
|
||||
### C. Completely Missing / Unimplemented (1 Screen)
|
||||
|
||||
| ID | Screen / Feature | Stitch Specification & User Context | Required Work to Implement | Complexity |
|
||||
|---|---|---|---|:---:|
|
||||
| **MOB-28b**| `RAD-01` Off-Grid Peer-to-Peer BLE Mesh Radar | Direct off-grid Bluetooth / Wi-Fi Direct mesh pack radar allowing pack riders to maintain formation radar and proximity alerts when riding in remote canyons without cellular service. | Requires BLE advertising/scanning peripheral service and peer-to-peer distance estimation protocol. | Very High (5+ days) |
|
||||
|
||||
---
|
||||
|
||||
## 3. Website Platform (24 Stitch Routes)
|
||||
|
||||
### A. Fully Implemented & Deployed (21 Routes)
|
||||
|
||||
| ID | Route | Implementation Details & Architecture | Verified Status |
|
||||
|---|---|---|:---:|
|
||||
| **WEB-01** | `GET /` (Homepage) | Full-width hero, 3D device HUD mockup, live telemetry strip (20 Hz IMU, 0.05s cadence, 100% offline, 0.01g lateral), core pillars, interactive lean angle slider, conversion CTA. | **VERIFIED (Live)** |
|
||||
| **WEB-02** | `GET /features` | High-fidelity technical diagrams, 20 Hz Kalman vs 1 Hz GPS comparison, gyroscopic physics, safety lean mute interlock, dual storage architecture. | **VERIFIED (Live)** |
|
||||
| **WEB-04** | `GET /download` (Download Hub Enhancements) | `DownloadHubClient`. **Dynamic client OS detection**, **SHA-256 verification checksum box with copy tooltip**, **instant phone install QR code generator**, and **numbered sideloading steps guide**. | **VERIFIED (NEW)** |
|
||||
| **WEB-05** | `GET /group-rides` | Search & filters, pace pills, public group rides list from Firestore, join flow. | **VERIFIED (Live)** |
|
||||
| **WEB-06** | `GET /group-rides/showcase` | Fullscreen radar simulation canvas, moving rider blips, pack roster, lead telemetry gauge, simulation scrubber controls. | **VERIFIED (Live)** |
|
||||
| **WEB-07** | `GET /group-rides/manage` | Organizer management console, hosted rides stats, upcoming/completed filter tabs, ride creation and editing connected to Firestore. | **VERIFIED (Live)** |
|
||||
| **WEB-08** | `GET /clubs` | Club directory cards, riding discipline filters, founder portal entry. | **VERIFIED (Live)** |
|
||||
| **WEB-09** | `GET /clubs/manage` | Officer command overview, club switcher, pending applications shortcut. | **VERIFIED (Live)** |
|
||||
| **WEB-10** | `GET /clubs/[id]/manage` | Member stats, upcoming rides, recent activity log stream connected to Firestore. | **VERIFIED (Live)** |
|
||||
| **WEB-11** | `GET /clubs/[id]/manage/profile` | Crest uploader, name, tagline, markdown bio, social links, location. | **VERIFIED (Live)** |
|
||||
| **WEB-12** | `GET /clubs/[id]/manage/applications`| Member applicant review, questionnaire answers, accept/decline actions. | **VERIFIED (Live)** |
|
||||
| **WEB-13** | `GET /clubs/[id]/manage/ranks-roles` (Interactive Hierarchy Builder & Permission Matrix) | `ClubHierarchyBuilder`, `ClubPermissionMatrix`, `RolesAndRanksSummary`. **Interactive visual 4-tier organizational hierarchy tree** (Executive Command, Leadership & Admin, Tactical Ops, Squad Formation) with rank node selection, rider assignment modal, and **customizable operational permission matrix across 6 key privileges** (`planRides`, `manageApplications`, `postAnnouncements`, `moderateWall`, `manageRoster`, `editProfile`) with interactive toggle switches and reset-to-defaults safety controls. | **VERIFIED (NEW)** |
|
||||
| **WEB-14** | `GET /clubs/[id]/manage/rides` | Club rides schedule, attendance logs, lead/sweep assignments. | **VERIFIED (Live)** |
|
||||
| **WEB-15** | `GET /clubs/[id]/manage/settings` | Privacy toggles, join codes, ownership transfer, disband club danger zone. | **VERIFIED (Live)** |
|
||||
| **WEB-16** | `GET /support` | Knowledge base search, system status indicator, support ticket submission form. | **VERIFIED (Live)** |
|
||||
| **WEB-17** | `GET /privacy` | Sticky TOC, 20 Hz IMU telemetry anonymization callouts, GDPR rights, international compliance (France, Germany, Switzerland). | **VERIFIED (Live)** |
|
||||
| **WEB-18** | `GET /terms` | Legal indemnity, safety speed disclaimers, track use terms. | **VERIFIED (Live)** |
|
||||
| **WEB-19** | `GET /login` | Email/password, Google auth, remember device, error handling. | **VERIFIED (Live)** |
|
||||
| **WEB-20** | `GET /register` | Onboarding form, bike details, password strength meter. | **VERIFIED (Live)** |
|
||||
| **WEB-21** | `GET /forgot-password` (Cryptographic Recovery) | `RecoveryForm`, `SegmentedOtpInput`. **2-step cryptographic password recovery workflow** (registered email input $\rightarrow$ 6-digit OTP verification challenge $\rightarrow$ new password strength & confirmation validation), auto-advance cells, and direct login redirection. | **VERIFIED (NEW)** |
|
||||
| **WEB-22** | `GET /verify-email` (Telemetry Signature Challenge) | `VerifyEmailForm`, `SegmentedOtpInput`. Stitch tactical card (`#070A0F`, cyan shield icon), **6-digit segmented numeric OTP input with auto-advance**, backspace navigation, paste handling, query param token support, and **60-second resend countdown timer**. | **VERIFIED (NEW)** |
|
||||
| **WEB-23** | `GET /account` (Telemetry Replay & Export) | `AppCloudData`, `WebTelemetryReplayModal`. **One-click GPX 1.1 and 20 Hz CSV export buttons**, and **in-browser interactive telemetry replay player** with dynamic canvas route heatmap, moving rider beacon, speed/lean/G-force HUD gauges, timeline scrubber, and corner grading. | **VERIFIED** |
|
||||
| **WEB-24** | `GET /admin` (Operations Console) | 8-tab command suite: Overview (with live metrics), Infrastructure (with dual speedtest & systemd logs), Users, Incidents, Audit Trail, Support (with ticket creator), Website CMS (with revision rollback), and Ops Controls (capability allowlisting). | **VERIFIED (Live)** |
|
||||
|
||||
---
|
||||
|
||||
### B. Partially Implemented / Remaining Scope (1 Route)
|
||||
|
||||
| ID | Route / Feature | What Is Implemented | What Is Missing / Non-Functional | Complexity |
|
||||
|---|---|---|---|:---:|
|
||||
| **WEB-03** | `GET /pricing` (Pricing & Membership) | 3-tier matrix (Free, Pro, Founder), monthly/annual billing cycle toggle, feature comparison table, FAQ accordion. | **Stripe / Payment Gateway Checkout**. "Start 30-Day Free Trial" and "Get Started" buttons link directly to `/account` without initiating a real payment transaction. | High (3 days) |
|
||||
|
||||
---
|
||||
|
||||
## 4. Backend API & Cloud Infrastructure Services
|
||||
|
||||
### A. Implemented & Operational Subsystems
|
||||
|
||||
1. **Authentication & Session Security**:
|
||||
- Endpoints: `/api/v1/auth/register`, `/api/v1/auth/login`, `/api/v1/auth/firebase/link`, `/api/v1/auth/sessions`, `/api/v1/auth/logout-all`.
|
||||
- Cookie + Bearer JWT support with role-based authorization (`owner`, `operator`, `rider`).
|
||||
2. **Vehicles & Garage API**:
|
||||
- Endpoints: `GET/POST/PATCH/DELETE /api/v1/vehicles`.
|
||||
3. **Rides & High-Frequency Telemetry**:
|
||||
- Endpoints: `GET/POST /api/v1/rides`, `/api/v1/rides/{id}/telemetry`.
|
||||
- SQLite Schema 7 $\rightarrow$ R2 binary bundle $\rightarrow$ Firestore synchronization.
|
||||
4. **Operations & SRE Command API**:
|
||||
- Comprehensive `/api/v1/ops/` suite: overview, health, dual speedtest, audit logs, incidents, users, support tickets, and CMS document revision management.
|
||||
|
||||
### B. Remaining Backend Capabilities
|
||||
|
||||
| Capability | Missing Endpoints / Components | Impact & Purpose | Complexity |
|
||||
|---|---|---|:---:|
|
||||
| **Stripe Webhook & Checkout API** | Missing `POST /api/v1/billing/create-checkout-session`, `POST /api/v1/billing/portal`, `POST /api/v1/billing/webhook`. | Prevents web riders from subscribing to MotorSignal Pro via credit card on the website. | High (3 days) |
|
||||
| **Transactional Email Dispatcher (Resend / SendGrid)** | Missing production SMTP / API dispatcher for 6-digit OTP email verification and password reset emails. | Currently tokens are generated in API/database but require live transactional email transport. | Medium (1.5 days) |
|
||||
| **Hardware CAN-Bus & OBD-II Driver** | Missing Bluetooth CAN-bus transceiver protocol parser in Flutter and Web Bluetooth flasher tool. | The hardware OBD-II dongle displayed in marketing materials is not yet supported in software. | Very High (Roadmap) |
|
||||
|
||||
---
|
||||
|
||||
## 5. Next Recommended Implementation Priorities
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
subgraph Completed Recently [COMPLETED & VERIFIED]
|
||||
C1["WEB-04: Download Hub (OS Detection, SHA-256, QR, Sideload Cards)"]
|
||||
C2["WEB-23: Web Telemetry GPX/CSV Export & Replay Modal"]
|
||||
C3["MOB-16: Motorcycle Maintenance Due Tracking & Service Logs"]
|
||||
C4["MOB-13: Forensic Replay Apex Grading & Multi-Color Heatmaps"]
|
||||
C5["WEB-22: Segmented OTP & Email Verification Challenge"]
|
||||
C6["WEB-21: Cryptographic 2-Step Password Recovery Workflow"]
|
||||
C7["MOB-09: Launch Curve Analysis & Density Altitude DA Calculation"]
|
||||
C8["MOB-17: Curvy Route Twistiness Selector & Elevation Profile Chart"]
|
||||
C9["MOB-24: Club Wall Discussion Feed & Member Roster Officer Badges"]
|
||||
C10["WEB-13: Interactive Club RBAC Hierarchy Builder & Permission Matrix"]
|
||||
C11["MOB-19: Community Social Feed, Route Track Painter & Fist Bumps"]
|
||||
end
|
||||
subgraph Priority 1 [Immediate Next Features]
|
||||
P1["WEB-03 / Stripe: Pro Membership Stripe Checkout & Webhook Integration"]
|
||||
P2["MOB-15: Camera Barcode / OCR VIN Scanner for Garage"]
|
||||
P3["MOB-28b: Off-Grid Peer-to-Peer BLE Mesh Pack Radar"]
|
||||
end
|
||||
Completed Recently --> Priority 1
|
||||
```
|
||||
|
||||
---
|
||||
*Report generated and verified against local source repositories and test suites (`flutter test`, `flutter analyze`, `vitest`).*
|
||||
|
|
@ -0,0 +1,300 @@
|
|||
# MotorSignal — Police & Speed Trap Alerts Architectural Research
|
||||
|
||||
**Document Version:** 1.0.0
|
||||
**Author:** Antigravity / MotorSignal Architecture Group
|
||||
**Status:** Approved Architectural Research & Options Analysis
|
||||
**Target Systems:** MotorSignal Flutter Client (`lib/services/alerts/`), MotorSignal Backend (`backend/motorsignal_api/`), Cloudflare R2 / Firestore Swarm Layer
|
||||
|
||||
---
|
||||
|
||||
## Executive Summary
|
||||
|
||||
Real-time speed camera and mobile police enforcement alerts represent one of the highest-value situational awareness features for motorcyclists. Unlike automotive drivers who can glance at large infotainment dashboards, motorcycle riders operate under extreme cognitive and physical constraints: hands are engaged with handlebar controls, visual focus must remain on road surfaces and vanishing points, and high cornering lean angles render sudden auditory distractions hazardous. Furthermore, motorcycle twisties and mountain passes frequently traverse cellular dead zones where conventional cloud-only navigation apps fail.
|
||||
|
||||
This research document evaluates the end-to-end options for implementing a production-grade, legally compliant, offline-resilient, and motorcycle-ergonomic police and speed trap alert system in MotorSignal.
|
||||
|
||||
### Key Strategic Recommendations
|
||||
1. **Hybrid Tri-Layer Architecture**:
|
||||
- **Layer 1 (Offline Static Base)**: Pre-cached fixed speed cameras and red-light cameras extracted from **OpenStreetMap (OSM)** under Open Database License (ODbL), stored locally in SQLite/Drift for 100% offline canyon coverage.
|
||||
- **Layer 2 (Commercial Cloud Feed)**: Integration of **HERE Technologies Safety Cameras API** for verified commercial fixed cameras, average-speed zones, and historical mobile enforcement hotspots with predictable RESTful pricing and legal indemnity.
|
||||
- **Layer 3 (MotorSignal Rider Swarm)**: Real-time peer-to-peer and cloud crowdsourcing over Firestore and group ride mesh networking, allowing pack leads and club members to report mobile speed traps and road hazards with 1-tap glove gestures and automated time-to-live (TTL) pruning.
|
||||
2. **Motorcycle-Specific Safety Interlock (Lean-Angle Mute)**:
|
||||
- Gate audio notifications behind `SensorFusionService` telemetry. If the motorcycle's lean angle exceeds **15°**, audio warnings are deferred or suppressed until the motorcycle returns to upright orientation (`< 10°` for 1.5 seconds) to prevent startling riders mid-corner.
|
||||
3. **Legal & Geofence Compliance**:
|
||||
- Implement automated jurisdictional compliance: exact camera warnings in the United States and UK, "Safety Zone" (Zone de Danger) compliance in France, and automatic feature deactivation in Germany (§ 23 Abs. 1c StVO) and Switzerland (Art. 57b SVG).
|
||||
|
||||
---
|
||||
|
||||
## 1. Existing MotorSignal Alert Pipeline Architecture
|
||||
|
||||
MotorSignal already possesses an alert architecture cleanly separated from the 20 Hz telemetry acquisition pipeline, fully respecting the repository's **Telemetry Freeze Boundary**.
|
||||
|
||||
### Current Components & Data Flow
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
subgraph UI ["User Interface Layer"]
|
||||
DAR["DashboardAlertRegion<br/>(Visual Banner & Dismiss)"]
|
||||
UMV["UnifiedMapView<br/>(Tactical Map Overlay)"]
|
||||
SET["SettingsScreen<br/>(Provider API Keys & Category Filters)"]
|
||||
end
|
||||
|
||||
subgraph Service ["Alerts Application Layer"]
|
||||
RAS["RoadAlertService<br/>• Position listener (LocationService)<br/>• Request serialization (45s / 500m)<br/>• 400m approach gate<br/>• Heading bearing filter (<= 100°)<br/>• 4-sec TTS speech cooldown"]
|
||||
TTS["FlutterTts<br/>(Voice Alerts)"]
|
||||
FTL["FieldTestLogger<br/>(Forensic Event Logging)"]
|
||||
end
|
||||
|
||||
subgraph Providers ["Alert Providers (lib/services/alerts/)"]
|
||||
TT["TomTomRoadAlertProvider<br/>(Incident Details API)"]
|
||||
CT["CommunityTrafficRoadAlertProvider<br/>(Waze / RapidAPI parser)"]
|
||||
MO["MockRoadAlertProvider<br/>(Debug & Diagnostic)"]
|
||||
end
|
||||
|
||||
UMV --> RAS
|
||||
DAR --> RAS
|
||||
SET --> RAS
|
||||
RAS --> TTS
|
||||
RAS --> FTL
|
||||
RAS --> TT
|
||||
RAS --> CT
|
||||
RAS --> MO
|
||||
```
|
||||
|
||||
### Existing Code Assets
|
||||
1. **[`lib/services/alerts/road_alert_models.dart`](file:///c:/Users/Bill/Desktop/flutter-app/lib/services/alerts/road_alert_models.dart)**:
|
||||
- Pre-defines `RoadAlertCategory.police` and `RoadAlertCategory.speedCamera` with corresponding iconography (`Icons.local_police`, `Icons.camera_alt`) and distinct color tokens (velocity blue, purple accent).
|
||||
- Models `RoadAlert` containing `latitude`, `longitude`, `heading`, `roadName`, `reportedAt`, `expiresAt`, `confidence` (0.0 to 1.0), `severity`, and `distanceFromUser`.
|
||||
2. **[`lib/services/alerts/road_alert_service.dart`](file:///c:/Users/Bill/Desktop/flutter-app/lib/services/alerts/road_alert_service.dart)**:
|
||||
- Subscribes to `locationServiceProvider.getFilteredPositionStream()`.
|
||||
- Implements request serialization: fetches from providers only when stationary timer exceeds **45 seconds** or displacement exceeds **500 meters**.
|
||||
- Implements approach detection: alerts within **400 meters** that pass the directional bearing filter (`_isAlertAheadOfRider` checks `delta <= 100.0°`) trigger voice synthesis via `FlutterTts` with a **4-second audio cooldown**.
|
||||
3. **[`lib/services/alerts/community_traffic_parser.dart`](file:///c:/Users/Bill/Desktop/flutter-app/lib/services/alerts/community_traffic_parser.dart)**:
|
||||
- Parses Waze-compatible JSON payloads, identifying `POLICE`, `POLICE_VISIBLE`, `POLICE_HIDDEN`, `SPEED_CAM`, and `RED_LIGHT_CAMERA`.
|
||||
4. **Current Architectural Deficiencies**:
|
||||
- **TomTom Provider**: Only queries `traffic/services/5/incidentDetails`, which is designed for traffic jams, construction, and road closures; it does not receive speed camera or police enforcement data without enterprise Speed Camera Services.
|
||||
- **Community Provider**: Uses an unofficial endpoint/API key against scraped Waze data (`wz_live_...` or RapidAPI proxies). This presents severe commercial licensing, rate-limiting, and TOS liabilities if packaged in an official production app store release.
|
||||
- **Zero Local Caching**: If cellular connection drops (common on canyon rides), no alerts can be queried or displayed.
|
||||
- **No Lean-Angle Safety Check**: Audio alerts currently fire regardless of bike lean angle or cornering state.
|
||||
|
||||
---
|
||||
|
||||
## 2. Comparative Analysis of Data Sources
|
||||
|
||||
| Criteria | HERE Technologies Safety Cameras | TomTom Speed Camera Services | OpenStreetMap (OSM / Overpass) | SCDB.info B2B Partner API | Unofficial Waze / RapidAPI Proxies | MotorSignal Rider Swarm (In-House) |
|
||||
| :--- | :--- | :--- | :--- | :--- | :--- | :--- |
|
||||
| **Fixed Speed Cameras** | Excellent (Global) | Excellent (Global) | Very Good (Crowdsourced) | Excellent (100k+ in 100+ countries) | Variable | User-submitted only |
|
||||
| **Mobile Police / Speed Traps** | Good (Verified zones & mobile spots) | Good (Historical mobile spots) | None (Static only) | Frequent mobile zones | Excellent (Real-time driver reports) | Excellent (High relevance for bike routes) |
|
||||
| **Red Light Cameras** | Yes | Yes | Yes (OSM tagged) | Yes | Yes | User-submitted only |
|
||||
| **Average Speed (Section Control)** | Yes (Start, end, corridor) | Yes (Corridor) | Partial (Relations) | Yes | Partial | Planned |
|
||||
| **Data Freshness** | Real-time / Daily | Real-time / Hourly | Monthly / Batch | Daily / Weekly | Sub-5 minute | Sub-second (< 500 ms mesh / Firestore) |
|
||||
| **Offline Capability** | Low (REST query required) | Low (REST / Protobuf) | **Exceptional** (100% pre-cacheable in Drift SQLite) | Very Good (Can download region DB) | Low (Online only) | **Exceptional** (Local P2P BLE mesh in packs) |
|
||||
| **Commercial Terms & Legality** | 100% Legal & Enterprise SLA | 100% Legal & Enterprise SLA | 100% Legal (ODbL with attribution) | 100% Legal (B2B commercial contract) | **High TOS & Trademark Risk** | 100% Proprietary & Owned |
|
||||
| **Pricing / Cost Structure** | Freemium tier; Pay-as-you-go per 1k transactions | Enterprise contract / B2B sales quota | **Free ($0)** | Monthly base fee + per-asset usage fee | $10–$100/mo on RapidAPI; breaks without warning | **Free** (utilizes existing Firebase/Firestore) |
|
||||
|
||||
---
|
||||
|
||||
## 3. Deep-Dive Provider Evaluations
|
||||
|
||||
### 3.1. OpenStreetMap (OSM) — Zero-Cost Offline Base Layer
|
||||
* **Primary Source / Specification**: OpenStreetMap Wiki: `Tag:highway=speed_camera` and Relation `enforcement=maxspeed`.
|
||||
* **How It Works**:
|
||||
OSM contributors tag physical stationary speed enforcement hardware globally using:
|
||||
```osm
|
||||
[out:json][timeout:25];
|
||||
(
|
||||
node["highway"="speed_camera"](bbox);
|
||||
node["enforcement"="maxspeed"](bbox);
|
||||
);
|
||||
out body;
|
||||
```
|
||||
* **Strengths**:
|
||||
- **Zero ongoing API fees**: Completely open under the Open Database License (ODbL).
|
||||
- **100% Offline Resilience**: Coordinates, enforced speed limits, and road names can be bundled or pre-downloaded per state/region into a local SQLite table. When a rider is carving through a canyon with no cellular bars, fixed camera alerts still fire accurately.
|
||||
- **High European & North American Density**: Fixed speed cameras in the UK, France, Germany, Italy, and US metro corridors have virtually 100% OSM coverage.
|
||||
* **Limitations**:
|
||||
- Zero mobile police presence or temporary radar gun traps.
|
||||
- Relies on volunteer community upkeep for speed limit updates.
|
||||
|
||||
### 3.2. HERE Technologies Safety Cameras API
|
||||
* **Primary Source / Specification**: [HERE Developer Portal — Safety Cameras Documentation](https://docs.here.com/safety-cameras/).
|
||||
* **Endpoint Architecture**:
|
||||
RESTful service supporting radius search and corridor search:
|
||||
`GET https://safetycameras.hereapi.com/v2/search?in=circle:latitude,longitude;r=radius_meters`
|
||||
- Headers: `Authorization: Bearer <HERE_TOKEN>`
|
||||
- Responses include camera type (`FIXED_SPEED_CAMERA`, `MOBILE_SPEED_CAMERA`, `RED_LIGHT_CAMERA`, `AVERAGE_SPEED_CAMERA`), enforcement speed limit, directionality, and approach bearings.
|
||||
* **Strengths**:
|
||||
- Accessible via self-service developer portal without enterprise-only gatekeeping.
|
||||
- Covers both fixed infrastructure and **frequent mobile speed enforcement zones** gathered from OEM connected vehicles.
|
||||
- Directional vector data included in response simplifies false-positive filtering.
|
||||
* **Limitations**:
|
||||
- Real-time mobile police reporting is based on statistical enforcement patterns rather than instantaneous crowd sightings.
|
||||
|
||||
### 3.3. TomTom Speed Camera & Safety Services
|
||||
* **Primary Source / Specification**: [TomTom Speed Camera Services Documentation](https://developer.tomtom.com/).
|
||||
* **Architecture**:
|
||||
- Standard TomTom Developer Portal Traffic API (`traffic/services/5/incidentDetails`) **does not** include speed cameras.
|
||||
- Speed Camera data is provided via TomTom's **Connected Services / Automotive API** (delivered over Protocol Buffers or dedicated REST endpoints) and requires commercial B2B provisioning.
|
||||
* **Strengths**:
|
||||
- Industry gold-standard used by Tier-1 automotive navigation systems.
|
||||
- Includes French "Danger Zone" transformations out-of-the-box for regulatory compliance.
|
||||
* **Limitations**:
|
||||
- Requires corporate sales engagement and contractual minimums. Not suitable for immediate indie developer self-service.
|
||||
|
||||
### 3.4. Community Aggregators & Waze Unofficial Proxies
|
||||
* **Primary Source**: Unofficial reverse proxies (`api.wazeapi.com`, RapidAPI Waze Scraper, OpenWebNinja).
|
||||
* **Architecture**:
|
||||
- Ingests user reports from Waze drivers: `POLICE_VISIBLE`, `POLICE_HIDDEN`, `SPEED_CAM`, `HAZARD`.
|
||||
* **Legal & Technical Risks**:
|
||||
- **Terms of Service Violation**: Waze/Google explicitly bans scraping, reverse engineering, and commercial republication of crowd data outside their municipal "Waze for Cities" program.
|
||||
- **Brittle Infrastructure**: Waze frequently alters backend protobuf tokens and IP-blocks third-party scrapers, resulting in sudden 403 Forbidden or 429 Too Many Requests errors.
|
||||
- **App Store Rejection**: Direct redistribution of scraped third-party proprietary data violates Apple App Store Review Guideline 5.2.2 and Google Play Developer Program policies.
|
||||
* **Architectural Recommendation**:
|
||||
- **Retain as an optional "User-Supplied API Key" feature**: Keep the existing `CommunityTrafficRoadAlertProvider` in MotorSignal settings, but label it clearly as "Custom / BYO Endpoint". Users who own a personal RapidAPI key can paste it in, which insulates MotorSignal from corporate scraping liabilities.
|
||||
|
||||
### 3.5. MotorSignal Rider Swarm (In-House Pack & Cloud Crowdsourcing)
|
||||
* **Primary Source**: MotorSignal Firestore Infrastructure + Bluetooth BLE Group Ride Mesh.
|
||||
* **How It Works**:
|
||||
MotorSignal already has real-time Group Ride state management (`group_ride_providers.dart`) and Firestore syncing:
|
||||
1. **1-Tap Reporting**: Rider taps a large handlebar-mounted button or uses voice command: "Report Police".
|
||||
2. **Pack Broadcast (< 500 ms)**: The alert broadcasts instantly to all riders in the active Group Ride (via Firestore listener or direct BLE mesh if out of cell service). Trailing riders receive immediate notification.
|
||||
3. **Global Cloud Aggregation**: Stored in Firestore collection `/road_alerts/{alertId}` with geospatial GeoHash indexing and a 60-minute automated Time-To-Live (TTL).
|
||||
4. **Verification & Voting**: Trailing riders passing within 200m see a simple glanceable button: `Confirm (👍)` or `Cleared (❌)`. Two "Cleared" votes instantly expire the alert.
|
||||
* **Strengths**:
|
||||
- Zero recurring third-party API license costs.
|
||||
- 100% legal, private, and owned by MotorSignal.
|
||||
- Captures motorcycle-specific hazards and twisty canyon speed traps that passenger car drivers never report.
|
||||
|
||||
---
|
||||
|
||||
## 4. Motorcycle Ergonomics & Human Factors
|
||||
|
||||
Operating a motorcycle at highway or track-day speeds requires a fundamentally different user interface paradigm compared to automotive navigation.
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A[Incoming Alert Detected] --> B{Motorcycle Lean Angle > 15°?}
|
||||
B -- YES (In Corner) --> C[Defer Audio Notification<br/>Queue in Memory]
|
||||
C --> D{Bike Upright & Steady?<br/>Lean < 10° for 1.5s}
|
||||
D -- YES --> E[Play Concise Warning Audio]
|
||||
B -- NO (Upright / Straight) --> E
|
||||
E --> F[Display High-Contrast HUD Banner]
|
||||
```
|
||||
|
||||
### 4.1. Lean-Angle Audio Suppression (Cornering Safety)
|
||||
* **Hazard**: A sudden, loud TTS voice announcement ("POLICE REPORTED AHEAD!") or alarm chime delivered into a rider's helmet intercom while dragging knee or executing a tight apex turn can induce panic braking, line disruption, or target fixation, leading to a crash.
|
||||
* **Solution**:
|
||||
- `SensorFusionService` in MotorSignal computes high-fidelity roll/pitch at 20 Hz.
|
||||
- When an alert triggers within the 400m distance threshold:
|
||||
```dart
|
||||
final currentLean = ref.read(sensorFusionServiceProvider).leanAngleDegrees.abs();
|
||||
if (currentLean > 15.0) {
|
||||
// Suppress immediate audio, queue alert until bike stands upright
|
||||
_queueDeferredAlert(alert);
|
||||
return;
|
||||
}
|
||||
```
|
||||
- Once the motorcycle returns to upright riding (`lean < 10°` for consecutive samples), the alert plays. If the rider passes the alert location while still in the turn, the audio is cleanly discarded.
|
||||
|
||||
### 4.2. Audio Design: Helmet Intercom Optimization
|
||||
* **TTS vs. Tone Beeps**:
|
||||
- Many riders find constant TTS voice announcements intrusive over helmet intercoms (Sena, Cardo, Packtalk) because they mute intercom communication with riding buddies or music.
|
||||
- **Proposed Dual-Mode Audio Setting**:
|
||||
1. **Voice Mode (Default)**: Crisp, 4-word TTS messages: *"Police 400 meters ahead."* / *"Speed camera ahead."*
|
||||
2. **Tactical Tone Mode**: Two high-frequency dual beeps (e.g., 880 Hz → 1760 Hz for speed camera; 587 Hz → 1174 Hz for police trap). Fast, recognizable, and non-intrusive.
|
||||
* **Audio Routing**:
|
||||
- Route alerts through audio channels configured for Bluetooth HFP/A2DP headset playback with automatic audio ducking.
|
||||
|
||||
### 4.3. Visual HUD & Glove-Friendly UI
|
||||
* **Glanceability**:
|
||||
- The alert banner (`DashboardAlertRegion`) must maintain high contrast (pure black background, neon velocity blue for police, vibrant magenta for speed camera).
|
||||
- High-visibility countdown distance: `400m` → `300m` → `200m` → `PASS`.
|
||||
* **Glove-Friendly Reporting**:
|
||||
- Tapping small icon buttons with thick leather motorcycle gloves while moving is impossible.
|
||||
- Provide a dedicated full-width "Quick Alert" gesture or long-press action on the tactical dashboard speedometer zone.
|
||||
|
||||
---
|
||||
|
||||
## 5. Legal, Regulatory & Geofence Compliance
|
||||
|
||||
| Jurisdiction | Legal Status of Speed Camera Alerts | Legal Status of Mobile Police Alerts | Required System Behavior |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| **United States** | Legal in 50 states (GPS software) | Legal (First Amendment protected) | Standard exact distance & location alerts enabled. *(Note: Radar detector hardware is banned in VA and DC, but GPS crowdsourced apps are legal).* |
|
||||
| **United Kingdom** | 100% Legal | 100% Legal | Standard exact distance & location alerts enabled. |
|
||||
| **France** | **Prohibited** (Art. R413-15 Code de la route) | **Prohibited** if exact location | Must transform exact points into a **"Zone de Danger"** (Danger Zone): alert covers a 4 km corridor on motorways, 2 km on secondary roads, 300 m in urban areas. Cannot state "Speed Camera"; must state "Accident / Danger Zone". |
|
||||
| **Germany** | **Prohibited** (§ 23 Abs. 1c StVO) | **Prohibited** while driving | Speed camera and speed trap warning features must be **disabled** when driving/riding in Germany. |
|
||||
| **Switzerland** | **Strictly Prohibited** (Art. 57b SVG) | **Strictly Prohibited** | Strict ban: device confiscation risk. Speed warning features must be automatically disabled via GPS boundary check. |
|
||||
| **Australia / New Zealand** | Legal in all states | Legal | Standard exact alerts enabled. |
|
||||
|
||||
### Geofencing Implementation Pattern
|
||||
Using coarse bounding boxes or country reverse geocoding in `RoadAlertService`:
|
||||
```dart
|
||||
enum AlertComplianceJurisdiction { standard, frenchDangerZone, prohibited }
|
||||
|
||||
AlertComplianceJurisdiction evaluateJurisdiction(double lat, double lng) {
|
||||
if (isInSwitzerland(lat, lng) || isInGermany(lat, lng)) {
|
||||
return AlertComplianceJurisdiction.prohibited;
|
||||
}
|
||||
if (isInFrance(lat, lng)) {
|
||||
return AlertComplianceJurisdiction.frenchDangerZone;
|
||||
}
|
||||
return AlertComplianceJurisdiction.standard;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Recommended Implementation Roadmap
|
||||
|
||||
### Phase 1: Zero-Cost Offline Static Camera Layer (OSM Cache)
|
||||
1. **Offline Spatial Dataset**:
|
||||
- Extract fixed speed cameras, red light cameras, and average speed camera nodes from OpenStreetMap for target regions.
|
||||
- Bundle as an offline SQLite asset or downloadable region pack (avoiding breaking changes to the core Drift Schema 7 database).
|
||||
2. **Provider Integration**:
|
||||
- Implement `OsmRoadAlertProvider implements RoadAlertProvider`.
|
||||
- Performs fast spatial bounding-box lookup around current GPS location.
|
||||
- 100% operational in mountain passes and cellular dead zones.
|
||||
|
||||
### Phase 2: MotorSignal Rider Swarm (Real-Time Group & Cloud Crowdsourcing)
|
||||
1. **Firestore Dynamic Layer**:
|
||||
- Collection `/road_alerts/{alertId}` with GeoHash, TTL index, category (`police`, `hazard`), reporter UID, and upvote counters.
|
||||
2. **Pack Mesh Broadcast**:
|
||||
- When a rider in an active Group Ride reports police, broadcast immediately to the active group session so all pack members receive audio/visual warnings regardless of external API configuration.
|
||||
3. **1-Tap Handlebar / Glove UI**:
|
||||
- Add a high-visibility, glove-friendly "Report Enforcement" overlay button on the dashboard and tactical map.
|
||||
|
||||
### Phase 3: Commercial Telematics Feed (HERE Technologies)
|
||||
1. **HERE Safety Cameras Provider**:
|
||||
- Implement `HereRoadAlertProvider implements RoadAlertProvider` using HERE's `/v2/search` circular proximity endpoint.
|
||||
- Supports verified historical mobile speed traps and active camera points.
|
||||
- Configurable API key with graceful fallback to OSM and Swarm layers.
|
||||
|
||||
### Phase 4: Motorcycle Ergonomics & Safety Controls
|
||||
1. **Lean-Angle Audio Interlock**:
|
||||
- Integrate `SensorFusionService` into `RoadAlertService` to defer or suppress audio announcements whenever bike lean angle exceeds **15°**.
|
||||
2. **Tactical Radar Tone Mode**:
|
||||
- Add settings toggle allowing riders to choose between spoken TTS voice alerts and dual-tone radar chirps.
|
||||
3. **Jurisdictional Geofencing**:
|
||||
- Automatically suppress camera notifications in Germany and Switzerland, and format as "Danger Zones" in France.
|
||||
|
||||
---
|
||||
|
||||
## 7. Verification & Safety Verification Gates
|
||||
|
||||
Before rolling out production road alert changes, the following verification gates must pass:
|
||||
1. **Telemetry Isolation**: Verify `TelemetryService` 20 Hz acquisition cadence is untouched and zero alert computations run on the sensor thread.
|
||||
2. **Drift Schema 7 Stability**: Verify database migrations and schema hashes remain unmutated unless an explicit migration plan is enacted.
|
||||
3. **Audio Safety**: Unit test verifying audio suppression during active roll/lean states:
|
||||
```dart
|
||||
test('Alert audio is suppressed when motorcycle lean angle exceeds 15 degrees', () async { ... });
|
||||
```
|
||||
4. **Offline Resilience**: Verify alert lookups succeed when device is in Airplane Mode using local cached OSM data.
|
||||
5. **Full Suite Execution**:
|
||||
```bash
|
||||
flutter test
|
||||
flutter analyze
|
||||
flutter build apk --debug
|
||||
```
|
||||
|
||||
---
|
||||
*End of Architectural Research Document.*
|
||||
|
|
@ -0,0 +1,783 @@
|
|||
# MotorSignal — Master Stitch Design Specification
|
||||
## Modern Bootstrap 5.3+ Responsive Architecture for Web & Mobile
|
||||
### Including Comprehensive UI Element Requirements for Every Page and Screen
|
||||
|
||||
**Document Version:** 1.1.0
|
||||
**Design System Target:** Bootstrap 5.3+ (Dark Cockpit Theme / Neon Telemetry Accents)
|
||||
**Target Runtimes:** MotorSignal Web Portal (`website/`) & MotorSignal Mobile App (`lib/`)
|
||||
**Design Engine Tool:** Google Stitch / StitchMCP (`create_design_system`, `generate_screen_from_text`)
|
||||
|
||||
---
|
||||
|
||||
## Executive Summary & Design System Foundations
|
||||
|
||||
This specification defines every single screen and page across the MotorSignal ecosystem (24 web routes and 32 mobile app screens) for automated design generation using **Stitch** into a modern, responsive **Bootstrap 5.3+** design system.
|
||||
|
||||
MotorSignal is a high-performance motorcycle telemetry, ride analysis, road alert, and pack ride platform. The design aesthetic balances **tactical dark cockpit utility** (optimised for glove-friendly touch and sunlight readability) with **clean, high-density telemetry data visualization**.
|
||||
|
||||
---
|
||||
|
||||
### Core Design Tokens (Bootstrap 5.3 SCSS / CSS Variables)
|
||||
|
||||
```scss
|
||||
:root {
|
||||
/* Surface & Background Colors */
|
||||
--ms-bg-canvas: #070A0F; /* Ultra-deep cockpit black */
|
||||
--ms-bg-card: #0D131F; /* Deep tactical blue-grey */
|
||||
--ms-bg-card-hover: #141C2E; /* Elevated surface hover */
|
||||
--ms-bg-glass: rgba(13, 19, 31, 0.75); /* Glassmorphism HUD panels */
|
||||
--ms-border: #1E293B; /* Slate-800 subtle borders */
|
||||
--ms-border-active: #00E5FF; /* Active focus / telemetry border */
|
||||
|
||||
/* High-Contrast Telemetry Accents */
|
||||
--ms-cyan-accent: #00E5FF; /* Primary brand / GPS / Telemetry */
|
||||
--ms-electric-blue: #2563EB; /* Secondary actions / standard buttons */
|
||||
--ms-neon-purple: #8B5CF6; /* Pro Tier / Club Badges */
|
||||
--ms-alert-red: #EF4444; /* Police speed traps / G-force brake threshold */
|
||||
--ms-hazard-amber: #F59E0B; /* Road hazards / Cautionary alerts */
|
||||
--ms-lean-green: #10B981; /* Active recording / Lean angle balance */
|
||||
|
||||
/* Typography */
|
||||
--ms-font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||||
--ms-font-telemetry: 'Orbitron', 'Rajdhani', monospace; /* Speeds, Angles, Timers */
|
||||
--ms-font-mono: 'JetBrains Mono', 'Fira Code', monospace; /* Logs, Diagnostics */
|
||||
|
||||
/* Spatial & Component Metrics */
|
||||
--ms-touch-target-min: 48px; /* Glove-friendly minimum tap area */
|
||||
--ms-card-radius: 14px; /* Modern rounded-3 styling */
|
||||
--ms-hud-blur: 16px; /* Backdrop blur filter */
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# PART I: WEBSITE PAGES (24 Routes)
|
||||
|
||||
---
|
||||
|
||||
### PAGE-WEB-01: Public Homepage
|
||||
- **Route:** `GET /`
|
||||
- **Target Audience:** Public visitors, motorcycle riders, track-day enthusiasts, clubs.
|
||||
- **Bootstrap 5.3 Grid Structure:**
|
||||
- Full-width hero container (`container-fluid px-lg-5`) with 2-column split on desktop (`col-lg-7` hero copy, `col-lg-5` interactive HUD phone mockup).
|
||||
- Floating Live Telemetry Strip (`container my-5` with `row g-3 row-cols-2 row-cols-md-4`).
|
||||
- Interactive Lap & Lean Visualizer section (`container py-5`).
|
||||
- 3-Column Core Value Pillars (`row g-4 row-cols-1 row-cols-md-3`).
|
||||
- Testimonial Carousel & Community Social Proof (`container py-5`).
|
||||
- High-impact Conversion CTA Banner with download badges.
|
||||
- **Required UI Elements & Controls:**
|
||||
- **Navigation Bar:** Glowing cyan brand logo (`MotorSignal`), desktop links (`Features`, `Group Rides`, `Clubs`, `Pricing`, `Support`), `Sign In` button, and `Download App` pill button (`btn btn-cyan rounded-pill`).
|
||||
- **Hero Title & Subtitle:** Display-3 bold headline with cyan highlight span, subtitle explaining 20 Hz acquisition and lean angle physics.
|
||||
- **Hero Actions:** Primary `Download Android APK` button with download icon, secondary `Explore Features` outline button, Google Play & Apple TestFlight store badges.
|
||||
- **Interactive 3D Phone HUD Mockup:** Frameless mobile viewport rendering real-time SVG 48° lean gauge, 62 MPH digital readout, G-force friction circle, and Waze police trap banner.
|
||||
- **Telemetry Metric Strip (4 Cards):**
|
||||
- `20 Hz IMU Engine`: Real-time Kalman acquisition vs 1 Hz standard phone GPS.
|
||||
- `0.05s Telemetry Cadence`: Sub-second forensic event resolution.
|
||||
- `100% Offline Resilience`: SQLite/Drift Schema 7 canyon recording.
|
||||
- `0.01g Lateral Precision`: In-corner braking and acceleration friction limits.
|
||||
- **Interactive Lean Angle Slider Widget:** Range input slider ($0^\circ$ to $55^\circ$) updating a live banking motorcycle SVG graphic and displaying the 15° audio mute safety threshold.
|
||||
- **3 Value Pillar Cards:**
|
||||
- Tactical Cockpit HUD (Minimal, Sport, Touring views).
|
||||
- Real-Time Waze Police & Camera Alerts (Strict `TYPE: POLICE` filter).
|
||||
- Live Group Ride Mesh Radar (Real-time pack formation and proximity alerts).
|
||||
- **Testimonial Slider:** Rider quotes with avatar image, rider handle, and motorcycle model badge (e.g. *Ducati Panigale V4*, *BMW R1250GS*).
|
||||
- **Footer:** Brand mission, platform links, legal terms, privacy, copyright notice, version pill.
|
||||
- **Stitch Generation Prompt:**
|
||||
> "Design a modern Bootstrap 5.3 dark-mode landing page for MotorSignal, a motorcycle telemetry and road alert platform. Use a deep navy-black canvas (#070A0F) with electric cyan (#00E5FF) and neon amber accents. Top navigation has a glowing cyan logo, links for Features, Group Rides, Clubs, Pricing, and a 'Download App' pill button. The hero section features a dual column: on the left, an aggressive headline 'High-Fidelity Telemetry for Every Corner', subtext, and call-to-action buttons; on the right, a 3D isometric glassmorphism smartphone showcasing an active cockpit with a 48-degree lean angle gauge, 0-60 performance card, and Waze police trap warning banner. Below the hero, include a live telemetry metric strip showing 20 Hz IMU acquisition, 0.05s latency, 100% offline sync, and 0-60 precision. Include cards for 3 pillars: Tactical Cockpit HUD, Real-Time Police & Hazard Swarm, and Mesh Group Ride Radar."
|
||||
|
||||
---
|
||||
|
||||
### PAGE-WEB-02: Features & Engineering Specifications
|
||||
- **Route:** `GET /features`
|
||||
- **Target Audience:** Riders demanding technical depth, engineers, track coaches.
|
||||
- **Bootstrap 5.3 Grid Structure:**
|
||||
- Header banner (`py-5 text-center`).
|
||||
- 4 Deep-Dive Alternating Feature Rows (`row align-items-center g-5 my-5`, alternating `col-lg-6` technical diagram and `col-lg-6` explanatory card).
|
||||
- Comparative Hardware & Sensor Matrix Table (`table-responsive` inside `card card-dark`).
|
||||
- **Required UI Elements & Controls:**
|
||||
- **Header Section:** Technical badge (`AEROSPACE-GRADE SENSOR FUSION`), Page title, technical whitepaper download link.
|
||||
- **Section 1: 20 Hz Telemetry Engine:** Dual-line canvas chart comparing 1 Hz GPS trajectory (stepped, inaccurate) vs 20 Hz MotorSignal Kalman trajectory (smooth, capturing mid-corner apex corrections).
|
||||
- **Section 2: Lean Angle Gyroscopic Physics:** Exploded technical schematic showing roll, pitch, and yaw vectors, 3-axis accelerometer and gyroscope integration, and lean estimation equations.
|
||||
- **Section 3: Motorcycle Safety Lean-Angle Mute (Cornering Interlock):** State diagram card showing audio warning suppression when lean $> 15^\circ$, and audio unmuting when bike returns upright ($< 10^\circ$) for 1.5 seconds.
|
||||
- **Section 4: Dual Storage & Offline Synchronization:** Architectural flow diagram showing SQLite/Drift Schema 7 local storage, SyncOutbox retry queue, Cloudflare R2 binary telemetry bundles, and Firestore metadata index.
|
||||
- **Hardware & Sensor Comparison Table:** Responsive data table with columns (Feature, Standard Phone Navigation, Dedicated Track Hardware, MotorSignal), comparing sample rates, offline reliability, police alert accuracy, and battery consumption.
|
||||
- **Technical FAQ Accordion:** 5 items answering questions about sensor calibration, mounting orientation, and GPS constellation locks.
|
||||
- **Stitch Generation Prompt:**
|
||||
> "Create a high-tech engineering features page in Bootstrap 5.3 for a motorcycle telemetry system. Dark mode with card surfaces (#0D131F) and fine borders (#1E293B). Display technical architectural diagrams with glowing cyan and purple vector graphics. Section 1 shows an interactive telemetry frequency comparison: a choppy 1 Hz standard GPS curve versus a smooth, high-fidelity 20 Hz MotorSignal Kalman-filtered curve. Section 2 highlights the motorcycle lean-angle algorithm with an exploded diagram of a superbike banked at 52 degrees with roll and yaw vectors. Section 3 illustrates the Safety Lean-Angle Mute interlock blocking distraction during apex. Include a comparison matrix table with checkmarks for Drift Schema 7, Cloudflare R2 binary bundles, and Waze real-time police alerts."
|
||||
|
||||
---
|
||||
|
||||
### PAGE-WEB-03: Membership & Pricing
|
||||
- **Route:** `GET /pricing`
|
||||
- **Target Audience:** Free tier riders looking to upgrade to Pro or Lifetime Founder.
|
||||
- **Bootstrap 5.3 Grid Structure:**
|
||||
- Header with Monthly / Annual Billing Toggle Switch (`form-check form-switch d-inline-flex`).
|
||||
- 3-Tier Pricing Card Deck (`row row-cols-1 row-cols-md-3 g-4 mb-5`).
|
||||
- Feature Comparison Breakdown Table (`table table-dark table-hover align-middle`).
|
||||
- Frequently Asked Questions Accordion (`col-lg-8 mx-auto`).
|
||||
- **Required UI Elements & Controls:**
|
||||
- **Billing Switch:** Centered toggle (`Monthly` vs `Annual`) with a pulsing badge (`SAVE 33% ON ANNUAL`).
|
||||
- **Card 1: Free Rider Tier:** Price (`$0 / month`), Feature checklist (10 recorded rides, Standard HUD cockpit, Offline OpenStreetMap base, Community hazard alerts), Action button (`Get Started Free`).
|
||||
- **Card 2: Pro Rider Tier (Featured):** Elevated glowing cyan border, `MOST POPULAR` floating badge, Price (`$9.99/mo` or `$79/yr`), Feature checklist (Unlimited rides, 20 Hz forensic telemetry export, Waze Police & HERE camera feeds, Draggy-style 0-60 launch mode, Live pack radar mesh, Cloud backup), Action button (`Start 14-Day Free Trial`).
|
||||
- **Card 3: Founder Lifetime Tier:** Gold and purple gradient header, `ONE-TIME PAYMENT` badge, Price (`$199 Lifetime`), Feature checklist (All Pro features forever, Club Founder & Officer toolkit, Physical engraved member patch, VIP Discord access), Action button (`Claim Founder Access`).
|
||||
- **Full Comparison Matrix Table:** 25 feature rows categorized by Telemetry, Road Alerts, Group Rides, and Cloud Storage with checkmarks and tooltips.
|
||||
- **FAQ Accordion:** 6 collapsible answers with clean plus/minus icons.
|
||||
- **Guarantee Pill:** 14-day money-back guarantee seal.
|
||||
- **Stitch Generation Prompt:**
|
||||
> "Design a modern Bootstrap 5.3 pricing page for a motorcycle performance app. Dark palette (#070A0F) with three distinct pricing tier cards. The center card 'Pro Rider' ($9.99/mo or $79/yr) is elevated with a glowing cyan neon border, a 'Recommended' floating pill badge, and an electric cyan 'Start 14-Day Free Trial' button. Left card is 'Rider Basic' (Free) with subtle slate styling. Right card is 'Founder Lifetime' ($199 once) with a deep purple and gold gradient crest. Below the cards, place a comprehensive comparison matrix table with sticky column headers, comparing features like 20 Hz acquisition, Waze Police speed trap warnings, Lean Angle HUD, and Group Ride Radar. Finish with a clean dark-themed FAQ accordion."
|
||||
|
||||
---
|
||||
|
||||
### PAGE-WEB-04: Download & Multi-Platform Hub
|
||||
- **Route:** `GET /download`
|
||||
- **Target Audience:** Riders downloading the Android APK directly or accessing Google Play / iOS TestFlight.
|
||||
- **Bootstrap 5.3 Grid Structure:**
|
||||
- Hero download section with dynamic device detection (`col-lg-6` direct download action, `col-lg-6` QR code transfer card).
|
||||
- Version Release Notes & Checksum Card (`col-lg-8 mx-auto mt-5`).
|
||||
- Step-by-step sideloading guide for Android APK (`row row-cols-1 row-cols-md-3 g-4`).
|
||||
- **Required UI Elements & Controls:**
|
||||
- **Primary Action Card:** Large direct download button (`Download MotorSignal APK - 221 MB`), version indicator (`v1.0.2-stable`), minimum OS requirements (`Android 10+ / API 29`).
|
||||
- **Integrity Verification Card:** SHA-256 checksum code block with a one-click `Copy Checksum` button.
|
||||
- **Instant Phone Install QR Code:** Dynamic QR code graphic with instruction text (*"Scan with your phone's camera to install directly"*).
|
||||
- **App Store Alternative Buttons:** Google Play badge, Apple TestFlight waitlist request button.
|
||||
- **Sideloading Instructions (3 Cards):**
|
||||
- Step 1: Download APK file.
|
||||
- Step 2: Open Downloads & allow *Install unknown apps* in Android Settings.
|
||||
- Step 3: Launch MotorSignal & grant Location and Sensor permissions.
|
||||
- **Changelog Accordion:** Collapsible release notes highlighting new features (e.g. Waze Police speed traps, Draggy launch mode).
|
||||
- **Stitch Generation Prompt:**
|
||||
> "Create a high-conversion download page in Bootstrap 5.3 for an Android motorcycle app. Dark background with glowing download buttons. Prominently display a large 'Download MotorSignal APK (v1.0.2)' primary action card featuring Android robot icon, file size pill (221 MB), SHA-256 hash box with one-click copy button, and a large QR code for instant phone installation. Include secondary buttons for Google Play and iOS TestFlight waitlist. Beneath, add 3 numbered icon cards showing installation steps: 1. Download APK, 2. Allow Unknown Sources, 3. Pair Bluetooth/GPS and Ride."
|
||||
|
||||
---
|
||||
|
||||
### PAGE-WEB-05: Public Group Rides Discovery
|
||||
- **Route:** `GET /group-rides`
|
||||
- **Target Audience:** Riders looking for local pack rides, meetups, and weekend rallies.
|
||||
- **Bootstrap 5.3 Grid Structure:**
|
||||
- Search & Filter Toolbar (`card card-dark p-3 mb-4` with inputs for City/Zip, Radius, Pace filter, Terrain).
|
||||
- 2-Column Split View: Interactive Web Map on left (`col-lg-7`), Scrollable Ride Cards List on right (`col-lg-5`).
|
||||
- **Required UI Elements & Controls:**
|
||||
- **Search Bar & Filters:** Search input with location pin icon, radius dropdown (10, 25, 50, 100 miles), pace selector pills (`All`, `Cruiser Chill`, `Brisk Twisties`, `Track/Spirited`), date range picker.
|
||||
- **Host Ride CTA Button:** Header action button (`+ Create Pack Ride`).
|
||||
- **Interactive Map:** Dark tactical tile map with numbered cluster pins, route polyline previews on card hover, and user location marker.
|
||||
- **Ride Cards List:** Scrollable list with ride card elements:
|
||||
- Route thumbnail map.
|
||||
- Ride Title, Date, and Departure Time badge.
|
||||
- Meeting location with distance from user (*"12.4 miles away"*).
|
||||
- Pace badge with color code (Green = Chill, Yellow = Moderate, Red = Spirited).
|
||||
- Rider RSVP avatar stack with count (e.g. `+18 riders`).
|
||||
- Route metrics: Total mileage and estimated ride duration.
|
||||
- Action button: `Join Pack` (opens Join Modal) or `View Briefing`.
|
||||
- **Join Ride Modal:** Rider motorcycle confirmation, emergency contact check, agreement to pack safety rules, and `Confirm RSVP` button.
|
||||
- **Stitch Generation Prompt:**
|
||||
> "Design a modern Bootstrap 5.3 split-screen group ride discovery page. The left 60% contains a full-height dark tactical map displaying glowing route lines and circular ride staging pins. The right 40% contains a scrollable feed of upcoming pack rides. Top search bar features inputs for location radius, pace filter pills (Casual, Moderate, Spirited), and date picker. Each ride card features a route thumbnail, departure time pill badge, distance, host club crest, attendee avatar stack (+14 riders), and a bright cyan 'Join Pack' button."
|
||||
|
||||
---
|
||||
|
||||
### PAGE-WEB-06: Live Group Ride Telemetry Showcase
|
||||
- **Route:** `GET /group-rides/showcase`
|
||||
- **Target Audience:** Users testing or previewing real-time mesh pack radar technology.
|
||||
- **Bootstrap 5.3 Grid Structure:**
|
||||
- Full-viewport HUD canvas (`vh-100 position-relative`).
|
||||
- Floating Left HUD: Roster of live riders in pack with real-time speed, gap distance, and battery status.
|
||||
- Floating Right HUD: Lead bike telemetry stream (Lean angle, speed, brake G-force).
|
||||
- Floating Bottom HUD: Timeline scrubber and interactive simulation controls.
|
||||
- **Required UI Elements & Controls:**
|
||||
- **Fullscreen Radar Canvas:** Concentric radar range circles (100 ft, 500 ft, 0.5 mi) with directional compass rose and 6 moving motorcycle blips.
|
||||
- **Pack Roster Card (Floating Left):**
|
||||
- Road Captain Lead: Name, bike model, live speed (64 MPH), GPS status.
|
||||
- Pack riders: Staggered formation order, gap distance (+0.1 mi, +0.3 mi), telemetry sync quality pill.
|
||||
- Tail Gunner Sweep: Sweeper handle, rear hazard warning status.
|
||||
- **Lead Telemetry Card (Floating Right):**
|
||||
- Live 38° lean angle arc gauge.
|
||||
- Digital speed readout (64 MPH).
|
||||
- Lateral and braking G-force vector bubble.
|
||||
- **Simulation Control Dock (Floating Bottom):**
|
||||
- Play / Pause button.
|
||||
- Simulation speed multiplier pills (`1x`, `2x`, `5x`).
|
||||
- Interactive timeline scrubber bar.
|
||||
- `Trigger Emergency Hazard Ping` button simulating real-time pack alert broadcast.
|
||||
- **Stitch Generation Prompt:**
|
||||
> "Design a futuristic, full-screen live pack telemetry showcase using Bootstrap 5.3 and dark glassmorphic HUD overlays. Center is a dark tactical map showing 6 motorcycle riders in formation on a mountain pass with directional arrows. Floating translucent card on the top left lists the pack roster with rider handles, gap distance (+0.2 mi), and live speeds. Floating top right card displays the Road Captain's active telemetry: an animated 38-degree lean gauge and 64 MPH speedometer. Bottom control dock has Play/Pause, speed multiplier (1x, 2x, 5x), and an emergency ping test button."
|
||||
|
||||
---
|
||||
|
||||
### PAGE-WEB-07: Web Group Ride Organizer & Management
|
||||
- **Route:** `GET /group-rides/manage`
|
||||
- **Target Audience:** Group ride organizers, road captains, club leaders.
|
||||
- **Bootstrap 5.3 Grid Structure:**
|
||||
- Page header with 'Create New Ride' button (`d-flex justify-content-between align-items-center mb-4`).
|
||||
- Stats row (`row g-3 mb-4`: Total Rides Hosted, Active RSVPs, Safety Incident Rate 0.0%).
|
||||
- Tabbed interface (`nav nav-pills mb-3`: Upcoming, In-Progress, Completed, Drafts).
|
||||
- Data table / Card list of organized rides with action dropdowns (`Edit`, `Roster`, `GPX Export`, `Cancel`).
|
||||
- **Required UI Elements & Controls:**
|
||||
- **Top KPI Metric Cards:**
|
||||
- `Hosted Rides`: Total count with monthly trend.
|
||||
- `Active RSVPs`: Confirmed attendees across upcoming rides.
|
||||
- `Pack Safety Score`: 100% incident-free completion rate.
|
||||
- **Filter Tabs:** `Upcoming (4)`, `Live Now (1)`, `Completed (28)`, `Drafts (2)`.
|
||||
- **Rides Table / Card List:**
|
||||
- Columns: Date & Time, Ride Name, Start/Finish Points, Pace Badge, Capacity Meter (e.g. `24/30 riders`), Live Status (`Staging`, `En Route`, `Finished`), and Action Menu.
|
||||
- Action Menu items: `Edit Route`, `Manage Attendee Roster`, `Broadcast Pack Announcement`, `Export GPX Cue Sheet`, `Cancel Ride`.
|
||||
- **Create Ride Modal:** Form fields for Title, Staging Address, Meeting Time, Kickstands Up (KSU) Time, Route upload (GPX) or route selector, Maximum Riders limit, Pace selection, Radio / Mesh Channel ID.
|
||||
- **Attendee Management Drawer:** List of attendees with check-in checkbox, bike model, emergency contact phone, and assigned pack role dropdown (`Lead`, `Sweep`, `Mid-Pack`).
|
||||
- **Stitch Generation Prompt:**
|
||||
> "Design a comprehensive Bootstrap 5.3 organizer management dashboard for motorcycle group rides. Dark UI (#0D131F) with clean white and slate text. Top metrics display: 12 Upcoming Rides, 148 Confirmed Riders, 100% On-Time Starts. Below is a responsive table of scheduled pack rides featuring columns: Date & Time, Route Name, Meeting Point, Pace, Capacity Progress Bar (24/30), Status Badge (Staging, Live, Finished), and Quick Actions (View Roster, Edit Route, Broadcast Alert, Cancel). Include a prominent cyan 'Create Group Ride' button."
|
||||
|
||||
---
|
||||
|
||||
### PAGE-WEB-08: Motorcycle Clubs Directory
|
||||
- **Route:** `GET /clubs`
|
||||
- **Target Audience:** Riders seeking riding clubs, brand chapters (Ducati, Harley, BMW, Yamaha), and enthusiast groups.
|
||||
- **Bootstrap 5.3 Grid Structure:**
|
||||
- Featured Club Hero Carousel / Masthead (`container mb-5`).
|
||||
- Search & Category Filter Bar (`d-flex flex-wrap gap-2 mb-4`).
|
||||
- 3-Column Club Card Grid (`row row-cols-1 row-cols-md-3 g-4`).
|
||||
- **Required UI Elements & Controls:**
|
||||
- **Directory Header:** Search input with magnifying glass, Location filter dropdown, Riding Discipline pill filters (`All`, `Sportbike / Canyons`, `Adventure / Dual Sport`, `Cruiser / Touring`, `Track Enthusiasts`).
|
||||
- **Club Cards Grid (3 Columns):**
|
||||
- Club Crest / Patch Emblem (circular bordered badge).
|
||||
- Club Name and Chapter Location (e.g. *Pacific Coast Riders — Bay Area Chapter*).
|
||||
- Membership Badge (`Open to Public`, `Application Required`, `Invite Only`).
|
||||
- Member Count Pill (`48 Members`).
|
||||
- Riding Style Tags (e.g. `#Twisties`, `#Ducati`, `#WeekendTrips`).
|
||||
- Club Bio / Mission Statement excerpt.
|
||||
- Action Button: `View Club & Apply` or `Explore Chapter`.
|
||||
- **Register Your Club Banner:** Bottom banner with CTA button (`Register a New Club / Chapter`).
|
||||
- **Stitch Generation Prompt:**
|
||||
> "Create a stylish motorcycle club directory page in Bootstrap 5.3 dark mode. Top hero features a dark leather and carbon fiber texture banner with the text 'Find Your Pack'. Below is a search bar with tags for Riding Style (Cruiser, ADV, Track, Sportbike) and Region. Grid displays club profile cards: each card has a circular club crest/logo, club name, chapter city, active member counter badge, short bio, tags, and a 'View Club / Apply' button with a subtle hover glow."
|
||||
|
||||
---
|
||||
|
||||
### PAGE-WEB-09: Club Founder & Officer Hub
|
||||
- **Route:** `GET /clubs/manage`
|
||||
- **Target Audience:** Club presidents, vice presidents, and road captains.
|
||||
- **Bootstrap 5.3 Grid Structure:**
|
||||
- Club selector dropdown for officers managing multiple chapters.
|
||||
- Multi-card overview (`col-lg-4` pending applications, `col-lg-4` upcoming rides, `col-lg-4` club treasury/dues).
|
||||
- Recent club activity log stream.
|
||||
- **Required UI Elements & Controls:**
|
||||
- **Top Navigation Bar:** Club switcher dropdown, Officer Rank badge (`President`), Quick Create Ride button.
|
||||
- **Officer KPI Cards:**
|
||||
- `Pending Applications`: Count pill with `Review Now` shortcut.
|
||||
- `Upcoming Club Rides`: Count with next ride countdown (*"Saturday 9:00 AM"*).
|
||||
- `Active Roster`: Total verified members with active rider percentage.
|
||||
- **Attention Required Banner:** Highlighted warning cards for unassigned Road Captain roles or unsigned club safety waivers.
|
||||
- **Recent Club Activity Feed:** Timestamped stream of member join requests, ride completions, and rank promotions.
|
||||
- **Stitch Generation Prompt:**
|
||||
> "Design a Bootstrap 5.3 executive hub for motorcycle club officers. Dark tactical dashboard with gold and cyan accenting. Prominently display the club crest and chapter title at the top with a club switcher dropdown. Three large summary cards display: Pending Membership Applications (4 waiting), Upcoming Club Rides (2 this week), and Active Roster (38 members). Below is an attention-required alert banner for unsigned safety waivers and an activity feed showing member rank promotions and recent ride completions."
|
||||
|
||||
---
|
||||
|
||||
### PAGE-WEB-10 to PAGE-WEB-15: Club Management Suite
|
||||
- **Routes:**
|
||||
- `PAGE-WEB-10`: `GET /clubs/[clubId]/manage` — Club Founder Overview Dashboard
|
||||
- `PAGE-WEB-11`: `GET /clubs/[clubId]/manage/profile` — Club Identity & Branding Editor
|
||||
- `PAGE-WEB-12`: `GET /clubs/[clubId]/manage/applications` — Member Applications & Onboarding
|
||||
- `PAGE-WEB-13`: `GET /clubs/[clubId]/manage/ranks-roles` — Hierarchy & Roles Builder
|
||||
- `PAGE-WEB-14`: `GET /clubs/[clubId]/manage/rides` — Club Rides Schedule & Attendance
|
||||
- `PAGE-WEB-15`: `GET /clubs/[clubId]/manage/settings` — Club Privacy & Governance Settings
|
||||
- **Bootstrap 5.3 Grid Structure:**
|
||||
- Shared Sidebar Layout (`col-lg-3` sticky navigation sidebar with club masthead, `col-lg-9` dynamic content panel).
|
||||
- **Required UI Elements & Controls Across Suite:**
|
||||
- **Sticky Sidebar:** Club crest, Club Name, Chapter, Vertical Nav Pills (`Overview`, `Profile Branding`, `Applications [badge]`, `Ranks & Roles`, `Club Rides`, `Governance Settings`).
|
||||
- **Profile Branding (`WEB-11`):** Crest logo uploader, Cover banner image uploader, Club Name text input, Tagline input, Markdown Bio editor, Social links (Instagram, Discord, Website), Primary Riding Location input, `Save Changes` button.
|
||||
- **Applications Queue (`WEB-12`):** List of applicant cards showing applicant name, motorcycle model, riding experience, answers to custom club screening questions, one-click `Accept Member` (green) and `Decline` (red) buttons.
|
||||
- **Ranks & Roles Builder (`WEB-13`):** Visual hierarchy tree (President $\rightarrow$ Vice President $\rightarrow$ Road Captain $\rightarrow$ Tail Gunner $\rightarrow$ Full Member $\rightarrow$ Prospect). Permission toggles for each rank: `Schedule Official Rides`, `Broadcast Emergency Alerts`, `Approve Applications`, `Manage Treasury`. Member assignment dropdown.
|
||||
- **Club Rides (`WEB-14`):** Monthly calendar view, ride staging checklist, assigned Road Captain and Sweeper badges, attendee sign-in log, GPX route attachment.
|
||||
- **Governance Settings (`WEB-15`):** Privacy toggle (`Public Directory`, `Unlisted`, `Strictly Private`), Invite Code generator with copy button, Membership Dues configuration, `Transfer Ownership` form, and `Disband Club` red danger zone card.
|
||||
- **Stitch Generation Prompt:**
|
||||
> "Design a comprehensive Club Management Suite in Bootstrap 5.3 featuring a two-column layout. The left sidebar contains the club crest, chapter name, and vertical nav pills: Overview, Profile Branding, Applications (badge: 3), Ranks & Roles, Scheduled Rides, and Governance Settings. The main content panel shows the 'Ranks & Roles Builder': a structured hierarchy table with officer badges (President, Road Captain, Tail Gunner, Active Member), permission toggles, and member assignments. Use dark tactical slate (#0D131F) surfaces with cyan and purple status indicators."
|
||||
|
||||
---
|
||||
|
||||
### PAGE-WEB-16: Support Desk & Customer Portal
|
||||
- **Route:** `GET /support`
|
||||
- **Target Audience:** Riders needing technical help, reporting bugs, or querying documentation.
|
||||
- **Bootstrap 5.3 Grid Structure:**
|
||||
- Search Header with prominent search input for knowledge base (`col-lg-6 mx-auto py-5`).
|
||||
- 3 Category Cards (`row g-4 mb-5`: Hardware & GPS Setup, Road Alerts & Waze, Account & Pro Billing).
|
||||
- Submit Support Ticket Form Card (`col-lg-8 mx-auto`).
|
||||
- **Required UI Elements & Controls:**
|
||||
- **Knowledge Search Bar:** Large input with search icon, live suggestion dropdown.
|
||||
- **System Status Indicator:** Pulsing green badge (*"All MotorSignal Services Operational: Operations API, R2 Sync, Waze Alert Feeds"*).
|
||||
- **3 Quick Topic Cards:**
|
||||
- `Sensor Calibration & Mounting Orientation`.
|
||||
- `Waze Police Alerts & HERE Safety Cameras Setup`.
|
||||
- `Pro Subscription & Telemetry Cloud Sync`.
|
||||
- **Ticket Submission Form Card:**
|
||||
- Reporter Name & Email (auto-filled if authenticated).
|
||||
- Category selector dropdown (`Telemetry / GPS`, `Road Alerts`, `Billing`, `Bug Report`, `Feature Idea`).
|
||||
- Severity radio pills (`Low`, `Medium`, `High`, `Critical / App Crash`).
|
||||
- Subject input and detailed markdown description textarea.
|
||||
- File upload drag-and-drop zone for logs or screenshots.
|
||||
- `Submit Support Ticket` button.
|
||||
- **Stitch Generation Prompt:**
|
||||
> "Design a clean, reassuring customer support desk in Bootstrap 5.3 dark mode. Top section features a large centered search bar 'Search tutorials, GPS troubleshooting, and FAQs' above a green status badge 'All MotorSignal Systems Operational'. Three category cards provide instant links to Sensor Calibration, Road Alerts Guide, and Cloud Sync. Below is an elevated card for submitting a ticket with fields for Subject, Category, Severity (Low, Medium, Critical), and File Attachment drag-and-drop area."
|
||||
|
||||
---
|
||||
|
||||
### PAGE-WEB-17 & PAGE-WEB-18: Legal, Compliance & Privacy
|
||||
- **Routes:** `GET /privacy` & `GET /terms`
|
||||
- **Target Audience:** General public, legal counsel, regulatory authorities.
|
||||
- **Bootstrap 5.3 Grid Structure:**
|
||||
- 2-Column Documentation Layout: Left sticky table of contents (`col-lg-3`), Right reading container (`col-lg-9` formatted typography).
|
||||
- **Required UI Elements & Controls:**
|
||||
- **Table of Contents:** Sticky left list group with smooth-scrolling anchors to each document section.
|
||||
- **Last Updated Badge:** Pill showing document version and effective date.
|
||||
- **Jurisdictional Compliance Callouts:**
|
||||
- United States: Road alert legality and FCC conformity callout.
|
||||
- France: Compliance with "Zones de Danger" (suppressing fixed camera coordinates into safety zone corridors).
|
||||
- Germany & Switzerland: Automatic road alert deactivation notice per § 23 Abs. 1c StVO and Art. 57b SVG.
|
||||
- **Telemetry Anonymization Card:** Plain-language explanation of how 20 Hz IMU data is scrubbed of rider identity before aggregated research modeling.
|
||||
- **Data Rights Request Form:** Download My Data button and Request Full Account Deletion button.
|
||||
- **Stitch Generation Prompt:**
|
||||
> "Create a polished, highly legible legal document page in Bootstrap 5.3. Dark slate background with high-contrast text. Left column features a sticky table of contents with smooth-scrolling links. Right column displays the Privacy Policy with highlighted callout banners (alerts) detailing 20 Hz Telemetry Anonymization, SQLite local storage encryption, and Cloudflare R2 privacy standards."
|
||||
|
||||
---
|
||||
|
||||
### PAGE-WEB-19 to PAGE-WEB-22: Authentication & Onboarding
|
||||
- **Routes:**
|
||||
- `PAGE-WEB-19`: `GET /login` — Rider Sign-In
|
||||
- `PAGE-WEB-20`: `GET /register` — Rider Account Registration
|
||||
- `PAGE-WEB-21`: `GET /forgot-password` — Password Reset Request
|
||||
- `PAGE-WEB-22`: `GET /verify-email` — Email Verification Challenge
|
||||
- **Bootstrap 5.3 Grid Structure:**
|
||||
- Centered Auth Box (`col-md-6 col-lg-5 col-xl-4 mx-auto my-5`).
|
||||
- **Required UI Elements & Controls Across Flow:**
|
||||
- **Brand Header:** Glowing cyan MotorSignal logo, tagline.
|
||||
- **Login (`WEB-19`):** Email floating label input, Password floating input with eye icon toggle, `Remember Me` checkbox, `Forgot Password?` link, `Sign In` button, Google Sign-In button, Apple Sign-In button, `Create Account` link.
|
||||
- **Register (`WEB-20`):** Full Name, Email, Password with live strength meter, Motorcycle Make & Model selection dropdown, Riding Style radio pills, Terms acceptance checkbox, `Create Rider Account` button.
|
||||
- **Forgot Password (`WEB-21`):** Email input, `Send Password Reset Link` button, Back to Sign In button.
|
||||
- **Verify Email (`WEB-22`):** 6-box segmented numeric OTP input with auto-advance, Resend code countdown timer (`Resend in 45s`), `Verify & Continue` button.
|
||||
- **Stitch Generation Prompt:**
|
||||
> "Design a sleek, modern Bootstrap 5.3 authentication screen for MotorSignal. Deep black canvas with a glowing cyan brand logo at the top. The card has a subtle glassmorphic border with floating form inputs for Email and Password, a 'Remember this device' toggle, and an electric cyan 'Sign In' button. Include a divider 'Or continue with' and full-width buttons for Google and Apple sign-in. Bottom links for 'Forgot password?' and 'Create an account'."
|
||||
|
||||
---
|
||||
|
||||
### PAGE-WEB-23: Rider Cloud Portal (My Account & Rides)
|
||||
- **Route:** `GET /account`
|
||||
- **Target Audience:** Authenticated riders reviewing their synced cloud data and bike garage.
|
||||
- **Bootstrap 5.3 Grid Structure:**
|
||||
- Top Profile Masthead: Rider avatar, total lifetime miles, max recorded lean angle, member tier badge.
|
||||
- Tabbed Content: Synced Cloud Rides, Virtual Garage, Subscription & Billing, Privacy & Export.
|
||||
- Responsive Ride Cards list with map thumbnails and download buttons (GPX, CSV).
|
||||
- **Required UI Elements & Controls:**
|
||||
- **Rider Masthead:** Profile avatar with edit badge, Rider handle (`@ApexHunter`), Membership pill (`PRO RIDER`), lifetime stat counters (`4,820 Total Miles`, `52° Peak Lean`, `14 Group Rides`).
|
||||
- **Tab 1: Cloud Rides:** Search and date filter bar. Card list of rides showing interactive elevation/speed thumbnail, motorcycle badge, distance, duration, top speed, and `Download GPX` / `Download CSV` buttons.
|
||||
- **Tab 2: Virtual Garage:** Bike stable cards displaying motorcycle photo, odometer, active bike badge, and `+ Add Motorcycle` modal button.
|
||||
- **Tab 3: Subscription & Billing:** Current plan card, renewal date, payment method card, `Upgrade to Lifetime Founder` button, `Cancel Subscription` button.
|
||||
- **Tab 4: Security & Export:** Change password form, 2-Factor Authentication toggle, `Export All Telemetry (ZIP)` button, `Delete Account` danger zone.
|
||||
- **Stitch Generation Prompt:**
|
||||
> "Design a modern Bootstrap 5.3 Rider Cloud Portal. Dark cockpit theme. Top masthead displays the rider's helmet avatar, handle '@ApexHunter', Pro Rider badge, and quick stats: 4,820 Miles, 51-degree Max Lean, 14 Group Rides. Below is a tabbed panel: 'My Cloud Rides' shows cards of recorded rides with elevation and speed profiles, date, duration, and GPX download buttons; 'My Garage' displays bike cards with odometer and maintenance alerts; 'Subscription' shows active Pro plan with card details."
|
||||
|
||||
---
|
||||
|
||||
### PAGE-WEB-24: Operations & Admin Console (8-Tab Command Suite)
|
||||
- **Route:** `GET /admin`
|
||||
- **Target Audience:** Internal staff, system operators, site reliability engineers.
|
||||
- **Bootstrap 5.3 Grid Structure:**
|
||||
- Full-width Operations Shell with persistent top bar (System status, active operators, server ping) and sticky left sidebar (8 tabs).
|
||||
- Main display container (`col-lg-10 p-4`).
|
||||
- **Required UI Elements & Controls by Tab:**
|
||||
- **Top Navigation Bar:** Host IP badge (`89.31.239.10`), Server Status (`Production OK`), Ping latency (`18ms`), Logged-in Operator handle, Sign Out button.
|
||||
- **Sidebar:** 8 Nav Pills with status indicator dots: `Overview`, `Infrastructure`, `Users`, `Incidents`, `Audit Trail`, `Support`, `Website CMS`, `Ops Controls`.
|
||||
- **Tab 1: Overview:**
|
||||
- `Operations API Card`: Healthy/Degraded badge, last successful upload timestamp, 24h upload error counter.
|
||||
- `Operations Database Card`: Connected badge, 18ms latency, Drift Schema 7 verified.
|
||||
- `Operations Access Card`: Healthy badge, permission enforcement verified, 24h auth failures.
|
||||
- `Audit Logging Card`: Write status, 24h failed writes count.
|
||||
- `Security & Access Events Card`: 1h/24h/7d filter pills, event table (Time, Event, IP, Outcome).
|
||||
- `Active Incidents Card`: Triage table (Case, Incident, Severity [Critical/High], Assigned Operator, Age).
|
||||
- `Website Activity Card`: Active riders counter, 24h sign-ins, new accounts.
|
||||
- **Tab 2: Infrastructure:**
|
||||
- Live Dials for CPU Utilization (14%), RAM (3.2 / 8 GB), Disk Space (42% used).
|
||||
- Systemd Service Status Table: `motorsignal-website` (active, running), `motorsignal-api` (active, running), `caddy` (active, running) with Restart action buttons.
|
||||
- Speedtest Module: Toggle between `Client to MotorSignal Server` and `MotorSignal Server to External Upstream` with real-time ping, download, and upload Mbps gauges.
|
||||
- Live Log Viewer: Collapsible black console box running live journalctl output with auto-scroll.
|
||||
- **Tab 3: User Management:** Search bar by email or user ID, role filter dropdown, user table (ID, Email, Registered Date, Status, Role, Pro Entitlement), action menu (`Suspend Account`, `Grant Pro`, `Reset Password`).
|
||||
- **Tab 4: Incidents & Alerts:** Incident triage queue, severity badges (Critical red, High amber), `Assign to Me` button, Incident detail modal with resolution notes and postmortem log.
|
||||
- **Tab 5: Audit Trail:** Searchable administrative actions log table, timestamp, operator email, action name, before/after JSON diff viewer.
|
||||
- **Tab 6: Support Tickets:** Inbound ticket queue, filter by status (Open, Pending, Resolved), ticket response composer with auto-filled staff email, close ticket button.
|
||||
- **Tab 7: Website CMS:** Document selector (Terms, Privacy, Features, Announcements), Markdown code editor, split live preview, Save Draft button, Publish Live button, Revision history rollback.
|
||||
- **Tab 8: Ops Controls:** Capability allowlist checkboxes, dry-run deployment simulator, maintenance mode toggle.
|
||||
- **Stitch Generation Prompt:**
|
||||
> "Design an enterprise Operations Command Console in Bootstrap 5.3 dark mode (#070A0F) for MotorSignal staff. Left dark sidebar contains glowing status indicators and nav links for: Overview, Infrastructure, Users, Incidents (badge: 2), Audit Trail, Support, CMS, and Ops Controls. The Overview view displays high-density telemetry cards: 'Operations API' (Healthy, 0 backlog), 'Database' (18ms latency, Drift Schema 7), 'Security Events' (Access denials graph), and an 'Active Incidents' table with priority badges (Critical in red, High in amber). Top bar features live host metrics (CPU 14%, RAM 38%, 89.31.239.10) and user avatar."
|
||||
|
||||
---
|
||||
|
||||
# PART II: MOBILE APP SCREENS (32 Screens)
|
||||
|
||||
---
|
||||
|
||||
### SCREEN-MOB-01: Dashboard — Minimal Cockpit HUD
|
||||
- **Screen ID / Route:** `DASH-01` (`/` Minimal Mode)
|
||||
- **Target Context:** Track days, night rides, extreme sunlight glare where only critical speed and alerts matter.
|
||||
- **Bootstrap Mobile Grid / Layout:**
|
||||
- Full-height dark canvas (`vh-100 bg-black text-center d-flex flex-column justify-content-between p-3`).
|
||||
- **Required UI Elements & Controls:**
|
||||
- **Top Status Bar:** Cockpit layout selector button, GPS status pill (`GPS 2D FIX`), Ambient temperature (`79° F`), Standby indicator (`● STANDBY`).
|
||||
- **Giant Digital Speed Readout:** 96pt digital speed number (`0`), unit label (`MPH` or `KM/H`), monospace high-contrast styling.
|
||||
- **Trip Distance & Time:** Minimal trip odometer pill (`0.00 MI`) and elapsed session timer (`00:00:00`).
|
||||
- **Primary Action Button:** Large full-width `Start Session` pill button (`btn btn-primary btn-lg py-3`).
|
||||
- **Bottom Navigation Bar:** 6-icon touch dock: `Dash` (active), `Map`, `Activity`, `Garage`, `Social`, `Settings`.
|
||||
- **Stitch Generation Prompt:**
|
||||
> "Design an ultra-clean, high-contrast mobile dashboard HUD in Bootstrap 5.3 mobile portrait mode (375x812). Pitch-black background (#000000). Center features an immense 96pt digital speedometer '0 MPH' in crisp white monospace font with subtle cyan glow. Top status row displays minimal pill indicators: 'GPS 2D FIX', '79 F', and a green 'STANDBY' dot. Bottom row has trip odometer '0.00 MI' and a prominent dark blue 'Start Session' action button."
|
||||
|
||||
---
|
||||
|
||||
### SCREEN-MOB-02: Dashboard — Sport Cockpit HUD
|
||||
- **Screen ID / Route:** `DASH-02` (`/` Sport Mode)
|
||||
- **Target Context:** Canyon carving, twisties, track sessions where lean angle and lateral G-forces are paramount.
|
||||
- **Bootstrap Mobile Grid / Layout:**
|
||||
- Multi-gauge grid (`container-fluid px-2 py-3`).
|
||||
- **Required UI Elements & Controls:**
|
||||
- **Top Bar:** Cockpit layout switcher icon, audio mode toggle (Tactical Tone vs Voice), GPS fix badge (`GPS 2D FIX`), Ambient temp, Recording state pill.
|
||||
- **Speedometer:** Central large speed counter (`0 MPH`).
|
||||
- **G-Force Radar Friction Circle (Left Gauge):** Concentric circles representing 0.5G and 1.0G limits, live moving blue G-force dot, Acceleration and Braking G readouts below.
|
||||
- **Motorcycle Lean Angle Gauge (Right Gauge):** Animated motorcycle silhouette banking dynamically, numerical degrees readout (`3° RIGHT`), peak memory markers (`MAX L 0°`, `MAX R 0°`).
|
||||
- **Trip Statistics Card:** 3 columns: `Trip (0.00 MI)`, `Top Speed (0 MPH)`, `Avg Speed (0.0 MPH)`.
|
||||
- **Start Session Action Button:** Large rounded button (`▶ Start Session`).
|
||||
- **Performance Launch Shortcut Card:** Lightning bolt icon, title (`PERFORMANCE LAUNCH`), subtitle (`0–60 MPH • 0–100 MPH`), `READY >` status badge.
|
||||
- **Persistent Bottom Navigation Bar:** Dash, Map, Activity, Garage, Social, Settings.
|
||||
- **Stitch Generation Prompt:**
|
||||
> "Design an aggressive, sporty motorcycle cockpit screen in Bootstrap 5.3 mobile layout. Deep black canvas with glowing electric cyan accents. Top displays speed '0 MPH'. Center section features two round telemetry gauges side-by-side: on the left, a G-Force radar friction circle with a glowing blue dot at center; on the right, an animated motorcycle icon banked at 3 degrees right with '3 DEG RIGHT' in blue and peak memory markers 'MAX L 0 / MAX R 0'. Below is a trip stats card, followed by a dark card with a lightning bolt icon: 'PERFORMANCE LAUNCH (0-60 MPH / 0-100 MPH) READY'. Bottom features a massive rounded 'Start Session' button and 6-icon bottom nav bar (Dash, Map, Activity, Garage, Social, Settings)."
|
||||
|
||||
---
|
||||
|
||||
### SCREEN-MOB-03: Dashboard — Touring Cockpit HUD
|
||||
- **Screen ID / Route:** `DASH-03` (`/` Touring Mode)
|
||||
- **Target Context:** Long-distance highway tours, cross-country ADV rallies.
|
||||
- **Bootstrap Mobile Grid / Layout:**
|
||||
- High-density information cluster (`container-fluid p-3`).
|
||||
- **Required UI Elements & Controls:**
|
||||
- **Top Cluster:** Digital Speed (`68 MPH`), Digital Compass heading (`NW 315°`), Current Altitude (`3,420 FT`).
|
||||
- **Road Alert Ticker Strip:** Live alert banner (*"Waze: Police trap reported 2.4 mi ahead on US-101"*).
|
||||
- **Touring Cards Grid (4 Tiles):**
|
||||
- `Trip A Odometer`: Distance and duration.
|
||||
- `Fuel / Range Estimator`: Estimated miles remaining.
|
||||
- `Sunset & ETA`: Time to next waypoint and sunset countdown.
|
||||
- `Weather Tile`: Current precipitation chance and wind speed.
|
||||
- **Start Session / Recording Controller.**
|
||||
- **Stitch Generation Prompt:**
|
||||
> "Design a touring-focused motorcycle dashboard screen in Bootstrap 5.3 mobile view. Dark background with organized navigation tiles. Top shows speed '68 MPH' alongside a digital compass heading 'NW 315' and elevation '3,420 FT'. Below is a horizontal strip showing the nearest Waze police alert 'Police reported 2.4 mi ahead on US-101'. Bottom section contains large odometer cards: 'Trip A: 142.6 MI', 'Fuel Range: 84 MI', 'Ride Time: 2h 15m', and an emergency weather alert pill."
|
||||
|
||||
---
|
||||
|
||||
### SCREEN-MOB-04: Active Ride Recording HUD
|
||||
- **Screen ID / Route:** `DASH-04` (State: `Recording`)
|
||||
- **Target Context:** Rider is actively moving; screen requires locked layout, anti-glare, and clear recording indicator.
|
||||
- **Bootstrap Mobile Grid / Layout:**
|
||||
- Pulsing red/green recording badge (`badge bg-danger-subtle text-danger border border-danger`).
|
||||
- **Required UI Elements & Controls:**
|
||||
- **Live Recording Header:** Pulsing red dot with text (`REC 20Hz - 01:24:18`).
|
||||
- **Real-Time Speed & Lean:** Large speed readout updating smoothly, dynamic lean angle indicator.
|
||||
- **Kickstand Safety Warning Indicator:** Flashes yellow if kickstand sensor triggers while moving.
|
||||
- **Slide-to-Stop Controller:** Horizontal slide gesture track preventing accidental pocket taps to end ride.
|
||||
- **Quick Hazard Drop Button:** Glove-friendly button to mark a road hazard or police trap for the pack.
|
||||
- **Stitch Generation Prompt:**
|
||||
> "Design an active recording state motorcycle HUD screen in Bootstrap 5.3 mobile view. A prominent pulsing red pill at top says 'REC 20Hz - 00:42:15'. Speed displays '74 MPH'. The lean angle gauge shows dynamic bank angle '38 DEG LEFT' with yellow peak indicators. Lateral G-meter shows 0.85G. At the bottom, a slide-to-stop control prevents accidental pocket touches, along with a secondary 'Mark Waypoint / Hazard' glove-friendly button."
|
||||
|
||||
---
|
||||
|
||||
### SCREEN-MOB-05 & SCREEN-MOB-06: Tactical Map & Layer Switcher
|
||||
- **Screen ID / Route:** `MAP-01` (`/map`) & `MAP-02` (Layer Drawer)
|
||||
- **Target Context:** Offline GPS navigation, trail riding, satellite terrain inspection.
|
||||
- **Bootstrap Mobile Grid / Layout:**
|
||||
- Full-screen interactive dark map canvas with floating control overlays.
|
||||
- **Required UI Elements & Controls:**
|
||||
- **Top Floating Search Card:** Address autocomplete input, destination search, recent places chips.
|
||||
- **Right Vertical HUD Controls:**
|
||||
- Compass Orient button (Toggle between North-up and Heading-up).
|
||||
- Map Layers button (opens Layer Drawer).
|
||||
- Re-Center on Rider GPS location button.
|
||||
- Zoom In (+) and Zoom Out (-) buttons.
|
||||
- **Bottom Layer Switcher Drawer (`MAP-02`):**
|
||||
- `Tactical Vector`: High-contrast dark vector map with highlighted twisty routes.
|
||||
- `Satellite 4K`: Esri World Imagery high-resolution raster tiles.
|
||||
- `Elevation 3D`: OpenTopoMap contour lines and mountain shading.
|
||||
- Toggles for `Police Traps Overlay`, `Group Ride Pack Blips`, and `Offline Cached Only`.
|
||||
- **Stitch Generation Prompt:**
|
||||
> "Design a tactical motorcycle GPS map screen in Bootstrap 5.3 mobile portrait. The screen is filled with a high-contrast dark vector map with highlighted twisty mountain roads in cyan. Floating top search card allows destination entry. Floating right vertical pill dock has glowing icon buttons for Compass Orient, Re-center Rider, and Map Layers. An open bottom sheet drawer reveals 3 selectable map styles with thumbnail previews: 'Tactical Dark' (selected with cyan border), 'Satellite 4K', and '3D Topo Elevation'."
|
||||
|
||||
---
|
||||
|
||||
### SCREEN-MOB-07: Road Alert & Police Radar Overlay
|
||||
- **Screen ID / Route:** `ALERT-01` (`/map` or Dashboard Alert State)
|
||||
- **Target Context:** Approaching mobile police speed trap, hidden camera, or hazard.
|
||||
- **Bootstrap Mobile Grid / Layout:**
|
||||
- High-urgency alert banner pinned below top bar (`card border-danger bg-danger-subtle text-white p-3`).
|
||||
- **Required UI Elements & Controls:**
|
||||
- **Urgent Alert Banner:** High-contrast red/amber card pinned across top third of screen.
|
||||
- **Alert Icon:** Flashing police badge icon (or camera icon).
|
||||
- **Alert Description:** Subtype-aware message (*"Hidden police speed trap reported on 2nd Ave"*).
|
||||
- **Distance Countdown Meter:** Real-time distance update (*"350 meters ahead"*).
|
||||
- **Reliability & Thumbs Up Counter:** e.g. `14 Confirmations (Waze)`.
|
||||
- **Glove-Friendly Actions:** Large `Mute Audio Tone` button and `Dismiss Alert` button.
|
||||
- **Stitch Generation Prompt:**
|
||||
> "Design an urgent road alert overlay on a motorcycle dashboard in Bootstrap 5.3 mobile view. Across the top third is an intense, high-visibility dark red banner with a flashing red police badge icon. Bold text reads: 'POLICE TRAP AHEAD - 350 METERS' with subtext 'Hidden radar reported on Skyline Blvd (18 confirmations)'. A large right-aligned button allows 1-tap glove dismissal 'Mute Tone'. The rest of the dashboard dims slightly to highlight the warning."
|
||||
|
||||
---
|
||||
|
||||
### SCREEN-MOB-08 & SCREEN-MOB-09: Performance Launch Mode & Run Analysis
|
||||
- **Screen ID / Route:** `PERF-01` (`/launch`) & `PERF-02` (`/launch/history`)
|
||||
- **Target Context:** Closed-course 0-60 MPH, 0-100 MPH, and 1/4 mile acceleration timing.
|
||||
- **Bootstrap Mobile Grid / Layout:**
|
||||
- Draggy-style staging interface.
|
||||
- **Required UI Elements & Controls:**
|
||||
- **Pre-Launch Staging Indicators:**
|
||||
- GPS Accuracy Pill: Must be $< \pm 2.0$ ft (`GPS FIX: ±1.2 FT OK`).
|
||||
- Slope Validation Pill: Must be within legal $\pm 1.0\%$ grade (`SLOPE: -0.3% VALID`).
|
||||
- Staging Status: `STOPPED - ACCELERATE TO TRIGGER LAUNCH`.
|
||||
- **Split Timing Tiles:**
|
||||
- `0–60 MPH`: Current run time, personal record badge.
|
||||
- `0–100 MPH`: Current run time.
|
||||
- `1/4 Mile`: Elapsed time and trap speed (e.g. `10.84s @ 132 MPH`).
|
||||
- `60–130 MPH`: Rolling acceleration timer.
|
||||
- **Run Telemetry Analysis (`PERF-02`):**
|
||||
- High-density chart showing Speed vs Time curve.
|
||||
- Secondary overlay showing Longitudinal Acceleration G-Force trace.
|
||||
- Density Altitude (DA) readout based on barometric pressure and temperature.
|
||||
- **Stitch Generation Prompt:**
|
||||
> "Design a Draggy-style performance launch mode screen in Bootstrap 5.3 mobile portrait. Pitch dark background. Top pill indicates 'GPS FIX: +/- 1.4 FT | SLOPE: -0.2% VALID'. Center features a large green glowing status 'READY TO LAUNCH - ACCELERATE TO TRIGGER'. Below are 3 high-contrast timing tiles: '0-60 MPH: 3.28s' with a gold trophy icon, '0-100 MPH: 7.41s', and '1/4 MILE: 10.92s @ 131 MPH'. A toggle button switches to the telemetry graph showing acceleration G-force curve."
|
||||
|
||||
---
|
||||
|
||||
### SCREEN-MOB-10 & SCREEN-MOB-11: Activity History & Personal Records
|
||||
- **Screen ID / Route:** `ACT-01` (`/activity?tab=rides`) & `ACT-02` (`/activity?tab=records`)
|
||||
- **Target Context:** Reviewing past motorcycle rides and personal best records.
|
||||
- **Bootstrap Mobile Grid / Layout:**
|
||||
- Top Segmented Pill Selector (`nav nav-pills nav-fill bg-dark p-1 rounded-pill mb-3`: 'Rides' vs 'Records').
|
||||
- **Required UI Elements & Controls:**
|
||||
- **Segmented Tab Switcher:** `Rides (48)` vs `Personal Records`.
|
||||
- **Rides Feed (`ACT-01`):**
|
||||
- Ride card with dark route thumbnail image.
|
||||
- Title (*"Saturday Morning Canyon Carve"*), Date, and Start Time.
|
||||
- Motorcycle used badge (*"Yamaha MT-09"*).
|
||||
- Key metrics chips: Distance (`84.2 MI`), Duration (`1h 42m`), Max Lean (`49°`), Top Speed (`88 MPH`).
|
||||
- Cloud Sync Badge (Green checkmark = Synced to R2/Firestore; Blue clock = Queued in local outbox).
|
||||
- **Personal Records View (`ACT-02`):**
|
||||
- Trophy cards for: Best 0-60 MPH, Maximum Left Lean ($54^\circ$), Maximum Right Lean ($53^\circ$), Highest Elevation Peak, Longest Single Ride Distance.
|
||||
- **Stitch Generation Prompt:**
|
||||
> "Design an activity history screen in Bootstrap 5.3 mobile view. Top has a rounded pill tab switcher with 'Rides (48)' and 'Records (Trophies)'. The active 'Rides' view lists cards: each card has a dark route preview thumbnail on the left, date 'Saturday Morning Blast', motorcycle badge 'Yamaha MT-09', and stats pills: '84.2 MI', '1h 42m', 'Max Lean: 49 deg', and a green cloud sync checkmark. Tapping switches to the Records view with gold and bronze trophy cards for All-Time Top Speed and Maximum Lean Angle."
|
||||
|
||||
---
|
||||
|
||||
### SCREEN-MOB-12 & SCREEN-MOB-13: Forensic Ride Detail & Interactive Replay
|
||||
- **Screen ID / Route:** `HIST-01` (`/history/:id`) & `REPLAY-01` (`/replay/:id`)
|
||||
- **Target Context:** Deep post-ride cornering analysis, telemetry playback, forensic export.
|
||||
- **Bootstrap Mobile Grid / Layout:**
|
||||
- Split view: Map on top half (`h-50`), Telemetry playback controls on bottom half (`h-50`).
|
||||
- **Required UI Elements & Controls:**
|
||||
- **Interactive Route Heatmap:** Route line color-coded by lean angle or speed (Cyan = upright, Yellow = moderate lean, Red = severe apex $> 45^\circ$).
|
||||
- **Interactive Telemetry Scrubber Bar:** Draggable playback slider moving synchronized dot along the map route.
|
||||
- **Synchronous Telemetry Readout:** Displays exact speed, lean angle, G-force, and elevation at the scrubber point.
|
||||
- **Corner-by-Corner Breakdown Table:** Lists each numbered corner with entry speed, apex lean angle, and exit speed.
|
||||
- **Export Action Buttons:** `Export GPX`, `Export CSV (20 Hz)`, `Export Forensic JSON`.
|
||||
- **Stitch Generation Prompt:**
|
||||
> "Design a post-ride forensic telemetry analysis screen in Bootstrap 5.3 mobile view. Top half displays an interactive map of the completed mountain pass with the route color-coded by lean angle (yellow for straight, cyan for 30 deg, red for 50 deg apex). Bottom half features a scrubbing playhead with Play/Pause buttons and live telemetry readout at that exact scrub point: '48 MPH | 46 DEG RIGHT LEAN | 0.82 LATERAL G'. Action bar at bottom has buttons: 'Export GPX' and 'Share to Social'."
|
||||
|
||||
---
|
||||
|
||||
### SCREEN-MOB-14 to SCREEN-MOB-16: Virtual Garage & Maintenance
|
||||
- **Screen ID / Route:** `GAR-01` (`/garage`), `GAR-02` (`/garage/add`), `GAR-03` (`/garage/:id`)
|
||||
- **Target Context:** Tracking motorcycle stable, tire wear, oil changes, chain service.
|
||||
- **Bootstrap Mobile Grid / Layout:**
|
||||
- Motorcycle card stack with maintenance alert badges.
|
||||
- **Required UI Elements & Controls:**
|
||||
- **Garage Hub (`GAR-01`):** Motorcycle cards showing bike photo, Make/Model, current odometer, active bike toggle badge, `+ Add Bike` button.
|
||||
- **Add Motorcycle (`GAR-02`):** Year, Make, Model text inputs, VIN scanner button, Tire size selector, Initial odometer, Photo upload button, `Save Motorcycle` button.
|
||||
- **Bike Detail & Service (`GAR-03`):**
|
||||
- Full bike specs card.
|
||||
- Maintenance alert pills: `Engine Oil (Due in 380 mi)`, `Chain Service (OK)`, `Brake Fluid (Good)`.
|
||||
- Service log history with `+ Log New Service` button.
|
||||
- **Stitch Generation Prompt:**
|
||||
> "Design a virtual garage screen in Bootstrap 5.3 mobile portrait. Top displays a photo card of a 2024 BMW S1000RR with a green 'ACTIVE BIKE' badge and odometer '6,420 MI'. Below are health monitor cards: 'Chain Maintenance: OK', 'Engine Oil: Due in 380 MI' (amber alert), and 'Tires: Pirelli Diablo Supercorsa (Front 2.3 bar, Rear 2.5 bar)'. Floating action button at bottom right allows 'Add New Motorcycle' or 'Log Service'."
|
||||
|
||||
---
|
||||
|
||||
### SCREEN-MOB-17 & SCREEN-MOB-18: Route Planner & Curvy Road Generator
|
||||
- **Screen ID / Route:** `ROUT-01` (`/routes/planner`) & `ROUT-02` (`/routes/:id`)
|
||||
- **Target Context:** Planning scenic twisty routes avoiding highways.
|
||||
- **Bootstrap Mobile Grid / Layout:**
|
||||
- Interactive map with bottom route configuration drawer.
|
||||
- **Required UI Elements & Controls:**
|
||||
- **Waypoint Inputs:** Start location, Waypoints (+ button), Destination address.
|
||||
- **Curviness / Twistiness Slider:** 3 settings (`Standard`, `Scenic Curvy`, `Extreme Mountain Passes`).
|
||||
- **Elevation Gain Profile:** Line chart showing climbs and descents.
|
||||
- **Route Summary Card:** Total distance (mi), estimated duration, curve count (e.g. `142 Corners`).
|
||||
- **Action Buttons:** `Save Route`, `Export to Pack Ride`, `Start Turn-by-Turn Navigation`.
|
||||
- **Stitch Generation Prompt:**
|
||||
> "Design a motorcycle route planner in Bootstrap 5.3 mobile view. Map background with waypoint pins (A, B, C). Bottom overlay card features start and destination inputs, a 'Curviness Priority' slider set to 'Maximum Twisties', and an elevation cross-section graph showing mountain climbs. A bright cyan button says 'Calculate Curvy Route (64 Mi, 142 Curves)'."
|
||||
|
||||
---
|
||||
|
||||
### SCREEN-MOB-19 to SCREEN-MOB-21: Social Feed, Profile & Friends
|
||||
- **Screen ID / Route:** `SOC-01` (`/social`), `SOC-02` (`/social/profile`), `SOC-03` (`/social/friends`)
|
||||
- **Target Context:** Sharing rides, viewing community feed, tracking friends on rides.
|
||||
- **Bootstrap Mobile Grid / Layout:**
|
||||
- Card feed layout with social interaction buttons.
|
||||
- **Required UI Elements & Controls:**
|
||||
- **Social Feed (`SOC-01`):** Feed cards displaying friend's ride title, route map snapshot, scenic photo, stats strip (Distance, Duration, Max Lean), Fist Bump (Like) counter button, Comment button.
|
||||
- **Rider Profile (`SOC-02`):** Rider avatar, handle, bio, trophy case (Badges earned), motorcycle stable showcase, follower/following counts, `Follow` / `Message` button.
|
||||
- **Friends List (`SOC-03`):** Search riders input, pending friend requests list, active friends list with mutual ride count and `Invite to Pack Ride` action.
|
||||
- **Stitch Generation Prompt:**
|
||||
> "Design a community social feed screen in Bootstrap 5.3 mobile view for motorcycle enthusiasts. Feed consists of dark cards showing friends' ride summaries: card header has rider avatar and handle 'Marcus @DucatiApex', route title 'Sunday Mulholland Run', an embedded dark map preview showing the route, stats strip (54 mi, 1h 12m, 52 deg max lean), a photo of the bike at the lookout, and interaction buttons for 'Give Fist Bump (34)' and 'Download GPX'."
|
||||
|
||||
---
|
||||
|
||||
### SCREEN-MOB-22 to SCREEN-MOB-24: Motorcycle Clubs Suite
|
||||
- **Screen ID / Route:** `CLUB-01` (`/social/clubs`), `CLUB-02` (`/social/clubs/create`), `CLUB-03` (`/social/clubs/:id`)
|
||||
- **Target Context:** Club memberships, official club wall, member ranks.
|
||||
- **Bootstrap Mobile Grid / Layout:**
|
||||
- Club discovery feed and club home screen.
|
||||
- **Required UI Elements & Controls:**
|
||||
- **Clubs Hub (`CLUB-01`):** Search bar, riding discipline pills, club cards with crest and member counts, `+ Create Club` button.
|
||||
- **Create Club (`CLUB-02`):** Club Name input, Patch/Crest logo upload, Chapter location, Privacy rules (Public / Application Only), Membership questions, Submit button.
|
||||
- **Club Detail (`CLUB-03`):**
|
||||
- Club crest header, member count, privacy badge.
|
||||
- Tab 1: Club Wall (pinned ride announcements, discussions).
|
||||
- Tab 2: Roster (member list with rank badges: President, Road Captain, Tail Gunner, Member).
|
||||
- Tab 3: Official Club Rides.
|
||||
- **Stitch Generation Prompt:**
|
||||
> "Design a motorcycle club home screen in Bootstrap 5.3 mobile view. Top header features a bold club emblem 'Pacific Coast Riders MC' over a carbon fiber background. Horizontal pills show Member Count (42), Chapter (Bay Area), and Privacy (Application Only). Below are two tabs: 'Club Wall' with pinned announcements for the Saturday morning ride, and 'Roster' displaying members with rank badges (Road Captain, Tail Gunner, Veteran)."
|
||||
|
||||
---
|
||||
|
||||
### SCREEN-MOB-25 to SCREEN-MOB-28: Group Rides & Live Pack Radar
|
||||
- **Screen ID / Route:** `GRP-01` (`/group-rides`), `GRP-02` (`/group-rides/create`), `GRP-03` (`/group-rides/:id`), `GRP-04` (`/group-rides/:id/live`)
|
||||
- **Target Context:** Staging, joining, and riding inside an active motorcycle pack with live mesh radar.
|
||||
- **Bootstrap Mobile Grid / Layout:**
|
||||
- Full-screen tactical radar mode.
|
||||
- **Required UI Elements & Controls:**
|
||||
- **Group Rides Hub (`GRP-01`):** Active pack rides list, `Enter Join Code` box, `Host Pack Ride` button.
|
||||
- **Create Group Ride (`GRP-02`):** Title, Staging point, Departure time, Route selector, Pace rules, Maximum rider limit.
|
||||
- **Ride Briefing (`GRP-03`):** Staging checklist, attendee roster, weather forecast, route overview map, `Check In` button.
|
||||
- **Live Pack Radar (`GRP-04`):**
|
||||
- Concentric proximity radar circles (100 ft, 500 ft, 0.5 mi).
|
||||
- Moving rider dots with custom role markers (Star = Road Captain Lead, Shield = Tail Gunner Sweep, Circle = Pack member).
|
||||
- Pack Health Banner (`PACK: 6 RIDERS CONNECTED | FORMATION STABLE`).
|
||||
- Large glove-friendly `EMERGENCY HAZARD PING` broadcast button.
|
||||
- **Stitch Generation Prompt:**
|
||||
> "Design an intense, tactical Live Pack Radar screen in Bootstrap 5.3 mobile view for motorcycle group rides. The screen is a dark radar grid with concentric distance circles (100m, 500m, 1km). Moving rider blips represent the pack: the lead bike has a cyan star 'Lead - Dave', the sweep bike has an amber shield 'Sweep - Sarah', and 4 rider blips form a staggered formation. Top displays 'PACK STATUS: 6 RIDERS CONNECTED | FORMATION STABLE'. Bottom has a red 'EMERGENCY HAZARD PING' glove-friendly button."
|
||||
|
||||
---
|
||||
|
||||
### SCREEN-MOB-29: MotorSignal Pro Paywall & Entitlements
|
||||
- **Screen ID / Route:** `PRO-01` (`/pro` or Settings Pro Card)
|
||||
- **Target Context:** Upgrading from Free to Pro membership.
|
||||
- **Bootstrap Mobile Grid / Layout:**
|
||||
- Full-screen upgrade modal with glowing neon purple/cyan styling.
|
||||
- **Required UI Elements & Controls:**
|
||||
- **Hero Value Header:** Glowing purple crest, headline (*"Unlock Full Forensic Telemetry"*).
|
||||
- **Feature Checklist:** 5 value bullet points with glowing cyan checkmarks (20 Hz Forensic Logging, Waze Police & Radar Traps, 3D Lean Angle Replay, Live Pack Mesh Radar, Draggy Launch Mode).
|
||||
- **Plan Selection Cards:**
|
||||
- `Annual Plan`: `$79.99 / year` with `Save 33% - Best Value` badge.
|
||||
- `Monthly Plan`: `$9.99 / month`.
|
||||
- **Primary Action Button:** Large glowing `Start 14-Day Free Trial` button.
|
||||
- **Footer Actions:** `Restore Purchase` link, Terms of Service, Privacy links.
|
||||
- **Stitch Generation Prompt:**
|
||||
> "Design a high-conversion mobile paywall screen for MotorSignal Pro in Bootstrap 5.3 mobile view. Dark background with glowing purple and cyan energy accents. Header reads 'Unlock Full Forensic Telemetry'. Bulleted benefits list includes: 20 Hz Sub-Second Logging, Live Waze Police Traps, 3D Lean Angle Replay, Unlimited Group Ride Mesh, and Draggy Launch Mode. Two selectable subscription cards: 'Annual - $79.99/yr ($6.67/mo - Best Value)' and 'Monthly - $9.99/mo'. Prominent glowing 'Unlock MotorSignal Pro' button at bottom."
|
||||
|
||||
---
|
||||
|
||||
### SCREEN-MOB-30 to SCREEN-MOB-32: Settings, Diagnostics & Sensor Streams
|
||||
- **Screen ID / Route:**
|
||||
- `SET-01`: `SETTINGS` (`/settings`)
|
||||
- `SET-02`: `ACCOUNT` (`/settings/account`)
|
||||
- `DIAG-01`: `DIAGNOSTICS` (`/settings/diagnostics`)
|
||||
- **Target Context:** System configuration, Waze API key setup, raw IMU sensor stream diagnostics.
|
||||
- **Bootstrap Mobile Grid / Layout:**
|
||||
- Grouped settings list (`list-group list-group-flush bg-transparent`).
|
||||
- **Required UI Elements & Controls:**
|
||||
- **Settings (`SET-01`):**
|
||||
- Units toggle (`MPH / Feet` vs `KM/H / Meters`).
|
||||
- Audio Mode selector (`Voice Alerts` vs `Tactical Tones`).
|
||||
- **Waze Police Alerts Card:** Toggle switch, OpenWebNinja API key text input, `Test Connection` button, live status badge (`Connected` in green).
|
||||
- **Lean Angle Audio Interlock Toggle:** `Mute Audio when cornering > 15°` switch.
|
||||
- **Account (`SET-02`):** Email, Password update, Cloud backup sync toggle, `Sign Out` button.
|
||||
- **Hardware Diagnostics (`DIAG-01`):**
|
||||
- Real-time 20 Hz Accelerometer stream box (X, Y, Z in m/s²).
|
||||
- Real-time 20 Hz Gyroscope stream box (Roll, Pitch, Yaw in rad/s).
|
||||
- GPS Status: Latitude, Longitude, Altitude, Horizontal Accuracy (meters), Constellation Satellites in view (e.g. 16 Sats).
|
||||
- Local Drift Database: Row counts for Telemetry, Rides, and Outbox Queue.
|
||||
- **Stitch Generation Prompt:**
|
||||
> "Design a technical settings and diagnostics screen in Bootstrap 5.3 mobile view. Section 1 is 'Road Alerts & Providers' featuring a Waze Police Alerts card with an active toggle switch, OpenWebNinja API key input field, and a 'Test Connection' button showing a green 'Connected' badge. Below is a toggle for 'Lean Angle Audio Mute (Mutes alerts when cornering > 15 deg)'. Section 2 is 'Hardware Diagnostics' showing a live sensor stream box with fast-updating numbers for 20 Hz Accelerometer, Gyroscope Roll Rate, and GPS Satellite Count (14 Sats, Fix 3D)."
|
||||
|
||||
---
|
||||
|
||||
## Master Screen Index & Stitch Cross-Reference
|
||||
|
||||
| Code | Platform | Route / Identifier | Screen Title | Primary Stitch Component Pattern |
|
||||
|---|---|---|---|---|
|
||||
| **WEB-01** | Web | `GET /` | Public Homepage & Hero | Full-width Hero, 3D Device Mockup, Telemetry Strip |
|
||||
| **WEB-02** | Web | `GET /features` | Features & Technical Specs | Telemetry Trace Charts, Kalman Filter Diagram |
|
||||
| **WEB-03** | Web | `GET /pricing` | Membership & Plans | 3-Tier Pricing Cards, Comparison Matrix Table |
|
||||
| **WEB-04** | Web | `GET /download` | App Download Hub | Direct APK Card, QR Code Generator, Play Badges |
|
||||
| **WEB-05** | Web | `GET /group-rides` | Group Rides Discovery | Split-screen Interactive Map & Ride Card Feed |
|
||||
| **WEB-06** | Web | `GET /group-rides/showcase` | Telemetry Showcase | Full-viewport HUD Canvas, Simulation Scrubber |
|
||||
| **WEB-07** | Web | `GET /group-rides/manage` | Ride Organizer Hub | Responsive Management Table, Attendee Modal |
|
||||
| **WEB-08** | Web | `GET /clubs` | Motorcycle Clubs Directory | Club Cards Grid, Riding Discipline Tag Filters |
|
||||
| **WEB-09** | Web | `GET /clubs/manage` | Club Founder Hub | Officer Command Cards, Attention Alert Banners |
|
||||
| **WEB-10** | Web | `GET /clubs/[id]/manage` | Club Founder Overview | Member Growth Charts, Staged Rides Roster |
|
||||
| **WEB-11** | Web | `GET /clubs/[id]/manage/profile` | Club Branding Editor | Crest/Cover Upload, Social Links, Club Bio |
|
||||
| **WEB-12** | Web | `GET /clubs/[id]/manage/applications` | Applications Queue | Applicant Questionnaires, One-click Accept/Deny |
|
||||
| **WEB-13** | Web | `GET /clubs/[id]/manage/ranks-roles` | Hierarchy Builder | Hierarchy Tree, Permission Toggle Switches |
|
||||
| **WEB-14** | Web | `GET /clubs/[id]/manage/rides` | Scheduled Rides Calendar | Club Ride Attendance Logs, Lead Assignments |
|
||||
| **WEB-15** | Web | `GET /clubs/[id]/manage/settings` | Club Governance Settings | Privacy Toggles, Join Codes, Disband Action |
|
||||
| **WEB-16** | Web | `GET /support` | Help Desk & Support | Knowledge Base Search, Ticket Submission Form |
|
||||
| **WEB-17** | Web | `GET /privacy` | Privacy & Anonymization | Sticky Table of Contents, Telemetry Callouts |
|
||||
| **WEB-18** | Web | `GET /terms` | Terms of Service | Legal Indemnity, Safety Disclaimer Layout |
|
||||
| **WEB-19** | Web | `GET /login` | Rider Sign-In | Centered Glassmorphism Auth Card, Social Sign-In |
|
||||
| **WEB-20** | Web | `GET /register` | Rider Registration | Multi-step Onboarding Form, Bike Model Input |
|
||||
| **WEB-21** | Web | `GET /forgot-password` | Password Recovery | Minimal Reset Card, Back to Sign-In Link |
|
||||
| **WEB-22** | Web | `GET /verify-email` | Email Verification | 6-Digit Code Input Challenge, Resend Timer |
|
||||
| **WEB-23** | Web | `GET /account` | Rider Cloud Portal | Synced Rides Grid, Virtual Garage, GDPR Export |
|
||||
| **WEB-24** | Web | `GET /admin` | Operations Console (8 Tabs) | Enterprise Top/Sidebar Shell, Dials, Incidents |
|
||||
| **MOB-01** | Mobile | `DASH-01` (`/` Minimal) | Minimal Cockpit HUD | Pitch-black, Giant Monospace Speed, Top Pills |
|
||||
| **MOB-02** | Mobile | `DASH-02` (`/` Sport) | Sport Cockpit HUD | G-Force Circle, Lean Angle Arc, 0-60 Shortcut |
|
||||
| **MOB-03** | Mobile | `DASH-03` (`/` Touring) | Touring Cockpit HUD | Compass, Elevation, Trip Odometer, Weather Tile |
|
||||
| **MOB-04** | Mobile | `DASH-04` (Recording) | Active Recording HUD | 20 Hz Pulsing REC Pill, Slide-to-Stop Slider |
|
||||
| **MOB-05** | Mobile | `MAP-01` (`/map`) | Tactical Map Screen | Dark Vector Map, Autocomplete, Floating Pills |
|
||||
| **MOB-06** | Mobile | `MAP-02` (Drawer) | Tactical Layer Overrides | Offcanvas Bottom Sheet with Satellite/3D Topo |
|
||||
| **MOB-07** | Mobile | `ALERT-01` (Alert) | Road Alert / Police Trap | Flashing Red Alert Card, Mute Tone Button |
|
||||
| **MOB-08** | Mobile | `PERF-01` (`/launch`) | Draggy Launch Timer | Christmas Tree Staging, Slope Valid Pill, Tiles |
|
||||
| **MOB-09** | Mobile | `PERF-02` (Analysis) | Launch Curve Analysis | Acceleration vs Time Curve, Longitudinal G Trace |
|
||||
| **MOB-10** | Mobile | `ACT-01` (`/activity?rides`) | Rides History List | Route Map Thumbnails, Lean/Speed Stats, Sync Icon |
|
||||
| **MOB-11** | Mobile | `ACT-02` (`/activity?records`)| Personal Records Trophy | Best 0-60, Max Lean Left/Right, Peak Altitude |
|
||||
| **MOB-12** | Mobile | `HIST-01` (`/history/:id`) | Forensic Ride Inspection | Route Map Heatmap, Telemetry Strip, GPX Export |
|
||||
| **MOB-13** | Mobile | `REPLAY-01` (`/replay/:id`) | Interactive Ride Replay | Scrubbing Timeline, Synchronous HUD Gauges |
|
||||
| **MOB-14** | Mobile | `GAR-01` (`/garage`) | Virtual Garage Hub | Motorcycle Cards Carousel, Service Status Alert |
|
||||
| **MOB-15** | Mobile | `GAR-02` (`/garage/add`) | Add Motorcycle Screen | Form Inputs, VIN Scanner, Tire Specifications |
|
||||
| **MOB-16** | Mobile | `GAR-03` (`/garage/:id`) | Bike Profile & Service | Odometer, Oil/Chain Due Cards, Connected Sensors |
|
||||
| **MOB-17** | Mobile | `ROUT-01` (`/routes/planner`) | Curvy Route Generator | Waypoints, Curviness Slider, Elevation Profile |
|
||||
| **MOB-18** | Mobile | `ROUT-02` (`/routes/:id`) | Route Detail & Navigation | Route Statistics, Cue Sheet, Turn-by-Turn Launch |
|
||||
| **MOB-19** | Mobile | `SOC-01` (`/social`) | Social Feed & Kudos | Friend Ride Cards, Map Previews, Fist Bumps |
|
||||
| **MOB-20** | Mobile | `SOC-02` (`/social/profile`) | Rider Public Profile | Avatar, Trophy Cabinet, Stable of Bikes, Stats |
|
||||
| **MOB-21** | Mobile | `SOC-03` (`/social/friends`) | Friends & Pack Network | Friend Search, Mutual Ride Stats, Invite Links |
|
||||
| **MOB-22** | Mobile | `CLUB-01` (`/social/clubs`) | Clubs Discovery Hub | Club Cards, Riding Style Filters, Regional Pins |
|
||||
| **MOB-23** | Mobile | `CLUB-02` (`/clubs/create`) | Create Club Wizard | Patch Upload, Mission Statement, Privacy Toggles |
|
||||
| **MOB-24** | Mobile | `CLUB-03` (`/clubs/:id`) | Club Detail & Roster | Club Wall, Announcements, Officer Badges |
|
||||
| **MOB-25** | Mobile | `GRP-01` (`/group-rides`) | Group Rides Hub | Join via Code, Upcoming Pack Rides Filter |
|
||||
| **MOB-26** | Mobile | `GRP-02` (`/group-rides/new`)| Create Group Ride | Staging Location, Route Attachment, Pace Rule |
|
||||
| **MOB-27** | Mobile | `GRP-03` (`/group-rides/:id`)| Ride Briefing & Staging | Attendee List, Weather Forecast, Safety Rules |
|
||||
| **MOB-28** | Mobile | `GRP-04` (Live Radar) | Live Pack Mesh Radar | Concentric Radar Rings, Lead/Sweep Blips, Ping |
|
||||
| **MOB-29** | Mobile | `PRO-01` (`/pro`) | MotorSignal Pro Paywall | Comparison Matrix, Monthly/Annual Cards, Restore |
|
||||
| **MOB-30** | Mobile | `SET-01` (`/settings`) | Settings & Road Alerts | Waze Provider Card, API Key Input, Test Button |
|
||||
| **MOB-31** | Mobile | `SET-02` (`/settings/account`)| Account & Security | Profile Credentials, Cloud Sync, GDPR Delete |
|
||||
| **MOB-32** | Mobile | `DIAG-01` (`/diagnostics`) | Sensor Stream Diagnostics | 20 Hz IMU Stream, GPS Accuracy, Drift DB Dump |
|
||||
|
||||
---
|
||||
|
||||
## Instructions for Stitch Implementation
|
||||
|
||||
When generating screens in Stitch:
|
||||
1. **Initialize Project / Design System**:
|
||||
- Run `create_design_system_from_design_md` using the tokens defined in the **Core Design Tokens** section above.
|
||||
- Set device type to `DESKTOP` for `WEB-01` through `WEB-24` and `MOBILE` for `MOB-01` through `MOB-32`.
|
||||
2. **Batch Screen Generation**:
|
||||
- Pass the exact prompt under each screen entry into Stitch's `generate_screen_from_text`.
|
||||
- Ensure all responsive breakpoints adhere to standard Bootstrap 5.3 (`col-12 col-md-6 col-lg-4` conventions).
|
||||
3. **Consistency Verification**:
|
||||
- Verify all telemetry gauges utilize monospace numbers (`font-monospace` or `font-telemetry`).
|
||||
- Verify all touch targets for mobile screens (`MOB-01` through `MOB-32`) maintain at least 48px height and width for motorcycle glove usability.
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
# MotorSignal Stitch Design System Catalog
|
||||
|
||||
Complete repository of all **56 screens and design assets** designed for MotorSignal in Stitch Project `4601768354582654042` under the **Tactical Cockpit Telemetry** design system (`assets/4db724bf91d547f2af8962ac368ba17b`).
|
||||
|
||||
All mobile screens adhere to glove-friendly ergonomics ($48\text{px}+$ touch targets), monospace tabular telemetry, high-contrast dark aesthetic (`#070A0F`), and electric cyan (`#00E5FF`) accents.
|
||||
|
||||
---
|
||||
|
||||
## Master Screen Catalog
|
||||
|
||||
| # | Screen / Route | Platform | Stitch ID | Screenshot | Bootstrap 5.3 Code |
|
||||
|---|---|---|---|---|---|
|
||||
| **01** | Activity & Telemetry Log (`/activity`) | Mobile | `db5e985e3e824760862f106a83552ce7` | [PNG](screenshots/01_activity_telemetry_log.png) | [HTML](code/01_activity_telemetry_log.html) |
|
||||
| **02** | Sport Cockpit HUD (`/` Sport Mode) | Mobile | `91e17eb17d80465bb9b89fdf10d5d04d` | [PNG](screenshots/02_sport_cockpit_hud.png) | [HTML](code/02_sport_cockpit_hud.html) |
|
||||
| **03** | Performance Launch Mode (`/launch`) | Mobile | `f5378007ff6e4d6f81abe4293814b7e6` | [PNG](screenshots/03_performance_launch_mode.png) | [HTML](code/03_performance_launch_mode.html) |
|
||||
| **04** | Tactical Map & Road Alert (`/map`) | Mobile | `15205bdce4624b7e9776684a3e5bd4e1` | [PNG](screenshots/04_tactical_map_road_alert.png) | [HTML](code/04_tactical_map_road_alert.html) |
|
||||
| **05** | Helmet Avatar Asset (Profile Graphic) | Asset | `1275a8b5233040aea9fd1a43401e0a53` | [PNG](screenshots/05_rider_helmet_avatar.png) | — |
|
||||
| **06** | MotorSignal Brand Logo (SVG) | Asset | `c7c5de78370646bd9bed436e4ba72c46` | [PNG](screenshots/06_brand_logo.png) | [SVG](code/06_brand_logo.html) |
|
||||
| **07** | Curvy Route & Apex Planner (`/routes/planner`) | Mobile | `edddf6a218374258877a3ce6fd4f9807` | [PNG](screenshots/07_curvy_route_apex_planner.png) | [HTML](code/07_curvy_route_apex_planner.html) |
|
||||
| **08** | Virtual Garage & Telemetry Hub (`/garage`) | Mobile | `b04f55308f3a42658aaa97e70ffdfb41` | [PNG](screenshots/08_virtual_garage_telemetry_hub.png) | [HTML](code/08_virtual_garage_telemetry_hub.html) |
|
||||
| **09** | Live Pack Mesh Radar (`/group-rides/:id/live`) | Mobile | `2ef987ee0a5047daa656f5696105d673` | [PNG](screenshots/09_live_pack_mesh_radar.png) | [HTML](code/09_live_pack_mesh_radar.html) |
|
||||
| **10** | Community Social Feed & Kudos (`/social`) | Mobile | `df3e66ec302f4fa5bfddef8c88a31051` | [PNG](screenshots/10_community_social_feed_kudos.png) | [HTML](code/10_community_social_feed_kudos.html) |
|
||||
| **11** | Motorcycle Clubs & Roster Wall (`/clubs/:id`) | Mobile | `b9dada26bc044b17a3107c025248dd9a` | [PNG](screenshots/11_motorcycle_clubs_roster_wall.png) | [HTML](code/11_motorcycle_clubs_roster_wall.html) |
|
||||
| **12** | Settings & Sensor Diagnostics (`/settings`) | Mobile | `c78d3e8126cf48b68d35df548fea00c7` | [PNG](screenshots/12_settings_sensor_diagnostics.png) | [HTML](code/12_settings_sensor_diagnostics.html) |
|
||||
| **13** | MotorSignal Pro Paywall (`/pro`) | Mobile | `2922e6c0365a4de8be8d1a93bdea3e1f` | [PNG](screenshots/13_motorsignal_pro_paywall.png) | [HTML](code/13_motorsignal_pro_paywall.html) |
|
||||
| **14** | Forensic Ride Replay (`/replay/:id`) | Mobile | `6979239dcf494c72a864de9b91ef40f8` | [PNG](screenshots/14_forensic_ride_replay_corner_analysis.png) | [HTML](code/14_forensic_ride_replay_corner_analysis.html) |
|
||||
| **15** | Add Motorcycle & VIN Scanner (`/garage/add`) | Mobile | `08de5b20a2954b90ba0aefa43cac363d` | [PNG](screenshots/15_add_motorcycle_vin_scanner.png) | [HTML](code/15_add_motorcycle_vin_scanner.html) |
|
||||
| **16** | Ride Briefing & Pack Staging (`/group-rides/:id`) | Mobile | `f5b750fcdedd468bbd114a4bde2fd643` | [PNG](screenshots/16_ride_briefing_pack_staging.png) | [HTML](code/16_ride_briefing_pack_staging.html) |
|
||||
| **17** | Membership & Pricing (`/pricing`) | Desktop | `537302f206b84011a408ed919df9f95d` | [PNG](screenshots/17_membership_pricing.png) | [HTML](code/17_membership_pricing.html) |
|
||||
| **18** | Download & Multi-Platform Hub (`/download`) | Desktop | `6aa19b9697f248ab8105fa7c367f27b2` | [PNG](screenshots/18_download_multiplatform_hub.png) | [HTML](code/18_download_multiplatform_hub.html) |
|
||||
| **19** | Features & Specifications (`/features`) | Desktop | `76c7f66b5a2a4b0d9bba865701b30886` | [PNG](screenshots/19_features_technical_specifications.png) | [HTML](code/19_features_technical_specifications.html) |
|
||||
| **20** | Public Homepage (`/`) | Desktop | `ddb3f431b25241c0b2719dd2e5665ab3` | [PNG](screenshots/20_public_homepage.png) | [HTML](code/20_public_homepage.html) |
|
||||
| **21** | Group Rides Discovery (`/group-rides`) | Desktop | `a6a8868451584392b28b1e120785c345` | [PNG](screenshots/21_group_rides_discovery.png) | [HTML](code/21_group_rides_discovery.html) |
|
||||
| **22** | Live Telemetry Showcase (`/group-rides/showcase`) | Desktop | `4bbc7e80d9654d69911b70831cbf8569` | [PNG](screenshots/22_live_telemetry_showcase.png) | [HTML](code/22_live_telemetry_showcase.html) |
|
||||
| **23** | Ride Organizer Hub (`/group-rides/manage`) | Desktop | `6330b31df21e4621a9b303ee02b6c97e` | [PNG](screenshots/23_ride_organizer_hub.png) | [HTML](code/23_ride_organizer_hub.html) |
|
||||
| **24** | Motorcycle Clubs Directory (`/clubs`) | Desktop | `85e75846ef914fe29189c15427009e1b` | [PNG](screenshots/24_motorcycle_clubs_directory.png) | [HTML](code/24_motorcycle_clubs_directory.html) |
|
||||
| **25** | Founder & Officer Hub (`/clubs/manage`) | Desktop | `4804aedf1dd24d52902bf1981125af51` | [PNG](screenshots/25_founder_officer_hub.png) | [HTML](code/25_founder_officer_hub.html) |
|
||||
| **26** | Roles & Ranks Builder (`/clubs/[id]/manage/ranks-roles`) | Desktop | `7ff4250616f44d89bde3fb02eec290b2` | [PNG](screenshots/26_roles_ranks_builder.png) | [HTML](code/26_roles_ranks_builder.html) |
|
||||
| **27** | Operations & Admin Console (`/admin`) | Desktop | `80734d4801414e1eb72dfdcf430adebb` | [PNG](screenshots/27_operations_admin_console.png) | [HTML](code/27_operations_admin_console.html) |
|
||||
| **28** | Minimal Cockpit HUD (`/` Minimal) | Mobile | `19fd3776ec65408b95706e0b6b55beae` | [PNG](screenshots/28_minimal_cockpit_hud.png) | [HTML](code/28_minimal_cockpit_hud.html) |
|
||||
| **29** | Touring Cockpit HUD (`/` Touring) | Mobile | `770611306f4c41cabe52838ed884531f` | [PNG](screenshots/29_touring_cockpit_hud.png) | [HTML](code/29_touring_cockpit_hud.html) |
|
||||
| **30** | Active Ride Recording HUD (`REC 20Hz`) | Mobile | `d6d8925252e84279979c572ee935e44d` | [PNG](screenshots/30_active_ride_recording_hud.png) | [HTML](code/30_active_ride_recording_hud.html) |
|
||||
| **31** | Tactical Map Layer Overrides (`/map` Drawer) | Mobile | `91fd702f9f754a7db64066763e33a795` | [PNG](screenshots/31_tactical_map_layer_overrides.png) | [HTML](code/31_tactical_map_layer_overrides.html) |
|
||||
| **32** | Launch Curve Analysis (`/launch/history`) | Mobile | `2d20b4fdbf6e4fa38cc6c2c3764bdceb` | [PNG](screenshots/32_launch_curve_analysis.png) | [HTML](code/32_launch_curve_analysis.html) |
|
||||
| **33** | Personal Records Trophy Cabinet (`/activity?records`) | Mobile | `92cb19cdf62f4f0c83094c66b13d714e` | [PNG](screenshots/33_personal_records_trophy_cabinet.png) | [HTML](code/33_personal_records_trophy_cabinet.html) |
|
||||
| **34** | Bike Maintenance & Service Due (`/garage/:id`) | Mobile | `ee994b906d2444aebfe8e43a37c44acd` | [PNG](screenshots/34_bike_maintenance_service_due.png) | [HTML](code/34_bike_maintenance_service_due.html) |
|
||||
| **35** | Route Detail & Turn Cue Sheet (`/routes/:id`) | Mobile | `21b6f6a1e8944be7aec4e47c50bdea34` | [PNG](screenshots/35_route_detail_turn_cue_sheet.png) | [HTML](code/35_route_detail_turn_cue_sheet.html) |
|
||||
| **36** | Rider Public Profile (`/social/profile`) | Mobile | `4c09ae5e0aee4735b10e988bdce0f42c` | [PNG](screenshots/36_rider_public_profile.png) | [HTML](code/36_rider_public_profile.html) |
|
||||
| **37** | Friends & Pack Network (`/social/friends`) | Mobile | `c024e9845ec84be4b0b7a1da7c236fb3` | [PNG](screenshots/37_friends_pack_network.png) | [HTML](code/37_friends_pack_network.html) |
|
||||
| **38** | Clubs Discovery Hub (`/social/clubs`) | Mobile | `3f51b297e18443b0ab583774926710f6` | [PNG](screenshots/38_clubs_discovery_hub.png) | [HTML](code/38_clubs_discovery_hub.html) |
|
||||
| **39** | Create Club Wizard (`/clubs/create`) | Mobile | `d229c09f9668497caa60019da039b1b6` | [PNG](screenshots/39_create_club_wizard.png) | [HTML](code/39_create_club_wizard.html) |
|
||||
| **40** | Group Rides Hub (`/group-rides`) | Mobile | `bd212a8fa11148688f18a3a1107ee452` | [PNG](screenshots/40_group_rides_hub.png) | [HTML](code/40_group_rides_hub.html) |
|
||||
| **41** | Create Group Ride Wizard (`/group-rides/new`) | Mobile | `a2bc511c1f514461835731e077094e57` | [PNG](screenshots/41_create_group_ride_wizard.png) | [HTML](code/41_create_group_ride_wizard.html) |
|
||||
| **42** | Account & Security Settings (`/settings/account`) | Mobile | `c7709851c0e140a294e7a95c38b55402` | [PNG](screenshots/42_account_security_settings.png) | [HTML](code/42_account_security_settings.html) |
|
||||
| **43** | Raw 20 Hz IMU Stream Diagnostics (`/diagnostics/raw`) | Mobile | `452885f190e54256bc31986924c3643a` | [PNG](screenshots/43_raw_imu_stream_diagnostics.png) | [HTML](code/43_raw_imu_stream_diagnostics.html) |
|
||||
| **44** | Club Founder Overview (`/clubs/[id]/manage`) | Desktop | `37cb597b8aee4b0994cfed1f92c93098` | [PNG](screenshots/44_club_founder_overview.png) | [HTML](code/44_club_founder_overview.html) |
|
||||
| **45** | Club Branding & Profile Editor (`/clubs/[id]/manage/profile`) | Desktop | `5ad8237fff0847399c8cd1310d39a1d8` | [PNG](screenshots/45_club_branding_editor.png) | [HTML](code/45_club_branding_editor.html) |
|
||||
| **46** | Membership Applications Queue (`/clubs/[id]/manage/applications`) | Desktop | `39bf9ac594ec4d9d8b28e54df7aa9f71` | [PNG](screenshots/46_membership_applications_queue.png) | [HTML](code/46_membership_applications_queue.html) |
|
||||
| **47** | Scheduled Rides Calendar & Attendance (`/clubs/[id]/manage/rides`) | Desktop | `52f503c93c14475f9e4b431b5663009d` | [PNG](screenshots/47_scheduled_rides_calendar.png) | [HTML](code/47_scheduled_rides_calendar.html) |
|
||||
| **48** | Club Governance & Disband Settings (`/clubs/[id]/manage/settings`) | Desktop | `64187aa76b6f4a428b9336041348e024` | [PNG](screenshots/48_club_governance_settings.png) | [HTML](code/48_club_governance_settings.html) |
|
||||
| **49** | Support Desk & Knowledge Base (`/support`) | Desktop | `9b15f9c4f639490f91168cec74875d3b` | [PNG](screenshots/49_support_desk_knowledge_base.png) | [HTML](code/49_support_desk_knowledge_base.html) |
|
||||
| **50** | Privacy & Anonymization Policy (`/privacy`) | Desktop | `9ad4b002758d4141bfd3bb015b47503e` | [PNG](screenshots/50_privacy_anonymization_policy.png) | [HTML](code/50_privacy_anonymization_policy.html) |
|
||||
| **51** | Terms of Service (`/terms`) | Desktop | `787412b3422d4f0b9866230f82548a3e` | [PNG](screenshots/51_terms_of_service.png) | [HTML](code/51_terms_of_service.html) |
|
||||
| **52** | Rider Sign-In (`/login`) | Desktop | `6092f47df7554a458a97afb50a9ca3df` | [PNG](screenshots/52_rider_sign_in.png) | [HTML](code/52_rider_sign_in.html) |
|
||||
| **53** | Rider Registration (`/register`) | Desktop | `21e5c82f87724fc2913fc36bfa78aca1` | [PNG](screenshots/53_rider_registration.png) | [HTML](code/53_rider_registration.html) |
|
||||
| **54** | Password Recovery (`/forgot-password`) | Desktop | `1c39e5faf31a4437b64d8d48ad942424` | [PNG](screenshots/54_password_recovery.png) | [HTML](code/54_password_recovery.html) |
|
||||
| **55** | Email Verification Challenge (`/verify-email`) | Desktop | `af13d44f62184b1eab47f00c27be72e7` | [PNG](screenshots/55_email_verification_challenge.png) | [HTML](code/55_email_verification_challenge.html) |
|
||||
| **56** | Rider Cloud Portal (`/account`) | Desktop | `f9d24db9a60f42b485566ed5829d9bd4` | [PNG](screenshots/56_rider_cloud_portal.png) | [HTML](code/56_rider_cloud_portal.html) |
|
||||
|
|
@ -0,0 +1,326 @@
|
|||
<!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, viewport-fit=cover" name="viewport"/><meta content="mobile_tab" name="shell-type"/><title>MotorSignal Cockpit HUD</title><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&family=JetBrains+Mono:wght@500;600;700&family=Space+Grotesk:wght@600;700&display=swap" rel="stylesheet"/><link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/><style>@layer base{html,body{width:100%;margin:0;padding:0;background-color:#101419;color:#e0e2ea;}body{overscroll-behavior:none;}.pb-safe{padding-bottom:env(safe-area-inset-bottom,0px);}.pt-safe{padding-top:env(safe-area-inset-top,0px);}main>:first-child{margin-top:0!important;}main>:last-child{margin-bottom:0!important;}}::-webkit-scrollbar{display:none;}</style><script src="https://cdn.tailwindcss.com"></script><script id="tailwind-config">tailwind.config = { darkMode: "class", theme: { extend: { "colors": { "on-primary": "#00363d", "tertiary-fixed-dim": "#d0bcff", "tertiary-container": "#d9c8ff", "on-primary-container": "#00626e", "surface-variant": "#32353b", "on-primary-fixed-variant": "#004f58", "surface-container-high": "#272a30", "outline-variant": "#3b494c", "surface-container": "#1d2025", "on-surface": "#e0e2ea", "background": "#101419", "primary-container": "#00e5ff", "inverse-surface": "#e0e2ea", "outline": "#849396", "on-secondary": "#002a78", "secondary-fixed-dim": "#b4c5ff", "on-tertiary": "#3c0091", "inverse-primary": "#006875", "surface-bright": "#36393f", "surface-container-low": "#181c21", "surface-container-highest": "#32353b", "inverse-on-surface": "#2d3036", "on-secondary-fixed": "#00174b", "primary": "#c3f5ff", "error-container": "#93000a", "surface-tint": "#00daf3", "on-tertiary-fixed-variant": "#5516be", "on-error-container": "#ffdad6", "primary-fixed-dim": "#00daf3", "tertiary-fixed": "#e9ddff", "on-primary-fixed": "#001f24", "on-error": "#690005", "surface-container-lowest": "#0b0e13", "secondary-container": "#0053db", "tertiary": "#f2e9ff", "surface-dim": "#101419", "on-surface-variant": "#bac9cc", "on-tertiary-container": "#6834d1", "primary-fixed": "#9cf0ff", "secondary-fixed": "#dbe1ff", "error": "#ffb4ab", "on-secondary-container": "#cdd7ff", "on-secondary-fixed-variant": "#003ea8", "surface": "#101419", "on-background": "#e0e2ea", "secondary": "#b4c5ff", "on-tertiary-fixed": "#23005c" }, "borderRadius": { "DEFAULT": "0.25rem", "lg": "0.5rem", "xl": "0.75rem", "full": "9999px" }, "spacing": { "margin-lg": "2rem", "space-xs": "0.25rem", "gutter-lg": "1.5rem", "space-xl": "2rem", "margin": "1rem", "space-sm": "0.5rem", "space-md": "1rem", "space-lg": "1.5rem", "gutter": "1rem" }, "fontFamily": { "headline-lg": ["Space Grotesk"], "body-lg": ["Inter"], "telemetry-metric-lg-mobile": ["JetBrains Mono"], "label-data": ["JetBrains Mono"], "display-hero": ["Space Grotesk"], "headline-sm": ["Space Grotesk"], "headline-md": ["Space Grotesk"], "label-caption": ["Inter"], "telemetry-metric-lg": ["JetBrains Mono"], "display-hero-mobile": ["Space Grotesk"], "telemetry-metric-md": ["JetBrains Mono"], "body-md": ["Inter"] }, "fontSize": { "headline-lg": ["32px", { "lineHeight": "40px", "letterSpacing": "-0.02em", "fontWeight": "700" }], "body-lg": ["16px", { "lineHeight": "24px", "fontWeight": "500" }], "telemetry-metric-lg-mobile": ["36px", { "lineHeight": "36px", "letterSpacing": "-0.03em", "fontWeight": "700" }], "label-data": ["12px", { "lineHeight": "16px", "letterSpacing": "0.08em", "fontWeight": "600" }], "display-hero": ["56px", { "lineHeight": "60px", "letterSpacing": "-0.03em", "fontWeight": "700" }], "headline-sm": ["20px", { "lineHeight": "28px", "fontWeight": "600" }], "headline-md": ["24px", { "lineHeight": "32px", "letterSpacing": "-0.01em", "fontWeight": "600" }], "label-caption": ["11px", { "lineHeight": "14px", "letterSpacing": "0.05em", "fontWeight": "600" }], "telemetry-metric-lg": ["48px", { "lineHeight": "48px", "letterSpacing": "-0.04em", "fontWeight": "700" }], "display-hero-mobile": ["40px", { "lineHeight": "44px", "letterSpacing": "-0.02em", "fontWeight": "700" }], "telemetry-metric-md": ["28px", { "lineHeight": "32px", "letterSpacing": "-0.02em", "fontWeight": "600" }], "body-md": ["14px", { "lineHeight": "20px", "fontWeight": "400" }] } } } }</script><style>
|
||||
body {
|
||||
min-height: max(884px, 100dvh);
|
||||
}
|
||||
</style>
|
||||
</head><body class="bg-surface font-body-md text-on-surface antialiased flex flex-col min-h-screen selection:bg-primary-container selection:text-on-primary-container"><header class="fixed top-0 w-full z-50 pt-safe bg-surface-container-lowest/85 backdrop-blur-xl shadow-[0_4px_20px_rgba(0,0,0,0.5)]"><div class="h-16 px-space-md flex items-center justify-between gap-space-sm"><div class="flex items-center gap-space-sm"><img alt="MotorSignal Brand Logo" class="h-8 w-auto object-contain drop-shadow-[0_0_8px_rgba(0,229,255,0.4)]" src="https://lh3.googleusercontent.com/aida/AEtjO1Vf56Tkh6bJ86BCfT5GHz_yPumvEXYLWojlNHAFG-cN4VvH_nLvEbWQ4x7uhJPRaAyO8ozAAbLI_huEN134QOIYp8BdHuqoZCsMk9_ILaUxZqilVgamefO6d2sG1R8laIWSUswanVsK9lfvIgppQm_XxBQipzkDgPwIoXk7yh10QTlmZqDICryF-1MoWFfFjM2zZswr6ynuAgZAviROYnFBF2D4hxm6YREQxkZQJaBcG9oAg_dYVgTHxwg"/><div class="flex flex-col"><span class="font-headline-sm text-headline-sm uppercase tracking-wider text-primary-fixed">MotorSignal</span><span class="font-label-caption text-label-caption text-on-surface-variant uppercase tracking-widest leading-none">Telemetry Log</span></div></div><div class="flex items-center gap-space-sm"><div class="hidden sm:flex items-center gap-space-xs bg-surface-container-low px-space-sm py-1 rounded-full"><span class="w-2 h-2 rounded-full bg-primary-container animate-pulse shadow-[0_0_6px_#00e5ff]"></span><span class="font-label-data text-label-data text-primary-fixed">GPS 3D FIX</span></div><div class="flex items-center gap-1.5 bg-surface-container px-2 py-1 rounded-full"><span class="material-symbols-outlined text-[15px] text-primary-container">bolt</span><span class="font-label-data text-label-data text-on-surface">98%</span><span class="w-1 h-1 rounded-full bg-outline-variant"></span><span class="material-symbols-outlined text-[15px] text-primary-container">cell_tower</span></div><button aria-label="Rider Profile" class="min-w-[44px] min-h-[44px] flex items-center justify-center p-1 rounded-full focus:outline-none focus:ring-2 focus:ring-primary-container" type="button"><img alt="Profile" class="w-8 h-8 rounded-full object-cover ring-2 ring-primary-container/40" src="https://lh3.googleusercontent.com/aida-public/AB6AXuBb6sR8Ta8-L1_TN1LuCBfSxtZxX9hKOFjd-RjllihDsnp6AG1GlMhL9bVlb-ibhIRT3HMw_caXK7BmwmvWKNBcuizyqswUQZNztavckRTN1Xa6qGML_0kv8qvV_hrXWWK1EjSjVFzhRyDzf6VdGnZvUpGsFFmSBcaGVrXmEWFYnIa-qHyeWxZlT_SJmPuQJPQKEWEo6vC6kdDzXNnhoB4tpRHjIjCstvTdooPc0KVN_x3BqqmqadNI"/></button></div></div></header><main class="flex-1 flex flex-col relative w-full pt-16 pb-20 bg-surface"><div class="flex flex-col w-full px-space-md py-space-md gap-space-md">
|
||||
<!-- Top Segmented Switcher -->
|
||||
<div class="w-full bg-surface-container-lowest p-1 rounded-xl flex items-center justify-between shadow-inner">
|
||||
<button class="flex-1 min-h-[48px] flex items-center justify-center gap-space-xs rounded-lg bg-surface-container-high text-primary-container shadow-md transition-all" id="tab-rides" type="button">
|
||||
<span class="material-symbols-outlined text-[18px]">route</span>
|
||||
<span class="font-headline-sm text-label-data uppercase tracking-wider">Recorded Rides (48)</span>
|
||||
</button>
|
||||
<button class="flex-1 min-h-[48px] flex items-center justify-center gap-space-xs rounded-lg text-on-surface-variant hover:text-on-surface transition-all" id="tab-trophies" type="button">
|
||||
<span class="material-symbols-outlined text-[18px]">military_tech</span>
|
||||
<span class="font-headline-sm text-label-data uppercase tracking-wider">Records & Trophies</span>
|
||||
</button>
|
||||
</div>
|
||||
<!-- Summary KPI Strip -->
|
||||
<div class="grid grid-cols-3 gap-space-sm w-full">
|
||||
<!-- Metric 1 -->
|
||||
<div class="bg-surface-container-low rounded-xl p-space-sm flex flex-col justify-between shadow-sm relative overflow-hidden group">
|
||||
<div class="flex items-center justify-between text-on-surface-variant">
|
||||
<span class="font-label-caption text-label-caption uppercase tracking-wider">Distance</span>
|
||||
<span class="material-symbols-outlined text-[16px] text-primary-container">speed</span>
|
||||
</div>
|
||||
<div class="mt-2 flex flex-col">
|
||||
<span class="font-telemetry-metric-md text-telemetry-metric-md text-on-surface leading-tight">4,820</span>
|
||||
<span class="font-label-data text-label-data text-on-surface-variant">TOT MILES</span>
|
||||
</div>
|
||||
<div class="absolute -right-2 -bottom-2 w-10 h-10 bg-primary-container/5 rounded-full pointer-events-none"></div>
|
||||
</div>
|
||||
<!-- Metric 2 -->
|
||||
<div class="bg-surface-container-low rounded-xl p-space-sm flex flex-col justify-between shadow-sm relative overflow-hidden group">
|
||||
<div class="flex items-center justify-between text-on-surface-variant">
|
||||
<span class="font-label-caption text-label-caption uppercase tracking-wider">Lean Max</span>
|
||||
<span class="material-symbols-outlined text-[16px] text-primary-fixed-dim">screen_rotation_alt</span>
|
||||
</div>
|
||||
<div class="mt-2 flex flex-col">
|
||||
<div class="flex items-baseline gap-0.5">
|
||||
<span class="font-telemetry-metric-md text-telemetry-metric-md text-primary-fixed-dim leading-tight">52</span>
|
||||
<span class="font-label-data text-label-data text-primary-fixed-dim font-bold">°</span>
|
||||
</div>
|
||||
<span class="font-label-data text-label-data text-on-surface-variant">PEAK ANGLE</span>
|
||||
</div>
|
||||
<div class="absolute -right-2 -bottom-2 w-10 h-10 bg-primary-fixed-dim/5 rounded-full pointer-events-none"></div>
|
||||
</div>
|
||||
<!-- Metric 3 -->
|
||||
<div class="bg-surface-container-low rounded-xl p-space-sm flex flex-col justify-between shadow-sm relative overflow-hidden group">
|
||||
<div class="flex items-center justify-between text-on-surface-variant">
|
||||
<span class="font-label-caption text-label-caption uppercase tracking-wider">Milestones</span>
|
||||
<span class="material-symbols-outlined text-[16px] text-tertiary-fixed-dim">workspace_premium</span>
|
||||
</div>
|
||||
<div class="mt-2 flex flex-col">
|
||||
<span class="font-telemetry-metric-md text-telemetry-metric-md text-tertiary-fixed-dim leading-tight">18</span>
|
||||
<span class="font-label-data text-label-data text-on-surface-variant">TROPHIES</span>
|
||||
</div>
|
||||
<div class="absolute -right-2 -bottom-2 w-10 h-10 bg-tertiary-fixed-dim/5 rounded-full pointer-events-none"></div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Search & Tactical Filters Bar -->
|
||||
<div class="w-full flex items-center gap-space-sm">
|
||||
<div class="flex-1 bg-surface-container-low rounded-xl px-space-md py-space-xs flex items-center gap-space-sm shadow-inner focus-within:bg-surface-container transition-all">
|
||||
<span class="material-symbols-outlined text-[20px] text-on-surface-variant">search</span>
|
||||
<input class="w-full bg-transparent text-on-surface placeholder:text-on-surface-variant/60 font-body-md text-body-md focus:outline-none min-h-[44px]" placeholder="Filter bike, canyon, date..." type="text"/>
|
||||
</div>
|
||||
<button aria-label="Toggle Filter Sliders" class="min-w-[48px] min-h-[48px] flex items-center justify-center bg-surface-container-low hover:bg-surface-container rounded-xl text-primary-container transition-colors shadow-sm" type="button">
|
||||
<span class="material-symbols-outlined text-[22px]">tune</span>
|
||||
</button>
|
||||
</div>
|
||||
<!-- Quick Filter Pills -->
|
||||
<div class="flex items-center gap-space-xs overflow-x-auto pb-1 no-scrollbar">
|
||||
<button class="bg-primary-container text-on-primary-container px-space-md py-1.5 rounded-full font-label-data text-label-data uppercase tracking-wider shrink-0 shadow-sm font-bold">All Bikes</button>
|
||||
<button class="bg-surface-container-low hover:bg-surface-container text-on-surface-variant px-space-md py-1.5 rounded-full font-label-data text-label-data uppercase tracking-wider shrink-0 transition-colors">Yamaha MT-09 SP</button>
|
||||
<button class="bg-surface-container-low hover:bg-surface-container text-on-surface-variant px-space-md py-1.5 rounded-full font-label-data text-label-data uppercase tracking-wider shrink-0 transition-colors">Ducati Panigale V4</button>
|
||||
<button class="bg-surface-container-low hover:bg-surface-container text-on-surface-variant px-space-md py-1.5 rounded-full font-label-data text-label-data uppercase tracking-wider shrink-0 transition-colors">>45° Lean Only</button>
|
||||
</div>
|
||||
<!-- Feeds Header with Status -->
|
||||
<div class="flex items-center justify-between pt-space-xs">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="font-headline-sm text-headline-sm text-on-surface uppercase tracking-tight">Recent Sessions</span>
|
||||
<span class="px-2 py-0.5 rounded bg-surface-container-high font-label-data text-label-caption text-primary-fixed">LOGS SECURE</span>
|
||||
</div>
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant uppercase tracking-widest">AUTO-SYNC ON</span>
|
||||
</div>
|
||||
<!-- FEATURED RIDE CARD: Saturday Morning Canyon Carve -->
|
||||
<div class="w-full bg-surface-container-low rounded-xl p-space-md flex flex-col gap-space-md shadow-md relative overflow-hidden">
|
||||
<!-- Background subtle gradient sheen -->
|
||||
<div class="absolute inset-0 bg-gradient-to-br from-primary-container/5 via-transparent to-secondary-container/5 pointer-events-none"></div>
|
||||
<!-- Header Meta Row -->
|
||||
<div class="flex items-start justify-between relative z-10">
|
||||
<div class="flex flex-col gap-0.5">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="font-headline-sm text-headline-sm text-on-surface font-bold leading-tight">Saturday Morning Canyon Carve</span>
|
||||
<span class="material-symbols-outlined text-[18px] text-primary-container">verified</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-space-sm font-label-data text-label-caption text-on-surface-variant">
|
||||
<span>Oct 14 • 8:42 AM</span>
|
||||
<span class="w-1 h-1 rounded-full bg-outline-variant"></span>
|
||||
<span class="text-primary-fixed">Yamaha MT-09 SP</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Green Cloud Synced Badge -->
|
||||
<div class="flex items-center gap-1.5 bg-surface-container-lowest px-2.5 py-1 rounded-full shadow-sm shrink-0">
|
||||
<span class="w-2 h-2 rounded-full bg-[#10b981] animate-pulse"></span>
|
||||
<span class="font-label-data text-label-caption text-[#10b981] uppercase font-bold tracking-wider">Synced</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Dark Tactical Map Visualizer with Dynamic Route Heatmap -->
|
||||
<div class="w-full h-48 rounded-lg bg-surface-container-lowest relative overflow-hidden shadow-inner group cursor-pointer" data-location="Angeles Crest Highway, California" style="">
|
||||
<div class="absolute inset-0 bg-gradient-to-t from-surface-container-lowest via-transparent to-transparent z-10 pointer-events-none"></div>
|
||||
<!-- Telemetry Overlay Ribbon -->
|
||||
<div class="absolute top-2 left-2 z-20 flex items-center gap-1.5 bg-surface-container-lowest/80 backdrop-blur-md px-2 py-1 rounded">
|
||||
<span class="material-symbols-outlined text-[14px] text-primary-container">near_me</span>
|
||||
<span class="font-label-data text-label-caption text-on-surface font-semibold">ANG_CREST_SECTOR_4</span>
|
||||
</div>
|
||||
<div class="absolute top-2 right-2 z-20 flex items-center gap-1 bg-surface-container-lowest/80 backdrop-blur-md px-2 py-1 rounded font-label-data text-label-caption text-primary-fixed-dim">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-primary-fixed-dim"></span>
|
||||
<span>20Hz GPS-IMU</span>
|
||||
</div>
|
||||
<!-- Rendered SVG Route Map with Heatmap Gradient Effect -->
|
||||
<svg class="w-full h-full p-4 relative z-10 filter drop-shadow-[0_0_12px_rgba(0,229,255,0.3)]" fill="none" viewbox="0 0 400 180" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<lineargradient id="routeGradient" x1="0%" x2="100%" y1="50%" y2="50%">
|
||||
<stop offset="0%" stop-color="#00e5ff"></stop>
|
||||
<stop offset="35%" stop-color="#00e5ff"></stop>
|
||||
<stop offset="52%" stop-color="#f59e0b"></stop>
|
||||
<stop offset="68%" stop-color="#ff4444"></stop>
|
||||
<stop offset="82%" stop-color="#f59e0b"></stop>
|
||||
<stop offset="100%" stop-color="#00e5ff"></stop>
|
||||
</lineargradient>
|
||||
<filter height="140%" id="apexGlow" width="140%" x="-20%" y="-20%">
|
||||
<fegaussianblur result="glow" stddeviation="3"></fegaussianblur>
|
||||
<fecomposite in="SourceGraphic" in2="glow" operator="over"></fecomposite>
|
||||
</filter>
|
||||
</defs>
|
||||
<!-- Waypoint Grid Matrix Backing -->
|
||||
<pattern height="24" id="tacticalGrid" patternunits="userSpaceOnUse" width="24">
|
||||
<circle cx="2" cy="2" fill="#32353b" r="0.8"></circle>
|
||||
</pattern>
|
||||
<rect fill="url(#tacticalGrid)" height="100%" opacity="0.6" width="100%"></rect>
|
||||
<!-- Track Path Outer Soft Aura -->
|
||||
<path d="M 20 140 C 70 140, 90 40, 150 45 C 190 48, 205 135, 250 135 C 290 135, 295 25, 335 30 C 365 35, 375 75, 385 75" opacity="0.12" stroke="#00e5ff" stroke-linecap="round" stroke-linejoin="round" stroke-width="8"></path>
|
||||
<!-- Heatmap Track Path -->
|
||||
<path d="M 20 140 C 70 140, 90 40, 150 45 C 190 48, 205 135, 250 135 C 290 135, 295 25, 335 30 C 365 35, 375 75, 385 75" stroke="url(#routeGradient)" stroke-linecap="round" stroke-linejoin="round" stroke-width="3.5"></path>
|
||||
<!-- Start Marker -->
|
||||
<circle cx="20" cy="140" fill="#00e5ff" r="4.5"></circle>
|
||||
<circle cx="20" cy="140" r="8" stroke="#00e5ff" stroke-dasharray="2 2" stroke-width="1.5"></circle>
|
||||
<!-- Critical Apex Peak Marker (49° Lean Hotspot) -->
|
||||
<g filter="url(#apexGlow)">
|
||||
<circle cx="315" cy="50" fill="#ff4444" r="5"></circle>
|
||||
<circle cx="315" cy="50" opacity="0.8" r="10" stroke="#ff4444" stroke-width="1.5"></circle>
|
||||
</g>
|
||||
<!-- Dynamic Apex Callout Tag -->
|
||||
<rect fill="#0b0e13" height="20" opacity="0.92" rx="4" width="56" x="290" y="68"></rect>
|
||||
<text fill="#ffb4ab" font-family="'JetBrains Mono', monospace" font-size="10" font-weight="700" x="295" y="82">49° APEX</text>
|
||||
</svg>
|
||||
<!-- Bottom HUD mini ticker overlay -->
|
||||
<div class="absolute bottom-2 left-3 right-3 z-20 flex items-center justify-between text-on-surface-variant font-label-data text-label-caption">
|
||||
<span class="flex items-center gap-1">
|
||||
<span class="w-2 h-2 rounded-full bg-primary-container"></span> Straight (65+ MPH)
|
||||
</span>
|
||||
<span class="flex items-center gap-1">
|
||||
<span class="w-2 h-2 rounded-full bg-[#f59e0b]"></span> Transition (38°)
|
||||
</span>
|
||||
<span class="flex items-center gap-1">
|
||||
<span class="w-2 h-2 rounded-full bg-[#ff4444]"></span> Max Apex (49°)
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 4 Key Telemetry Chips Grid -->
|
||||
<div class="grid grid-cols-2 sm:grid-cols-4 gap-space-sm relative z-10">
|
||||
<!-- Chip 1: Distance -->
|
||||
<div class="bg-surface-container p-2.5 rounded-lg flex flex-col justify-center">
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant uppercase tracking-wider">Distance</span>
|
||||
<div class="flex items-baseline gap-1 mt-0.5">
|
||||
<span class="font-telemetry-metric-md text-telemetry-metric-md text-on-surface font-bold leading-tight">84.2</span>
|
||||
<span class="font-label-data text-label-caption text-primary-fixed">MI</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Chip 2: Duration -->
|
||||
<div class="bg-surface-container p-2.5 rounded-lg flex flex-col justify-center">
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant uppercase tracking-wider">Duration</span>
|
||||
<div class="flex items-baseline gap-1 mt-0.5">
|
||||
<span class="font-telemetry-metric-md text-telemetry-metric-md text-on-surface font-bold leading-tight">1h 42m</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Chip 3: Max Lean -->
|
||||
<div class="bg-surface-container p-2.5 rounded-lg flex flex-col justify-center relative overflow-hidden">
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant uppercase tracking-wider">Max Lean</span>
|
||||
<span class="font-label-data text-[10px] text-error font-bold uppercase">Right</span>
|
||||
</div>
|
||||
<div class="flex items-baseline gap-1 mt-0.5">
|
||||
<span class="font-telemetry-metric-md text-telemetry-metric-md text-primary-container font-bold leading-tight">49°</span>
|
||||
<span class="material-symbols-outlined text-[14px] text-primary-container">turn_sharp_right</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Chip 4: Top Speed -->
|
||||
<div class="bg-surface-container p-2.5 rounded-lg flex flex-col justify-center">
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant uppercase tracking-wider">Top Speed</span>
|
||||
<div class="flex items-baseline gap-1 mt-0.5">
|
||||
<span class="font-telemetry-metric-md text-telemetry-metric-md text-on-surface font-bold leading-tight">88</span>
|
||||
<span class="font-label-data text-label-caption text-on-surface-variant">MPH</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Forensic Actions Row -->
|
||||
<div class="flex flex-col sm:flex-row items-stretch sm:items-center gap-space-xs pt-1 relative z-10">
|
||||
<!-- Primary Forensic Replay Trigger -->
|
||||
<button class="flex-1 min-h-[48px] bg-primary-container text-on-primary-container rounded-lg px-space-md py-2 flex items-center justify-center gap-2 font-label-data text-label-data font-bold uppercase tracking-wider shadow-[0_0_16px_rgba(0,229,255,0.35)] active:scale-[0.98] transition-transform" type="button">
|
||||
<span class="material-symbols-outlined text-[20px]">slow_motion_video</span>
|
||||
<span>Forensic Replay</span>
|
||||
</button>
|
||||
<!-- GPX Export Action -->
|
||||
<button class="min-h-[48px] px-space-md bg-surface-container-high hover:bg-surface-bright text-on-surface rounded-lg flex items-center justify-center gap-2 font-label-data text-label-data font-semibold uppercase tracking-wider transition-colors" type="button">
|
||||
<span class="material-symbols-outlined text-[18px] text-primary-fixed">file_download</span>
|
||||
<span>Export GPX</span>
|
||||
</button>
|
||||
<!-- Telemetry CSV Action -->
|
||||
<button class="min-h-[48px] px-space-md bg-surface-container-high hover:bg-surface-bright text-on-surface rounded-lg flex items-center justify-center gap-2 font-label-data text-label-data font-semibold uppercase tracking-wider transition-colors" type="button">
|
||||
<span class="material-symbols-outlined text-[18px] text-tertiary-fixed-dim">query_stats</span>
|
||||
<span>CSV (20Hz)</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- SECONDARY RIDE CARD: Palomar Mountain Apex Run -->
|
||||
<div class="w-full bg-surface-container-low rounded-xl p-space-md flex flex-col gap-space-md shadow-sm relative overflow-hidden transition-all hover:bg-surface-container">
|
||||
<div class="flex items-start justify-between">
|
||||
<div class="flex flex-col gap-0.5">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="font-headline-sm text-headline-sm text-on-surface font-bold leading-tight">Palomar Mountain Apex Run</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-space-sm font-label-data text-label-caption text-on-surface-variant">
|
||||
<span>Oct 08 • 9:15 AM</span>
|
||||
<span class="w-1 h-1 rounded-full bg-outline-variant"></span>
|
||||
<span class="text-secondary-fixed">Ducati Panigale V4</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Trophy Badge -->
|
||||
<div class="flex items-center gap-1 bg-tertiary-container/20 text-tertiary-fixed px-2 py-0.5 rounded-full font-label-data text-label-caption font-semibold">
|
||||
<span class="material-symbols-outlined text-[14px]">emoji_events</span>
|
||||
<span>NEW PR</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Secondary Map Mini Graphic preview + Metric combo -->
|
||||
<div class="grid grid-cols-1 sm:grid-cols-3 gap-space-sm items-center">
|
||||
<!-- Mini Map Sector Visual -->
|
||||
<div class="h-28 bg-surface-container-lowest rounded-lg p-2 relative flex items-center justify-center overflow-hidden">
|
||||
<svg class="w-full h-full opacity-70" fill="none" viewbox="0 0 200 80">
|
||||
<path d="M 10 70 C 40 70, 50 10, 90 20 C 130 30, 150 70, 190 20" stroke="#b4c5ff" stroke-dasharray="3 3" stroke-linecap="round" stroke-width="2.5"></path>
|
||||
<circle cx="90" cy="20" fill="#00e5ff" r="4"></circle>
|
||||
<circle cx="160" cy="50" fill="#ffb4ab" r="5"></circle>
|
||||
</svg>
|
||||
<span class="absolute bottom-1 right-2 font-label-data text-[10px] text-on-surface-variant uppercase">S2 TIGHT SWITCHBACKS</span>
|
||||
</div>
|
||||
<!-- Quick Metrics 2-column on mobile -->
|
||||
<div class="col-span-2 grid grid-cols-2 gap-space-sm">
|
||||
<div class="bg-surface-container p-2.5 rounded-lg flex flex-col justify-center">
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant uppercase tracking-wider">Peak Lean Angle</span>
|
||||
<div class="flex items-baseline gap-1 mt-0.5">
|
||||
<span class="font-telemetry-metric-md text-telemetry-metric-md text-primary-fixed-dim font-bold">52°</span>
|
||||
<span class="font-label-data text-label-caption text-primary-fixed-dim">LEFT</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-surface-container p-2.5 rounded-lg flex flex-col justify-center">
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant uppercase tracking-wider">Track Top Speed</span>
|
||||
<div class="flex items-baseline gap-1 mt-0.5">
|
||||
<span class="font-telemetry-metric-md text-telemetry-metric-md text-on-surface font-bold">112</span>
|
||||
<span class="font-label-data text-label-caption text-on-surface-variant">MPH</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Secondary Action Strip -->
|
||||
<div class="flex items-center justify-between pt-1 font-label-data text-label-data">
|
||||
<div class="flex items-center gap-2 text-on-surface-variant">
|
||||
<span class="material-symbols-outlined text-[16px]">cloud_done</span>
|
||||
<span class="text-label-caption uppercase tracking-wider">R2 Backed (54.4 MB)</span>
|
||||
</div>
|
||||
<button class="min-h-[44px] px-space-md py-1.5 rounded-lg bg-surface-container-high hover:bg-surface-bright text-primary-container flex items-center gap-1.5 transition-colors uppercase font-bold tracking-wider" type="button">
|
||||
<span>Inspect Telemetry</span>
|
||||
<span class="material-symbols-outlined text-[16px]">arrow_forward</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Micro telemetry diagnostic badge row -->
|
||||
<div class="w-full flex items-center justify-center gap-space-md py-space-sm opacity-60">
|
||||
<div class="flex items-center gap-1 font-label-data text-[11px] text-on-surface-variant">
|
||||
<span class="material-symbols-outlined text-[14px] text-primary-container">memory</span>
|
||||
<span>IMU CALIBRATION: ±0.04° OK</span>
|
||||
</div>
|
||||
<div class="w-1 h-1 rounded-full bg-outline-variant"></div>
|
||||
<div class="flex items-center gap-1 font-label-data text-[11px] text-on-surface-variant">
|
||||
<span class="material-symbols-outlined text-[14px] text-[#10b981]">sensors</span>
|
||||
<span>OBD-II CAN LOGGING ACTIVE</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Interactive Tab & Replay Trigger Handlers -->
|
||||
<script>
|
||||
(function() {
|
||||
const tabRides = document.getElementById('tab-rides');
|
||||
const tabTrophies = document.getElementById('tab-trophies');
|
||||
|
||||
if (tabRides && tabTrophies) {
|
||||
tabTrophies.addEventListener('click', () => {
|
||||
tabTrophies.classList.add('bg-surface-container-high', 'text-primary-container', 'shadow-md');
|
||||
tabTrophies.classList.remove('text-on-surface-variant');
|
||||
|
||||
tabRides.classList.remove('bg-surface-container-high', 'text-primary-container', 'shadow-md');
|
||||
tabRides.classList.add('text-on-surface-variant');
|
||||
});
|
||||
|
||||
tabRides.addEventListener('click', () => {
|
||||
tabRides.classList.add('bg-surface-container-high', 'text-primary-container', 'shadow-md');
|
||||
tabRides.classList.remove('text-on-surface-variant');
|
||||
|
||||
tabTrophies.classList.remove('bg-surface-container-high', 'text-primary-container', 'shadow-md');
|
||||
tabTrophies.classList.add('text-on-surface-variant');
|
||||
});
|
||||
}
|
||||
})();
|
||||
</script></main><nav class="fixed bottom-0 w-full z-50 pb-safe bg-surface-container-lowest/90 backdrop-blur-xl shadow-[0_-4px_24px_rgba(0,0,0,0.6)]" data-active-classes="text-primary-container font-headline-sm [filter:drop-shadow(0_0_8px_rgba(0,229,255,0.5))]"><div class="grid grid-cols-6 items-center h-20 px-space-xs"><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="cockpit-dash" href="#"><span class="material-symbols-outlined text-[24px]">speed</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Dash</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="tactical-radar-map" href="#"><span class="material-symbols-outlined text-[24px]">radar</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Map</span></a><a aria-current="page" class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 transition-all duration-200 text-primary-container font-headline-sm [filter:drop-shadow(0_0_8px_rgba(0,229,255,0.5))]" data-path="telemetry-log" href="#"><span class="material-symbols-outlined text-[24px]">monitoring</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Activity</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="bike-garage" href="#"><span class="material-symbols-outlined text-[24px]">two_wheeler</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Garage</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="pack-comms" href="#"><span class="material-symbols-outlined text-[24px]">groups_3</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Social</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="hud-settings" href="#"><span class="material-symbols-outlined text-[24px]">tune</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Settings</span></a></div></nav></body></html>
|
||||
|
|
@ -0,0 +1,244 @@
|
|||
<!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, viewport-fit=cover" name="viewport"/><meta content="mobile_tab" name="shell-type"/><title>MotorSignal Cockpit HUD</title><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&family=JetBrains+Mono:wght@500;600;700&family=Space+Grotesk:wght@600;700&display=swap" rel="stylesheet"/><link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/><style>@layer base{html,body{width:100%;margin:0;padding:0;background-color:#101419;color:#e0e2ea;}body{overscroll-behavior:none;}.pb-safe{padding-bottom:env(safe-area-inset-bottom,0px);}.pt-safe{padding-top:env(safe-area-inset-top,0px);}main>:first-child{margin-top:0!important;}main>:last-child{margin-bottom:0!important;}}::-webkit-scrollbar{display:none;}</style><script src="https://cdn.tailwindcss.com"></script><script id="tailwind-config">tailwind.config = { darkMode: "class", theme: { extend: { "colors": { "on-primary": "#00363d", "tertiary-fixed-dim": "#d0bcff", "tertiary-container": "#d9c8ff", "on-primary-container": "#00626e", "surface-variant": "#32353b", "on-primary-fixed-variant": "#004f58", "surface-container-high": "#272a30", "outline-variant": "#3b494c", "surface-container": "#1d2025", "on-surface": "#e0e2ea", "background": "#101419", "primary-container": "#00e5ff", "inverse-surface": "#e0e2ea", "outline": "#849396", "on-secondary": "#002a78", "secondary-fixed-dim": "#b4c5ff", "on-tertiary": "#3c0091", "inverse-primary": "#006875", "surface-bright": "#36393f", "surface-container-low": "#181c21", "surface-container-highest": "#32353b", "inverse-on-surface": "#2d3036", "on-secondary-fixed": "#00174b", "primary": "#c3f5ff", "error-container": "#93000a", "surface-tint": "#00daf3", "on-tertiary-fixed-variant": "#5516be", "on-error-container": "#ffdad6", "primary-fixed-dim": "#00daf3", "tertiary-fixed": "#e9ddff", "on-primary-fixed": "#001f24", "on-error": "#690005", "surface-container-lowest": "#0b0e13", "secondary-container": "#0053db", "tertiary": "#f2e9ff", "surface-dim": "#101419", "on-surface-variant": "#bac9cc", "on-tertiary-container": "#6834d1", "primary-fixed": "#9cf0ff", "secondary-fixed": "#dbe1ff", "error": "#ffb4ab", "on-secondary-container": "#cdd7ff", "on-secondary-fixed-variant": "#003ea8", "surface": "#101419", "on-background": "#e0e2ea", "secondary": "#b4c5ff", "on-tertiary-fixed": "#23005c" }, "borderRadius": { "DEFAULT": "0.25rem", "lg": "0.5rem", "xl": "0.75rem", "full": "9999px" }, "spacing": { "margin-lg": "2rem", "space-xs": "0.25rem", "gutter-lg": "1.5rem", "space-xl": "2rem", "margin": "1rem", "space-sm": "0.5rem", "space-md": "1rem", "space-lg": "1.5rem", "gutter": "1rem" }, "fontFamily": { "headline-lg": ["Space Grotesk"], "body-lg": ["Inter"], "telemetry-metric-lg-mobile": ["JetBrains Mono"], "label-data": ["JetBrains Mono"], "display-hero": ["Space Grotesk"], "headline-sm": ["Space Grotesk"], "headline-md": ["Space Grotesk"], "label-caption": ["Inter"], "telemetry-metric-lg": ["JetBrains Mono"], "display-hero-mobile": ["Space Grotesk"], "telemetry-metric-md": ["JetBrains Mono"], "body-md": ["Inter"] }, "fontSize": { "headline-lg": ["32px", { "lineHeight": "40px", "letterSpacing": "-0.02em", "fontWeight": "700" }], "body-lg": ["16px", { "lineHeight": "24px", "fontWeight": "500" }], "telemetry-metric-lg-mobile": ["36px", { "lineHeight": "36px", "letterSpacing": "-0.03em", "fontWeight": "700" }], "label-data": ["12px", { "lineHeight": "16px", "letterSpacing": "0.08em", "fontWeight": "600" }], "display-hero": ["56px", { "lineHeight": "60px", "letterSpacing": "-0.03em", "fontWeight": "700" }], "headline-sm": ["20px", { "lineHeight": "28px", "fontWeight": "600" }], "headline-md": ["24px", { "lineHeight": "32px", "letterSpacing": "-0.01em", "fontWeight": "600" }], "label-caption": ["11px", { "lineHeight": "14px", "letterSpacing": "0.05em", "fontWeight": "600" }], "telemetry-metric-lg": ["48px", { "lineHeight": "48px", "letterSpacing": "-0.04em", "fontWeight": "700" }], "display-hero-mobile": ["40px", { "lineHeight": "44px", "letterSpacing": "-0.02em", "fontWeight": "700" }], "telemetry-metric-md": ["28px", { "lineHeight": "32px", "letterSpacing": "-0.02em", "fontWeight": "600" }], "body-md": ["14px", { "lineHeight": "20px", "fontWeight": "400" }] } } } }</script><style>
|
||||
body {
|
||||
min-height: max(884px, 100dvh);
|
||||
}
|
||||
</style>
|
||||
</head><body class="bg-surface font-body-md text-on-surface antialiased flex flex-col min-h-screen selection:bg-primary-container selection:text-on-primary-container"><header class="fixed top-0 w-full z-50 pt-safe bg-surface-container-lowest/85 backdrop-blur-xl shadow-[0_4px_20px_rgba(0,0,0,0.5)]"><div class="h-16 px-space-md flex items-center justify-between gap-space-sm"><div class="flex items-center gap-space-sm"><img alt="MotorSignal Brand Logo" class="h-8 w-auto object-contain drop-shadow-[0_0_8px_rgba(0,229,255,0.4)]" src="https://lh3.googleusercontent.com/aida/AEtjO1Vf56Tkh6bJ86BCfT5GHz_yPumvEXYLWojlNHAFG-cN4VvH_nLvEbWQ4x7uhJPRaAyO8ozAAbLI_huEN134QOIYp8BdHuqoZCsMk9_ILaUxZqilVgamefO6d2sG1R8laIWSUswanVsK9lfvIgppQm_XxBQipzkDgPwIoXk7yh10QTlmZqDICryF-1MoWFfFjM2zZswr6ynuAgZAviROYnFBF2D4hxm6YREQxkZQJaBcG9oAg_dYVgTHxwg"/><div class="flex flex-col"><span class="font-headline-sm text-headline-sm uppercase tracking-wider text-primary-fixed">MotorSignal</span><span class="font-label-caption text-label-caption text-on-surface-variant uppercase tracking-widest leading-none">Cockpit Dash</span></div></div><div class="flex items-center gap-space-sm"><div class="hidden sm:flex items-center gap-space-xs bg-surface-container-low px-space-sm py-1 rounded-full"><span class="w-2 h-2 rounded-full bg-primary-container animate-pulse shadow-[0_0_6px_#00e5ff]"></span><span class="font-label-data text-label-data text-primary-fixed">GPS 3D FIX</span></div><div class="flex items-center gap-1.5 bg-surface-container px-2 py-1 rounded-full"><span class="material-symbols-outlined text-[15px] text-primary-container">bolt</span><span class="font-label-data text-label-data text-on-surface">98%</span><span class="w-1 h-1 rounded-full bg-outline-variant"></span><span class="material-symbols-outlined text-[15px] text-primary-container">cell_tower</span></div><button aria-label="Rider Profile" class="min-w-[44px] min-h-[44px] flex items-center justify-center p-1 rounded-full focus:outline-none focus:ring-2 focus:ring-primary-container" type="button"><img alt="Profile" class="w-8 h-8 rounded-full object-cover ring-2 ring-primary-container/40" src="https://lh3.googleusercontent.com/aida-public/AB6AXuBb6sR8Ta8-L1_TN1LuCBfSxtZxX9hKOFjd-RjllihDsnp6AG1GlMhL9bVlb-ibhIRT3HMw_caXK7BmwmvWKNBcuizyqswUQZNztavckRTN1Xa6qGML_0kv8qvV_hrXWWK1EjSjVFzhRyDzf6VdGnZvUpGsFFmSBcaGVrXmEWFYnIa-qHyeWxZlT_SJmPuQJPQKEWEo6vC6kdDzXNnhoB4tpRHjIjCstvTdooPc0KVN_x3BqqmqadNI"/></button></div></div></header><main class="flex-1 flex flex-col relative w-full pt-16 pb-20 bg-surface"><div class="flex flex-col w-full px-space-md py-space-sm gap-space-md">
|
||||
<!-- Top Status Row & HUD Mode Switcher -->
|
||||
<section class="flex flex-col gap-space-sm">
|
||||
<!-- Quick System Badges Bar -->
|
||||
<div class="flex items-center justify-between text-on-surface-variant bg-surface-container-lowest p-space-xs rounded-xl shadow-sm">
|
||||
<div class="flex items-center gap-space-xs">
|
||||
<span class="inline-flex items-center gap-1 px-2 py-0.5 rounded-full bg-surface-container text-primary-container font-label-data text-label-data">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-primary-container shadow-[0_0_8px_#00e5ff] animate-pulse"></span>
|
||||
GPS 2D FIX
|
||||
</span>
|
||||
<span class="inline-flex items-center gap-1 px-2 py-0.5 rounded-full bg-surface-container font-label-data text-label-data text-on-surface">
|
||||
<span class="material-symbols-outlined text-[14px] text-primary-container">thermostat</span>
|
||||
79° F
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-space-xs">
|
||||
<button class="flex items-center gap-1 px-2 py-1 rounded-lg bg-surface-container text-primary-fixed hover:bg-surface-container-high transition-colors" id="audioToggleBtn" type="button">
|
||||
<span class="material-symbols-outlined text-[15px] text-primary-container">volume_up</span>
|
||||
<span class="font-label-caption text-label-caption tracking-wider uppercase">Tactical Tone</span>
|
||||
</button>
|
||||
<span class="inline-flex items-center gap-1 px-2 py-0.5 rounded-full bg-surface-container-high text-outline font-label-data text-label-data">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-outline"></span>
|
||||
STANDBY
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Mode Selector Runway -->
|
||||
<div class="grid grid-cols-3 p-1 rounded-xl bg-surface-container-lowest shadow-inner gap-1">
|
||||
<button class="py-2 rounded-lg font-headline-sm text-label-caption tracking-wider uppercase transition-all duration-200 text-on-surface-variant hover:text-on-surface" type="button">
|
||||
Minimal
|
||||
</button>
|
||||
<button class="py-2 rounded-lg font-headline-sm text-label-caption tracking-wider uppercase bg-primary-container text-on-primary-container shadow-[0_0_12px_rgba(0,229,255,0.4)]" type="button">
|
||||
Sport HUD
|
||||
</button>
|
||||
<button class="py-2 rounded-lg font-headline-sm text-label-caption tracking-wider uppercase transition-all duration-200 text-on-surface-variant hover:text-on-surface" type="button">
|
||||
Touring
|
||||
</button>
|
||||
</div>
|
||||
</section>
|
||||
<!-- Primary Telemetry Cluster -->
|
||||
<section class="flex flex-col gap-space-sm">
|
||||
<!-- Big Digital Speedometer Readout -->
|
||||
<div class="relative flex flex-col items-center justify-center p-space-lg rounded-xl bg-surface-container-lowest overflow-hidden shadow-md">
|
||||
<!-- Glow ambient background light ring -->
|
||||
<div class="absolute w-44 h-44 rounded-full bg-primary-container/10 blur-3xl pointer-events-none"></div>
|
||||
<div class="flex items-baseline justify-center relative">
|
||||
<span class="font-telemetry-metric-lg-mobile text-[88px] leading-none font-bold text-on-surface tracking-tighter drop-shadow-[0_0_24px_rgba(0,229,255,0.25)]" id="speedValue">
|
||||
0
|
||||
</span>
|
||||
</div>
|
||||
<div class="mt-2 flex items-center gap-space-xs">
|
||||
<span class="px-3 py-0.5 rounded-full bg-primary-container text-on-primary-container font-label-data text-label-data tracking-widest uppercase shadow-[0_0_8px_rgba(0,229,255,0.35)]">
|
||||
MPH
|
||||
</span>
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant tracking-wider uppercase">
|
||||
RADAR LOCK • IDLE
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Dual Circular Telemetry Gauges -->
|
||||
<div class="grid grid-cols-2 gap-space-sm">
|
||||
<!-- Left Gauge: G-Force Radar Friction Circle -->
|
||||
<div class="flex flex-col items-center p-space-sm rounded-xl bg-surface-container-low shadow-sm">
|
||||
<div class="w-full flex justify-between items-center mb-1 text-on-surface-variant">
|
||||
<span class="font-label-data text-label-caption uppercase tracking-wider text-primary-fixed">G-FORCE RADAR</span>
|
||||
<span class="material-symbols-outlined text-[14px] text-primary-container">adjust</span>
|
||||
</div>
|
||||
<div class="relative w-32 h-32 flex items-center justify-center my-1">
|
||||
<!-- Concentric target rings SVG -->
|
||||
<svg class="w-full h-full" fill="none" viewbox="0 0 120 120">
|
||||
<!-- 1.0G Ring -->
|
||||
<circle class="stroke-surface-variant" cx="60" cy="60" r="54" stroke-dasharray="3 3" stroke-width="1.5"></circle>
|
||||
<!-- 0.5G Ring -->
|
||||
<circle class="stroke-surface-variant" cx="60" cy="60" r="28" stroke-dasharray="2 2" stroke-width="1.5"></circle>
|
||||
<!-- Target crosshairs -->
|
||||
<line class="stroke-surface-container-high" stroke-width="1" x1="60" x2="60" y1="6" y2="114"></line>
|
||||
<line class="stroke-surface-container-high" stroke-width="1" x1="6" x2="114" y1="60" y2="60"></line>
|
||||
<!-- Center Origin Pivot -->
|
||||
<circle class="fill-outline" cx="60" cy="60" r="3"></circle>
|
||||
</svg>
|
||||
<!-- Dynamic glowing G-Force point bubble -->
|
||||
<div class="absolute w-4 h-4 rounded-full bg-primary-container shadow-[0_0_12px_#00e5ff] transition-transform duration-300 transform translate-x-0 translate-y-0" id="gForcePoint"></div>
|
||||
</div>
|
||||
<div class="w-full grid grid-cols-2 gap-1 pt-1 mt-1 text-center bg-surface-container-lowest rounded-lg p-1">
|
||||
<div>
|
||||
<div class="font-label-caption text-label-caption text-on-surface-variant uppercase">ACCEL</div>
|
||||
<div class="font-telemetry-metric-md text-label-data text-on-surface font-bold">0.00G</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="font-label-caption text-label-caption text-on-surface-variant uppercase">BRAKE</div>
|
||||
<div class="font-telemetry-metric-md text-label-data text-primary-container font-bold">0.00G</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Right Gauge: Motorcycle Lean Angle Arc -->
|
||||
<div class="flex flex-col items-center p-space-sm rounded-xl bg-surface-container-low shadow-sm">
|
||||
<div class="w-full flex justify-between items-center mb-1 text-on-surface-variant">
|
||||
<span class="font-label-data text-label-caption uppercase tracking-wider text-primary-fixed">LEAN ANGLE ARC</span>
|
||||
<span class="material-symbols-outlined text-[14px] text-primary-container">explore</span>
|
||||
</div>
|
||||
<div class="relative w-32 h-32 flex items-center justify-center my-1">
|
||||
<!-- Lean Angle Gauge Backdrop SVG -->
|
||||
<svg class="w-full h-full -rotate-90" viewbox="0 0 120 120">
|
||||
<!-- Background Arc -->
|
||||
<circle class="stroke-surface-container-high" cx="60" cy="60" fill="transparent" r="48" stroke-dasharray="150" stroke-dashoffset="0" stroke-linecap="round" stroke-width="6"></circle>
|
||||
<!-- Active Lean Marker Arc (3 deg) -->
|
||||
<circle class="stroke-primary-container" cx="60" cy="60" fill="transparent" r="48" stroke-dasharray="301" stroke-dashoffset="290" stroke-linecap="round" stroke-width="6"></circle>
|
||||
</svg>
|
||||
<!-- Motorbike Centered Silhouette banking -->
|
||||
<div class="absolute inset-0 flex flex-col items-center justify-center">
|
||||
<span class="material-symbols-outlined text-[34px] text-primary drop-shadow-[0_0_6px_rgba(0,229,255,0.6)] transform rotate-3 transition-transform duration-300">
|
||||
two_wheeler
|
||||
</span>
|
||||
</div>
|
||||
<!-- Bottom Lean Value Overlay -->
|
||||
<div class="absolute bottom-1 px-2 py-0.5 rounded bg-surface-container-lowest text-center">
|
||||
<span class="font-telemetry-metric-md text-[13px] text-primary-container font-bold leading-none">
|
||||
3° RIGHT
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Peak Memory Readouts -->
|
||||
<div class="w-full grid grid-cols-2 gap-1 pt-1 mt-1 text-center bg-surface-container-lowest rounded-lg p-1">
|
||||
<div>
|
||||
<div class="font-label-caption text-label-caption text-on-surface-variant uppercase">MAX L</div>
|
||||
<div class="font-telemetry-metric-md text-label-data text-on-surface font-bold">0°</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="font-label-caption text-label-caption text-on-surface-variant uppercase">MAX R</div>
|
||||
<div class="font-telemetry-metric-md text-label-data text-on-surface font-bold">0°</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- Trip Statistics Metric Bar -->
|
||||
<section class="rounded-xl bg-surface-container-low p-space-sm shadow-sm">
|
||||
<div class="grid grid-cols-3 divide-x-0 gap-2 text-center">
|
||||
<div class="flex flex-col items-center justify-center p-2 rounded-lg bg-surface-container-lowest">
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant uppercase tracking-wider">Trip Distance</span>
|
||||
<span class="font-telemetry-metric-md text-body-lg text-on-surface font-bold tracking-tight mt-0.5">0.00 <span class="text-label-caption text-on-surface-variant font-normal">MI</span></span>
|
||||
</div>
|
||||
<div class="flex flex-col items-center justify-center p-2 rounded-lg bg-surface-container-lowest">
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant uppercase tracking-wider">Top Speed</span>
|
||||
<span class="font-telemetry-metric-md text-body-lg text-primary-fixed font-bold tracking-tight mt-0.5">0 <span class="text-label-caption text-on-surface-variant font-normal">MPH</span></span>
|
||||
</div>
|
||||
<div class="flex flex-col items-center justify-center p-2 rounded-lg bg-surface-container-lowest">
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant uppercase tracking-wider">Avg Speed</span>
|
||||
<span class="font-telemetry-metric-md text-body-lg text-on-surface font-bold tracking-tight mt-0.5">0.0 <span class="text-label-caption text-on-surface-variant font-normal">MPH</span></span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- Performance Launch Shortcut Module -->
|
||||
<section class="relative overflow-hidden rounded-xl bg-surface-container p-space-md shadow-md group active:scale-[0.99] transition-transform">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-space-sm">
|
||||
<div class="w-10 h-10 rounded-xl bg-surface-container-highest flex items-center justify-center shadow-inner">
|
||||
<span class="material-symbols-outlined text-[24px] text-primary-container drop-shadow-[0_0_8px_#00e5ff]">
|
||||
bolt
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<div class="flex items-center gap-1.5">
|
||||
<span class="font-headline-sm text-body-lg font-bold tracking-wide uppercase text-on-surface">
|
||||
Performance Launch
|
||||
</span>
|
||||
</div>
|
||||
<span class="font-label-data text-label-caption text-on-surface-variant tracking-wider">
|
||||
0–60 MPH • 0–100 MPH • 1/4 MILE
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-1 px-3 py-1.5 rounded-full bg-surface-container-lowest text-primary-container shadow-[0_0_10px_rgba(0,229,255,0.2)]">
|
||||
<span class="w-2 h-2 rounded-full bg-primary-container animate-ping"></span>
|
||||
<span class="font-label-data text-label-data font-bold">READY ></span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- Primary Action Control: Huge Glove-Friendly Start Trigger -->
|
||||
<section class="pt-space-xs pb-space-sm">
|
||||
<button class="w-full min-h-[56px] py-4 px-6 rounded-full bg-primary-container text-on-primary-container font-headline-sm text-body-lg font-bold uppercase tracking-widest flex items-center justify-center gap-space-sm shadow-[0_0_24px_rgba(0,229,255,0.5)] active:bg-surface-tint active:scale-[0.98] transition-all" id="startSessionBtn" type="button">
|
||||
<span class="material-symbols-outlined text-[28px] fill-current">
|
||||
play_arrow
|
||||
</span>
|
||||
<span>Start Session</span>
|
||||
</button>
|
||||
</section>
|
||||
</div>
|
||||
<script>
|
||||
// Tactical micro-interaction for Cockpit HUD simulation
|
||||
(function initCockpitInteractions() {
|
||||
const startBtn = document.getElementById('startSessionBtn');
|
||||
const audioBtn = document.getElementById('audioToggleBtn');
|
||||
const speedEl = document.getElementById('speedValue');
|
||||
let sessionActive = false;
|
||||
|
||||
if (startBtn) {
|
||||
startBtn.addEventListener('click', () => {
|
||||
sessionActive = !sessionActive;
|
||||
if (sessionActive) {
|
||||
startBtn.classList.remove('bg-primary-container', 'text-on-primary-container');
|
||||
startBtn.classList.add('bg-error-container', 'text-on-error-container', 'shadow-[0_0_24px_rgba(239,68,68,0.5)]');
|
||||
startBtn.innerHTML = `
|
||||
<span class="material-symbols-outlined text-[28px]">pause</span>
|
||||
<span>Recording Active • Tap to End</span>
|
||||
`;
|
||||
if (speedEl) speedEl.textContent = '14';
|
||||
} else {
|
||||
startBtn.classList.remove('bg-error-container', 'text-on-error-container', 'shadow-[0_0_24px_rgba(239,68,68,0.5)]');
|
||||
startBtn.classList.add('bg-primary-container', 'text-on-primary-container', 'shadow-[0_0_24px_rgba(0,229,255,0.5)]');
|
||||
startBtn.innerHTML = `
|
||||
<span class="material-symbols-outlined text-[28px]">play_arrow</span>
|
||||
<span>Start Session</span>
|
||||
`;
|
||||
if (speedEl) speedEl.textContent = '0';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (audioBtn) {
|
||||
audioBtn.addEventListener('click', () => {
|
||||
const icon = audioBtn.querySelector('.material-symbols-outlined');
|
||||
const text = audioBtn.querySelector('span:last-child');
|
||||
if (icon && text) {
|
||||
if (icon.textContent === 'volume_up') {
|
||||
icon.textContent = 'volume_off';
|
||||
text.textContent = 'Muted';
|
||||
} else {
|
||||
icon.textContent = 'volume_up';
|
||||
text.textContent = 'Tactical Tone';
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
})();
|
||||
</script></main><nav class="fixed bottom-0 w-full z-50 pb-safe bg-surface-container-lowest/90 backdrop-blur-xl shadow-[0_-4px_24px_rgba(0,0,0,0.6)]" data-active-classes="text-primary-container font-headline-sm [filter:drop-shadow(0_0_8px_rgba(0,229,255,0.5))]"><div class="grid grid-cols-6 items-center h-20 px-space-xs"><a aria-current="page" class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 transition-all duration-200 text-primary-container font-headline-sm [filter:drop-shadow(0_0_8px_rgba(0,229,255,0.5))]" data-path="cockpit-dash" href="#"><span class="material-symbols-outlined text-[24px]">speed</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Dash</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="tactical-radar-map" href="#"><span class="material-symbols-outlined text-[24px]">radar</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Map</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="telemetry-log" href="#"><span class="material-symbols-outlined text-[24px]">monitoring</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Activity</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="bike-garage" href="#"><span class="material-symbols-outlined text-[24px]">two_wheeler</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Garage</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="pack-comms" href="#"><span class="material-symbols-outlined text-[24px]">groups_3</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Social</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="hud-settings" href="#"><span class="material-symbols-outlined text-[24px]">tune</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Settings</span></a></div></nav></body></html>
|
||||
|
|
@ -0,0 +1,351 @@
|
|||
<!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, viewport-fit=cover" name="viewport"/><meta content="mobile_tab" name="shell-type"/><title>MotorSignal Cockpit HUD</title><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&family=JetBrains+Mono:wght@500;600;700&family=Space+Grotesk:wght@600;700&display=swap" rel="stylesheet"/><link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/><style>@layer base{html,body{width:100%;margin:0;padding:0;background-color:#101419;color:#e0e2ea;}body{overscroll-behavior:none;}.pb-safe{padding-bottom:env(safe-area-inset-bottom,0px);}.pt-safe{padding-top:env(safe-area-inset-top,0px);}main>:first-child{margin-top:0!important;}main>:last-child{margin-bottom:0!important;}}::-webkit-scrollbar{display:none;}</style><script src="https://cdn.tailwindcss.com"></script><script id="tailwind-config">tailwind.config = { darkMode: "class", theme: { extend: { "colors": { "on-primary": "#00363d", "tertiary-fixed-dim": "#d0bcff", "tertiary-container": "#d9c8ff", "on-primary-container": "#00626e", "surface-variant": "#32353b", "on-primary-fixed-variant": "#004f58", "surface-container-high": "#272a30", "outline-variant": "#3b494c", "surface-container": "#1d2025", "on-surface": "#e0e2ea", "background": "#101419", "primary-container": "#00e5ff", "inverse-surface": "#e0e2ea", "outline": "#849396", "on-secondary": "#002a78", "secondary-fixed-dim": "#b4c5ff", "on-tertiary": "#3c0091", "inverse-primary": "#006875", "surface-bright": "#36393f", "surface-container-low": "#181c21", "surface-container-highest": "#32353b", "inverse-on-surface": "#2d3036", "on-secondary-fixed": "#00174b", "primary": "#c3f5ff", "error-container": "#93000a", "surface-tint": "#00daf3", "on-tertiary-fixed-variant": "#5516be", "on-error-container": "#ffdad6", "primary-fixed-dim": "#00daf3", "tertiary-fixed": "#e9ddff", "on-primary-fixed": "#001f24", "on-error": "#690005", "surface-container-lowest": "#0b0e13", "secondary-container": "#0053db", "tertiary": "#f2e9ff", "surface-dim": "#101419", "on-surface-variant": "#bac9cc", "on-tertiary-container": "#6834d1", "primary-fixed": "#9cf0ff", "secondary-fixed": "#dbe1ff", "error": "#ffb4ab", "on-secondary-container": "#cdd7ff", "on-secondary-fixed-variant": "#003ea8", "surface": "#101419", "on-background": "#e0e2ea", "secondary": "#b4c5ff", "on-tertiary-fixed": "#23005c" }, "borderRadius": { "DEFAULT": "0.25rem", "lg": "0.5rem", "xl": "0.75rem", "full": "9999px" }, "spacing": { "margin-lg": "2rem", "space-xs": "0.25rem", "gutter-lg": "1.5rem", "space-xl": "2rem", "margin": "1rem", "space-sm": "0.5rem", "space-md": "1rem", "space-lg": "1.5rem", "gutter": "1rem" }, "fontFamily": { "headline-lg": ["Space Grotesk"], "body-lg": ["Inter"], "telemetry-metric-lg-mobile": ["JetBrains Mono"], "label-data": ["JetBrains Mono"], "display-hero": ["Space Grotesk"], "headline-sm": ["Space Grotesk"], "headline-md": ["Space Grotesk"], "label-caption": ["Inter"], "telemetry-metric-lg": ["JetBrains Mono"], "display-hero-mobile": ["Space Grotesk"], "telemetry-metric-md": ["JetBrains Mono"], "body-md": ["Inter"] }, "fontSize": { "headline-lg": ["32px", { "lineHeight": "40px", "letterSpacing": "-0.02em", "fontWeight": "700" }], "body-lg": ["16px", { "lineHeight": "24px", "fontWeight": "500" }], "telemetry-metric-lg-mobile": ["36px", { "lineHeight": "36px", "letterSpacing": "-0.03em", "fontWeight": "700" }], "label-data": ["12px", { "lineHeight": "16px", "letterSpacing": "0.08em", "fontWeight": "600" }], "display-hero": ["56px", { "lineHeight": "60px", "letterSpacing": "-0.03em", "fontWeight": "700" }], "headline-sm": ["20px", { "lineHeight": "28px", "fontWeight": "600" }], "headline-md": ["24px", { "lineHeight": "32px", "letterSpacing": "-0.01em", "fontWeight": "600" }], "label-caption": ["11px", { "lineHeight": "14px", "letterSpacing": "0.05em", "fontWeight": "600" }], "telemetry-metric-lg": ["48px", { "lineHeight": "48px", "letterSpacing": "-0.04em", "fontWeight": "700" }], "display-hero-mobile": ["40px", { "lineHeight": "44px", "letterSpacing": "-0.02em", "fontWeight": "700" }], "telemetry-metric-md": ["28px", { "lineHeight": "32px", "letterSpacing": "-0.02em", "fontWeight": "600" }], "body-md": ["14px", { "lineHeight": "20px", "fontWeight": "400" }] } } } }</script><style>
|
||||
body {
|
||||
min-height: max(884px, 100dvh);
|
||||
}
|
||||
</style>
|
||||
</head><body class="bg-surface font-body-md text-on-surface antialiased flex flex-col min-h-screen selection:bg-primary-container selection:text-on-primary-container"><header class="fixed top-0 w-full z-50 pt-safe bg-surface-container-lowest/85 backdrop-blur-xl shadow-[0_4px_20px_rgba(0,0,0,0.5)]"><div class="h-16 px-space-md flex items-center justify-between gap-space-sm"><div class="flex items-center gap-space-sm"><img alt="MotorSignal Brand Logo" class="h-8 w-auto object-contain drop-shadow-[0_0_8px_rgba(0,229,255,0.4)]" src="https://lh3.googleusercontent.com/aida/AEtjO1Vf56Tkh6bJ86BCfT5GHz_yPumvEXYLWojlNHAFG-cN4VvH_nLvEbWQ4x7uhJPRaAyO8ozAAbLI_huEN134QOIYp8BdHuqoZCsMk9_ILaUxZqilVgamefO6d2sG1R8laIWSUswanVsK9lfvIgppQm_XxBQipzkDgPwIoXk7yh10QTlmZqDICryF-1MoWFfFjM2zZswr6ynuAgZAviROYnFBF2D4hxm6YREQxkZQJaBcG9oAg_dYVgTHxwg"/><div class="flex flex-col"><span class="font-headline-sm text-headline-sm uppercase tracking-wider text-primary-fixed">MotorSignal</span><span class="font-label-caption text-label-caption text-on-surface-variant uppercase tracking-widest leading-none">Telemetry Log</span></div></div><div class="flex items-center gap-space-sm"><div class="hidden sm:flex items-center gap-space-xs bg-surface-container-low px-space-sm py-1 rounded-full"><span class="w-2 h-2 rounded-full bg-primary-container animate-pulse shadow-[0_0_6px_#00e5ff]"></span><span class="font-label-data text-label-data text-primary-fixed">GPS 3D FIX</span></div><div class="flex items-center gap-1.5 bg-surface-container px-2 py-1 rounded-full"><span class="material-symbols-outlined text-[15px] text-primary-container">bolt</span><span class="font-label-data text-label-data text-on-surface">98%</span><span class="w-1 h-1 rounded-full bg-outline-variant"></span><span class="material-symbols-outlined text-[15px] text-primary-container">cell_tower</span></div><button aria-label="Rider Profile" class="min-w-[44px] min-h-[44px] flex items-center justify-center p-1 rounded-full focus:outline-none focus:ring-2 focus:ring-primary-container" type="button"><img alt="Profile" class="w-8 h-8 rounded-full object-cover ring-2 ring-primary-container/40" src="https://lh3.googleusercontent.com/aida-public/AB6AXuBb6sR8Ta8-L1_TN1LuCBfSxtZxX9hKOFjd-RjllihDsnp6AG1GlMhL9bVlb-ibhIRT3HMw_caXK7BmwmvWKNBcuizyqswUQZNztavckRTN1Xa6qGML_0kv8qvV_hrXWWK1EjSjVFzhRyDzf6VdGnZvUpGsFFmSBcaGVrXmEWFYnIa-qHyeWxZlT_SJmPuQJPQKEWEo6vC6kdDzXNnhoB4tpRHjIjCstvTdooPc0KVN_x3BqqmqadNI"/></button></div></div></header><main class="flex-1 flex flex-col relative w-full pt-16 pb-20 bg-surface"><div class="flex flex-col w-full px-space-md py-space-md gap-space-md">
|
||||
<!-- Staging Environment Badges Strip -->
|
||||
<div class="flex items-center justify-between gap-space-xs overflow-x-auto no-scrollbar py-0.5">
|
||||
<div class="flex items-center gap-1.5 bg-surface-container-high px-space-sm py-1 rounded-full shrink-0 shadow-sm">
|
||||
<span class="w-2 h-2 rounded-full bg-primary-container animate-ping"></span>
|
||||
<span class="font-label-data text-label-data text-primary-fixed uppercase tracking-wider">GPS FIX: ±1.2 FT OK</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-1.5 bg-surface-container-high px-space-sm py-1 rounded-full shrink-0 shadow-sm">
|
||||
<span class="material-symbols-outlined text-[14px] text-primary-fixed-dim" style="font-variation-settings: 'FILL' 1;">check_circle</span>
|
||||
<span class="font-label-data text-label-data text-primary uppercase tracking-wider">SLOPE: -0.3% VALID</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-1.5 bg-surface-container-low px-space-sm py-1 rounded-full shrink-0 shadow-sm">
|
||||
<span class="material-symbols-outlined text-[14px] text-on-surface-variant">air</span>
|
||||
<span class="font-label-data text-label-data text-on-surface-variant uppercase tracking-wider">DA: 1,240 FT</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Christmas Tree Drag Racing Staging Cluster -->
|
||||
<div class="flex flex-col bg-surface-container-lowest rounded-xl p-space-md gap-space-md relative overflow-hidden shadow-xl">
|
||||
<div class="absolute inset-0 bg-gradient-to-b from-primary-container/5 via-transparent to-transparent pointer-events-none"></div>
|
||||
<div class="flex items-center justify-between z-10">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-primary-container text-[20px]">vertical_align_bottom</span>
|
||||
<span class="font-headline-sm text-headline-sm uppercase tracking-wider text-on-surface">NHRA Pro Tree</span>
|
||||
</div>
|
||||
<span class="font-label-data text-label-data px-2 py-0.5 rounded bg-primary-container/20 text-primary-fixed uppercase tracking-widest" id="systemModeBadge">AUTO SENSE</span>
|
||||
</div>
|
||||
<!-- Tree Vertical Layout with Two Columns of Lights -->
|
||||
<div class="flex items-center justify-center gap-6 py-2 z-10">
|
||||
<!-- Left Tree Branch -->
|
||||
<div class="flex flex-col items-center gap-3">
|
||||
<!-- Pre-Stage Amber -->
|
||||
<div class="w-10 h-10 rounded-full bg-surface-container flex items-center justify-center transition-all duration-300 shadow-[0_0_16px_rgba(245,158,11,0.6)] bg-amber-400" id="lightPreStageL">
|
||||
<span class="w-4 h-4 rounded-full bg-amber-200"></span>
|
||||
</div>
|
||||
<!-- Stage Amber -->
|
||||
<div class="w-10 h-10 rounded-full bg-surface-container flex items-center justify-center transition-all duration-300 shadow-[0_0_16px_rgba(245,158,11,0.6)] bg-amber-400" id="lightStageL">
|
||||
<span class="w-4 h-4 rounded-full bg-amber-200"></span>
|
||||
</div>
|
||||
<!-- Triple Amber Countdown Bulbs -->
|
||||
<div class="w-9 h-9 rounded-full bg-surface-container-highest flex items-center justify-center transition-all duration-200" id="lightCount1L">
|
||||
<span class="w-3.5 h-3.5 rounded-full bg-surface-container"></span>
|
||||
</div>
|
||||
<div class="w-9 h-9 rounded-full bg-surface-container-highest flex items-center justify-center transition-all duration-200" id="lightCount2L">
|
||||
<span class="w-3.5 h-3.5 rounded-full bg-surface-container"></span>
|
||||
</div>
|
||||
<!-- Launch Green Bulb -->
|
||||
<div class="w-11 h-11 rounded-full bg-surface-container-highest flex items-center justify-center transition-all duration-200" id="lightGreenL">
|
||||
<span class="w-4 h-4 rounded-full bg-surface-container"></span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Center Pillar / Status Line -->
|
||||
<div class="flex flex-col items-center justify-between h-48 py-1">
|
||||
<span class="font-label-data text-label-data text-on-surface-variant">PRE</span>
|
||||
<span class="font-label-data text-label-data text-on-surface-variant">STG</span>
|
||||
<span class="font-label-data text-label-data text-outline">.500</span>
|
||||
<span class="font-label-data text-label-data text-outline">.500</span>
|
||||
<span class="font-label-data text-label-data font-bold text-primary-fixed">GO</span>
|
||||
</div>
|
||||
<!-- Right Tree Branch -->
|
||||
<div class="flex flex-col items-center gap-3">
|
||||
<!-- Pre-Stage Amber -->
|
||||
<div class="w-10 h-10 rounded-full bg-surface-container flex items-center justify-center transition-all duration-300 shadow-[0_0_16px_rgba(245,158,11,0.6)] bg-amber-400" id="lightPreStageR">
|
||||
<span class="w-4 h-4 rounded-full bg-amber-200"></span>
|
||||
</div>
|
||||
<!-- Stage Amber -->
|
||||
<div class="w-10 h-10 rounded-full bg-surface-container flex items-center justify-center transition-all duration-300 shadow-[0_0_16px_rgba(245,158,11,0.6)] bg-amber-400" id="lightStageR">
|
||||
<span class="w-4 h-4 rounded-full bg-amber-200"></span>
|
||||
</div>
|
||||
<!-- Triple Amber Countdown Bulbs -->
|
||||
<div class="w-9 h-9 rounded-full bg-surface-container-highest flex items-center justify-center transition-all duration-200" id="lightCount1R">
|
||||
<span class="w-3.5 h-3.5 rounded-full bg-surface-container"></span>
|
||||
</div>
|
||||
<div class="w-9 h-9 rounded-full bg-surface-container-highest flex items-center justify-center transition-all duration-200" id="lightCount2R">
|
||||
<span class="w-3.5 h-3.5 rounded-full bg-surface-container"></span>
|
||||
</div>
|
||||
<!-- Launch Green Bulb -->
|
||||
<div class="w-11 h-11 rounded-full bg-surface-container-highest flex items-center justify-center transition-all duration-200" id="lightGreenR">
|
||||
<span class="w-4 h-4 rounded-full bg-surface-container"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Glowing Tactical Banner -->
|
||||
<div class="relative overflow-hidden flex items-center justify-center gap-2 bg-primary-container/15 py-3 px-space-sm rounded-lg shadow-lg" id="launchTriggerBanner">
|
||||
<span class="w-2.5 h-2.5 rounded-full bg-primary-container animate-pulse"></span>
|
||||
<span class="font-label-data text-label-data text-primary-fixed uppercase tracking-wider text-center">
|
||||
STOPPED — READY TO LAUNCH (ACCELERATE TO TRIGGER)
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Split Timing Performance Tiles (2-Column Grid) -->
|
||||
<div class="grid grid-cols-2 gap-space-sm w-full">
|
||||
<!-- Tile 1: 0-60 MPH (Featured with Personal Best) -->
|
||||
<div class="flex flex-col bg-surface-container-high rounded-xl p-space-sm justify-between shadow-md relative overflow-hidden">
|
||||
<div class="flex items-center justify-between w-full">
|
||||
<span class="font-label-data text-label-data text-on-surface-variant uppercase">0–60 MPH</span>
|
||||
<div class="flex items-center gap-1 text-amber-300 bg-amber-400/10 px-1.5 py-0.5 rounded">
|
||||
<span class="material-symbols-outlined text-[13px]" style="font-variation-settings: 'FILL' 1;">emoji_events</span>
|
||||
<span class="font-label-caption text-label-caption">PB</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="my-1">
|
||||
<div class="flex items-baseline gap-1">
|
||||
<span class="font-telemetry-metric-lg-mobile text-telemetry-metric-lg-mobile text-primary tracking-tighter">3.28</span>
|
||||
<span class="font-label-data text-label-data text-on-surface-variant">SEC</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center justify-between w-full pt-1">
|
||||
<span class="font-label-caption text-label-caption text-error flex items-center">
|
||||
<span class="material-symbols-outlined text-[12px]">arrow_upward</span>+0.12s vs PB
|
||||
</span>
|
||||
<span class="font-label-data text-label-data text-primary-fixed">1.12G PEAK</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Tile 2: 0-100 MPH -->
|
||||
<div class="flex flex-col bg-surface-container-high rounded-xl p-space-sm justify-between shadow-md">
|
||||
<div class="flex items-center justify-between w-full">
|
||||
<span class="font-label-data text-label-data text-on-surface-variant uppercase">0–100 MPH</span>
|
||||
<span class="material-symbols-outlined text-[16px] text-on-surface-variant">speed</span>
|
||||
</div>
|
||||
<div class="my-1">
|
||||
<div class="flex items-baseline gap-1">
|
||||
<span class="font-telemetry-metric-lg-mobile text-telemetry-metric-lg-mobile text-on-surface tracking-tighter">7.41</span>
|
||||
<span class="font-label-data text-label-data text-on-surface-variant">SEC</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center justify-between w-full pt-1">
|
||||
<span class="font-label-caption text-label-caption text-primary-fixed flex items-center">
|
||||
<span class="material-symbols-outlined text-[12px]">arrow_downward</span>-0.08s BEST
|
||||
</span>
|
||||
<span class="font-label-data text-label-data text-outline">VALID</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Tile 3: 1/4 MILE -->
|
||||
<div class="flex flex-col bg-surface-container-high rounded-xl p-space-sm justify-between shadow-md">
|
||||
<div class="flex items-center justify-between w-full">
|
||||
<span class="font-label-data text-label-data text-on-surface-variant uppercase">1/4 MILE TRAP</span>
|
||||
<span class="material-symbols-outlined text-[16px] text-primary-container">flag</span>
|
||||
</div>
|
||||
<div class="my-1">
|
||||
<div class="flex items-baseline gap-1">
|
||||
<span class="font-telemetry-metric-lg-mobile text-telemetry-metric-lg-mobile text-primary tracking-tighter">10.92</span>
|
||||
<span class="font-label-data text-label-data text-on-surface-variant">SEC</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center justify-between w-full pt-1">
|
||||
<span class="font-label-data text-label-data text-primary-fixed font-bold">@ 131.4 MPH</span>
|
||||
<span class="font-label-caption text-label-caption text-outline">SLOPE -0.2%</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Tile 4: 60-130 MPH -->
|
||||
<div class="flex flex-col bg-surface-container-high rounded-xl p-space-sm justify-between shadow-md">
|
||||
<div class="flex items-center justify-between w-full">
|
||||
<span class="font-label-data text-label-data text-on-surface-variant uppercase">60–130 MPH</span>
|
||||
<span class="material-symbols-outlined text-[16px] text-on-surface-variant">rocket_launch</span>
|
||||
</div>
|
||||
<div class="my-1">
|
||||
<div class="flex items-baseline gap-1">
|
||||
<span class="font-telemetry-metric-lg-mobile text-telemetry-metric-lg-mobile text-on-surface tracking-tighter">6.15</span>
|
||||
<span class="font-label-data text-label-data text-on-surface-variant">SEC</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center justify-between w-full pt-1">
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant">ROLLING RUN</span>
|
||||
<span class="font-label-data text-label-data text-primary-fixed">0.82G AVG</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Telemetry Acceleration Curve Card -->
|
||||
<div class="flex flex-col bg-surface-container rounded-xl p-space-md gap-space-sm shadow-lg">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex flex-col">
|
||||
<span class="font-headline-sm text-headline-sm uppercase text-on-surface">Telemetry Curve</span>
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant">PREVIOUS PASS: SPEED VS LONGITUDINAL G</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-space-sm">
|
||||
<div class="flex items-center gap-1">
|
||||
<span class="w-2 h-2 rounded-full bg-primary-container"></span>
|
||||
<span class="font-label-caption text-label-caption text-primary">SPEED</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-1">
|
||||
<span class="w-2 h-2 rounded-full bg-secondary"></span>
|
||||
<span class="font-label-caption text-label-caption text-secondary">G-FORCE</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Inline SVG Chart Display -->
|
||||
<div class="relative w-full h-36 bg-surface-container-lowest rounded-lg p-2 flex items-center justify-center overflow-hidden">
|
||||
<!-- Subtle Grid Lines -->
|
||||
<svg class="absolute inset-0 w-full h-full stroke-surface-variant/40" xmlns="http://www.w3.org/2000/svg">
|
||||
<line stroke-dasharray="3,3" stroke-width="1" x1="0" x2="100%" y1="25%" y2="25%"></line>
|
||||
<line stroke-dasharray="3,3" stroke-width="1" x1="0" x2="100%" y1="50%" y2="50%"></line>
|
||||
<line stroke-dasharray="3,3" stroke-width="1" x1="0" x2="100%" y1="75%" y2="75%"></line>
|
||||
<line stroke-dasharray="3,3" stroke-width="1" x1="25%" x2="25%" y1="0" y2="100%"></line>
|
||||
<line stroke-dasharray="3,3" stroke-width="1" x1="50%" x2="50%" y1="0" y2="100%"></line>
|
||||
<line stroke-dasharray="3,3" stroke-width="1" x1="75%" x2="75%" y1="0" y2="100%"></line>
|
||||
</svg>
|
||||
<!-- Curve Graphic -->
|
||||
<svg class="w-full h-full relative z-10" preserveaspectratio="none" viewbox="0 0 320 120">
|
||||
<defs>
|
||||
<lineargradient id="speedGrad" x1="0" x2="0" y1="0" y2="1">
|
||||
<stop offset="0%" stop-color="#00daf3" stop-opacity="0.35"></stop>
|
||||
<stop offset="100%" stop-color="#00daf3" stop-opacity="0.0"></stop>
|
||||
</lineargradient>
|
||||
</defs>
|
||||
<!-- Speed Area Fill -->
|
||||
<path d="M 0,115 Q 40,95 80,60 T 160,28 T 240,15 T 320,10 L 320,115 Z" fill="url(#speedGrad)"></path>
|
||||
<!-- Speed Trace Line -->
|
||||
<path d="M 0,115 Q 40,95 80,60 T 160,28 T 240,15 T 320,10" fill="none" stroke="#00e5ff" stroke-linecap="round" stroke-width="2.5"></path>
|
||||
<!-- G-Force Spike Curve (Peaks at 1.15G then tapers) -->
|
||||
<path d="M 0,95 Q 15,12 35,8 Q 65,30 110,65 Q 180,82 320,88" fill="none" stroke="#b4c5ff" stroke-dasharray="4,2" stroke-width="1.8"></path>
|
||||
<!-- Peak G marker point -->
|
||||
<circle class="animate-pulse" cx="35" cy="8" fill="#ffffff" r="3.5"></circle>
|
||||
</svg>
|
||||
<!-- Apex G Annotation Overlay -->
|
||||
<div class="absolute top-2 left-10 bg-secondary-container px-1.5 py-0.5 rounded shadow-sm z-20">
|
||||
<span class="font-label-data text-label-data text-on-secondary-container">1.15G TRACTION PEAK</span>
|
||||
</div>
|
||||
<!-- Trap Speed Annotation -->
|
||||
<div class="absolute top-2 right-2 bg-surface-container-high px-1.5 py-0.5 rounded z-20">
|
||||
<span class="font-label-data text-label-data text-primary-fixed">131.4 MPH</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Quick Stats Bar Below Chart -->
|
||||
<div class="grid grid-cols-3 gap-space-xs text-center pt-1">
|
||||
<div class="flex flex-col bg-surface-container-low py-1.5 px-1 rounded">
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant">60-FT TIME</span>
|
||||
<span class="font-label-data text-label-data text-on-surface">1.71s</span>
|
||||
</div>
|
||||
<div class="flex flex-col bg-surface-container-low py-1.5 px-1 rounded">
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant">330-FT TIME</span>
|
||||
<span class="font-label-data text-label-data text-on-surface">4.62s</span>
|
||||
</div>
|
||||
<div class="flex flex-col bg-surface-container-low py-1.5 px-1 rounded">
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant">1/8 MILE</span>
|
||||
<span class="font-label-data text-label-data text-primary-fixed">7.04s @ 104M</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Primary Launch Controls (Glove-Friendly Touch Area) -->
|
||||
<div class="flex flex-col gap-space-sm pt-space-xs">
|
||||
<div class="grid grid-cols-5 gap-space-sm">
|
||||
<!-- Arm Launch Button (Spans 3 cols) -->
|
||||
<button class="col-span-3 min-h-[56px] bg-primary-container hover:bg-primary-fixed-dim text-on-primary-container rounded-xl flex items-center justify-center gap-2 font-telemetry-metric-md text-telemetry-metric-md font-bold uppercase transition-transform active:scale-95 shadow-[0_0_20px_rgba(0,229,255,0.4)]" id="armLaunchBtn" type="button">
|
||||
<span class="material-symbols-outlined text-[26px]">sensors</span>
|
||||
<span>ARM SENSOR</span>
|
||||
</button>
|
||||
<!-- Abort Button (Spans 2 cols) -->
|
||||
<button class="col-span-2 min-h-[56px] bg-surface-container-high hover:bg-error-container text-on-surface hover:text-on-error-container rounded-xl flex items-center justify-center gap-1.5 font-label-data text-label-data font-bold uppercase transition-colors active:scale-95" id="abortBtn" type="button">
|
||||
<span class="material-symbols-outlined text-[20px] text-error">close</span>
|
||||
<span>ABORT</span>
|
||||
</button>
|
||||
</div>
|
||||
<!-- History & DA Analysis Link -->
|
||||
<a class="w-full py-2.5 flex items-center justify-center gap-1.5 rounded-lg bg-surface-container-low hover:bg-surface-container transition-colors text-on-surface-variant hover:text-primary" href="#">
|
||||
<span class="material-symbols-outlined text-[16px] text-primary-container">query_stats</span>
|
||||
<span class="font-label-data text-label-data uppercase tracking-wider">VIEW PASS LOG & DA ANALYSIS</span>
|
||||
<span class="material-symbols-outlined text-[16px]">chevron_right</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Inline Micro-Interactions Script for Launch Sequence Simulation -->
|
||||
<script>
|
||||
(function() {
|
||||
const armBtn = document.getElementById('armLaunchBtn');
|
||||
const abortBtn = document.getElementById('abortBtn');
|
||||
const banner = document.getElementById('launchTriggerBanner');
|
||||
const modeBadge = document.getElementById('systemModeBadge');
|
||||
|
||||
const l1L = document.getElementById('lightCount1L');
|
||||
const l1R = document.getElementById('lightCount1R');
|
||||
const l2L = document.getElementById('lightCount2L');
|
||||
const l2R = document.getElementById('lightCount2R');
|
||||
const grnL = document.getElementById('lightGreenL');
|
||||
const grnR = document.getElementById('lightGreenR');
|
||||
|
||||
let countdownTimer = null;
|
||||
let isArmed = false;
|
||||
|
||||
function resetTree() {
|
||||
if (countdownTimer) clearTimeout(countdownTimer);
|
||||
isArmed = false;
|
||||
|
||||
[l1L, l1R, l2L, l2R].forEach(el => {
|
||||
el.className = 'w-9 h-9 rounded-full bg-surface-container-highest flex items-center justify-center transition-all duration-200';
|
||||
el.firstElementChild.className = 'w-3.5 h-3.5 rounded-full bg-surface-container';
|
||||
});
|
||||
|
||||
[grnL, grnR].forEach(el => {
|
||||
el.className = 'w-11 h-11 rounded-full bg-surface-container-highest flex items-center justify-center transition-all duration-200';
|
||||
el.firstElementChild.className = 'w-4 h-4 rounded-full bg-surface-container';
|
||||
});
|
||||
|
||||
armBtn.className = 'col-span-3 min-h-[56px] bg-primary-container hover:bg-primary-fixed-dim text-on-primary-container rounded-xl flex items-center justify-center gap-2 font-telemetry-metric-md text-telemetry-metric-md font-bold uppercase transition-transform active:scale-95 shadow-[0_0_20px_rgba(0,229,255,0.4)]';
|
||||
armBtn.querySelector('span:last-child').textContent = 'ARM SENSOR';
|
||||
modeBadge.textContent = 'AUTO SENSE';
|
||||
banner.className = 'relative overflow-hidden flex items-center justify-center gap-2 bg-primary-container/15 py-3 px-space-sm rounded-lg shadow-lg';
|
||||
banner.querySelector('span:last-child').textContent = 'STOPPED — READY TO LAUNCH (ACCELERATE TO TRIGGER)';
|
||||
}
|
||||
|
||||
armBtn.addEventListener('click', () => {
|
||||
if (isArmed) {
|
||||
resetTree();
|
||||
return;
|
||||
}
|
||||
|
||||
isArmed = true;
|
||||
armBtn.className = 'col-span-3 min-h-[56px] bg-amber-400 text-on-primary-fixed rounded-xl flex items-center justify-center gap-2 font-telemetry-metric-md text-telemetry-metric-md font-bold uppercase shadow-[0_0_20px_rgba(245,158,11,0.5)]';
|
||||
armBtn.querySelector('span:last-child').textContent = 'COUNTDOWN...';
|
||||
modeBadge.textContent = 'ARMED PRO';
|
||||
banner.querySelector('span:last-child').textContent = 'STAGED: DROP CLUTCH ON GREEN';
|
||||
|
||||
// Step 1: First Amber drop
|
||||
countdownTimer = setTimeout(() => {
|
||||
[l1L, l1R].forEach(el => {
|
||||
el.className = 'w-9 h-9 rounded-full bg-amber-400 flex items-center justify-center transition-all duration-100 shadow-[0_0_14px_rgba(245,158,11,0.8)]';
|
||||
el.firstElementChild.className = 'w-3.5 h-3.5 rounded-full bg-amber-100';
|
||||
});
|
||||
|
||||
// Step 2: Second Amber
|
||||
countdownTimer = setTimeout(() => {
|
||||
[l2L, l2R].forEach(el => {
|
||||
el.className = 'w-9 h-9 rounded-full bg-amber-400 flex items-center justify-center transition-all duration-100 shadow-[0_0_14px_rgba(245,158,11,0.8)]';
|
||||
el.firstElementChild.className = 'w-3.5 h-3.5 rounded-full bg-amber-100';
|
||||
});
|
||||
|
||||
// Step 3: GREEN FLASH
|
||||
countdownTimer = setTimeout(() => {
|
||||
[grnL, grnR].forEach(el => {
|
||||
el.className = 'w-11 h-11 rounded-full bg-primary-container flex items-center justify-center transition-all duration-75 shadow-[0_0_24px_rgba(0,229,255,1)]';
|
||||
el.firstElementChild.className = 'w-5 h-5 rounded-full bg-white';
|
||||
});
|
||||
banner.className = 'relative overflow-hidden flex items-center justify-center gap-2 bg-primary-container py-3 px-space-sm rounded-lg shadow-[0_0_25px_rgba(0,229,255,0.7)] text-on-primary-container';
|
||||
banner.querySelector('span:last-child').className = 'font-label-data text-label-data text-on-primary-container uppercase font-bold tracking-widest text-center';
|
||||
banner.querySelector('span:last-child').textContent = 'GREEN GREEN GREEN! FULL THROTTLE';
|
||||
armBtn.querySelector('span:last-child').textContent = 'ACTIVE LOGGING';
|
||||
}, 500);
|
||||
}, 500);
|
||||
}, 500);
|
||||
});
|
||||
|
||||
abortBtn.addEventListener('click', resetTree);
|
||||
})();
|
||||
</script></main><nav class="fixed bottom-0 w-full z-50 pb-safe bg-surface-container-lowest/90 backdrop-blur-xl shadow-[0_-4px_24px_rgba(0,0,0,0.6)]" data-active-classes="text-primary-container font-headline-sm [filter:drop-shadow(0_0_8px_rgba(0,229,255,0.5))]"><div class="grid grid-cols-6 items-center h-20 px-space-xs"><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="cockpit-dash" href="#"><span class="material-symbols-outlined text-[24px]">speed</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Dash</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="tactical-radar-map" href="#"><span class="material-symbols-outlined text-[24px]">radar</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Map</span></a><a aria-current="page" class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 transition-all duration-200 text-primary-container font-headline-sm [filter:drop-shadow(0_0_8px_rgba(0,229,255,0.5))]" data-path="telemetry-log" href="#"><span class="material-symbols-outlined text-[24px]">monitoring</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Activity</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="bike-garage" href="#"><span class="material-symbols-outlined text-[24px]">two_wheeler</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Garage</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="pack-comms" href="#"><span class="material-symbols-outlined text-[24px]">groups_3</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Social</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="hud-settings" href="#"><span class="material-symbols-outlined text-[24px]">tune</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Settings</span></a></div></nav></body></html>
|
||||
|
|
@ -0,0 +1,339 @@
|
|||
<!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, viewport-fit=cover" name="viewport"/><meta content="mobile_tab" name="shell-type"/><title>MotorSignal Cockpit HUD</title><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&family=JetBrains+Mono:wght@500;600;700&family=Space+Grotesk:wght@600;700&display=swap" rel="stylesheet"/><link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/><style>@layer base{html,body{width:100%;margin:0;padding:0;background-color:#101419;color:#e0e2ea;}body{overscroll-behavior:none;}.pb-safe{padding-bottom:env(safe-area-inset-bottom,0px);}.pt-safe{padding-top:env(safe-area-inset-top,0px);}main>:first-child{margin-top:0!important;}main>:last-child{margin-bottom:0!important;}}::-webkit-scrollbar{display:none;}</style><script src="https://cdn.tailwindcss.com"></script><script id="tailwind-config">tailwind.config = { darkMode: "class", theme: { extend: { "colors": { "on-primary": "#00363d", "tertiary-fixed-dim": "#d0bcff", "tertiary-container": "#d9c8ff", "on-primary-container": "#00626e", "surface-variant": "#32353b", "on-primary-fixed-variant": "#004f58", "surface-container-high": "#272a30", "outline-variant": "#3b494c", "surface-container": "#1d2025", "on-surface": "#e0e2ea", "background": "#101419", "primary-container": "#00e5ff", "inverse-surface": "#e0e2ea", "outline": "#849396", "on-secondary": "#002a78", "secondary-fixed-dim": "#b4c5ff", "on-tertiary": "#3c0091", "inverse-primary": "#006875", "surface-bright": "#36393f", "surface-container-low": "#181c21", "surface-container-highest": "#32353b", "inverse-on-surface": "#2d3036", "on-secondary-fixed": "#00174b", "primary": "#c3f5ff", "error-container": "#93000a", "surface-tint": "#00daf3", "on-tertiary-fixed-variant": "#5516be", "on-error-container": "#ffdad6", "primary-fixed-dim": "#00daf3", "tertiary-fixed": "#e9ddff", "on-primary-fixed": "#001f24", "on-error": "#690005", "surface-container-lowest": "#0b0e13", "secondary-container": "#0053db", "tertiary": "#f2e9ff", "surface-dim": "#101419", "on-surface-variant": "#bac9cc", "on-tertiary-container": "#6834d1", "primary-fixed": "#9cf0ff", "secondary-fixed": "#dbe1ff", "error": "#ffb4ab", "on-secondary-container": "#cdd7ff", "on-secondary-fixed-variant": "#003ea8", "surface": "#101419", "on-background": "#e0e2ea", "secondary": "#b4c5ff", "on-tertiary-fixed": "#23005c" }, "borderRadius": { "DEFAULT": "0.25rem", "lg": "0.5rem", "xl": "0.75rem", "full": "9999px" }, "spacing": { "margin-lg": "2rem", "space-xs": "0.25rem", "gutter-lg": "1.5rem", "space-xl": "2rem", "margin": "1rem", "space-sm": "0.5rem", "space-md": "1rem", "space-lg": "1.5rem", "gutter": "1rem" }, "fontFamily": { "headline-lg": ["Space Grotesk"], "body-lg": ["Inter"], "telemetry-metric-lg-mobile": ["JetBrains Mono"], "label-data": ["JetBrains Mono"], "display-hero": ["Space Grotesk"], "headline-sm": ["Space Grotesk"], "headline-md": ["Space Grotesk"], "label-caption": ["Inter"], "telemetry-metric-lg": ["JetBrains Mono"], "display-hero-mobile": ["Space Grotesk"], "telemetry-metric-md": ["JetBrains Mono"], "body-md": ["Inter"] }, "fontSize": { "headline-lg": ["32px", { "lineHeight": "40px", "letterSpacing": "-0.02em", "fontWeight": "700" }], "body-lg": ["16px", { "lineHeight": "24px", "fontWeight": "500" }], "telemetry-metric-lg-mobile": ["36px", { "lineHeight": "36px", "letterSpacing": "-0.03em", "fontWeight": "700" }], "label-data": ["12px", { "lineHeight": "16px", "letterSpacing": "0.08em", "fontWeight": "600" }], "display-hero": ["56px", { "lineHeight": "60px", "letterSpacing": "-0.03em", "fontWeight": "700" }], "headline-sm": ["20px", { "lineHeight": "28px", "fontWeight": "600" }], "headline-md": ["24px", { "lineHeight": "32px", "letterSpacing": "-0.01em", "fontWeight": "600" }], "label-caption": ["11px", { "lineHeight": "14px", "letterSpacing": "0.05em", "fontWeight": "600" }], "telemetry-metric-lg": ["48px", { "lineHeight": "48px", "letterSpacing": "-0.04em", "fontWeight": "700" }], "display-hero-mobile": ["40px", { "lineHeight": "44px", "letterSpacing": "-0.02em", "fontWeight": "700" }], "telemetry-metric-md": ["28px", { "lineHeight": "32px", "letterSpacing": "-0.02em", "fontWeight": "600" }], "body-md": ["14px", { "lineHeight": "20px", "fontWeight": "400" }] } } } }</script><style>
|
||||
body {
|
||||
min-height: max(884px, 100dvh);
|
||||
}
|
||||
</style>
|
||||
</head><body class="bg-surface font-body-md text-on-surface antialiased flex flex-col min-h-screen selection:bg-primary-container selection:text-on-primary-container"><header class="fixed top-0 w-full z-50 pt-safe bg-surface-container-lowest/85 backdrop-blur-xl shadow-[0_4px_20px_rgba(0,0,0,0.5)]"><div class="h-16 px-space-md flex items-center justify-between gap-space-sm"><div class="flex items-center gap-space-sm"><img alt="MotorSignal Brand Logo" class="h-8 w-auto object-contain drop-shadow-[0_0_8px_rgba(0,229,255,0.4)]" src="https://lh3.googleusercontent.com/aida/AEtjO1Vf56Tkh6bJ86BCfT5GHz_yPumvEXYLWojlNHAFG-cN4VvH_nLvEbWQ4x7uhJPRaAyO8ozAAbLI_huEN134QOIYp8BdHuqoZCsMk9_ILaUxZqilVgamefO6d2sG1R8laIWSUswanVsK9lfvIgppQm_XxBQipzkDgPwIoXk7yh10QTlmZqDICryF-1MoWFfFjM2zZswr6ynuAgZAviROYnFBF2D4hxm6YREQxkZQJaBcG9oAg_dYVgTHxwg"/><div class="flex flex-col"><span class="font-headline-sm text-headline-sm uppercase tracking-wider text-primary-fixed">MotorSignal</span><span class="font-label-caption text-label-caption text-on-surface-variant uppercase tracking-widest leading-none">Tactical Radar Map</span></div></div><div class="flex items-center gap-space-sm"><div class="hidden sm:flex items-center gap-space-xs bg-surface-container-low px-space-sm py-1 rounded-full"><span class="w-2 h-2 rounded-full bg-primary-container animate-pulse shadow-[0_0_6px_#00e5ff]"></span><span class="font-label-data text-label-data text-primary-fixed">GPS 3D FIX</span></div><div class="flex items-center gap-1.5 bg-surface-container px-2 py-1 rounded-full"><span class="material-symbols-outlined text-[15px] text-primary-container">bolt</span><span class="font-label-data text-label-data text-on-surface">98%</span><span class="w-1 h-1 rounded-full bg-outline-variant"></span><span class="material-symbols-outlined text-[15px] text-primary-container">cell_tower</span></div><button aria-label="Rider Profile" class="min-w-[44px] min-h-[44px] flex items-center justify-center p-1 rounded-full focus:outline-none focus:ring-2 focus:ring-primary-container" type="button"><img alt="Profile" class="w-8 h-8 rounded-full object-cover ring-2 ring-primary-container/40" src="https://lh3.googleusercontent.com/aida-public/AB6AXuBb6sR8Ta8-L1_TN1LuCBfSxtZxX9hKOFjd-RjllihDsnp6AG1GlMhL9bVlb-ibhIRT3HMw_caXK7BmwmvWKNBcuizyqswUQZNztavckRTN1Xa6qGML_0kv8qvV_hrXWWK1EjSjVFzhRyDzf6VdGnZvUpGsFFmSBcaGVrXmEWFYnIa-qHyeWxZlT_SJmPuQJPQKEWEo6vC6kdDzXNnhoB4tpRHjIjCstvTdooPc0KVN_x3BqqmqadNI"/></button></div></div></header><main class="flex-1 flex flex-col relative w-full pt-16 pb-20 bg-surface"><div class="flex flex-col w-full relative select-none">
|
||||
<!-- Interactive Ambient Tactical Radar Map Canvas Simulation -->
|
||||
<div class="relative w-full h-[620px] sm:h-[700px] overflow-hidden bg-surface-container-lowest flex items-center justify-center">
|
||||
<!-- Underlay Satellite/Terrain Mock with Dark Filter -->
|
||||
<div class="absolute inset-0 w-full h-full bg-cover bg-center opacity-30 mix-blend-luminosity scale-105" data-location="Skyline Boulevard, Woodside, California" style="background-image: url('https://lh3.googleusercontent.com/aida-public/AB6AXuCPmWsOmSpH3UsexJqWF9EL6VhfkjthhiRBT4iz7KDbBJfldWByxUc3Iprer3Fpi1wci2ihgjxkyu__vgmg8LUD6weL0lHmPjJ1ioMcvnt9GiJSZ7td_lxlIAYdiVk4aHhxsifdJVHKWsBkrDsREC60UVkoQSQ4a7Vi9y-ub_X4bfknK6zvaRX5qfcvd6rOgq52MD1vzxLmCbv5hv_4eJNFN8LNXLBJUFP6DCi3MEf1yFz-Nj-nbrnz')"></div>
|
||||
<!-- Grid overlay and tactical coordinate crosshairs -->
|
||||
<div class="absolute inset-0 bg-[radial-gradient(#1e293b_1px,transparent_1px)] [background-size:24px_24px] opacity-40 pointer-events-none"></div>
|
||||
<div class="absolute inset-0 bg-gradient-to-t from-surface via-transparent to-surface-container-lowest/80 pointer-events-none"></div>
|
||||
<!-- Mountain Twisties Topo Vector SVG & Route Polyline -->
|
||||
<svg class="absolute inset-0 w-full h-full pointer-events-none" fill="none" preserveaspectratio="xMidYMid slice" viewbox="0 0 400 700" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<!-- Route Glow Filter -->
|
||||
<filter height="140%" id="routeGlow" width="140%" x="-20%" y="-20%">
|
||||
<fegaussianblur result="blur" stddeviation="5"></fegaussianblur>
|
||||
<femerge>
|
||||
<femergenode in="blur"></femergenode>
|
||||
<femergenode in="SourceGraphic"></femergenode>
|
||||
</femerge>
|
||||
</filter>
|
||||
<!-- Hazard Zone Glow -->
|
||||
<filter height="160%" id="hazardGlow" width="160%" x="-30%" y="-30%">
|
||||
<fegaussianblur result="blur" stddeviation="8"></fegaussianblur>
|
||||
<femerge>
|
||||
<femergenode in="blur"></femergenode>
|
||||
<femergenode in="SourceGraphic"></femergenode>
|
||||
</femerge>
|
||||
</filter>
|
||||
</defs>
|
||||
<!-- Faint Topo Elevation Rings -->
|
||||
<path d="M-50,220 C60,180 180,260 260,200 C340,140 420,210 460,180" opacity="0.3" stroke="#32353b" stroke-dasharray="4 6" stroke-width="1"></path>
|
||||
<path d="M-40,310 C80,270 170,360 290,300 C390,250 430,320 480,290" opacity="0.25" stroke="#32353b" stroke-dasharray="3 4" stroke-width="1"></path>
|
||||
<path d="M-20,440 C100,400 200,480 320,410 C390,380 430,450 490,430" opacity="0.2" stroke="#32353b" stroke-width="1"></path>
|
||||
<!-- Secondary Ridge Road (Ghost Path) -->
|
||||
<path d="M70,680 Q110,540 130,460 T220,320 T290,120 T310,-20" stroke="#1d2025" stroke-linecap="round" stroke-width="6"></path>
|
||||
<!-- Primary High-Grip Mountain Route (Skyline Twisties Polyline) -->
|
||||
<path class="drop-shadow-[0_0_12px_#00e5ff]" d="M190,690 C195,620 185,570 140,520 C95,470 110,400 170,360 C230,320 280,310 270,240 C260,180 160,160 185,90 C200,40 240,10 250,-30" filter="url(#routeGlow)" id="track-path" stroke="#00e5ff" stroke-linecap="round" stroke-linejoin="round" stroke-width="5"></path>
|
||||
<!-- Apex Corner Turn Badges -->
|
||||
<g transform="translate(112, 420)">
|
||||
<circle fill="#181c21" r="14" stroke="#00e5ff" stroke-width="1"></circle>
|
||||
<text class="font-label-data text-[10px] font-bold" fill="#00e5ff" text-anchor="middle" x="0" y="4">R42</text>
|
||||
</g>
|
||||
<g transform="translate(262, 280)">
|
||||
<circle fill="#181c21" r="14" stroke="#00e5ff" stroke-width="1"></circle>
|
||||
<text class="font-label-data text-[10px] font-bold" fill="#00e5ff" text-anchor="middle" x="0" y="4">L38</text>
|
||||
</g>
|
||||
<!-- Danger/Police Radar Hotspot Zone (Stationary Marker 350m ahead) -->
|
||||
<g transform="translate(268, 220)">
|
||||
<!-- Pulsing radar halo -->
|
||||
<circle class="animate-ping" fill="#93000a" opacity="0.3" r="36" style="animation-duration: 2.2s;"></circle>
|
||||
<circle fill="#93000a" filter="url(#hazardGlow)" opacity="0.5" r="22"></circle>
|
||||
<circle fill="#ffb4ab" r="14"></circle>
|
||||
<path d="M-6,-6 L6,6 M6,-6 L-6,6" stroke="#690005" stroke-linecap="round" stroke-width="2.5"></path>
|
||||
</g>
|
||||
<!-- Active Rider Cockpit Blip with Sweeping Photon Directional Beam -->
|
||||
<g id="rider-blip" transform="translate(150, 480)">
|
||||
<!-- Forward Directional Headlight Cone -->
|
||||
<polygon fill="url(#beamGrad)" opacity="0.35" points="0,0 -40,-90 40,-90"></polygon>
|
||||
<!-- Proximity sonar pulse ring -->
|
||||
<circle class="animate-ping" fill="none" r="28" stroke="#00e5ff" stroke-width="1" style="animation-duration: 3s;"></circle>
|
||||
<circle class="shadow-lg" fill="#00363d" r="18" stroke="#00e5ff" stroke-width="2"></circle>
|
||||
<circle fill="#00e5ff" r="8"></circle>
|
||||
<!-- Heading Indicator Needle -->
|
||||
<polygon fill="#ffffff" points="0,-14 -4,-4 4,-4"></polygon>
|
||||
</g>
|
||||
<lineargradient id="beamGrad" x1="0%" x2="0%" y1="100%" y2="0%">
|
||||
<stop offset="0%" stop-color="#00e5ff" stop-opacity="0.8"></stop>
|
||||
<stop offset="100%" stop-color="#00e5ff" stop-opacity="0"></stop>
|
||||
</lineargradient>
|
||||
</svg>
|
||||
<!-- FLOATING TOP HUD: SEARCH & QUICK WAYPOINTS -->
|
||||
<div class="absolute top-3 inset-x-3 z-30 flex flex-col gap-space-xs">
|
||||
<!-- Glove-Engineered Address Search Bar -->
|
||||
<div class="flex items-center w-full h-14 bg-surface-container-high/95 backdrop-blur-md rounded-xl px-space-md shadow-xl transition-all">
|
||||
<span class="material-symbols-outlined text-primary-container text-[24px] mr- space-sm">search</span>
|
||||
<input class="flex-1 bg-transparent text-on-surface placeholder:text-on-surface-variant font-body-md text-body-md focus:outline-none min-w-0" placeholder="Search route, waypoints, twisties..." type="text" value="Skyline Blvd (CA-35)"/>
|
||||
<button aria-label="Clear or voice search" class="min-w-[44px] min-h-[44px] flex items-center justify-center text-primary-container rounded-lg active:bg-surface-variant" type="button">
|
||||
<span class="material-symbols-outlined text-[22px]">mic</span>
|
||||
</button>
|
||||
</div>
|
||||
<!-- Quick Route Category Chips (Horizontal Scrollable) -->
|
||||
<div class="flex items-center gap-space-xs overflow-x-auto no-scrollbar py-1">
|
||||
<button class="flex items-center gap-1.5 px-3 py-1.5 rounded-full bg-primary-container text-on-primary-container font-label-data text-label-data shrink-0 shadow-md active:scale-95 transition-transform" type="button">
|
||||
<span class="material-symbols-outlined text-[15px]">verified</span>
|
||||
<span>Skyline Blvd</span>
|
||||
</button>
|
||||
<button class="flex items-center gap-1.5 px-3 py-1.5 rounded-full bg-surface-container text-on-surface-variant font-label-data text-label-data shrink-0 shadow-sm active:bg-surface-variant transition-colors" type="button">
|
||||
<span class="material-symbols-outlined text-[15px] text-tertiary-fixed-dim">restaurant</span>
|
||||
<span>Alice's Restaurant</span>
|
||||
</button>
|
||||
<button class="flex items-center gap-1.5 px-3 py-1.5 rounded-full bg-surface-container text-on-surface-variant font-label-data text-label-data shrink-0 shadow-sm active:bg-surface-variant transition-colors" type="button">
|
||||
<span class="material-symbols-outlined text-[15px] text-secondary">alt_route</span>
|
||||
<span>Bear Creek Rd</span>
|
||||
</button>
|
||||
<button class="flex items-center gap-1.5 px-3 py-1.5 rounded-full bg-surface-container text-on-surface-variant font-label-data text-label-data shrink-0 shadow-sm active:bg-surface-variant transition-colors" type="button">
|
||||
<span class="material-symbols-outlined text-[15px] text-primary-container">landscape</span>
|
||||
<span>Page Mill Apex</span>
|
||||
</button>
|
||||
</div>
|
||||
<!-- SCREEN-MOB-07: URGENT POLICE RADAR ALERT OVERLAY CARD -->
|
||||
<div class="w-full mt-1 bg-surface-container-lowest/95 backdrop-blur-xl rounded-xl p-space-md shadow-2xl relative overflow-hidden transition-all duration-300" id="radarAlertBanner">
|
||||
<!-- Visual Accent Warning Lightbar -->
|
||||
<div class="absolute top-0 inset-x-0 h-1 bg-error animate-pulse"></div>
|
||||
<div class="flex items-start gap-space-sm">
|
||||
<!-- Flashing Police Radar Beacon Icon -->
|
||||
<div class="w-12 h-12 rounded-xl bg-error-container flex items-center justify-center shrink-0 shadow-[0_0_16px_rgba(239,68,68,0.4)]">
|
||||
<span class="material-symbols-outlined text-error text-[28px] animate-bounce">local_police</span>
|
||||
</div>
|
||||
<!-- Alert Details & Threat Metrology -->
|
||||
<div class="flex-1 min-w-0">
|
||||
<div class="flex items-center justify-between gap-1 mb-0.5">
|
||||
<span class="font-headline-sm text-label-data uppercase tracking-wider text-error font-bold truncate">POLICE TRAP AHEAD</span>
|
||||
<!-- Proximity Telemetry Badge -->
|
||||
<span class="px-2 py-0.5 rounded-full bg-error-container font-label-data text-label-caption text-error font-bold shrink-0" id="countdownBadge">
|
||||
350 M
|
||||
</span>
|
||||
</div>
|
||||
<p class="font-body-md text-label-caption text-on-surface leading-tight line-clamp-2">
|
||||
Hidden radar speed gun verified on Skyline Blvd descent.
|
||||
</p>
|
||||
<p class="font-label-data text-[10px] text-on-surface-variant mt-0.5">
|
||||
14 Waze confirmations • 47s ago • Limit 45 MPH
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Glove-Friendly 1-Tap Tactical Action Bar -->
|
||||
<div class="grid grid-cols-2 gap-space-sm mt-3 pt-2">
|
||||
<button class="h-12 flex items-center justify-center gap-1.5 rounded-lg bg-surface-container text-on-surface font-label-data text-label-data uppercase tracking-wider active:bg-surface-variant transition-colors" id="muteToneBtn" type="button">
|
||||
<span class="material-symbols-outlined text-[18px] text-primary-container">volume_off</span>
|
||||
<span id="muteLabel">Mute Tone</span>
|
||||
</button>
|
||||
<button class="h-12 flex items-center justify-center gap-1.5 rounded-lg bg-surface-container-high text-on-surface-variant font-label-data text-label-data uppercase tracking-wider active:bg-surface-variant transition-colors" id="dismissAlertBtn" type="button">
|
||||
<span class="material-symbols-outlined text-[18px]">check</span>
|
||||
<span>Dismiss</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- FLOATING RIGHT VERTICAL HUD DOCK (Glove-Sized 48px+ Hit Targets) -->
|
||||
<div class="absolute right-3 bottom-24 z-30 flex flex-col gap-2">
|
||||
<!-- Compass / Heading Orientation Toggle -->
|
||||
<button aria-label="Toggle North-Up vs Heading-Up" class="w-13 h-13 min-w-[50px] min-h-[50px] rounded-xl bg-surface-container-high/90 backdrop-blur-md flex flex-col items-center justify-center shadow-lg active:scale-95 transition-all" id="compassBtn" type="button">
|
||||
<span class="material-symbols-outlined text-primary-container text-[24px]">explore</span>
|
||||
<span class="font-label-data text-[9px] text-on-surface-variant uppercase -mt-0.5">HEAD</span>
|
||||
</button>
|
||||
<!-- Map Layer Switcher Button -->
|
||||
<button aria-label="Open Map Layer Controls" class="w-13 h-13 min-w-[50px] min-h-[50px] rounded-xl bg-surface-container-high/90 backdrop-blur-md flex items-center justify-center shadow-lg active:scale-95 transition-all text-on-surface" id="openLayersBtn" type="button">
|
||||
<span class="material-symbols-outlined text-[24px] text-primary-container">layers</span>
|
||||
</button>
|
||||
<!-- Re-Center Live GPS Button -->
|
||||
<button aria-label="Recenter on Motorcycle Blip" class="w-13 h-13 min-w-[50px] min-h-[50px] rounded-xl bg-surface-container-high/90 backdrop-blur-md flex items-center justify-center shadow-lg active:scale-95 transition-all text-on-surface" id="recenterGpsBtn" type="button">
|
||||
<span class="material-symbols-outlined text-[24px] text-primary-container animate-pulse">my_location</span>
|
||||
</button>
|
||||
<!-- Glove Zoom Step Controls -->
|
||||
<div class="flex flex-col bg-surface-container-high/90 backdrop-blur-md rounded-xl shadow-lg overflow-hidden">
|
||||
<button aria-label="Zoom Map In" class="w-13 h-12 min-w-[50px] flex items-center justify-center text-on-surface active:bg-surface-variant transition-colors" id="zoomInBtn" type="button">
|
||||
<span class="material-symbols-outlined text-[24px]">add</span>
|
||||
</button>
|
||||
<div class="h-[1px] w-full bg-outline-variant/30"></div>
|
||||
<button aria-label="Zoom Map Out" class="w-13 h-12 min-w-[50px] flex items-center justify-center text-on-surface active:bg-surface-variant transition-colors" id="zoomOutBtn" type="button">
|
||||
<span class="material-symbols-outlined text-[24px]">remove</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- FLOATING LEFT TELEMETRY QUICK-STATS PILL -->
|
||||
<div class="absolute left-3 bottom-24 z-30 flex flex-col gap-2">
|
||||
<div class="bg-surface-container-lowest/90 backdrop-blur-md px-3 py-2 rounded-xl shadow-lg flex flex-col items-start min-w-[90px]">
|
||||
<span class="font-label-data text-label-caption text-on-surface-variant uppercase">Lean Max</span>
|
||||
<div class="flex items-baseline gap-1">
|
||||
<span class="font-telemetry-metric-md text-headline-sm text-primary-container font-bold">44°</span>
|
||||
<span class="font-label-data text-[10px] text-primary-fixed">LEFT</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-surface-container-lowest/90 backdrop-blur-md px-3 py-2 rounded-xl shadow-lg flex flex-col items-start min-w-[90px]">
|
||||
<span class="font-label-data text-label-caption text-on-surface-variant uppercase">Elevation</span>
|
||||
<div class="flex items-baseline gap-1">
|
||||
<span class="font-telemetry-metric-md text-headline-sm text-on-surface font-bold">2,140</span>
|
||||
<span class="font-label-data text-[10px] text-on-surface-variant">FT</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- BOTTOM SHEET PREVIEW: MAP LAYERS & RADAR FEEDS -->
|
||||
<div class="absolute bottom-0 inset-x-0 z-40 bg-surface-container-low/95 backdrop-blur-2xl rounded-t-2xl px-space-md pt-3 pb-space-lg shadow-2xl transition-all duration-300" id="layerBottomSheet">
|
||||
<!-- Drag handle -->
|
||||
<div class="w-12 h-1 bg-surface-variant rounded-full mx-auto mb-3"></div>
|
||||
<!-- Header with status -->
|
||||
<div class="flex items-center justify-between mb-3">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-primary-container text-[20px]">layers</span>
|
||||
<span class="font-headline-sm text-body-lg uppercase tracking-wider font-bold">Tactical Map Layers</span>
|
||||
</div>
|
||||
<span class="px-2 py-0.5 rounded-full bg-surface-container-high font-label-data text-label-caption text-primary-fixed">
|
||||
GPS ACTIVE
|
||||
</span>
|
||||
</div>
|
||||
<!-- Layer Preset Cards Grid -->
|
||||
<div class="grid grid-cols-3 gap-space-sm mb-4">
|
||||
<!-- Tactical Dark Vector (Active) -->
|
||||
<button class="flex flex-col items-start p-2.5 rounded-xl bg-surface-container-highest text-left shadow-sm transition-all relative overflow-hidden group" type="button">
|
||||
<div class="w-full h-12 rounded-lg bg-surface-container-lowest mb-2 flex items-center justify-center relative overflow-hidden">
|
||||
<div class="absolute inset-0 bg-gradient-to-tr from-primary-container/20 to-transparent"></div>
|
||||
<span class="material-symbols-outlined text-primary-container text-[24px]">dark_mode</span>
|
||||
</div>
|
||||
<span class="font-label-data text-label-caption font-bold text-primary truncate w-full">Tactical Dark</span>
|
||||
<span class="font-label-data text-[10px] text-on-surface-variant">Vector HUD</span>
|
||||
<!-- Active Dot Badge -->
|
||||
<div class="absolute top-2 right-2 w-2 h-2 rounded-full bg-primary-container"></div>
|
||||
</button>
|
||||
<!-- Satellite 4K -->
|
||||
<button class="flex flex-col items-start p-2.5 rounded-xl bg-surface-container text-left shadow-sm active:bg-surface-variant transition-all" type="button">
|
||||
<div class="w-full h-12 rounded-lg bg-surface-container-low mb-2 flex items-center justify-center relative overflow-hidden">
|
||||
<div class="absolute inset-0 bg-cover bg-center opacity-60" data-location="California Coastal Mountains" style="background-image: url('https://lh3.googleusercontent.com/aida-public/AB6AXuAq_LMmPaEtLaA8hTzcSH-Y3oZyv__12BPKdl5uflHZ8DhaZ28YIKhGbWzodOrgT3ArjsB1Ltc_Z_Ot5LW9oBhjfoK5KtrRf1H1XLxEdkMRVuBO1Ax1eMl_KpD-TSbm3HiNw-YHbOpUvYeinqC6hr1iBlMm0U0JgwfsoxtBK_jod0oGlsWiCThvvO4-FOER-Fb-WMqNjkOgBL7jn9Uzde1cuz3QZJJsOv6Cm3C7irRMLFlSJYneohRC')"></div>
|
||||
<span class="material-symbols-outlined text-on-surface text-[24px] relative z-10">satellite_alt</span>
|
||||
</div>
|
||||
<span class="font-label-data text-label-caption font-semibold text-on-surface truncate w-full">Satellite 4K</span>
|
||||
<span class="font-label-data text-[10px] text-on-surface-variant">Photo Real</span>
|
||||
</button>
|
||||
<!-- 3D Topo Elevation -->
|
||||
<button class="flex flex-col items-start p-2.5 rounded-xl bg-surface-container text-left shadow-sm active:bg-surface-variant transition-all" type="button">
|
||||
<div class="w-full h-12 rounded-lg bg-surface-container-low mb-2 flex items-center justify-center relative overflow-hidden">
|
||||
<span class="material-symbols-outlined text-secondary text-[24px]">filter_hdr</span>
|
||||
</div>
|
||||
<span class="font-label-data text-label-caption font-semibold text-on-surface truncate w-full">3D Topo</span>
|
||||
<span class="font-label-data text-[10px] text-on-surface-variant">Apex Pitch</span>
|
||||
</button>
|
||||
</div>
|
||||
<!-- Tactical Feature Toggles -->
|
||||
<div class="flex flex-col gap-2">
|
||||
<!-- Police Trap Radar Mesh -->
|
||||
<div class="flex items-center justify-between p-3 rounded-xl bg-surface-container">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="w-9 h-9 rounded-lg bg-error-container/60 flex items-center justify-center text-error">
|
||||
<span class="material-symbols-outlined text-[20px]">radar</span>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<span class="font-body-md text-label-data text-on-surface font-semibold">Police Traps & Lasers</span>
|
||||
<span class="font-label-data text-[10px] text-on-surface-variant">Community + Radar detectors</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Tactile Glove Toggle Switch -->
|
||||
<button aria-checked="true" class="w-14 h-8 rounded-full bg-primary-container flex items-center px-1 transition-colors" role="switch" type="button">
|
||||
<div class="w-6 h-6 rounded-full bg-on-primary-container shadow-md transform translate-x-6 transition-transform"></div>
|
||||
</button>
|
||||
</div>
|
||||
<!-- Pack Comms Mesh Radar -->
|
||||
<div class="flex items-center justify-between p-3 rounded-xl bg-surface-container">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="w-9 h-9 rounded-lg bg-secondary-container/40 flex items-center justify-center text-secondary">
|
||||
<span class="material-symbols-outlined text-[20px]">group_work</span>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<span class="font-body-md text-label-data text-on-surface font-semibold">Mesh Pack Proximity</span>
|
||||
<span class="font-label-data text-[10px] text-on-surface-variant">4 Active Riders within 1.2 km</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Tactile Glove Toggle Switch -->
|
||||
<button aria-checked="true" class="w-14 h-8 rounded-full bg-primary-container flex items-center px-1 transition-colors" role="switch" type="button">
|
||||
<div class="w-6 h-6 rounded-full bg-on-primary-container shadow-md transform translate-x-6 transition-transform"></div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
// Tactical micro-interactions for glove cockpit usage
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const alertCard = document.getElementById('radarAlertBanner');
|
||||
const dismissBtn = document.getElementById('dismissAlertBtn');
|
||||
const muteToneBtn = document.getElementById('muteToneBtn');
|
||||
const muteLabel = document.getElementById('muteLabel');
|
||||
const countdownBadge = document.getElementById('countdownBadge');
|
||||
const compassBtn = document.getElementById('compassBtn');
|
||||
const zoomInBtn = document.getElementById('zoomInBtn');
|
||||
const zoomOutBtn = document.getElementById('zoomOutBtn');
|
||||
const recenterBtn = document.getElementById('recenterGpsBtn');
|
||||
|
||||
// Simulate real-time closing speed on police trap (350m countdown)
|
||||
let currentDistance = 350;
|
||||
const distanceInterval = setInterval(() => {
|
||||
if (currentDistance > 40) {
|
||||
currentDistance -= Math.floor(Math.random() * 8) + 4;
|
||||
countdownBadge.textContent = `${currentDistance} M`;
|
||||
} else {
|
||||
countdownBadge.textContent = 'PASSING';
|
||||
countdownBadge.classList.remove('bg-error-container');
|
||||
countdownBadge.classList.add('bg-surface-variant');
|
||||
}
|
||||
}, 900);
|
||||
|
||||
// Dismiss alert banner with smooth collapse
|
||||
dismissBtn?.addEventListener('click', () => {
|
||||
alertCard.style.opacity = '0';
|
||||
alertCard.style.transform = 'translateY(-10px)';
|
||||
setTimeout(() => {
|
||||
alertCard.style.display = 'none';
|
||||
}, 300);
|
||||
clearInterval(distanceInterval);
|
||||
});
|
||||
|
||||
// Mute tone button toggle
|
||||
let isMuted = false;
|
||||
muteToneBtn?.addEventListener('click', () => {
|
||||
isMuted = !isMuted;
|
||||
if (isMuted) {
|
||||
muteLabel.textContent = 'MUTED';
|
||||
muteToneBtn.classList.add('text-error');
|
||||
} else {
|
||||
muteLabel.textContent = 'MUTE TONE';
|
||||
muteToneBtn.classList.remove('text-error');
|
||||
}
|
||||
});
|
||||
|
||||
// Compass Orientation Click feedback
|
||||
let isHeadingUp = true;
|
||||
compassBtn?.addEventListener('click', () => {
|
||||
isHeadingUp = !isHeadingUp;
|
||||
const label = compassBtn.querySelector('span:last-child');
|
||||
if (isHeadingUp) {
|
||||
label.textContent = 'HEAD';
|
||||
} else {
|
||||
label.textContent = 'NORTH';
|
||||
}
|
||||
});
|
||||
|
||||
// Re-center tactile punch
|
||||
recenterBtn?.addEventListener('click', () => {
|
||||
recenterBtn.classList.add('scale-110');
|
||||
setTimeout(() => recenterBtn.classList.remove('scale-110'), 200);
|
||||
});
|
||||
});
|
||||
</script></main><nav class="fixed bottom-0 w-full z-50 pb-safe bg-surface-container-lowest/90 backdrop-blur-xl shadow-[0_-4px_24px_rgba(0,0,0,0.6)]" data-active-classes="text-primary-container font-headline-sm [filter:drop-shadow(0_0_8px_rgba(0,229,255,0.5))]"><div class="grid grid-cols-6 items-center h-20 px-space-xs"><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="cockpit-dash" href="#"><span class="material-symbols-outlined text-[24px]">speed</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Dash</span></a><a aria-current="page" class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 transition-all duration-200 text-primary-container font-headline-sm [filter:drop-shadow(0_0_8px_rgba(0,229,255,0.5))]" data-path="tactical-radar-map" href="#"><span class="material-symbols-outlined text-[24px]">radar</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Map</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="telemetry-log" href="#"><span class="material-symbols-outlined text-[24px]">monitoring</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Activity</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="bike-garage" href="#"><span class="material-symbols-outlined text-[24px]">two_wheeler</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Garage</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="pack-comms" href="#"><span class="material-symbols-outlined text-[24px]">groups_3</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Social</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="hud-settings" href="#"><span class="material-symbols-outlined text-[24px]">tune</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Settings</span></a></div></nav></body></html>
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 240 60" width="240" height="60" fill="none">
|
||||
<defs>
|
||||
<linearGradient id="neonCyan" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" stop-color="#00E5FF"/>
|
||||
<stop offset="100%" stop-color="#2563EB"/>
|
||||
</linearGradient>
|
||||
<filter id="glow" x="-20%" y="-20%" width="140%" height="140%">
|
||||
<feGaussianBlur stdDeviation="3" result="blur"/>
|
||||
<feMerge>
|
||||
<feMergeNode in="blur"/>
|
||||
<feMergeNode in="SourceGraphic"/>
|
||||
</feMerge>
|
||||
</filter>
|
||||
</defs>
|
||||
<!-- Telemetry Apex Signal Icon -->
|
||||
<path d="M12 42L24 16L32 32L38 22L46 42" stroke="url(#neonCyan)" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round" filter="url(#glow)"/>
|
||||
<circle cx="24" cy="16" r="3.5" fill="#00E5FF" filter="url(#glow)"/>
|
||||
<circle cx="38" cy="22" r="2.5" fill="#10B981"/>
|
||||
<path d="M6 34C10 20 22 10 38 10" stroke="#00E5FF" stroke-width="1.5" stroke-dasharray="2 2" opacity="0.6"/>
|
||||
<!-- Brand Text -->
|
||||
<text x="56" y="38" font-family="'Orbitron', sans-serif" font-weight="900" font-size="22" fill="#FFFFFF" letter-spacing="1.5">MOTOR<tspan fill="#00E5FF">SIGNAL</tspan></text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
|
|
@ -0,0 +1,296 @@
|
|||
<!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, viewport-fit=cover" name="viewport"/><meta content="mobile_tab" name="shell-type"/><title>MotorSignal Cockpit HUD</title><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&family=JetBrains+Mono:wght@500;600;700&family=Space+Grotesk:wght@600;700&display=swap" rel="stylesheet"/><link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/><style>@layer base{html,body{width:100%;margin:0;padding:0;background-color:#101419;color:#e0e2ea;}body{overscroll-behavior:none;}.pb-safe{padding-bottom:env(safe-area-inset-bottom,0px);}.pt-safe{padding-top:env(safe-area-inset-top,0px);}main>:first-child{margin-top:0!important;}main>:last-child{margin-bottom:0!important;}}::-webkit-scrollbar{display:none;}</style><script src="https://cdn.tailwindcss.com"></script><script id="tailwind-config">tailwind.config = { darkMode: "class", theme: { extend: { "colors": { "on-primary": "#00363d", "tertiary-fixed-dim": "#d0bcff", "tertiary-container": "#d9c8ff", "on-primary-container": "#00626e", "surface-variant": "#32353b", "on-primary-fixed-variant": "#004f58", "surface-container-high": "#272a30", "outline-variant": "#3b494c", "surface-container": "#1d2025", "on-surface": "#e0e2ea", "background": "#101419", "primary-container": "#00e5ff", "inverse-surface": "#e0e2ea", "outline": "#849396", "on-secondary": "#002a78", "secondary-fixed-dim": "#b4c5ff", "on-tertiary": "#3c0091", "inverse-primary": "#006875", "surface-bright": "#36393f", "surface-container-low": "#181c21", "surface-container-highest": "#32353b", "inverse-on-surface": "#2d3036", "on-secondary-fixed": "#00174b", "primary": "#c3f5ff", "error-container": "#93000a", "surface-tint": "#00daf3", "on-tertiary-fixed-variant": "#5516be", "on-error-container": "#ffdad6", "primary-fixed-dim": "#00daf3", "tertiary-fixed": "#e9ddff", "on-primary-fixed": "#001f24", "on-error": "#690005", "surface-container-lowest": "#0b0e13", "secondary-container": "#0053db", "tertiary": "#f2e9ff", "surface-dim": "#101419", "on-surface-variant": "#bac9cc", "on-tertiary-container": "#6834d1", "primary-fixed": "#9cf0ff", "secondary-fixed": "#dbe1ff", "error": "#ffb4ab", "on-secondary-container": "#cdd7ff", "on-secondary-fixed-variant": "#003ea8", "surface": "#101419", "on-background": "#e0e2ea", "secondary": "#b4c5ff", "on-tertiary-fixed": "#23005c" }, "borderRadius": { "DEFAULT": "0.25rem", "lg": "0.5rem", "xl": "0.75rem", "full": "9999px" }, "spacing": { "margin-lg": "2rem", "space-xs": "0.25rem", "gutter-lg": "1.5rem", "space-xl": "2rem", "margin": "1rem", "space-sm": "0.5rem", "space-md": "1rem", "space-lg": "1.5rem", "gutter": "1rem" }, "fontFamily": { "headline-lg": ["Space Grotesk"], "body-lg": ["Inter"], "telemetry-metric-lg-mobile": ["JetBrains Mono"], "label-data": ["JetBrains Mono"], "display-hero": ["Space Grotesk"], "headline-sm": ["Space Grotesk"], "headline-md": ["Space Grotesk"], "label-caption": ["Inter"], "telemetry-metric-lg": ["JetBrains Mono"], "display-hero-mobile": ["Space Grotesk"], "telemetry-metric-md": ["JetBrains Mono"], "body-md": ["Inter"] }, "fontSize": { "headline-lg": ["32px", { "lineHeight": "40px", "letterSpacing": "-0.02em", "fontWeight": "700" }], "body-lg": ["16px", { "lineHeight": "24px", "fontWeight": "500" }], "telemetry-metric-lg-mobile": ["36px", { "lineHeight": "36px", "letterSpacing": "-0.03em", "fontWeight": "700" }], "label-data": ["12px", { "lineHeight": "16px", "letterSpacing": "0.08em", "fontWeight": "600" }], "display-hero": ["56px", { "lineHeight": "60px", "letterSpacing": "-0.03em", "fontWeight": "700" }], "headline-sm": ["20px", { "lineHeight": "28px", "fontWeight": "600" }], "headline-md": ["24px", { "lineHeight": "32px", "letterSpacing": "-0.01em", "fontWeight": "600" }], "label-caption": ["11px", { "lineHeight": "14px", "letterSpacing": "0.05em", "fontWeight": "600" }], "telemetry-metric-lg": ["48px", { "lineHeight": "48px", "letterSpacing": "-0.04em", "fontWeight": "700" }], "display-hero-mobile": ["40px", { "lineHeight": "44px", "letterSpacing": "-0.02em", "fontWeight": "700" }], "telemetry-metric-md": ["28px", { "lineHeight": "32px", "letterSpacing": "-0.02em", "fontWeight": "600" }], "body-md": ["14px", { "lineHeight": "20px", "fontWeight": "400" }] } } } }</script><style>
|
||||
body {
|
||||
min-height: max(884px, 100dvh);
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
body {
|
||||
min-height: max(884px, 100dvh);
|
||||
}
|
||||
</style>
|
||||
</head><body class="bg-surface font-body-md text-on-surface antialiased flex flex-col min-h-screen selection:bg-primary-container selection:text-on-primary-container"><header class="fixed top-0 w-full z-50 pt-safe bg-surface-container-lowest/85 backdrop-blur-xl shadow-[0_4px_20px_rgba(0,0,0,0.5)]"><div class="h-16 px-space-md flex items-center justify-between gap-space-sm"><div class="flex items-center gap-space-sm"><img alt="MotorSignal Brand Logo" class="h-8 w-auto object-contain drop-shadow-[0_0_8px_rgba(0,229,255,0.4)]" src="https://lh3.googleusercontent.com/aida/AEtjO1Vf56Tkh6bJ86BCfT5GHz_yPumvEXYLWojlNHAFG-cN4VvH_nLvEbWQ4x7uhJPRaAyO8ozAAbLI_huEN134QOIYp8BdHuqoZCsMk9_ILaUxZqilVgamefO6d2sG1R8laIWSUswanVsK9lfvIgppQm_XxBQipzkDgPwIoXk7yh10QTlmZqDICryF-1MoWFfFjM2zZswr6ynuAgZAviROYnFBF2D4hxm6YREQxkZQJaBcG9oAg_dYVgTHxwg"/><div class="flex flex-col"><span class="font-headline-sm text-headline-sm uppercase tracking-wider text-primary-fixed">MotorSignal</span><span class="font-label-caption text-label-caption text-on-surface-variant uppercase tracking-widest leading-none">Telemetry Log</span></div></div><div class="flex items-center gap-space-sm"><div class="hidden sm:flex items-center gap-space-xs bg-surface-container-low px-space-sm py-1 rounded-full"><span class="w-2 h-2 rounded-full bg-primary-container animate-pulse shadow-[0_0_6px_#00e5ff]"></span><span class="font-label-data text-label-data text-primary-fixed">GPS 3D FIX</span></div><div class="flex items-center gap-1.5 bg-surface-container px-2 py-1 rounded-full"><span class="material-symbols-outlined text-[15px] text-primary-container">bolt</span><span class="font-label-data text-label-data text-on-surface">98%</span><span class="w-1 h-1 rounded-full bg-outline-variant"></span><span class="material-symbols-outlined text-[15px] text-primary-container">cell_tower</span></div><button aria-label="Rider Profile" class="min-w-[44px] min-h-[44px] flex items-center justify-center p-1 rounded-full focus:outline-none focus:ring-2 focus:ring-primary-container" type="button"><img alt="Profile" class="w-8 h-8 rounded-full object-cover ring-2 ring-primary-container/40" src="https://lh3.googleusercontent.com/aida-public/AB6AXuBb6sR8Ta8-L1_TN1LuCBfSxtZxX9hKOFjd-RjllihDsnp6AG1GlMhL9bVlb-ibhIRT3HMw_caXK7BmwmvWKNBcuizyqswUQZNztavckRTN1Xa6qGML_0kv8qvV_hrXWWK1EjSjVFzhRyDzf6VdGnZvUpGsFFmSBcaGVrXmEWFYnIa-qHyeWxZlT_SJmPuQJPQKEWEo6vC6kdDzXNnhoB4tpRHjIjCstvTdooPc0KVN_x3BqqmqadNI"/></button></div></div></header><main class="flex-1 flex flex-col relative w-full pt-16 pb-20 bg-surface"><div class="flex flex-col w-full px-space-md py-space-sm space-y-space-md">
|
||||
<!-- Tactical Navigation & Route Inputs -->
|
||||
<section class="bg-surface-container-low rounded-xl p-space-md shadow-md flex flex-col space-y-space-sm relative overflow-hidden">
|
||||
<div class="flex items-center justify-between pb-space-xs">
|
||||
<div class="flex items-center gap-space-xs">
|
||||
<span class="w-2 h-2 rounded-full bg-primary-container shadow-[0_0_8px_#00daf3]"></span>
|
||||
<span class="font-label-data text-label-data text-on-surface-variant uppercase tracking-wider">Tactical Route Engine v4.2</span>
|
||||
</div>
|
||||
<span class="font-label-caption text-label-caption text-primary-fixed bg-surface-container-highest px-2 py-0.5 rounded-full uppercase">IMU-Synced</span>
|
||||
</div>
|
||||
<!-- Origin & Destination Inputs -->
|
||||
<div class="space-y-space-xs">
|
||||
<!-- Origin -->
|
||||
<div class="flex items-center gap-space-sm bg-surface-container-lowest px-space-md py-2.5 rounded-lg min-h-[48px]">
|
||||
<span class="material-symbols-outlined text-[20px] text-primary-fixed-dim">my_location</span>
|
||||
<div class="flex-1 min-w-0">
|
||||
<span class="block font-label-caption text-label-caption text-outline uppercase tracking-wider">Origin</span>
|
||||
<p class="font-body-md text-body-md text-on-surface truncate font-medium">Current Location (Silicon Valley)</p>
|
||||
</div>
|
||||
<span class="material-symbols-outlined text-[18px] text-outline">gps_fixed</span>
|
||||
</div>
|
||||
<!-- Connecting Node Line -->
|
||||
<div class="flex items-center pl-6 py-0.5">
|
||||
<div class="w-0.5 h-4 bg-outline-variant rounded-full"></div>
|
||||
<span class="font-label-caption text-label-caption text-outline-variant pl-3 tracking-widest text-[9px] uppercase">Route Vector 284° NW</span>
|
||||
</div>
|
||||
<!-- Destination -->
|
||||
<div class="flex items-center gap-space-sm bg-surface-container-lowest px-space-md py-2.5 rounded-lg min-h-[48px]">
|
||||
<span class="material-symbols-outlined text-[20px] text-primary-container">flag</span>
|
||||
<div class="flex-1 min-w-0">
|
||||
<span class="block font-label-caption text-label-caption text-outline uppercase tracking-wider">Destination</span>
|
||||
<p class="font-body-md text-body-md text-primary font-medium truncate">Alice's Restaurant via Skyline & Hwy 9</p>
|
||||
</div>
|
||||
<button aria-label="Swap Waypoints" class="min-w-[40px] min-h-[40px] flex items-center justify-center text-outline hover:text-primary transition-colors" type="button">
|
||||
<span class="material-symbols-outlined text-[20px]">swap_vert</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Mountain Pass Waypoint Chip -->
|
||||
<div class="flex items-center justify-between pt-1">
|
||||
<button class="inline-flex items-center gap-1.5 bg-surface-container-high hover:bg-surface-container-highest px-3 py-2 rounded-full min-h-[48px] text-on-surface transition-all active:scale-95" type="button">
|
||||
<span class="material-symbols-outlined text-[18px] text-primary-container">add_location_alt</span>
|
||||
<span class="font-label-caption text-label-caption uppercase tracking-wider text-primary-fixed">+ Add Mountain Pass Waypoint</span>
|
||||
</button>
|
||||
<span class="font-label-data text-label-data text-on-surface-variant">Saratoga Gap (+1)</span>
|
||||
</div>
|
||||
</section>
|
||||
<!-- Curviness Priority Selector -->
|
||||
<section class="space-y-space-xs">
|
||||
<div class="flex items-center justify-between px-1">
|
||||
<h2 class="font-headline-sm text-headline-sm uppercase tracking-wider text-on-surface flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-primary-container text-[22px]">alt_route</span>
|
||||
Curviness Profile
|
||||
</h2>
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant uppercase tracking-widest">Apex Filter</span>
|
||||
</div>
|
||||
<!-- Segmented Pill Controls -->
|
||||
<div class="grid grid-cols-3 gap-space-xs bg-surface-container-lowest p-1.5 rounded-xl" id="curviness-selector">
|
||||
<!-- Standard Direct -->
|
||||
<button class="curviness-pill flex flex-col items-center justify-center py-2 px-1 rounded-lg min-h-[48px] text-on-surface-variant hover:text-on-surface bg-transparent transition-all" type="button">
|
||||
<span class="material-symbols-outlined text-[20px] mb-0.5">straighten</span>
|
||||
<span class="font-label-caption text-label-caption uppercase text-center leading-tight">Standard<br/>Direct</span>
|
||||
</button>
|
||||
<!-- Scenic Twisty -->
|
||||
<button class="curviness-pill flex flex-col items-center justify-center py-2 px-1 rounded-lg min-h-[48px] text-on-surface-variant hover:text-on-surface bg-transparent transition-all" type="button">
|
||||
<span class="material-symbols-outlined text-[20px] mb-0.5">explore</span>
|
||||
<span class="font-label-caption text-label-caption uppercase text-center leading-tight">Scenic<br/>Twisty</span>
|
||||
</button>
|
||||
<!-- Extreme Apex / Knee Down (Active) -->
|
||||
<button class="curviness-pill active bg-surface-container-high shadow-[0_0_16px_rgba(0,229,255,0.25)] flex flex-col items-center justify-center py-2 px-1 rounded-lg min-h-[48px] text-primary-container transition-all relative overflow-hidden" type="button">
|
||||
<div class="absolute inset-0 bg-primary-container/10"></div>
|
||||
<div class="flex items-center gap-0.5 relative z-10">
|
||||
<span class="material-symbols-outlined text-[18px] text-primary-container">local_fire_department</span>
|
||||
<span class="material-symbols-outlined text-[18px] text-primary-container">sports_motorsports</span>
|
||||
</div>
|
||||
<span class="font-label-caption text-label-caption font-semibold uppercase text-center leading-tight mt-0.5 text-primary-fixed relative z-10">Extreme Apex<br/><span class="text-[9px] text-primary-container">Knee Down</span></span>
|
||||
</button>
|
||||
</div>
|
||||
</section>
|
||||
<!-- Route Summary Telemetry Card -->
|
||||
<section class="bg-surface-container-low rounded-xl p-space-md shadow-lg space-y-space-md">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-space-xs">
|
||||
<span class="material-symbols-outlined text-primary-container text-[22px]">analytics</span>
|
||||
<h3 class="font-headline-sm text-headline-sm uppercase tracking-wide text-on-surface">Route Telemetry</h3>
|
||||
</div>
|
||||
<div class="flex items-center gap-1.5 bg-surface-container-highest px-2.5 py-1 rounded-full">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-primary-container animate-ping"></span>
|
||||
<span class="font-label-data text-label-data text-primary-fixed uppercase tracking-wider">Optimized</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Main Telemetry Grid (2x2 Mobile) -->
|
||||
<div class="grid grid-cols-2 gap-space-sm">
|
||||
<!-- Distance Metric -->
|
||||
<div class="bg-surface-container p-space-sm rounded-lg flex flex-col justify-between">
|
||||
<span class="font-label-data text-label-data text-on-surface-variant uppercase">Total Distance</span>
|
||||
<div class="flex items-baseline gap-1 mt-1">
|
||||
<span class="font-telemetry-metric-lg-mobile text-telemetry-metric-lg-mobile text-on-surface">64.2</span>
|
||||
<span class="font-label-data text-label-data text-primary-container uppercase">MI</span>
|
||||
</div>
|
||||
<span class="font-label-caption text-label-caption text-outline text-[10px] mt-1">103.3 KM Total</span>
|
||||
</div>
|
||||
<!-- Duration Metric -->
|
||||
<div class="bg-surface-container p-space-sm rounded-lg flex flex-col justify-between">
|
||||
<span class="font-label-data text-label-data text-on-surface-variant uppercase">Est. Duration</span>
|
||||
<div class="flex items-baseline gap-1 mt-1">
|
||||
<span class="font-telemetry-metric-lg-mobile text-telemetry-metric-lg-mobile text-on-surface">1<span class="text-secondary text-[24px]">h</span> 28<span class="text-secondary text-[24px]">m</span></span>
|
||||
</div>
|
||||
<span class="font-label-caption text-label-caption text-outline text-[10px] mt-1">Pace Factor: 1.25x</span>
|
||||
</div>
|
||||
<!-- Curve Density Metric -->
|
||||
<div class="bg-surface-container p-space-sm rounded-lg flex flex-col justify-between">
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="font-label-data text-label-data text-on-surface-variant uppercase">Curve Count</span>
|
||||
<span class="material-symbols-outlined text-[16px] text-primary-container">turn_sharp_right</span>
|
||||
</div>
|
||||
<div class="flex items-baseline gap-1 mt-1">
|
||||
<span class="font-telemetry-metric-lg-mobile text-telemetry-metric-lg-mobile text-primary-fixed">184</span>
|
||||
<span class="font-label-data text-label-data text-on-surface-variant uppercase">Corners</span>
|
||||
</div>
|
||||
<span class="font-label-caption text-label-caption text-error-container bg-error/10 px-1.5 py-0.5 rounded text-[10px] font-semibold mt-1 inline-block">42 Severe >45°</span>
|
||||
</div>
|
||||
<!-- Elevation Metric -->
|
||||
<div class="bg-surface-container p-space-sm rounded-lg flex flex-col justify-between">
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="font-label-data text-label-data text-on-surface-variant uppercase">Elevation Δ</span>
|
||||
<span class="material-symbols-outlined text-[16px] text-secondary">elevation</span>
|
||||
</div>
|
||||
<div class="flex items-baseline gap-1 mt-1">
|
||||
<span class="font-telemetry-metric-lg-mobile text-telemetry-metric-lg-mobile text-secondary-fixed">+3,420</span>
|
||||
<span class="font-label-data text-label-data text-on-surface-variant uppercase">FT</span>
|
||||
</div>
|
||||
<span class="font-label-caption text-label-caption text-outline text-[10px] mt-1">Peak: 3,214 FT (Skyline)</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Cross-Section Elevation & Grade Profile SVG -->
|
||||
<div class="bg-surface-container-lowest p-space-sm rounded-lg space-y-space-xs">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-1.5">
|
||||
<span class="material-symbols-outlined text-[16px] text-primary-container">terrain</span>
|
||||
<span class="font-label-data text-label-data text-on-surface-variant uppercase">Profile: Skyline Switchbacks & Hwy 9</span>
|
||||
</div>
|
||||
<span class="font-label-caption text-label-caption text-primary-fixed bg-surface-container px-2 py-0.5 rounded">Grade ±12% Max</span>
|
||||
</div>
|
||||
<!-- Vector Cross-Section Chart -->
|
||||
<div class="relative w-full h-24 overflow-hidden pt-2">
|
||||
<svg class="w-full h-full" fill="none" preserveaspectratio="none" viewbox="0 0 340 80">
|
||||
<defs>
|
||||
<lineargradient id="elevationGrad" x1="0" x2="0" y1="0" y2="1">
|
||||
<stop offset="0%" stop-color="#00daf3" stop-opacity="0.45"></stop>
|
||||
<stop offset="100%" stop-color="#00daf3" stop-opacity="0.02"></stop>
|
||||
</lineargradient>
|
||||
<lineargradient id="lineGrad" x1="0" x2="1" y1="0" y2="0">
|
||||
<stop offset="0%" stop-color="#00daf3"></stop>
|
||||
<stop offset="50%" stop-color="#b4c5ff"></stop>
|
||||
<stop offset="85%" stop-color="#00e5ff"></stop>
|
||||
<stop offset="100%" stop-color="#c3f5ff"></stop>
|
||||
</lineargradient>
|
||||
</defs>
|
||||
<!-- Grid Lines -->
|
||||
<line stroke="#32353b" stroke-dasharray="2 2" stroke-width="0.8" x1="0" x2="340" y1="20" y2="20"></line>
|
||||
<line stroke="#32353b" stroke-dasharray="2 2" stroke-width="0.8" x1="0" x2="340" y1="50" y2="50"></line>
|
||||
<!-- Area Fill Under Path -->
|
||||
<path d="M0 65 Q 40 60 70 48 T 130 35 T 180 15 T 230 18 T 280 42 L 340 55 L 340 80 L 0 80 Z" fill="url(#elevationGrad)"></path>
|
||||
<!-- Elevation Contour Stroke -->
|
||||
<path d="M0 65 Q 40 60 70 48 T 130 35 T 180 15 T 230 18 T 280 42 L 340 55" stroke="url(#lineGrad)" stroke-linecap="round" stroke-width="2.5"></path>
|
||||
<!-- High Apex Points on Curve -->
|
||||
<circle class="shadow-[0_0_8px_#00e5ff]" cx="180" cy="15" fill="#00e5ff" r="3.5"></circle>
|
||||
<circle cx="230" cy="18" fill="#b4c5ff" r="3"></circle>
|
||||
<circle cx="280" cy="42" fill="#00e5ff" r="3"></circle>
|
||||
</svg>
|
||||
<!-- Peak Overlays -->
|
||||
<div class="absolute top-1 left-[48%] -translate-x-1/2 flex items-center gap-1 bg-surface-container-high/90 px-1.5 py-0.5 rounded shadow">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-primary-container"></span>
|
||||
<span class="font-label-caption text-[10px] text-primary-fixed uppercase tracking-wider">Apex Pass 3.2k'</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Distance Markers -->
|
||||
<div class="flex justify-between font-label-data text-label-data text-outline pt-0.5 text-[10px]">
|
||||
<span>0 MI</span>
|
||||
<span>18 MI (Foothills)</span>
|
||||
<span>42 MI (Skyline Gap)</span>
|
||||
<span>64.2 MI</span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- Route Visual Snapshot & Location Imagery -->
|
||||
<section class="space-y-space-xs">
|
||||
<div class="flex items-center justify-between px-1">
|
||||
<span class="font-headline-sm text-headline-sm uppercase tracking-wider text-on-surface flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-primary-container text-[20px]">panorama_photosphere</span>
|
||||
Wayline Visual
|
||||
</span>
|
||||
<span class="font-label-caption text-label-caption text-outline uppercase tracking-wider">Hwy 9 Northbound</span>
|
||||
</div>
|
||||
<div class="relative w-full h-36 rounded-xl overflow-hidden shadow-md">
|
||||
<img class="w-full h-full object-cover" data-alt="High angle shot of a pristine asphalt mountain pass carving sharply through dense redwood forests with motorcycle lean tire marks. Moody dusk mist, cool blue and cyan rim lighting, futuristic HUD telemetry overlay vibe, tactical motorsport atmosphere." src="https://lh3.googleusercontent.com/aida-public/AB6AXuDHnd2Pxnb3Cg97VasZp4K9wmy7Lxn3vUC7asEcD2zm-gTLHKHowad7hMuL3z9wGYcb-EZFS9EoPvOgWifCuJXnjA4LmYDsJxtWA6O7b50dRqav11TiUBa44KtUsAPDx4ZVaFvT13DmQ8mB296WsQEWm8-JH5pivM5xt8IefyTrL5ELMKzAUFUaB_pIwcX_hNfgTNwAaC_l8uE_8LHNu7AIKAbX6oS35RCOT8ld8_kY-bjfbe5rgVIs"/>
|
||||
<div class="absolute inset-0 bg-gradient-to-t from-surface-container-lowest via-surface-container-lowest/30 to-transparent"></div>
|
||||
<div class="absolute bottom-2.5 left-3 right-3 flex items-center justify-between">
|
||||
<div>
|
||||
<p class="font-headline-sm text-headline-sm text-on-surface leading-tight">Saratoga Gap Hairpins</p>
|
||||
<p class="font-label-caption text-label-caption text-primary-container tracking-wider uppercase">Chicane Zone • 8 Rapid Sweepers</p>
|
||||
</div>
|
||||
<div class="flex items-center gap-1 bg-surface-container-lowest/90 px-2 py-1 rounded-full shadow">
|
||||
<span class="material-symbols-outlined text-[16px] text-primary-container">speed</span>
|
||||
<span class="font-label-data text-label-data text-on-surface">54 MPH AVG</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- Road Condition & Hazard Preview Pills -->
|
||||
<section class="space-y-space-xs">
|
||||
<div class="flex items-center justify-between px-1">
|
||||
<span class="font-label-data text-label-data text-on-surface-variant uppercase tracking-wider">Live Ground Surface & Risk Matrix</span>
|
||||
<span class="font-label-caption text-label-caption text-primary-fixed">Packs: 12 Active Riders</span>
|
||||
</div>
|
||||
<!-- Pill Carousel / Flow -->
|
||||
<div class="flex flex-wrap gap-space-xs">
|
||||
<!-- Pavement Pill -->
|
||||
<div class="flex items-center gap-1.5 bg-surface-container-high px-3 py-2 rounded-full min-h-[44px]">
|
||||
<span class="material-symbols-outlined text-[18px] text-primary-container">wb_sunny</span>
|
||||
<div class="flex items-baseline gap-1">
|
||||
<span class="font-label-caption text-label-caption text-on-surface font-semibold">Dry Pavement</span>
|
||||
<span class="font-label-data text-label-data text-primary-fixed">94%</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Police Trap Pill -->
|
||||
<div class="flex items-center gap-1.5 bg-surface-container-high px-3 py-2 rounded-full min-h-[44px]">
|
||||
<span class="material-symbols-outlined text-[18px] text-primary-container">security</span>
|
||||
<div class="flex items-baseline gap-1">
|
||||
<span class="font-label-caption text-label-caption text-on-surface font-semibold">Radar Traps</span>
|
||||
<span class="font-label-data text-label-data text-primary-fixed">0 Rep</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Grip Index Pill -->
|
||||
<div class="flex items-center gap-1.5 bg-surface-container-high px-3 py-2 rounded-full min-h-[44px]">
|
||||
<span class="material-symbols-outlined text-[18px] text-primary-container">tire_repair</span>
|
||||
<div class="flex items-baseline gap-1">
|
||||
<span class="font-label-caption text-label-caption text-on-surface font-semibold">Grip Index:</span>
|
||||
<span class="font-label-data text-label-data text-primary-fixed">HIGH (μ 0.92)</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Fog/Visibility Warning Pill -->
|
||||
<div class="flex items-center gap-1.5 bg-surface-container-high px-3 py-2 rounded-full min-h-[44px]">
|
||||
<span class="material-symbols-outlined text-[18px] text-secondary">cloud</span>
|
||||
<span class="font-label-caption text-label-caption text-on-surface">Light Ridge Mist 3%</span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- Bottom Action Dock (Massive Glove-Friendly Controls) -->
|
||||
<section class="space-y-space-xs pt-space-xs">
|
||||
<!-- Primary Big Action Launch Button -->
|
||||
<button class="w-full bg-primary-container hover:bg-surface-tint active:scale-[0.98] text-on-primary-container font-telemetry-metric-md text-telemetry-metric-md min-h-[58px] rounded-xl flex items-center justify-center gap-space-sm shadow-[0_0_24px_rgba(0,229,255,0.45)] transition-all" type="button">
|
||||
<span class="material-symbols-outlined text-[28px] text-on-primary-container">navigation</span>
|
||||
<span class="font-bold tracking-tight uppercase text-headline-sm font-headline-sm">LAUNCH NAVIGATION</span>
|
||||
</button>
|
||||
<!-- Secondary Pack Coordination & TBT Guidance Control -->
|
||||
<div class="grid grid-cols-2 gap-space-sm">
|
||||
<button class="bg-surface-container-high hover:bg-surface-container-highest active:scale-[0.97] text-on-surface py-3 px-space-sm rounded-lg min-h-[48px] flex items-center justify-center gap-2 transition-all" type="button">
|
||||
<span class="material-symbols-outlined text-[20px] text-primary-fixed">directions</span>
|
||||
<span class="font-label-caption text-label-caption uppercase tracking-wider font-semibold">TBT Cockpit HUD</span>
|
||||
</button>
|
||||
<button class="bg-surface-container-high hover:bg-surface-container-highest active:scale-[0.97] text-on-surface py-3 px-space-sm rounded-lg min-h-[48px] flex items-center justify-center gap-2 transition-all" type="button">
|
||||
<span class="material-symbols-outlined text-[20px] text-secondary">share_location</span>
|
||||
<span class="font-label-caption text-label-caption uppercase tracking-wider font-semibold text-secondary-fixed">EXPORT TO PACK</span>
|
||||
</button>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
<script>
|
||||
// Simple Pill Selection Interaction for Curviness Control
|
||||
document.querySelectorAll('#curviness-selector .curviness-pill').forEach(pill => {
|
||||
pill.addEventListener('click', () => {
|
||||
document.querySelectorAll('#curviness-selector .curviness-pill').forEach(p => {
|
||||
p.classList.remove('active', 'bg-surface-container-high', 'shadow-[0_0_16px_rgba(0,229,255,0.25)]', 'text-primary-container');
|
||||
p.classList.add('text-on-surface-variant', 'bg-transparent');
|
||||
});
|
||||
pill.classList.remove('text-on-surface-variant', 'bg-transparent');
|
||||
pill.classList.add('active', 'bg-surface-container-high', 'shadow-[0_0_16px_rgba(0,229,255,0.25)]', 'text-primary-container');
|
||||
});
|
||||
});
|
||||
</script></main><nav class="fixed bottom-0 w-full z-50 pb-safe bg-surface-container-lowest/90 backdrop-blur-xl shadow-[0_-4px_24px_rgba(0,0,0,0.6)]" data-active-classes="text-primary-container font-headline-sm [filter:drop-shadow(0_0_8px_rgba(0,229,255,0.5))]"><div class="grid grid-cols-6 items-center h-20 px-space-xs"><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="cockpit-dash" href="#"><span class="material-symbols-outlined text-[24px]">speed</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Dash</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="tactical-radar-map" href="#"><span class="material-symbols-outlined text-[24px]">radar</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Map</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="telemetry-log" href="#"><span class="material-symbols-outlined text-[24px]">monitoring</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Activity</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="bike-garage" href="#"><span class="material-symbols-outlined text-[24px]">two_wheeler</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Garage</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="pack-comms" href="#"><span class="material-symbols-outlined text-[24px]">groups_3</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Social</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="hud-settings" href="#"><span class="material-symbols-outlined text-[24px]">tune</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Settings</span></a></div></nav></body></html>
|
||||
|
|
@ -0,0 +1,285 @@
|
|||
<!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, viewport-fit=cover" name="viewport"/><meta content="mobile_tab" name="shell-type"/><title>MotorSignal Cockpit HUD</title><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&family=JetBrains+Mono:wght@500;600;700&family=Space+Grotesk:wght@600;700&display=swap" rel="stylesheet"/><link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/><style>@layer base{html,body{width:100%;margin:0;padding:0;background-color:#101419;color:#e0e2ea;}body{overscroll-behavior:none;}.pb-safe{padding-bottom:env(safe-area-inset-bottom,0px);}.pt-safe{padding-top:env(safe-area-inset-top,0px);}main>:first-child{margin-top:0!important;}main>:last-child{margin-bottom:0!important;}}::-webkit-scrollbar{display:none;}</style><script src="https://cdn.tailwindcss.com"></script><script id="tailwind-config">tailwind.config = { darkMode: "class", theme: { extend: { "colors": { "on-primary": "#00363d", "tertiary-fixed-dim": "#d0bcff", "tertiary-container": "#d9c8ff", "on-primary-container": "#00626e", "surface-variant": "#32353b", "on-primary-fixed-variant": "#004f58", "surface-container-high": "#272a30", "outline-variant": "#3b494c", "surface-container": "#1d2025", "on-surface": "#e0e2ea", "background": "#101419", "primary-container": "#00e5ff", "inverse-surface": "#e0e2ea", "outline": "#849396", "on-secondary": "#002a78", "secondary-fixed-dim": "#b4c5ff", "on-tertiary": "#3c0091", "inverse-primary": "#006875", "surface-bright": "#36393f", "surface-container-low": "#181c21", "surface-container-highest": "#32353b", "inverse-on-surface": "#2d3036", "on-secondary-fixed": "#00174b", "primary": "#c3f5ff", "error-container": "#93000a", "surface-tint": "#00daf3", "on-tertiary-fixed-variant": "#5516be", "on-error-container": "#ffdad6", "primary-fixed-dim": "#00daf3", "tertiary-fixed": "#e9ddff", "on-primary-fixed": "#001f24", "on-error": "#690005", "surface-container-lowest": "#0b0e13", "secondary-container": "#0053db", "tertiary": "#f2e9ff", "surface-dim": "#101419", "on-surface-variant": "#bac9cc", "on-tertiary-container": "#6834d1", "primary-fixed": "#9cf0ff", "secondary-fixed": "#dbe1ff", "error": "#ffb4ab", "on-secondary-container": "#cdd7ff", "on-secondary-fixed-variant": "#003ea8", "surface": "#101419", "on-background": "#e0e2ea", "secondary": "#b4c5ff", "on-tertiary-fixed": "#23005c" }, "borderRadius": { "DEFAULT": "0.25rem", "lg": "0.5rem", "xl": "0.75rem", "full": "9999px" }, "spacing": { "margin-lg": "2rem", "space-xs": "0.25rem", "gutter-lg": "1.5rem", "space-xl": "2rem", "margin": "1rem", "space-sm": "0.5rem", "space-md": "1rem", "space-lg": "1.5rem", "gutter": "1rem" }, "fontFamily": { "headline-lg": ["Space Grotesk"], "body-lg": ["Inter"], "telemetry-metric-lg-mobile": ["JetBrains Mono"], "label-data": ["JetBrains Mono"], "display-hero": ["Space Grotesk"], "headline-sm": ["Space Grotesk"], "headline-md": ["Space Grotesk"], "label-caption": ["Inter"], "telemetry-metric-lg": ["JetBrains Mono"], "display-hero-mobile": ["Space Grotesk"], "telemetry-metric-md": ["JetBrains Mono"], "body-md": ["Inter"] }, "fontSize": { "headline-lg": ["32px", { "lineHeight": "40px", "letterSpacing": "-0.02em", "fontWeight": "700" }], "body-lg": ["16px", { "lineHeight": "24px", "fontWeight": "500" }], "telemetry-metric-lg-mobile": ["36px", { "lineHeight": "36px", "letterSpacing": "-0.03em", "fontWeight": "700" }], "label-data": ["12px", { "lineHeight": "16px", "letterSpacing": "0.08em", "fontWeight": "600" }], "display-hero": ["56px", { "lineHeight": "60px", "letterSpacing": "-0.03em", "fontWeight": "700" }], "headline-sm": ["20px", { "lineHeight": "28px", "fontWeight": "600" }], "headline-md": ["24px", { "lineHeight": "32px", "letterSpacing": "-0.01em", "fontWeight": "600" }], "label-caption": ["11px", { "lineHeight": "14px", "letterSpacing": "0.05em", "fontWeight": "600" }], "telemetry-metric-lg": ["48px", { "lineHeight": "48px", "letterSpacing": "-0.04em", "fontWeight": "700" }], "display-hero-mobile": ["40px", { "lineHeight": "44px", "letterSpacing": "-0.02em", "fontWeight": "700" }], "telemetry-metric-md": ["28px", { "lineHeight": "32px", "letterSpacing": "-0.02em", "fontWeight": "600" }], "body-md": ["14px", { "lineHeight": "20px", "fontWeight": "400" }] } } } }</script><style>
|
||||
body {
|
||||
min-height: max(884px, 100dvh);
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
body {
|
||||
min-height: max(884px, 100dvh);
|
||||
}
|
||||
</style>
|
||||
</head><body class="bg-surface font-body-md text-on-surface antialiased flex flex-col min-h-screen selection:bg-primary-container selection:text-on-primary-container"><header class="fixed top-0 w-full z-50 pt-safe bg-surface-container-lowest/85 backdrop-blur-xl shadow-[0_4px_20px_rgba(0,0,0,0.5)]"><div class="h-16 px-space-md flex items-center justify-between gap-space-sm"><div class="flex items-center gap-space-sm"><img alt="MotorSignal Brand Logo" class="h-8 w-auto object-contain drop-shadow-[0_0_8px_rgba(0,229,255,0.4)]" src="https://lh3.googleusercontent.com/aida/AEtjO1Vf56Tkh6bJ86BCfT5GHz_yPumvEXYLWojlNHAFG-cN4VvH_nLvEbWQ4x7uhJPRaAyO8ozAAbLI_huEN134QOIYp8BdHuqoZCsMk9_ILaUxZqilVgamefO6d2sG1R8laIWSUswanVsK9lfvIgppQm_XxBQipzkDgPwIoXk7yh10QTlmZqDICryF-1MoWFfFjM2zZswr6ynuAgZAviROYnFBF2D4hxm6YREQxkZQJaBcG9oAg_dYVgTHxwg"/><div class="flex flex-col"><span class="font-headline-sm text-headline-sm uppercase tracking-wider text-primary-fixed">MotorSignal</span><span class="font-label-caption text-label-caption text-on-surface-variant uppercase tracking-widest leading-none">Telemetry Log</span></div></div><div class="flex items-center gap-space-sm"><div class="hidden sm:flex items-center gap-space-xs bg-surface-container-low px-space-sm py-1 rounded-full"><span class="w-2 h-2 rounded-full bg-primary-container animate-pulse shadow-[0_0_6px_#00e5ff]"></span><span class="font-label-data text-label-data text-primary-fixed">GPS 3D FIX</span></div><div class="flex items-center gap-1.5 bg-surface-container px-2 py-1 rounded-full"><span class="material-symbols-outlined text-[15px] text-primary-container">bolt</span><span class="font-label-data text-label-data text-on-surface">98%</span><span class="w-1 h-1 rounded-full bg-outline-variant"></span><span class="material-symbols-outlined text-[15px] text-primary-container">cell_tower</span></div><button aria-label="Rider Profile" class="min-w-[44px] min-h-[44px] flex items-center justify-center p-1 rounded-full focus:outline-none focus:ring-2 focus:ring-primary-container" type="button"><img alt="Profile" class="w-8 h-8 rounded-full object-cover ring-2 ring-primary-container/40" src="https://lh3.googleusercontent.com/aida-public/AB6AXuBb6sR8Ta8-L1_TN1LuCBfSxtZxX9hKOFjd-RjllihDsnp6AG1GlMhL9bVlb-ibhIRT3HMw_caXK7BmwmvWKNBcuizyqswUQZNztavckRTN1Xa6qGML_0kv8qvV_hrXWWK1EjSjVFzhRyDzf6VdGnZvUpGsFFmSBcaGVrXmEWFYnIa-qHyeWxZlT_SJmPuQJPQKEWEo6vC6kdDzXNnhoB4tpRHjIjCstvTdooPc0KVN_x3BqqmqadNI"/></button></div></div></header><main class="flex-1 flex flex-col relative w-full pt-16 pb-20 bg-surface"><div class="flex flex-col w-full px-space-md py-space-sm space-y-space-md">
|
||||
<!-- Bike Selector Tabs: The Stable -->
|
||||
<div class="flex items-center gap-space-sm overflow-x-auto pb-1 no-scrollbar">
|
||||
<!-- Active Bike: Ducati -->
|
||||
<button class="flex-shrink-0 flex items-center gap-space-sm bg-surface-container-high px-space-md py-2.5 rounded-xl shadow-md min-h-[48px] text-left transition-all duration-200" type="button">
|
||||
<div class="w-2.5 h-2.5 rounded-full bg-primary-container shadow-[0_0_8px_#00e5ff] animate-pulse"></div>
|
||||
<div class="flex flex-col">
|
||||
<div class="flex items-center gap-1.5">
|
||||
<span class="font-headline-sm text-[15px] font-bold text-on-surface tracking-tight">Panigale V4 S</span>
|
||||
<span class="px-1.5 py-0.5 rounded-full bg-emerald-500/20 text-emerald-400 font-label-caption text-[9px] tracking-wider uppercase font-semibold">Active</span>
|
||||
</div>
|
||||
<span class="font-label-data text-label-data text-on-surface-variant text-[11px]">2024 • 214 HP</span>
|
||||
</div>
|
||||
</button>
|
||||
<!-- Standby Bike: MT-09 SP -->
|
||||
<button class="flex-shrink-0 flex items-center gap-space-sm bg-surface-container-low px-space-md py-2.5 rounded-xl min-h-[48px] text-left opacity-70 hover:opacity-100 transition-opacity" type="button">
|
||||
<div class="w-2 h-2 rounded-full bg-outline"></div>
|
||||
<div class="flex flex-col">
|
||||
<span class="font-headline-sm text-[15px] font-bold text-on-surface tracking-tight">Yamaha MT-09 SP</span>
|
||||
<span class="font-label-data text-label-data text-on-surface-variant text-[11px]">2023 • 117 HP</span>
|
||||
</div>
|
||||
</button>
|
||||
<!-- Quick Add Stable Slot -->
|
||||
<button aria-label="Add slot" class="flex-shrink-0 flex items-center justify-center w-12 h-12 bg-surface-container-low rounded-xl text-primary-container hover:bg-surface-container-high transition-colors" type="button">
|
||||
<span class="material-symbols-outlined text-[20px]">add</span>
|
||||
</button>
|
||||
</div>
|
||||
<!-- Hero Motorcycle Card -->
|
||||
<div class="relative w-full rounded-xl overflow-hidden bg-surface-container-lowest shadow-xl flex flex-col">
|
||||
<!-- Visual Image with Tactical Gradients -->
|
||||
<div class="relative w-full h-44 bg-surface-container-low overflow-hidden">
|
||||
<img class="w-full h-full object-cover object-center" data-alt="A dramatic low-angle studio shot of a 2024 Ducati Panigale V4 S superbike in deep Rosso Corsa with exposed carbon fiber aerodynamic winglets and titanium exhaust. Tactical cold neon cyan and deep blue ambient light traces the sharp lines of the fuel tank and fairings under high-performance dark workshop conditions." src="https://lh3.googleusercontent.com/aida-public/AB6AXuA54_Q1s9BmuQC5nedSez6uFW75E5VbHw6nGxmVQZ_ZDlKAfbv4aNhq4pgA2v3iDvokB14GMxjDR3LnhCFG_RFtyhHi_EIys1PILhwRdjOOvFLmYj9Lyd4m8j0LQNCCWumT9pE58c3gLWCJZP533zNx-cXyXDWetgdF8E2zg7N8Twrq5Cg8m3j6SMY8XC7noX08bonLonMX75_-mK2golA-Wo1PVcJEjCrRErmfp-vDdF9TuRNORU2J"/>
|
||||
<div class="absolute inset-0 bg-gradient-to-t from-surface-container-lowest via-surface-container-lowest/40 to-transparent"></div>
|
||||
<div class="absolute top-3 left-3 flex items-center gap-1.5 px-2.5 py-1 rounded-full bg-surface-container-lowest/80 backdrop-blur-md">
|
||||
<span class="w-2 h-2 rounded-full bg-primary-container animate-ping"></span>
|
||||
<span class="font-label-data text-label-data text-primary-fixed uppercase tracking-wider text-[10px]">OBD-II CAN BUS: ACTIVE 50Hz</span>
|
||||
</div>
|
||||
<div class="absolute top-3 right-3 px-2 py-1 rounded-lg bg-surface-container-lowest/80 backdrop-blur-md flex items-center gap-1">
|
||||
<span class="material-symbols-outlined text-[14px] text-primary-container">speed</span>
|
||||
<span class="font-label-data text-label-data text-on-surface font-bold text-[11px]">6,420 MI</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Machine Specs & Diagnostics Bar -->
|
||||
<div class="p-space-md flex flex-col space-y-space-md">
|
||||
<div class="flex items-end justify-between">
|
||||
<div>
|
||||
<span class="font-label-caption text-label-caption uppercase tracking-widest text-primary-container">Desmosedici Stradale</span>
|
||||
<h2 class="font-headline-md text-headline-md tracking-tight text-on-surface">2024 Ducati Panigale V4 S</h2>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<span class="font-label-caption text-label-caption uppercase tracking-widest text-on-surface-variant">Output</span>
|
||||
<p class="font-telemetry-metric-md text-telemetry-metric-md text-primary font-bold leading-none">214 <span class="text-[14px] font-normal text-on-surface-variant font-label-data">HP</span></p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Quick Telemetry Vital Strip: Fuel Gauge & Thermal Map -->
|
||||
<div class="bg-surface-container-low p-space-sm rounded-xl flex flex-col space-y-2">
|
||||
<div class="flex items-center justify-between font-label-data text-label-data">
|
||||
<span class="flex items-center gap-1 text-on-surface">
|
||||
<span class="material-symbols-outlined text-[16px] text-primary-container">local_gas_station</span>
|
||||
FUEL TANK
|
||||
</span>
|
||||
<span class="text-primary-fixed font-bold">78% • 142 MI RANGE</span>
|
||||
</div>
|
||||
<!-- Progress Bar -->
|
||||
<div class="w-full h-2 rounded-full bg-surface-container-highest overflow-hidden">
|
||||
<div class="h-full bg-primary-container rounded-full shadow-[0_0_10px_#00e5ff]" style="width: 78%"></div>
|
||||
</div>
|
||||
<div class="flex justify-between items-center text-[10px] font-label-caption text-on-surface-variant pt-0.5">
|
||||
<span>RESERVE TRIP: 0.0 MI</span>
|
||||
<span>16.0 L / 4.23 US GAL</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Service & Wear Telemetry Dashboard Header -->
|
||||
<div class="flex items-center justify-between pt-1">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-primary-container text-[20px]">health_and_safety</span>
|
||||
<h3 class="font-headline-sm text-[18px] uppercase tracking-wide text-on-surface">Wear & Diagnostics</h3>
|
||||
</div>
|
||||
<span class="px-2 py-0.5 rounded-full bg-surface-container-high text-on-surface-variant font-label-data text-[10px] uppercase">Telemetry Sync: 2m ago</span>
|
||||
</div>
|
||||
<!-- Telemetry Wear Bento Grid -->
|
||||
<div class="grid grid-cols-2 gap-space-sm">
|
||||
<!-- Tile 1: Engine Oil (Caution Amber) -->
|
||||
<div class="bg-surface-container-low p-space-sm rounded-xl flex flex-col justify-between shadow-md relative overflow-hidden">
|
||||
<div class="flex items-start justify-between">
|
||||
<div class="flex items-center gap-1.5">
|
||||
<span class="material-symbols-outlined text-[18px] text-amber-400">oil_barrel</span>
|
||||
<span class="font-label-caption text-label-caption uppercase tracking-wider text-on-surface-variant">Engine Oil</span>
|
||||
</div>
|
||||
<span class="px-1.5 py-0.5 rounded bg-amber-500/20 text-amber-400 font-label-data text-[9px] uppercase font-bold tracking-wider">Caution</span>
|
||||
</div>
|
||||
<div class="my-2">
|
||||
<div class="font-telemetry-metric-md text-[22px] font-bold text-amber-300 leading-tight">380 <span class="font-label-data text-[12px] text-on-surface-variant">MI</span></div>
|
||||
<span class="font-label-caption text-[11px] text-on-surface-variant">Shell Advance 15W-50</span>
|
||||
</div>
|
||||
<div class="w-full bg-surface-container-highest h-1.5 rounded-full overflow-hidden">
|
||||
<div class="bg-amber-400 h-full rounded-full shadow-[0_0_8px_rgba(251,191,36,0.6)]" style="width: 88%"></div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Tile 2: Chain Slack (Optimal Green) -->
|
||||
<div class="bg-surface-container-low p-space-sm rounded-xl flex flex-col justify-between shadow-md">
|
||||
<div class="flex items-start justify-between">
|
||||
<div class="flex items-center gap-1.5">
|
||||
<span class="material-symbols-outlined text-[18px] text-emerald-400">link</span>
|
||||
<span class="font-label-caption text-label-caption uppercase tracking-wider text-on-surface-variant">Chain Tension</span>
|
||||
</div>
|
||||
<span class="px-1.5 py-0.5 rounded bg-emerald-500/20 text-emerald-400 font-label-data text-[9px] uppercase font-bold tracking-wider">Optimal</span>
|
||||
</div>
|
||||
<div class="my-2">
|
||||
<div class="font-telemetry-metric-md text-[22px] font-bold text-on-surface leading-tight">28 <span class="font-label-data text-[12px] text-on-surface-variant">mm</span></div>
|
||||
<span class="font-label-caption text-[11px] text-on-surface-variant">Spec Range: 27-30mm</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between text-[10px] font-label-data text-emerald-400">
|
||||
<span>DID 520 EVR3</span>
|
||||
<span>CLEAN</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Tile 3: Brake Fluid Moisture (Good) -->
|
||||
<div class="bg-surface-container-low p-space-sm rounded-xl flex flex-col justify-between shadow-md">
|
||||
<div class="flex items-start justify-between">
|
||||
<div class="flex items-center gap-1.5">
|
||||
<span class="material-symbols-outlined text-[18px] text-primary-container">water_drop</span>
|
||||
<span class="font-label-caption text-label-caption uppercase tracking-wider text-on-surface-variant">Brake Fluid</span>
|
||||
</div>
|
||||
<span class="px-1.5 py-0.5 rounded bg-primary-container/20 text-primary-fixed font-label-data text-[9px] uppercase font-bold tracking-wider">1.2% H₂O</span>
|
||||
</div>
|
||||
<div class="my-2">
|
||||
<div class="font-telemetry-metric-md text-[22px] font-bold text-on-surface leading-tight">Brembo <span class="font-label-data text-[12px] text-on-surface-variant">DOT 5.1</span></div>
|
||||
<span class="font-label-caption text-[11px] text-emerald-400">Moisture Content Safe</span>
|
||||
</div>
|
||||
<div class="w-full bg-surface-container-highest h-1.5 rounded-full overflow-hidden">
|
||||
<div class="bg-primary-container h-full rounded-full" style="width: 24%"></div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Tile 4: Desmo Valve Service Countdown -->
|
||||
<div class="bg-surface-container-low p-space-sm rounded-xl flex flex-col justify-between shadow-md">
|
||||
<div class="flex items-start justify-between">
|
||||
<div class="flex items-center gap-1.5">
|
||||
<span class="material-symbols-outlined text-[18px] text-primary-fixed">tune</span>
|
||||
<span class="font-label-caption text-label-caption uppercase tracking-wider text-on-surface-variant">Desmo Valve</span>
|
||||
</div>
|
||||
<span class="px-1.5 py-0.5 rounded bg-surface-container-high text-on-surface-variant font-label-data text-[9px] uppercase font-bold">Scheduled</span>
|
||||
</div>
|
||||
<div class="my-2">
|
||||
<div class="font-telemetry-metric-md text-[22px] font-bold text-on-surface leading-tight">8,580 <span class="font-label-data text-[12px] text-on-surface-variant">MI REM</span></div>
|
||||
<span class="font-label-caption text-[11px] text-on-surface-variant">Target: 15,000 MI Service</span>
|
||||
</div>
|
||||
<div class="w-full bg-surface-container-highest h-1.5 rounded-full overflow-hidden">
|
||||
<div class="bg-secondary-container h-full rounded-full" style="width: 42%"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Full-Span TPMS & Tire Telemetry Card -->
|
||||
<div class="bg-surface-container-low p-space-md rounded-xl shadow-lg flex flex-col space-y-space-sm">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-[20px] text-primary-container">tire_repair</span>
|
||||
<div>
|
||||
<h4 class="font-headline-sm text-[16px] text-on-surface leading-tight">Tire Telemetry (TPMS CAN-BUS)</h4>
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant">Pirelli Diablo Supercorsa SP V4</span>
|
||||
</div>
|
||||
</div>
|
||||
<span class="px-2 py-0.5 rounded-full bg-emerald-500/20 text-emerald-400 font-label-data text-[10px] font-bold uppercase tracking-wider">Hot Track Ready</span>
|
||||
</div>
|
||||
<!-- Dual Tire Monitor (Front & Rear) -->
|
||||
<div class="grid grid-cols-2 gap-space-sm pt-2">
|
||||
<!-- Front Tire Data -->
|
||||
<div class="bg-surface-container p-space-sm rounded-xl flex flex-col items-center text-center">
|
||||
<div class="flex items-center gap-1 font-label-caption text-label-caption text-on-surface-variant uppercase tracking-widest mb-1">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-primary-container"></span>
|
||||
Front 120/70 ZR17
|
||||
</div>
|
||||
<div class="font-telemetry-metric-lg-mobile text-telemetry-metric-lg-mobile text-on-surface font-bold tracking-tight">
|
||||
33.5 <span class="font-label-data text-[12px] text-primary-container">PSI</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-2 mt-1 text-[11px] font-label-data text-on-surface-variant">
|
||||
<span class="flex items-center gap-0.5 text-primary-fixed">
|
||||
<span class="material-symbols-outlined text-[13px]">thermostat</span> 48°C
|
||||
</span>
|
||||
<span>•</span>
|
||||
<span class="text-emerald-400 font-bold">Optimal</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Rear Tire Data -->
|
||||
<div class="bg-surface-container p-space-sm rounded-xl flex flex-col items-center text-center">
|
||||
<div class="flex items-center gap-1 font-label-caption text-label-caption text-on-surface-variant uppercase tracking-widest mb-1">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-primary-container"></span>
|
||||
Rear 200/60 ZR17
|
||||
</div>
|
||||
<div class="font-telemetry-metric-lg-mobile text-telemetry-metric-lg-mobile text-on-surface font-bold tracking-tight">
|
||||
36.0 <span class="font-label-data text-[12px] text-primary-container">PSI</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-2 mt-1 text-[11px] font-label-data text-on-surface-variant">
|
||||
<span class="flex items-center gap-0.5 text-primary-fixed">
|
||||
<span class="material-symbols-outlined text-[13px]">thermostat</span> 54°C
|
||||
</span>
|
||||
<span>•</span>
|
||||
<span class="text-emerald-400 font-bold">Optimal</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Upcoming Maintenance Timeline Log -->
|
||||
<div class="flex flex-col space-y-space-sm pt-2">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-primary-container text-[20px]">event_note</span>
|
||||
<h3 class="font-headline-sm text-[18px] uppercase tracking-wide text-on-surface">Service Log & Timeline</h3>
|
||||
</div>
|
||||
<!-- Secondary Cockpit Action: Log Service Button (min 48px hit) -->
|
||||
<button class="min-h-[48px] px-3.5 py-1.5 bg-surface-container-high hover:bg-surface-bright rounded-xl text-primary font-label-data text-[12px] font-bold uppercase tracking-wider flex items-center gap-1 transition-all" type="button">
|
||||
<span class="material-symbols-outlined text-[16px] text-primary-container">add_circle</span>
|
||||
+ Log Service
|
||||
</button>
|
||||
</div>
|
||||
<!-- Timeline Entries -->
|
||||
<div class="space-y-2">
|
||||
<!-- Item 1: Pending Action -->
|
||||
<div class="bg-surface-container-low p-space-sm rounded-xl flex items-center justify-between">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="w-10 h-10 rounded-xl bg-amber-500/20 text-amber-400 flex items-center justify-center flex-shrink-0">
|
||||
<span class="material-symbols-outlined text-[20px]">build</span>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="font-body-lg text-[14px] font-semibold text-on-surface">6,800 MI Minor Service</span>
|
||||
<span class="px-1.5 py-0.2 rounded bg-amber-500/20 text-amber-400 font-label-caption text-[9px] uppercase font-bold">Due Soon</span>
|
||||
</div>
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant">Oil + OEM Filter + Sump Magnet Clear</span>
|
||||
</div>
|
||||
</div>
|
||||
<span class="font-label-data text-label-data text-amber-300 font-bold text-right">+380 MI</span>
|
||||
</div>
|
||||
<!-- Item 2: Completed Service -->
|
||||
<div class="bg-surface-container-low p-space-sm rounded-xl flex items-center justify-between opacity-80">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="w-10 h-10 rounded-xl bg-surface-container-high text-primary-fixed flex items-center justify-center flex-shrink-0">
|
||||
<span class="material-symbols-outlined text-[20px]">check_circle</span>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<span class="font-body-lg text-[14px] font-semibold text-on-surface">Brake Pads Replaced (Brembo Z04)</span>
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant">Logged at 5,900 MI by Pro Italia Tech</span>
|
||||
</div>
|
||||
</div>
|
||||
<span class="font-label-data text-label-data text-on-surface-variant text-right">520 MI ago</span>
|
||||
</div>
|
||||
<!-- Item 3: Completed Service -->
|
||||
<div class="bg-surface-container-low p-space-sm rounded-xl flex items-center justify-between opacity-80">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="w-10 h-10 rounded-xl bg-surface-container-high text-primary-fixed flex items-center justify-center flex-shrink-0">
|
||||
<span class="material-symbols-outlined text-[20px]">check_circle</span>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<span class="font-body-lg text-[14px] font-semibold text-on-surface">Öhlins Smart EC 2.0 Firmware Flash</span>
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant">Suspension ECU v4.8 Update</span>
|
||||
</div>
|
||||
</div>
|
||||
<span class="font-label-data text-label-data text-on-surface-variant text-right">1,120 MI ago</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Primary Cockpit Call-To-Action: Add Motorcycle Button -->
|
||||
<div class="pt-2 pb-space-sm">
|
||||
<button class="w-full min-h-[52px] h-[52px] bg-primary-container text-on-primary font-headline-sm text-[16px] font-bold uppercase tracking-wider rounded-xl shadow-[0_0_16px_rgba(0,229,255,0.4)] flex items-center justify-center gap-2 hover:bg-primary-fixed-dim transition-all active:scale-[0.99]" type="button">
|
||||
<span class="material-symbols-outlined text-[22px]">two_wheeler</span>
|
||||
Add Motorcycle to Garage
|
||||
</button>
|
||||
</div>
|
||||
</div></main><nav class="fixed bottom-0 w-full z-50 pb-safe bg-surface-container-lowest/90 backdrop-blur-xl shadow-[0_-4px_24px_rgba(0,0,0,0.6)]" data-active-classes="text-primary-container font-headline-sm [filter:drop-shadow(0_0_8px_rgba(0,229,255,0.5))]"><div class="grid grid-cols-6 items-center h-20 px-space-xs"><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="cockpit-dash" href="#"><span class="material-symbols-outlined text-[24px]">speed</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Dash</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="tactical-radar-map" href="#"><span class="material-symbols-outlined text-[24px]">radar</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Map</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="telemetry-log" href="#"><span class="material-symbols-outlined text-[24px]">monitoring</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Activity</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="bike-garage" href="#"><span class="material-symbols-outlined text-[24px]">two_wheeler</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Garage</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="pack-comms" href="#"><span class="material-symbols-outlined text-[24px]">groups_3</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Social</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="hud-settings" href="#"><span class="material-symbols-outlined text-[24px]">tune</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Settings</span></a></div></nav></body></html>
|
||||
|
|
@ -0,0 +1,225 @@
|
|||
<!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, viewport-fit=cover" name="viewport"/><meta content="mobile_tab" name="shell-type"/><title>MotorSignal Cockpit HUD</title><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&family=JetBrains+Mono:wght@500;600;700&family=Space+Grotesk:wght@600;700&display=swap" rel="stylesheet"/><link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/><style>@layer base{html,body{width:100%;margin:0;padding:0;background-color:#101419;color:#e0e2ea;}body{overscroll-behavior:none;}.pb-safe{padding-bottom:env(safe-area-inset-bottom,0px);}.pt-safe{padding-top:env(safe-area-inset-top,0px);}main>:first-child{margin-top:0!important;}main>:last-child{margin-bottom:0!important;}}::-webkit-scrollbar{display:none;}</style><script src="https://cdn.tailwindcss.com"></script><script id="tailwind-config">tailwind.config = { darkMode: "class", theme: { extend: { "colors": { "on-primary": "#00363d", "tertiary-fixed-dim": "#d0bcff", "tertiary-container": "#d9c8ff", "on-primary-container": "#00626e", "surface-variant": "#32353b", "on-primary-fixed-variant": "#004f58", "surface-container-high": "#272a30", "outline-variant": "#3b494c", "surface-container": "#1d2025", "on-surface": "#e0e2ea", "background": "#101419", "primary-container": "#00e5ff", "inverse-surface": "#e0e2ea", "outline": "#849396", "on-secondary": "#002a78", "secondary-fixed-dim": "#b4c5ff", "on-tertiary": "#3c0091", "inverse-primary": "#006875", "surface-bright": "#36393f", "surface-container-low": "#181c21", "surface-container-highest": "#32353b", "inverse-on-surface": "#2d3036", "on-secondary-fixed": "#00174b", "primary": "#c3f5ff", "error-container": "#93000a", "surface-tint": "#00daf3", "on-tertiary-fixed-variant": "#5516be", "on-error-container": "#ffdad6", "primary-fixed-dim": "#00daf3", "tertiary-fixed": "#e9ddff", "on-primary-fixed": "#001f24", "on-error": "#690005", "surface-container-lowest": "#0b0e13", "secondary-container": "#0053db", "tertiary": "#f2e9ff", "surface-dim": "#101419", "on-surface-variant": "#bac9cc", "on-tertiary-container": "#6834d1", "primary-fixed": "#9cf0ff", "secondary-fixed": "#dbe1ff", "error": "#ffb4ab", "on-secondary-container": "#cdd7ff", "on-secondary-fixed-variant": "#003ea8", "surface": "#101419", "on-background": "#e0e2ea", "secondary": "#b4c5ff", "on-tertiary-fixed": "#23005c" }, "borderRadius": { "DEFAULT": "0.25rem", "lg": "0.5rem", "xl": "0.75rem", "full": "9999px" }, "spacing": { "margin-lg": "2rem", "space-xs": "0.25rem", "gutter-lg": "1.5rem", "space-xl": "2rem", "margin": "1rem", "space-sm": "0.5rem", "space-md": "1rem", "space-lg": "1.5rem", "gutter": "1rem" }, "fontFamily": { "headline-lg": ["Space Grotesk"], "body-lg": ["Inter"], "telemetry-metric-lg-mobile": ["JetBrains Mono"], "label-data": ["JetBrains Mono"], "display-hero": ["Space Grotesk"], "headline-sm": ["Space Grotesk"], "headline-md": ["Space Grotesk"], "label-caption": ["Inter"], "telemetry-metric-lg": ["JetBrains Mono"], "display-hero-mobile": ["Space Grotesk"], "telemetry-metric-md": ["JetBrains Mono"], "body-md": ["Inter"] }, "fontSize": { "headline-lg": ["32px", { "lineHeight": "40px", "letterSpacing": "-0.02em", "fontWeight": "700" }], "body-lg": ["16px", { "lineHeight": "24px", "fontWeight": "500" }], "telemetry-metric-lg-mobile": ["36px", { "lineHeight": "36px", "letterSpacing": "-0.03em", "fontWeight": "700" }], "label-data": ["12px", { "lineHeight": "16px", "letterSpacing": "0.08em", "fontWeight": "600" }], "display-hero": ["56px", { "lineHeight": "60px", "letterSpacing": "-0.03em", "fontWeight": "700" }], "headline-sm": ["20px", { "lineHeight": "28px", "fontWeight": "600" }], "headline-md": ["24px", { "lineHeight": "32px", "letterSpacing": "-0.01em", "fontWeight": "600" }], "label-caption": ["11px", { "lineHeight": "14px", "letterSpacing": "0.05em", "fontWeight": "600" }], "telemetry-metric-lg": ["48px", { "lineHeight": "48px", "letterSpacing": "-0.04em", "fontWeight": "700" }], "display-hero-mobile": ["40px", { "lineHeight": "44px", "letterSpacing": "-0.02em", "fontWeight": "700" }], "telemetry-metric-md": ["28px", { "lineHeight": "32px", "letterSpacing": "-0.02em", "fontWeight": "600" }], "body-md": ["14px", { "lineHeight": "20px", "fontWeight": "400" }] } } } }</script><style>
|
||||
body {
|
||||
min-height: max(884px, 100dvh);
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
body {
|
||||
min-height: max(884px, 100dvh);
|
||||
}
|
||||
</style>
|
||||
</head><body class="bg-surface font-body-md text-on-surface antialiased flex flex-col min-h-screen selection:bg-primary-container selection:text-on-primary-container"><header class="fixed top-0 w-full z-50 pt-safe bg-surface-container-lowest/85 backdrop-blur-xl shadow-[0_4px_20px_rgba(0,0,0,0.5)]"><div class="h-16 px-space-md flex items-center justify-between gap-space-sm"><div class="flex items-center gap-space-sm"><img alt="MotorSignal Brand Logo" class="h-8 w-auto object-contain drop-shadow-[0_0_8px_rgba(0,229,255,0.4)]" src="https://lh3.googleusercontent.com/aida/AEtjO1Vf56Tkh6bJ86BCfT5GHz_yPumvEXYLWojlNHAFG-cN4VvH_nLvEbWQ4x7uhJPRaAyO8ozAAbLI_huEN134QOIYp8BdHuqoZCsMk9_ILaUxZqilVgamefO6d2sG1R8laIWSUswanVsK9lfvIgppQm_XxBQipzkDgPwIoXk7yh10QTlmZqDICryF-1MoWFfFjM2zZswr6ynuAgZAviROYnFBF2D4hxm6YREQxkZQJaBcG9oAg_dYVgTHxwg"/><div class="flex flex-col"><span class="font-headline-sm text-headline-sm uppercase tracking-wider text-primary-fixed">MotorSignal</span><span class="font-label-caption text-label-caption text-on-surface-variant uppercase tracking-widest leading-none">Telemetry Log</span></div></div><div class="flex items-center gap-space-sm"><div class="hidden sm:flex items-center gap-space-xs bg-surface-container-low px-space-sm py-1 rounded-full"><span class="w-2 h-2 rounded-full bg-primary-container animate-pulse shadow-[0_0_6px_#00e5ff]"></span><span class="font-label-data text-label-data text-primary-fixed">GPS 3D FIX</span></div><div class="flex items-center gap-1.5 bg-surface-container px-2 py-1 rounded-full"><span class="material-symbols-outlined text-[15px] text-primary-container">bolt</span><span class="font-label-data text-label-data text-on-surface">98%</span><span class="w-1 h-1 rounded-full bg-outline-variant"></span><span class="material-symbols-outlined text-[15px] text-primary-container">cell_tower</span></div><button aria-label="Rider Profile" class="min-w-[44px] min-h-[44px] flex items-center justify-center p-1 rounded-full focus:outline-none focus:ring-2 focus:ring-primary-container" type="button"><img alt="Profile" class="w-8 h-8 rounded-full object-cover ring-2 ring-primary-container/40" src="https://lh3.googleusercontent.com/aida-public/AB6AXuBb6sR8Ta8-L1_TN1LuCBfSxtZxX9hKOFjd-RjllihDsnp6AG1GlMhL9bVlb-ibhIRT3HMw_caXK7BmwmvWKNBcuizyqswUQZNztavckRTN1Xa6qGML_0kv8qvV_hrXWWK1EjSjVFzhRyDzf6VdGnZvUpGsFFmSBcaGVrXmEWFYnIa-qHyeWxZlT_SJmPuQJPQKEWEo6vC6kdDzXNnhoB4tpRHjIjCstvTdooPc0KVN_x3BqqmqadNI"/></button></div></div></header><main class="flex-1 flex flex-col relative w-full pt-16 pb-20 bg-surface"><div class="flex flex-col w-full text-on-surface select-none pb-8">
|
||||
<div class="flex flex-col gap-space-sm px-space-md pt-space-xs pb-space-sm bg-surface-container-lowest">
|
||||
<div class="flex items-center justify-between px-space-sm py-1.5 rounded-lg bg-surface-container-low shadow-sm">
|
||||
<div class="flex items-center gap-space-xs">
|
||||
<span class="w-2.5 h-2.5 rounded-full bg-primary-container animate-ping"></span>
|
||||
<span class="font-label-data text-label-data text-primary-fixed uppercase tracking-wider">PACK STATUS: 6 ACTIVE</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-space-xs font-label-data text-label-data text-on-surface-variant">
|
||||
<span class="text-primary">MESH CH-04</span>
|
||||
<span>•</span>
|
||||
<span class="text-primary-fixed">STABLE</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid grid-cols-3 gap-space-xs">
|
||||
<div class="flex flex-col items-center justify-center p-2 rounded-lg bg-surface-container-high shadow-md">
|
||||
<span class="font-label-caption text-label-caption uppercase tracking-wider text-on-surface-variant">Pack Avg</span>
|
||||
<div class="flex items-baseline gap-1 mt-0.5">
|
||||
<span class="font-telemetry-metric-md text-telemetry-metric-md text-primary font-bold">62</span>
|
||||
<span class="font-label-data text-[10px] text-on-surface-variant">MPH</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col items-center justify-center p-2 rounded-lg bg-surface-container-high shadow-md">
|
||||
<span class="font-label-caption text-label-caption uppercase tracking-wider text-on-surface-variant">Spread</span>
|
||||
<div class="flex items-baseline gap-1 mt-0.5">
|
||||
<span class="font-telemetry-metric-md text-telemetry-metric-md text-secondary font-bold">0.9</span>
|
||||
<span class="font-label-data text-[10px] text-on-surface-variant">MI</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col items-center justify-center p-2 rounded-lg bg-surface-container-high shadow-md">
|
||||
<span class="font-label-caption text-label-caption uppercase tracking-wider text-on-surface-variant">Ad-Hoc Mesh</span>
|
||||
<div class="flex items-baseline gap-1 mt-0.5">
|
||||
<span class="font-telemetry-metric-md text-telemetry-metric-md text-primary-container font-bold">98</span>
|
||||
<span class="font-label-data text-[10px] text-on-surface-variant">%</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="relative w-full aspect-square max-w-[420px] mx-auto overflow-hidden bg-surface-container-lowest my-space-xs flex items-center justify-center">
|
||||
<div class="absolute inset-0 bg-[radial-gradient(ellipse_at_center,_var(--tw-gradient-stops))] from-surface-container/60 via-surface-container-lowest to-surface-container-lowest"></div>
|
||||
<svg class="absolute inset-0 w-full h-full p-4 pointer-events-none" viewbox="0 0 400 400">
|
||||
<circle cx="200" cy="200" fill="none" r="180" stroke="#272a30" stroke-dasharray="3 3" stroke-width="1.5"></circle>
|
||||
<circle cx="200" cy="200" fill="none" r="135" stroke="#272a30" stroke-width="1.5"></circle>
|
||||
<circle cx="200" cy="200" fill="none" r="90" stroke="#32353b" stroke-dasharray="4 4" stroke-width="1.5"></circle>
|
||||
<circle cx="200" cy="200" fill="none" r="45" stroke="#3b494c" stroke-width="1.5"></circle>
|
||||
<line stroke="#1d2025" stroke-width="1" x1="200" x2="200" y1="10" y2="390"></line>
|
||||
<line stroke="#1d2025" stroke-width="1" x1="10" x2="390" y1="200" y2="200"></line>
|
||||
<line stroke="#1d2025" stroke-dasharray="2 4" stroke-width="0.75" x1="65" x2="335" y1="65" y2="335"></line>
|
||||
<line stroke="#1d2025" stroke-dasharray="2 4" stroke-width="0.75" x1="335" x2="65" y1="65" y2="335"></line>
|
||||
<text fill="#849396" font-family="JetBrains Mono" font-size="9" font-weight="600" x="204" y="152">100M</text>
|
||||
<text fill="#849396" font-family="JetBrains Mono" font-size="9" font-weight="600" x="204" y="107">500M</text>
|
||||
<text fill="#849396" font-family="JetBrains Mono" font-size="9" font-weight="600" x="204" y="62">1.0KM</text>
|
||||
<text fill="#849396" font-family="JetBrains Mono" font-size="9" font-weight="600" x="204" y="18">2.0KM</text>
|
||||
<path d="M 200 200 L 320 80 A 170 170 0 0 0 200 30 Z" fill="url(#sweepGlow)" opacity="0.4">
|
||||
<animatetransform attributename="transform" dur="4s" from="0 200 200" repeatcount="indefinite" to="360 200 200" type="rotate"></animatetransform>
|
||||
</path>
|
||||
<defs>
|
||||
<lineargradient id="sweepGlow" x1="0%" x2="100%" y1="0%" y2="100%">
|
||||
<stop offset="0%" stop-color="#00e5ff" stop-opacity="0.35"></stop>
|
||||
<stop offset="100%" stop-color="#00e5ff" stop-opacity="0.0"></stop>
|
||||
</lineargradient>
|
||||
</defs>
|
||||
<polygon fill="#00e5ff" points="200,6 195,14 205,14"></polygon>
|
||||
<text fill="#00e5ff" font-family="Space Grotesk" font-size="10" font-weight="700" text-anchor="middle" x="200" y="24">334° NW</text>
|
||||
</svg>
|
||||
<div class="relative w-full h-full">
|
||||
<div class="absolute top-[28%] left-[52%] -translate-x-1/2 -translate-y-1/2 flex items-center gap-1.5 transition-all duration-300">
|
||||
<div class="w-8 h-8 rounded-full bg-primary-container/20 flex items-center justify-center shadow-[0_0_12px_#00e5ff]">
|
||||
<span class="material-symbols-outlined text-[18px] text-primary-container" style="font-variation-settings: 'FILL' 1;">stars</span>
|
||||
</div>
|
||||
<div class="bg-surface-container-high/90 px-1.5 py-0.5 rounded shadow">
|
||||
<p class="font-label-data text-[10px] text-primary-fixed leading-none font-bold">Dave [LEAD]</p>
|
||||
<p class="font-label-caption text-[9px] text-primary leading-none mt-0.5">64 MPH • GAP: 0s</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="absolute top-[40%] left-[36%] -translate-x-1/2 -translate-y-1/2 flex items-center gap-1.5">
|
||||
<div class="w-6 h-6 rounded-full bg-surface-bright flex items-center justify-center shadow">
|
||||
<span class="w-2.5 h-2.5 rounded-full bg-primary-fixed"></span>
|
||||
</div>
|
||||
<div class="bg-surface-container-high/80 px-1 py-0.5 rounded shadow">
|
||||
<p class="font-label-data text-[9px] text-on-surface leading-none">Ghost</p>
|
||||
<p class="font-label-caption text-[8px] text-on-surface-variant leading-none">+0.12s</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="absolute top-[48%] left-[64%] -translate-x-1/2 -translate-y-1/2 flex items-center gap-1.5">
|
||||
<div class="w-6 h-6 rounded-full bg-surface-bright flex items-center justify-center shadow">
|
||||
<span class="w-2.5 h-2.5 rounded-full bg-primary-fixed"></span>
|
||||
</div>
|
||||
<div class="bg-surface-container-high/80 px-1 py-0.5 rounded shadow">
|
||||
<p class="font-label-data text-[9px] text-on-surface leading-none">Viper</p>
|
||||
<p class="font-label-caption text-[8px] text-on-surface-variant leading-none">+0.26s</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="absolute top-[52%] left-[48%] -translate-x-1/2 -translate-y-1/2 z-20 flex flex-col items-center">
|
||||
<div class="relative flex items-center justify-center">
|
||||
<div class="absolute w-8 h-8 rounded-full bg-primary/20 animate-ping"></div>
|
||||
<div class="w-7 h-7 rounded-full bg-primary text-on-primary flex items-center justify-center shadow-[0_0_14px_#c3f5ff]">
|
||||
<span class="material-symbols-outlined text-[16px]">navigation</span>
|
||||
</div>
|
||||
</div>
|
||||
<span class="bg-surface-container-lowest/90 px-1 rounded font-label-data text-[8px] text-primary mt-1 font-bold">YOU</span>
|
||||
</div>
|
||||
<div class="absolute top-[65%] left-[34%] -translate-x-1/2 -translate-y-1/2 flex items-center gap-1.5">
|
||||
<div class="w-6 h-6 rounded-full bg-surface-bright flex items-center justify-center shadow">
|
||||
<span class="w-2.5 h-2.5 rounded-full bg-primary-fixed"></span>
|
||||
</div>
|
||||
<div class="bg-surface-container-high/80 px-1 py-0.5 rounded shadow">
|
||||
<p class="font-label-data text-[9px] text-on-surface leading-none">Rook</p>
|
||||
<p class="font-label-caption text-[8px] text-on-surface-variant leading-none">+0.51s</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="absolute top-[72%] left-[62%] -translate-x-1/2 -translate-y-1/2 flex items-center gap-1.5">
|
||||
<div class="w-6 h-6 rounded-full bg-surface-bright flex items-center justify-center shadow">
|
||||
<span class="w-2.5 h-2.5 rounded-full bg-primary-fixed"></span>
|
||||
</div>
|
||||
<div class="bg-surface-container-high/80 px-1 py-0.5 rounded shadow">
|
||||
<p class="font-label-data text-[9px] text-on-surface leading-none">Apex</p>
|
||||
<p class="font-label-caption text-[8px] text-on-surface-variant leading-none">+0.68s</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="absolute top-[84%] left-[45%] -translate-x-1/2 -translate-y-1/2 flex items-center gap-1.5">
|
||||
<div class="w-8 h-8 rounded-full bg-secondary-container/40 flex items-center justify-center shadow-[0_0_12px_#0053db]">
|
||||
<span class="material-symbols-outlined text-[18px] text-secondary" style="font-variation-settings: 'FILL' 1;">shield</span>
|
||||
</div>
|
||||
<div class="bg-surface-container-high/90 px-1.5 py-0.5 rounded shadow">
|
||||
<p class="font-label-data text-[10px] text-secondary-fixed leading-none font-bold">Sarah [SWEEP]</p>
|
||||
<p class="font-label-caption text-[9px] text-secondary leading-none mt-0.5">+0.8 KM • 61 MPH</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="absolute bottom-2 right-2 bg-surface-container-lowest/80 px-2 py-1 rounded flex items-center gap-1">
|
||||
<span class="material-symbols-outlined text-[14px] text-primary">layers</span>
|
||||
<span class="font-label-data text-[10px] text-on-surface-variant">STAGGERED 2X2</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="px-space-md flex flex-col gap-space-sm">
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="font-label-caption text-label-caption uppercase tracking-wider text-on-surface-variant">Pack Roster & Distance</span>
|
||||
<span class="font-label-data text-label-data text-primary">6 PAIRED</span>
|
||||
</div>
|
||||
<div class="grid grid-cols-2 gap-space-xs">
|
||||
<div class="flex items-center gap-2 p-2 rounded-xl bg-surface-container shadow-sm">
|
||||
<div class="w-9 h-9 rounded-lg bg-surface-container-highest flex items-center justify-center shrink-0">
|
||||
<span class="material-symbols-outlined text-primary text-[20px]">sports_motorsports</span>
|
||||
</div>
|
||||
<div class="flex flex-col min-w-0">
|
||||
<div class="flex items-center gap-1">
|
||||
<span class="font-headline-sm text-[13px] text-on-surface truncate">Dave</span>
|
||||
<span class="font-label-caption text-[9px] bg-primary/20 text-primary px-1 rounded font-bold">CAP</span>
|
||||
</div>
|
||||
<span class="font-label-data text-[11px] text-primary-fixed-dim">Lead • 0.0s gap</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-2 p-2 rounded-xl bg-surface-container shadow-sm">
|
||||
<div class="w-9 h-9 rounded-lg bg-surface-container-highest flex items-center justify-center shrink-0">
|
||||
<span class="material-symbols-outlined text-secondary text-[20px]">sports_motorsports</span>
|
||||
</div>
|
||||
<div class="flex flex-col min-w-0">
|
||||
<div class="flex items-center gap-1">
|
||||
<span class="font-headline-sm text-[13px] text-on-surface truncate">Sarah</span>
|
||||
<span class="font-label-caption text-[9px] bg-secondary-container/40 text-secondary-fixed px-1 rounded font-bold">TAIL</span>
|
||||
</div>
|
||||
<span class="font-label-data text-[11px] text-secondary">+0.8km • 61mph</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col gap-space-xs mt-space-xs">
|
||||
<button class="w-full min-h-[58px] bg-error-container text-on-error-container rounded-xl flex items-center justify-center gap-space-sm px-space-md shadow-[0_0_20px_rgba(239,68,68,0.4)] active:scale-[0.98] transition-transform" id="hazardPingBtn" type="button">
|
||||
<span class="material-symbols-outlined text-[28px] text-error animate-pulse">warning</span>
|
||||
<div class="flex flex-col text-left">
|
||||
<span class="font-headline-sm text-headline-sm leading-tight uppercase font-bold tracking-wide text-error">EMERGENCY HAZARD PING</span>
|
||||
<span class="font-label-caption text-label-caption text-on-error-container/90 uppercase">Hold / Tap to broadcast pothole, gravel, or stop</span>
|
||||
</div>
|
||||
</button>
|
||||
<div class="grid grid-cols-2 gap-space-xs">
|
||||
<button class="min-h-[52px] bg-secondary-container text-on-secondary-container rounded-xl flex items-center justify-center gap-2 px-space-sm active:bg-secondary-fixed transition-colors" id="audioPttBtn" type="button">
|
||||
<span class="material-symbols-outlined text-[24px]">mic</span>
|
||||
<span class="font-headline-sm text-[15px] uppercase font-bold tracking-wider">AUDIO PTT</span>
|
||||
</button>
|
||||
<button class="min-h-[52px] bg-surface-container-high text-on-surface rounded-xl flex items-center justify-center gap-2 px-space-sm active:bg-surface-container-highest transition-colors" id="recenterBtn" type="button">
|
||||
<span class="material-symbols-outlined text-[22px] text-primary">my_location</span>
|
||||
<span class="font-headline-sm text-[15px] uppercase font-bold tracking-wider">CENTER HUD</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
const ptt = document.getElementById('audioPttBtn');
|
||||
if (ptt) {
|
||||
ptt.addEventListener('pointerdown', () => {
|
||||
ptt.classList.remove('bg-secondary-container', 'text-on-secondary-container');
|
||||
ptt.classList.add('bg-primary-container', 'text-on-primary-container', 'shadow-[0_0_16px_#00e5ff]');
|
||||
});
|
||||
const releasePtt = () => {
|
||||
ptt.classList.remove('bg-primary-container', 'text-on-primary-container', 'shadow-[0_0_16px_#00e5ff]');
|
||||
ptt.classList.add('bg-secondary-container', 'text-on-secondary-container');
|
||||
};
|
||||
ptt.addEventListener('pointerup', releasePtt);
|
||||
ptt.addEventListener('pointerleave', releasePtt);
|
||||
}
|
||||
|
||||
const hazard = document.getElementById('hazardPingBtn');
|
||||
if (hazard) {
|
||||
hazard.addEventListener('click', () => {
|
||||
hazard.classList.add('ring-4', 'ring-error');
|
||||
setTimeout(() => {
|
||||
hazard.classList.remove('ring-4', 'ring-error');
|
||||
}, 500);
|
||||
});
|
||||
}
|
||||
</script></main><nav class="fixed bottom-0 w-full z-50 pb-safe bg-surface-container-lowest/90 backdrop-blur-xl shadow-[0_-4px_24px_rgba(0,0,0,0.6)]" data-active-classes="text-primary-container font-headline-sm [filter:drop-shadow(0_0_8px_rgba(0,229,255,0.5))]"><div class="grid grid-cols-6 items-center h-20 px-space-xs"><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="cockpit-dash" href="#"><span class="material-symbols-outlined text-[24px]">speed</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Dash</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="tactical-radar-map" href="#"><span class="material-symbols-outlined text-[24px]">radar</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Map</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="telemetry-log" href="#"><span class="material-symbols-outlined text-[24px]">monitoring</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Activity</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="bike-garage" href="#"><span class="material-symbols-outlined text-[24px]">two_wheeler</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Garage</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="pack-comms" href="#"><span class="material-symbols-outlined text-[24px]">groups_3</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Social</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="hud-settings" href="#"><span class="material-symbols-outlined text-[24px]">tune</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Settings</span></a></div></nav></body></html>
|
||||
|
|
@ -0,0 +1,292 @@
|
|||
<!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, viewport-fit=cover" name="viewport"/><meta content="mobile_tab" name="shell-type"/><title>MotorSignal Cockpit HUD</title><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&family=JetBrains+Mono:wght@500;600;700&family=Space+Grotesk:wght@600;700&display=swap" rel="stylesheet"/><link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/><style>@layer base{html,body{width:100%;margin:0;padding:0;background-color:#101419;color:#e0e2ea;}body{overscroll-behavior:none;}.pb-safe{padding-bottom:env(safe-area-inset-bottom,0px);}.pt-safe{padding-top:env(safe-area-inset-top,0px);}main>:first-child{margin-top:0!important;}main>:last-child{margin-bottom:0!important;}}::-webkit-scrollbar{display:none;}</style><script src="https://cdn.tailwindcss.com"></script><script id="tailwind-config">tailwind.config = { darkMode: "class", theme: { extend: { "colors": { "on-primary": "#00363d", "tertiary-fixed-dim": "#d0bcff", "tertiary-container": "#d9c8ff", "on-primary-container": "#00626e", "surface-variant": "#32353b", "on-primary-fixed-variant": "#004f58", "surface-container-high": "#272a30", "outline-variant": "#3b494c", "surface-container": "#1d2025", "on-surface": "#e0e2ea", "background": "#101419", "primary-container": "#00e5ff", "inverse-surface": "#e0e2ea", "outline": "#849396", "on-secondary": "#002a78", "secondary-fixed-dim": "#b4c5ff", "on-tertiary": "#3c0091", "inverse-primary": "#006875", "surface-bright": "#36393f", "surface-container-low": "#181c21", "surface-container-highest": "#32353b", "inverse-on-surface": "#2d3036", "on-secondary-fixed": "#00174b", "primary": "#c3f5ff", "error-container": "#93000a", "surface-tint": "#00daf3", "on-tertiary-fixed-variant": "#5516be", "on-error-container": "#ffdad6", "primary-fixed-dim": "#00daf3", "tertiary-fixed": "#e9ddff", "on-primary-fixed": "#001f24", "on-error": "#690005", "surface-container-lowest": "#0b0e13", "secondary-container": "#0053db", "tertiary": "#f2e9ff", "surface-dim": "#101419", "on-surface-variant": "#bac9cc", "on-tertiary-container": "#6834d1", "primary-fixed": "#9cf0ff", "secondary-fixed": "#dbe1ff", "error": "#ffb4ab", "on-secondary-container": "#cdd7ff", "on-secondary-fixed-variant": "#003ea8", "surface": "#101419", "on-background": "#e0e2ea", "secondary": "#b4c5ff", "on-tertiary-fixed": "#23005c" }, "borderRadius": { "DEFAULT": "0.25rem", "lg": "0.5rem", "xl": "0.75rem", "full": "9999px" }, "spacing": { "margin-lg": "2rem", "space-xs": "0.25rem", "gutter-lg": "1.5rem", "space-xl": "2rem", "margin": "1rem", "space-sm": "0.5rem", "space-md": "1rem", "space-lg": "1.5rem", "gutter": "1rem" }, "fontFamily": { "headline-lg": ["Space Grotesk"], "body-lg": ["Inter"], "telemetry-metric-lg-mobile": ["JetBrains Mono"], "label-data": ["JetBrains Mono"], "display-hero": ["Space Grotesk"], "headline-sm": ["Space Grotesk"], "headline-md": ["Space Grotesk"], "label-caption": ["Inter"], "telemetry-metric-lg": ["JetBrains Mono"], "display-hero-mobile": ["Space Grotesk"], "telemetry-metric-md": ["JetBrains Mono"], "body-md": ["Inter"] }, "fontSize": { "headline-lg": ["32px", { "lineHeight": "40px", "letterSpacing": "-0.02em", "fontWeight": "700" }], "body-lg": ["16px", { "lineHeight": "24px", "fontWeight": "500" }], "telemetry-metric-lg-mobile": ["36px", { "lineHeight": "36px", "letterSpacing": "-0.03em", "fontWeight": "700" }], "label-data": ["12px", { "lineHeight": "16px", "letterSpacing": "0.08em", "fontWeight": "600" }], "display-hero": ["56px", { "lineHeight": "60px", "letterSpacing": "-0.03em", "fontWeight": "700" }], "headline-sm": ["20px", { "lineHeight": "28px", "fontWeight": "600" }], "headline-md": ["24px", { "lineHeight": "32px", "letterSpacing": "-0.01em", "fontWeight": "600" }], "label-caption": ["11px", { "lineHeight": "14px", "letterSpacing": "0.05em", "fontWeight": "600" }], "telemetry-metric-lg": ["48px", { "lineHeight": "48px", "letterSpacing": "-0.04em", "fontWeight": "700" }], "display-hero-mobile": ["40px", { "lineHeight": "44px", "letterSpacing": "-0.02em", "fontWeight": "700" }], "telemetry-metric-md": ["28px", { "lineHeight": "32px", "letterSpacing": "-0.02em", "fontWeight": "600" }], "body-md": ["14px", { "lineHeight": "20px", "fontWeight": "400" }] } } } }</script><style>
|
||||
body {
|
||||
min-height: max(884px, 100dvh);
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
body {
|
||||
min-height: max(884px, 100dvh);
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
body {
|
||||
min-height: max(884px, 100dvh);
|
||||
}
|
||||
</style>
|
||||
</head><body class="bg-surface font-body-md text-on-surface antialiased flex flex-col min-h-screen selection:bg-primary-container selection:text-on-primary-container"><header class="fixed top-0 w-full z-50 pt-safe bg-surface-container-lowest/85 backdrop-blur-xl shadow-[0_4px_20px_rgba(0,0,0,0.5)]"><div class="h-16 px-space-md flex items-center justify-between gap-space-sm"><div class="flex items-center gap-space-sm"><img alt="MotorSignal Brand Logo" class="h-8 w-auto object-contain drop-shadow-[0_0_8px_rgba(0,229,255,0.4)]" src="https://lh3.googleusercontent.com/aida/AEtjO1Vf56Tkh6bJ86BCfT5GHz_yPumvEXYLWojlNHAFG-cN4VvH_nLvEbWQ4x7uhJPRaAyO8ozAAbLI_huEN134QOIYp8BdHuqoZCsMk9_ILaUxZqilVgamefO6d2sG1R8laIWSUswanVsK9lfvIgppQm_XxBQipzkDgPwIoXk7yh10QTlmZqDICryF-1MoWFfFjM2zZswr6ynuAgZAviROYnFBF2D4hxm6YREQxkZQJaBcG9oAg_dYVgTHxwg"/><div class="flex flex-col"><span class="font-headline-sm text-headline-sm uppercase tracking-wider text-primary-fixed">MotorSignal</span><span class="font-label-caption text-label-caption text-on-surface-variant uppercase tracking-widest leading-none">Telemetry Log</span></div></div><div class="flex items-center gap-space-sm"><div class="hidden sm:flex items-center gap-space-xs bg-surface-container-low px-space-sm py-1 rounded-full"><span class="w-2 h-2 rounded-full bg-primary-container animate-pulse shadow-[0_0_6px_#00e5ff]"></span><span class="font-label-data text-label-data text-primary-fixed">GPS 3D FIX</span></div><div class="flex items-center gap-1.5 bg-surface-container px-2 py-1 rounded-full"><span class="material-symbols-outlined text-[15px] text-primary-container">bolt</span><span class="font-label-data text-label-data text-on-surface">98%</span><span class="w-1 h-1 rounded-full bg-outline-variant"></span><span class="material-symbols-outlined text-[15px] text-primary-container">cell_tower</span></div><button aria-label="Rider Profile" class="min-w-[44px] min-h-[44px] flex items-center justify-center p-1 rounded-full focus:outline-none focus:ring-2 focus:ring-primary-container" type="button"><img alt="Profile" class="w-8 h-8 rounded-full object-cover ring-2 ring-primary-container/40" src="https://lh3.googleusercontent.com/aida-public/AB6AXuBb6sR8Ta8-L1_TN1LuCBfSxtZxX9hKOFjd-RjllihDsnp6AG1GlMhL9bVlb-ibhIRT3HMw_caXK7BmwmvWKNBcuizyqswUQZNztavckRTN1Xa6qGML_0kv8qvV_hrXWWK1EjSjVFzhRyDzf6VdGnZvUpGsFFmSBcaGVrXmEWFYnIa-qHyeWxZlT_SJmPuQJPQKEWEo6vC6kdDzXNnhoB4tpRHjIjCstvTdooPc0KVN_x3BqqmqadNI"/></button></div></div></header><main class="flex-1 flex flex-col relative w-full pt-16 pb-20 bg-surface"><div class="flex flex-col w-full px-space-md py-space-sm space-y-space-md">
|
||||
<!-- Top Context Header & Filter Bar -->
|
||||
<section class="flex flex-col space-y-space-sm">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-space-xs bg-surface-container-low px-space-sm py-1 rounded-full shadow-sm">
|
||||
<span class="w-2 h-2 rounded-full bg-primary-container shadow-[0_0_8px_#00e5ff] animate-pulse"></span>
|
||||
<span class="font-label-data text-label-data uppercase tracking-wider text-primary-fixed">Squad & Canyon Feed</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-1.5 bg-surface-container-high px-space-sm py-1 rounded-full">
|
||||
<span class="material-symbols-outlined text-[14px] text-primary-container">sensors</span>
|
||||
<span class="font-label-caption text-label-caption uppercase tracking-wider text-primary-fixed">24 Active</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Segmented Filter Control -->
|
||||
<div class="grid grid-cols-3 gap-1 bg-surface-container-lowest p-1 rounded-xl shadow-inner">
|
||||
<button class="min-h-[44px] flex items-center justify-center rounded-lg bg-primary-container text-on-primary-container font-headline-sm text-label-data uppercase tracking-wider font-bold transition-all shadow-md active:scale-95" type="button">
|
||||
All Activity
|
||||
</button>
|
||||
<button class="min-h-[44px] flex items-center justify-center rounded-lg bg-transparent text-on-surface-variant hover:text-on-surface font-body-md text-label-data uppercase tracking-wider transition-colors active:scale-95" type="button">
|
||||
Club Only
|
||||
</button>
|
||||
<button class="min-h-[44px] flex items-center justify-center rounded-lg bg-transparent text-on-surface-variant hover:text-on-surface font-body-md text-label-data uppercase tracking-wider transition-colors active:scale-95" type="button">
|
||||
Nearby Packs
|
||||
</button>
|
||||
</div>
|
||||
</section>
|
||||
<!-- Feed Card 1: ApexMarcus Track Telemetry -->
|
||||
<article class="flex flex-col bg-surface-container rounded-xl shadow-xl overflow-hidden">
|
||||
<!-- Card Header -->
|
||||
<div class="p-space-md flex items-start justify-between gap-space-sm">
|
||||
<div class="flex items-center gap-space-sm min-w-0">
|
||||
<div class="relative shrink-0">
|
||||
<img class="w-12 h-12 rounded-xl object-cover" data-alt="Close up dark tactical carbon fiber motorcycle helmet with high-contrast electric cyan reflective visor shield in dim moody garage lighting" src="https://lh3.googleusercontent.com/aida-public/AB6AXuATclWgveTDldOfvuEzN_hG-E-Yk0iA79W1c4kohdfXEyA_gl-6pKw79J3a_2LiEvCT8Ud7RU05CZQJjwFXmOAO2eQqYVxXj1ze_BNGK-9WsWexN4eKQMU8K_gt2ufh8-PdcnR5d9Xyb5Sobm2ni5IYs13Ec8jVG-jLPLEeXBZ3brRGYuaPm0tE8VWQBQ9xVqF8cITFuG9pK2hAs6quazz8cdblukHVxpq1E9FUGSv3mqUMY4-eJoE7"/>
|
||||
<span class="absolute -bottom-1 -right-1 w-3.5 h-3.5 bg-primary-container rounded-full shadow-[0_0_6px_#00e5ff]"></span>
|
||||
</div>
|
||||
<div class="flex flex-col min-w-0">
|
||||
<div class="flex items-center gap-1.5 flex-wrap">
|
||||
<span class="font-headline-sm text-headline-sm text-on-surface truncate">@ApexMarcus</span>
|
||||
<span class="bg-primary-container/20 text-primary font-label-data text-label-caption px-1.5 py-0.5 rounded uppercase font-bold tracking-widest">PRO</span>
|
||||
</div>
|
||||
<p class="font-body-md text-label-caption text-on-surface-variant truncate">Bay Area Twisties Club</p>
|
||||
<span class="font-label-caption text-label-caption text-outline">28m ago • Alice's Restaurant</span>
|
||||
</div>
|
||||
</div>
|
||||
<button aria-label="Card Options" class="min-h-[48px] min-w-[48px] flex items-center justify-center text-on-surface-variant hover:text-on-surface rounded-lg active:bg-surface-container-high transition-colors" type="button">
|
||||
<span class="material-symbols-outlined text-[20px]">more_vert</span>
|
||||
</button>
|
||||
</div>
|
||||
<!-- Title & Bike Tag -->
|
||||
<div class="px-space-md pb-space-sm space-y-1">
|
||||
<h2 class="font-headline-md text-headline-md text-primary tracking-tight">Sunday Skyline & Pescadero Carve</h2>
|
||||
<div class="inline-flex items-center gap-1.5 bg-surface-container-low px-2 py-1 rounded-md">
|
||||
<span class="material-symbols-outlined text-[14px] text-primary-container">sports_motorsports</span>
|
||||
<span class="font-label-data text-label-caption text-on-surface font-semibold tracking-wide">2024 Ducati Streetfighter V4</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Telemetry Strip (4 Inset Metrics) -->
|
||||
<div class="px-space-md py-space-xs">
|
||||
<div class="grid grid-cols-2 gap-space-xs bg-surface-container-lowest p-space-sm rounded-xl">
|
||||
<div class="flex flex-col bg-surface-container-low p-space-sm rounded-lg">
|
||||
<span class="font-label-data text-label-caption uppercase tracking-wider text-outline">Distance</span>
|
||||
<div class="flex items-baseline gap-1 mt-0.5">
|
||||
<span class="font-telemetry-metric-lg-mobile text-telemetry-metric-lg-mobile text-on-surface">68.4</span>
|
||||
<span class="font-label-data text-label-caption text-on-surface-variant font-bold">MI</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col bg-surface-container-low p-space-sm rounded-lg">
|
||||
<span class="font-label-data text-label-caption uppercase tracking-wider text-outline">Duration</span>
|
||||
<div class="flex items-baseline gap-1 mt-0.5">
|
||||
<span class="font-telemetry-metric-lg-mobile text-telemetry-metric-lg-mobile text-on-surface">1h 14m</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col bg-surface-container-low p-space-sm rounded-lg">
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="font-label-data text-label-caption uppercase tracking-wider text-outline">Max Lean</span>
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-primary-container"></span>
|
||||
</div>
|
||||
<div class="flex items-baseline gap-1 mt-0.5">
|
||||
<span class="font-telemetry-metric-lg-mobile text-telemetry-metric-lg-mobile text-primary font-bold">51°</span>
|
||||
<span class="font-label-data text-label-caption text-primary-fixed uppercase">RIGHT</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col bg-surface-container-low p-space-sm rounded-lg">
|
||||
<span class="font-label-data text-label-caption uppercase tracking-wider text-outline">Pace Factor</span>
|
||||
<div class="flex items-baseline gap-1 mt-0.5">
|
||||
<span class="font-telemetry-metric-lg-mobile text-telemetry-metric-lg-mobile text-secondary font-bold">1.32x</span>
|
||||
<span class="font-label-data text-label-caption text-on-surface-variant">Spirited</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Route Polyline Snapshot Preview -->
|
||||
<div class="px-space-md py-space-sm">
|
||||
<div class="relative w-full h-44 bg-surface-container-lowest rounded-xl overflow-hidden flex items-center justify-center shadow-inner">
|
||||
<!-- Grid Matrix Overlay Background -->
|
||||
<svg class="absolute inset-0 w-full h-full opacity-20" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<pattern height="24" id="grid-matrix" patternunits="userSpaceOnUse" width="24">
|
||||
<path d="M 24 0 L 0 0 0 24" fill="none" stroke="#3b494c" stroke-width="0.5"></path>
|
||||
</pattern>
|
||||
</defs>
|
||||
<rect fill="url(#grid-matrix)" height="100%" width="100%"></rect>
|
||||
</svg>
|
||||
<!-- Route Visualization (High Contrast Cyan & Amber Twist Track) -->
|
||||
<svg class="relative w-full h-full p-4" fill="none" viewbox="0 0 320 140" xmlns="http://www.w3.org/2000/svg">
|
||||
<!-- Background Glow Shadow Path -->
|
||||
<path class="opacity-30 blur-sm" d="M 20 110 C 60 110, 80 40, 120 40 C 150 40, 140 100, 180 100 C 220 100, 240 25, 295 30" stroke="#00e5ff" stroke-linecap="round" stroke-linejoin="round" stroke-width="6"></path>
|
||||
<!-- Active Vector Trail -->
|
||||
<path d="M 20 110 C 60 110, 80 40, 120 40 C 150 40, 140 100, 180 100 C 220 100, 240 25, 295 30" stroke="#c3f5ff" stroke-linecap="round" stroke-linejoin="round" stroke-width="3"></path>
|
||||
<!-- High G-Force Apex Segment Highlight (Amber Sector) -->
|
||||
<path class="drop-shadow-[0_0_8px_#f59e0b]" d="M 120 40 C 135 40, 140 70, 155 85" stroke="#f59e0b" stroke-linecap="round" stroke-width="4"></path>
|
||||
<!-- Start Marker -->
|
||||
<circle cx="20" cy="110" fill="#00e5ff" r="4.5"></circle>
|
||||
<circle class="animate-spin" cx="20" cy="110" r="8" stroke="#00e5ff" stroke-dasharray="2 2" stroke-width="1.5"></circle>
|
||||
<!-- Apex Markers with Degree Badges -->
|
||||
<circle cx="120" cy="40" fill="#00e5ff" r="4"></circle>
|
||||
<circle cx="240" cy="25" fill="#f59e0b" r="4"></circle>
|
||||
<text fill="#c3f5ff" font-family="JetBrains Mono" font-size="9" font-weight="700" text-anchor="middle" x="120" y="28">51° APEX</text>
|
||||
<text fill="#ffb4ab" font-family="JetBrains Mono" font-size="9" font-weight="700" text-anchor="middle" x="240" y="16">48° SWEEP</text>
|
||||
<text fill="#bac9cc" font-family="JetBrains Mono" font-size="9" font-weight="600" text-anchor="middle" x="295" y="46">FINISH</text>
|
||||
</svg>
|
||||
<div class="absolute bottom-2 left-3 flex items-center gap-1.5 bg-surface-container-high/90 backdrop-blur px-2 py-0.5 rounded">
|
||||
<span class="material-symbols-outlined text-[12px] text-primary-container">altitude</span>
|
||||
<span class="font-label-data text-label-caption text-on-surface-variant">ELV +2,140 FT</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Live Interaction Bar & Kudos Controls -->
|
||||
<div class="px-space-md pt-space-xs pb-space-md flex flex-col space-y-space-sm">
|
||||
<div class="flex items-center justify-between gap-space-xs">
|
||||
<!-- Fist Bump Interactive Button -->
|
||||
<button class="fist-bump-btn min-h-[48px] px-3 flex-1 flex items-center justify-center gap-2 rounded-xl bg-primary-container text-on-primary-container font-headline-sm text-label-data uppercase tracking-wider font-bold shadow-[0_0_12px_rgba(0,229,255,0.3)] active:scale-95 transition-all" type="button">
|
||||
<span class="text-base select-none">👊</span>
|
||||
<span class="bump-count">42 Bumps</span>
|
||||
</button>
|
||||
<!-- Comments Action -->
|
||||
<button class="min-h-[48px] px-3 flex-1 flex items-center justify-center gap-1.5 rounded-xl bg-surface-container-high text-on-surface hover:bg-surface-container-highest font-headline-sm text-label-data uppercase tracking-wider font-semibold active:scale-95 transition-all" type="button">
|
||||
<span class="material-symbols-outlined text-[18px] text-primary">chat_bubble</span>
|
||||
<span>12</span>
|
||||
</button>
|
||||
<!-- GPX Action -->
|
||||
<button aria-label="Download GPX Track" class="min-h-[48px] min-w-[48px] flex items-center justify-center rounded-xl bg-surface-container-high text-on-surface hover:text-primary active:scale-95 transition-all" type="button">
|
||||
<span class="material-symbols-outlined text-[20px]">download</span>
|
||||
</button>
|
||||
</div>
|
||||
<!-- Telemetry Deep Dive Inspector Trigger -->
|
||||
<button class="min-h-[48px] w-full flex items-center justify-center gap-2 rounded-xl bg-surface-container-low hover:bg-surface-container-high text-primary font-headline-sm text-label-data uppercase tracking-widest font-bold active:scale-[0.98] transition-all" type="button">
|
||||
<span class="material-symbols-outlined text-[18px] text-primary-container">bolt</span>
|
||||
<span>Inspect Telemetry Graph</span>
|
||||
</button>
|
||||
</div>
|
||||
</article>
|
||||
<!-- Feed Card 2: SarahSweep Scenic Mountain Run -->
|
||||
<article class="flex flex-col bg-surface-container rounded-xl shadow-xl overflow-hidden">
|
||||
<!-- Card Header -->
|
||||
<div class="p-space-md flex items-start justify-between gap-space-sm">
|
||||
<div class="flex items-center gap-space-sm min-w-0">
|
||||
<div class="relative shrink-0">
|
||||
<img class="w-12 h-12 rounded-xl object-cover" data-alt="Tactical female rider wearing aggressive aerodynamic matte grey helmet with polarized copper orange visor under dramatic sunlit coastal canyon ridge" src="https://lh3.googleusercontent.com/aida-public/AB6AXuCfNhhekgWRRUR4-J5tGeciMSqcLVDOEFgQbQLLsJZpZ-BuQQ05SlevGT2LyJZt27RvSINJbktjk1ZDPLQ0KMDJDgXagPieFA-VNwv8ZO6bqRg1fp2QTD2KqTG3A4p6jotSKAYCnyuMZ_B8EO0TxpALQ-foc3sZhitOCHowmJYgQDA-D9O-v82t7vsqwsS7G-qY7nZrygu8ZJKRUuu9nWBloJKP9MbeUeozmrt46oY9JhegJYBNZtKa"/>
|
||||
<span class="absolute -bottom-1 -right-1 w-3.5 h-3.5 bg-secondary rounded-full shadow-[0_0_6px_#b4c5ff]"></span>
|
||||
</div>
|
||||
<div class="flex flex-col min-w-0">
|
||||
<div class="flex items-center gap-1.5 flex-wrap">
|
||||
<span class="font-headline-sm text-headline-sm text-on-surface truncate">@SarahSweep</span>
|
||||
<span class="bg-secondary-container/40 text-secondary-fixed font-label-data text-label-caption px-1.5 py-0.5 rounded uppercase font-bold tracking-wider">ROAD CAPTAIN</span>
|
||||
</div>
|
||||
<p class="font-body-md text-label-caption text-on-surface-variant truncate">Pacific Coast Riders</p>
|
||||
<span class="font-label-caption text-label-caption text-outline">2h ago • Mulholland Hwy</span>
|
||||
</div>
|
||||
</div>
|
||||
<button aria-label="Card Options" class="min-h-[48px] min-w-[48px] flex items-center justify-center text-on-surface-variant hover:text-on-surface rounded-lg active:bg-surface-container-high transition-colors" type="button">
|
||||
<span class="material-symbols-outlined text-[20px]">more_vert</span>
|
||||
</button>
|
||||
</div>
|
||||
<!-- Title & Motorbike Identity -->
|
||||
<div class="px-space-md pb-space-sm space-y-1">
|
||||
<h2 class="font-headline-md text-headline-md text-secondary-fixed tracking-tight">The Snake & Rock Store Pace Lap</h2>
|
||||
<div class="inline-flex items-center gap-1.5 bg-surface-container-low px-2 py-1 rounded-md">
|
||||
<span class="material-symbols-outlined text-[14px] text-secondary">sports_motorsports</span>
|
||||
<span class="font-label-data text-label-caption text-on-surface font-semibold tracking-wide">Yamaha MT-09 SP</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Scenic Hairpin Photo Module -->
|
||||
<div class="px-space-md py-space-xs">
|
||||
<div class="relative w-full h-48 rounded-xl overflow-hidden shadow-lg group">
|
||||
<img class="w-full h-full object-cover" data-alt="High angle panoramic viewpoint of dramatic curving asphalt coastal canyon hairpin turn with blue ocean cliffs below and aggressive sportbike leaning into turn" src="https://lh3.googleusercontent.com/aida-public/AB6AXuCI9HLi3RptEAD0X0dm6sqtLft75DezxisCbc97PR2MuxHkjg8q3SZFPf4w8szC1s9dMd09awV9bdewYOjcaNPiXkA1hraIdZZulDJ5SOflusc663JrKLltOxVMN7jLyGwjQD4CkYKT3RlUPw5mkY8gnRkmR_YYufd4TtdzsTun29lqJr75EUDTuMx6W14j8rfbiBbNND-Sd8nJ0Bv2fylV_bEPJdNeZt_mGBzf4Q9kcbfQO6916tGs"/>
|
||||
<div class="absolute inset-0 bg-gradient-to-t from-surface-container-lowest via-transparent to-transparent opacity-80"></div>
|
||||
<div class="absolute bottom-2.5 left-3 right-3 flex items-center justify-between">
|
||||
<div class="flex items-center gap-1.5 bg-surface-container-lowest/80 backdrop-blur-md px-2 py-1 rounded-md">
|
||||
<span class="material-symbols-outlined text-[14px] text-primary-container">photo_camera</span>
|
||||
<span class="font-label-caption text-label-caption text-on-surface">Rock Store Lookout</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-1 bg-surface-container-lowest/80 backdrop-blur-md px-2 py-1 rounded-md text-on-surface-variant">
|
||||
<span class="material-symbols-outlined text-[14px] text-primary">verified</span>
|
||||
<span class="font-label-data text-label-caption text-primary">GPS VERIFIED</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Telemetry Statistics Strip -->
|
||||
<div class="px-space-md py-space-sm">
|
||||
<div class="grid grid-cols-4 gap-1.5 bg-surface-container-lowest p-space-sm rounded-xl text-center">
|
||||
<div class="flex flex-col items-center">
|
||||
<span class="font-label-data text-label-caption text-outline uppercase">Dist</span>
|
||||
<span class="font-telemetry-metric-md text-headline-sm text-on-surface font-bold mt-0.5">44.2</span>
|
||||
<span class="font-label-caption text-[10px] text-on-surface-variant">MI</span>
|
||||
</div>
|
||||
<div class="flex flex-col items-center">
|
||||
<span class="font-label-data text-label-caption text-outline uppercase">Time</span>
|
||||
<span class="font-telemetry-metric-md text-headline-sm text-on-surface font-bold mt-0.5">48m</span>
|
||||
<span class="font-label-caption text-[10px] text-on-surface-variant">20S</span>
|
||||
</div>
|
||||
<div class="flex flex-col items-center">
|
||||
<span class="font-label-data text-label-caption text-outline uppercase">Lean</span>
|
||||
<span class="font-telemetry-metric-md text-headline-sm text-primary font-bold mt-0.5">48°</span>
|
||||
<span class="font-label-caption text-[10px] text-primary-fixed">PEAK</span>
|
||||
</div>
|
||||
<div class="flex flex-col items-center">
|
||||
<span class="font-label-data text-label-caption text-outline uppercase">Safety</span>
|
||||
<span class="font-telemetry-metric-md text-headline-sm text-secondary font-bold mt-0.5">0</span>
|
||||
<span class="font-label-caption text-[10px] text-secondary">HAZARDS</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Action Buttons -->
|
||||
<div class="px-space-md pb-space-md flex items-center justify-between gap-space-xs">
|
||||
<!-- Fist Bumps -->
|
||||
<button class="fist-bump-btn min-h-[48px] px-3 flex-1 flex items-center justify-center gap-1.5 rounded-xl bg-surface-container-high text-on-surface hover:text-primary active:scale-95 transition-all" type="button">
|
||||
<span class="text-base select-none">👊</span>
|
||||
<span class="bump-count font-label-data text-label-data font-bold">28 Bumps</span>
|
||||
</button>
|
||||
<!-- Comments -->
|
||||
<button class="min-h-[48px] px-3 flex-1 flex items-center justify-center gap-1.5 rounded-xl bg-surface-container-high text-on-surface hover:text-primary font-headline-sm text-label-data uppercase tracking-wider font-semibold active:scale-95 transition-all" type="button">
|
||||
<span class="material-symbols-outlined text-[18px]">chat_bubble</span>
|
||||
<span>6</span>
|
||||
</button>
|
||||
<!-- Join Next Run CTA -->
|
||||
<button class="min-h-[48px] px-4 flex items-center justify-center gap-1.5 rounded-xl bg-secondary-container text-on-secondary font-headline-sm text-label-data uppercase tracking-wider font-bold shadow-md hover:bg-secondary active:scale-95 transition-all" type="button">
|
||||
<span class="material-symbols-outlined text-[18px]">group_add</span>
|
||||
<span>Join Run</span>
|
||||
</button>
|
||||
</div>
|
||||
</article>
|
||||
<!-- Sticky Glove-Friendly Share Session Action Bar -->
|
||||
<div class="sticky bottom-2 w-full pt-space-xs pb-1 z-20">
|
||||
<button class="w-full min-h-[52px] px-space-md bg-primary-container text-on-primary-container font-headline-sm text-headline-sm uppercase tracking-wider font-bold rounded-xl shadow-[0_0_20px_rgba(0,229,255,0.45)] flex items-center justify-center gap-space-sm active:scale-[0.98] transition-all" type="button">
|
||||
<span class="material-symbols-outlined text-[24px]">add_circle</span>
|
||||
<span>Share Recent Session</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
// Glove-friendly micro-interaction for fist bumping
|
||||
document.querySelectorAll('.fist-bump-btn').forEach(button => {
|
||||
let bumped = false;
|
||||
button.addEventListener('click', () => {
|
||||
const countSpan = button.querySelector('.bump-count');
|
||||
if (!countSpan) return;
|
||||
|
||||
const currentVal = parseInt(countSpan.textContent) || 0;
|
||||
if (!bumped) {
|
||||
countSpan.textContent = (currentVal + 1) + ' Bumps';
|
||||
button.classList.add('scale-105');
|
||||
setTimeout(() => button.classList.remove('scale-105'), 150);
|
||||
bumped = true;
|
||||
} else {
|
||||
countSpan.textContent = (currentVal - 1) + ' Bumps';
|
||||
bumped = false;
|
||||
}
|
||||
});
|
||||
});
|
||||
</script></main><nav class="fixed bottom-0 w-full z-50 pb-safe bg-surface-container-lowest/90 backdrop-blur-xl shadow-[0_-4px_24px_rgba(0,0,0,0.6)]" data-active-classes="text-primary-container font-headline-sm [filter:drop-shadow(0_0_8px_rgba(0,229,255,0.5))]"><div class="grid grid-cols-6 items-center h-20 px-space-xs"><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="cockpit-dash" href="#"><span class="material-symbols-outlined text-[24px]">speed</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Dash</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="tactical-radar-map" href="#"><span class="material-symbols-outlined text-[24px]">radar</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Map</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="telemetry-log" href="#"><span class="material-symbols-outlined text-[24px]">monitoring</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Activity</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="bike-garage" href="#"><span class="material-symbols-outlined text-[24px]">two_wheeler</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Garage</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="pack-comms" href="#"><span class="material-symbols-outlined text-[24px]">groups_3</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Social</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="hud-settings" href="#"><span class="material-symbols-outlined text-[24px]">tune</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Settings</span></a></div></nav></body></html>
|
||||
|
|
@ -0,0 +1,318 @@
|
|||
<!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, viewport-fit=cover" name="viewport"/><meta content="mobile_tab" name="shell-type"/><title>MotorSignal Cockpit HUD</title><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&family=JetBrains+Mono:wght@500;600;700&family=Space+Grotesk:wght@600;700&display=swap" rel="stylesheet"/><link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/><style>@layer base{html,body{width:100%;margin:0;padding:0;background-color:#101419;color:#e0e2ea;}body{overscroll-behavior:none;}.pb-safe{padding-bottom:env(safe-area-inset-bottom,0px);}.pt-safe{padding-top:env(safe-area-inset-top,0px);}main>:first-child{margin-top:0!important;}main>:last-child{margin-bottom:0!important;}}::-webkit-scrollbar{display:none;}</style><script src="https://cdn.tailwindcss.com"></script><script id="tailwind-config">tailwind.config = { darkMode: "class", theme: { extend: { "colors": { "on-primary": "#00363d", "tertiary-fixed-dim": "#d0bcff", "tertiary-container": "#d9c8ff", "on-primary-container": "#00626e", "surface-variant": "#32353b", "on-primary-fixed-variant": "#004f58", "surface-container-high": "#272a30", "outline-variant": "#3b494c", "surface-container": "#1d2025", "on-surface": "#e0e2ea", "background": "#101419", "primary-container": "#00e5ff", "inverse-surface": "#e0e2ea", "outline": "#849396", "on-secondary": "#002a78", "secondary-fixed-dim": "#b4c5ff", "on-tertiary": "#3c0091", "inverse-primary": "#006875", "surface-bright": "#36393f", "surface-container-low": "#181c21", "surface-container-highest": "#32353b", "inverse-on-surface": "#2d3036", "on-secondary-fixed": "#00174b", "primary": "#c3f5ff", "error-container": "#93000a", "surface-tint": "#00daf3", "on-tertiary-fixed-variant": "#5516be", "on-error-container": "#ffdad6", "primary-fixed-dim": "#00daf3", "tertiary-fixed": "#e9ddff", "on-primary-fixed": "#001f24", "on-error": "#690005", "surface-container-lowest": "#0b0e13", "secondary-container": "#0053db", "tertiary": "#f2e9ff", "surface-dim": "#101419", "on-surface-variant": "#bac9cc", "on-tertiary-container": "#6834d1", "primary-fixed": "#9cf0ff", "secondary-fixed": "#dbe1ff", "error": "#ffb4ab", "on-secondary-container": "#cdd7ff", "on-secondary-fixed-variant": "#003ea8", "surface": "#101419", "on-background": "#e0e2ea", "secondary": "#b4c5ff", "on-tertiary-fixed": "#23005c" }, "borderRadius": { "DEFAULT": "0.25rem", "lg": "0.5rem", "xl": "0.75rem", "full": "9999px" }, "spacing": { "margin-lg": "2rem", "space-xs": "0.25rem", "gutter-lg": "1.5rem", "space-xl": "2rem", "margin": "1rem", "space-sm": "0.5rem", "space-md": "1rem", "space-lg": "1.5rem", "gutter": "1rem" }, "fontFamily": { "headline-lg": ["Space Grotesk"], "body-lg": ["Inter"], "telemetry-metric-lg-mobile": ["JetBrains Mono"], "label-data": ["JetBrains Mono"], "display-hero": ["Space Grotesk"], "headline-sm": ["Space Grotesk"], "headline-md": ["Space Grotesk"], "label-caption": ["Inter"], "telemetry-metric-lg": ["JetBrains Mono"], "display-hero-mobile": ["Space Grotesk"], "telemetry-metric-md": ["JetBrains Mono"], "body-md": ["Inter"] }, "fontSize": { "headline-lg": ["32px", { "lineHeight": "40px", "letterSpacing": "-0.02em", "fontWeight": "700" }], "body-lg": ["16px", { "lineHeight": "24px", "fontWeight": "500" }], "telemetry-metric-lg-mobile": ["36px", { "lineHeight": "36px", "letterSpacing": "-0.03em", "fontWeight": "700" }], "label-data": ["12px", { "lineHeight": "16px", "letterSpacing": "0.08em", "fontWeight": "600" }], "display-hero": ["56px", { "lineHeight": "60px", "letterSpacing": "-0.03em", "fontWeight": "700" }], "headline-sm": ["20px", { "lineHeight": "28px", "fontWeight": "600" }], "headline-md": ["24px", { "lineHeight": "32px", "letterSpacing": "-0.01em", "fontWeight": "600" }], "label-caption": ["11px", { "lineHeight": "14px", "letterSpacing": "0.05em", "fontWeight": "600" }], "telemetry-metric-lg": ["48px", { "lineHeight": "48px", "letterSpacing": "-0.04em", "fontWeight": "700" }], "display-hero-mobile": ["40px", { "lineHeight": "44px", "letterSpacing": "-0.02em", "fontWeight": "700" }], "telemetry-metric-md": ["28px", { "lineHeight": "32px", "letterSpacing": "-0.02em", "fontWeight": "600" }], "body-md": ["14px", { "lineHeight": "20px", "fontWeight": "400" }] } } } }</script><style>
|
||||
body {
|
||||
min-height: max(884px, 100dvh);
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
body {
|
||||
min-height: max(884px, 100dvh);
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
body {
|
||||
min-height: max(884px, 100dvh);
|
||||
}
|
||||
</style>
|
||||
</head><body class="bg-surface font-body-md text-on-surface antialiased flex flex-col min-h-screen selection:bg-primary-container selection:text-on-primary-container"><header class="fixed top-0 w-full z-50 pt-safe bg-surface-container-lowest/85 backdrop-blur-xl shadow-[0_4px_20px_rgba(0,0,0,0.5)]"><div class="h-16 px-space-md flex items-center justify-between gap-space-sm"><div class="flex items-center gap-space-sm"><img alt="MotorSignal Brand Logo" class="h-8 w-auto object-contain drop-shadow-[0_0_8px_rgba(0,229,255,0.4)]" src="https://lh3.googleusercontent.com/aida/AEtjO1Vf56Tkh6bJ86BCfT5GHz_yPumvEXYLWojlNHAFG-cN4VvH_nLvEbWQ4x7uhJPRaAyO8ozAAbLI_huEN134QOIYp8BdHuqoZCsMk9_ILaUxZqilVgamefO6d2sG1R8laIWSUswanVsK9lfvIgppQm_XxBQipzkDgPwIoXk7yh10QTlmZqDICryF-1MoWFfFjM2zZswr6ynuAgZAviROYnFBF2D4hxm6YREQxkZQJaBcG9oAg_dYVgTHxwg"/><div class="flex flex-col"><span class="font-headline-sm text-headline-sm uppercase tracking-wider text-primary-fixed">MotorSignal</span><span class="font-label-caption text-label-caption text-on-surface-variant uppercase tracking-widest leading-none">Telemetry Log</span></div></div><div class="flex items-center gap-space-sm"><div class="hidden sm:flex items-center gap-space-xs bg-surface-container-low px-space-sm py-1 rounded-full"><span class="w-2 h-2 rounded-full bg-primary-container animate-pulse shadow-[0_0_6px_#00e5ff]"></span><span class="font-label-data text-label-data text-primary-fixed">GPS 3D FIX</span></div><div class="flex items-center gap-1.5 bg-surface-container px-2 py-1 rounded-full"><span class="material-symbols-outlined text-[15px] text-primary-container">bolt</span><span class="font-label-data text-label-data text-on-surface">98%</span><span class="w-1 h-1 rounded-full bg-outline-variant"></span><span class="material-symbols-outlined text-[15px] text-primary-container">cell_tower</span></div><button aria-label="Rider Profile" class="min-w-[44px] min-h-[44px] flex items-center justify-center p-1 rounded-full focus:outline-none focus:ring-2 focus:ring-primary-container" type="button"><img alt="Profile" class="w-8 h-8 rounded-full object-cover ring-2 ring-primary-container/40" src="https://lh3.googleusercontent.com/aida-public/AB6AXuBb6sR8Ta8-L1_TN1LuCBfSxtZxX9hKOFjd-RjllihDsnp6AG1GlMhL9bVlb-ibhIRT3HMw_caXK7BmwmvWKNBcuizyqswUQZNztavckRTN1Xa6qGML_0kv8qvV_hrXWWK1EjSjVFzhRyDzf6VdGnZvUpGsFFmSBcaGVrXmEWFYnIa-qHyeWxZlT_SJmPuQJPQKEWEo6vC6kdDzXNnhoB4tpRHjIjCstvTdooPc0KVN_x3BqqmqadNI"/></button></div></div></header><main class="flex-1 flex flex-col relative w-full pt-16 pb-20 bg-surface"><div class="flex flex-col w-full px-space-md py-space-sm gap-space-lg selection:bg-primary-container selection:text-on-primary-container">
|
||||
<!-- MASTHEAD / SPOTLIGHT BANNER -->
|
||||
<section class="relative w-full rounded-xl overflow-hidden bg-surface-container-low shadow-xl">
|
||||
<!-- Atmospheric Underlay Image -->
|
||||
<div class="relative w-full h-36 bg-surface-container-highest overflow-hidden">
|
||||
<div class="w-full h-full bg-cover bg-center" data-alt="Cinematic wide angle shot of high-powered sport motorcycles carving across the iconic Bixby Bridge along the Pacific Coast Highway at twilight. Moody deep navy and electric cyan atmospheric lighting, with wet asphalt reflecting sharp LED headlight beams. High contrast tactical aerospace ambiance, sleek carbon-fiber textures, and low coastal fog rolling off dark cliffs." style="background-image: url('https://lh3.googleusercontent.com/aida-public/AB6AXuCRlqklpedAn90thIb6kEZ9xClNcdBu6dkx_3KX3F9tNIs9J71BiofrD_eg6AmJs_0LNov8RhCcPmbW7sQ3z_XrULYq6BcIGqTHgvOn2w0Gffd8l1Zs3uPZNtt6W-O_GSQIFKfhKMLG_wwhdiY2DLCH43Z2AQwv643U4xiMN1JTcRyjrpP6NbxmKAO1CR-tEgm8MYvsIMo4djFUYNU4926_w4z-eFCh2rsr_bV98fhBxCBStzjJFWvw')">
|
||||
</div>
|
||||
<div class="absolute inset-0 bg-gradient-to-t from-surface-container-low via-surface-container-low/60 to-transparent"></div>
|
||||
<!-- Privacy Badge (Top Right) -->
|
||||
<div class="absolute top-3 right-3 flex items-center gap-1.5 bg-surface-container-lowest/90 px-2.5 py-1 rounded-full shadow-md">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-secondary-container"></span>
|
||||
<span class="font-label-caption text-label-caption uppercase tracking-wider text-secondary">APPLICATION ONLY / SCREENED</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Club Patch & Identification Grid -->
|
||||
<div class="px-space-md pb-space-md pt-0 -mt-10 relative flex flex-col gap-space-md">
|
||||
<div class="flex items-end justify-between gap-space-sm">
|
||||
<!-- Tactical Emblem / Patch -->
|
||||
<div class="relative w-20 h-20 rounded-full bg-surface-container-lowest p-1 shadow-2xl flex-shrink-0">
|
||||
<div class="w-full h-full rounded-full bg-surface-container flex items-center justify-center relative overflow-hidden">
|
||||
<!-- Neon Apex Glow Accent -->
|
||||
<div class="absolute inset-0 bg-gradient-to-tr from-tertiary-container/30 via-primary-container/20 to-transparent"></div>
|
||||
<span class="material-symbols-outlined text-[36px] text-primary-container drop-shadow-[0_0_10px_rgba(0,229,255,0.7)]">sports_motorsports</span>
|
||||
</div>
|
||||
<div class="absolute -bottom-1 -right-1 bg-surface-container-high text-primary-container rounded-full p-1 shadow-sm flex items-center justify-center">
|
||||
<span class="material-symbols-outlined text-[16px]">verified</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Quick Interaction Actions -->
|
||||
<div class="flex items-center gap-space-xs mb-1">
|
||||
<button class="min-h-[48px] px-space-md bg-surface-container hover:bg-surface-bright active:bg-surface-variant text-on-surface rounded-lg font-label-data text-label-data uppercase tracking-wider transition-all flex items-center gap-1.5 shadow-sm" type="button">
|
||||
<span class="material-symbols-outlined text-[18px] text-tertiary-fixed-dim">share</span>
|
||||
<span>Share</span>
|
||||
</button>
|
||||
<button class="min-h-[48px] px-space-md bg-secondary-container hover:bg-secondary active:opacity-90 text-on-secondary-container rounded-lg font-label-data text-label-data uppercase tracking-wider transition-all flex items-center gap-1.5 shadow-md" type="button">
|
||||
<span class="material-symbols-outlined text-[18px]">how_to_reg</span>
|
||||
<span>Apply</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Club Title Info -->
|
||||
<div class="flex flex-col gap-0.5">
|
||||
<div class="flex items-center gap-2">
|
||||
<h1 class="font-headline-md text-headline-md uppercase tracking-tight text-on-surface">Pacific Coast Riders MC</h1>
|
||||
</div>
|
||||
<p class="font-label-caption text-label-caption uppercase tracking-widest text-on-surface-variant flex items-center gap-1.5">
|
||||
<span class="material-symbols-outlined text-[14px] text-primary-container">location_on</span>
|
||||
Chapter: Bay Area / NorCal Sector
|
||||
</p>
|
||||
</div>
|
||||
<!-- Telemetry Stats Strip -->
|
||||
<div class="grid grid-cols-3 gap-space-xs bg-surface-container-lowest p-space-sm rounded-lg">
|
||||
<div class="flex flex-col items-center justify-center text-center p-1">
|
||||
<span class="font-label-caption text-label-caption uppercase text-on-surface-variant tracking-wider">Pack</span>
|
||||
<span class="font-telemetry-metric-md text-telemetry-metric-md text-on-surface">58</span>
|
||||
<span class="font-label-caption text-[10px] text-on-surface-variant">Members</span>
|
||||
</div>
|
||||
<div class="flex flex-col items-center justify-center text-center p-1 bg-surface-container-low rounded">
|
||||
<span class="font-label-caption text-label-caption uppercase text-primary-container tracking-wider">Runs</span>
|
||||
<span class="font-telemetry-metric-md text-telemetry-metric-md text-primary-fixed">14</span>
|
||||
<span class="font-label-caption text-[10px] text-on-surface-variant">Active</span>
|
||||
</div>
|
||||
<div class="flex flex-col items-center justify-center text-center p-1">
|
||||
<span class="font-label-caption text-label-caption uppercase text-on-surface-variant tracking-wider">Score</span>
|
||||
<span class="font-telemetry-metric-md text-telemetry-metric-md text-secondary-fixed">99.4%</span>
|
||||
<span class="font-label-caption text-[10px] text-on-surface-variant">Cohesion</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- CLUB NAVIGATION TABS (48px Hit Targets) -->
|
||||
<section class="w-full flex items-center gap-space-xs bg-surface-container-lowest p-1.5 rounded-xl shadow-inner">
|
||||
<button class="flex-1 min-h-[48px] rounded-lg bg-surface-container text-primary-container font-label-data text-label-data uppercase tracking-wider flex items-center justify-center gap-1.5 shadow-sm" type="button">
|
||||
<span class="material-symbols-outlined text-[18px]">forum</span>
|
||||
<span>Club Wall</span>
|
||||
</button>
|
||||
<button class="flex-1 min-h-[48px] rounded-lg hover:bg-surface-container-low text-on-surface-variant font-label-data text-label-data uppercase tracking-wider flex items-center justify-center gap-1.5 transition-colors" type="button">
|
||||
<span class="material-symbols-outlined text-[18px]">badge</span>
|
||||
<span>Officers</span>
|
||||
</button>
|
||||
<button class="flex-1 min-h-[48px] rounded-lg hover:bg-surface-container-low text-on-surface-variant font-label-data text-label-data uppercase tracking-wider flex items-center justify-center gap-1.5 transition-colors" type="button">
|
||||
<span class="material-symbols-outlined text-[18px]">calendar_month</span>
|
||||
<span>Rides</span>
|
||||
</button>
|
||||
</section>
|
||||
<!-- 1. PINNED CLUB RUN CARD -->
|
||||
<section class="flex flex-col gap-space-xs">
|
||||
<div class="flex items-center justify-between px-1">
|
||||
<div class="flex items-center gap-1.5">
|
||||
<span class="material-symbols-outlined text-[18px] text-tertiary-container animate-pulse">push_pin</span>
|
||||
<span class="font-label-data text-label-data uppercase tracking-widest text-on-surface-variant">Pinned Announcement</span>
|
||||
</div>
|
||||
<span class="font-label-caption text-label-caption uppercase text-primary-container tracking-wider">KSU T-Minus 42h</span>
|
||||
</div>
|
||||
<div class="bg-surface-container-high rounded-xl p-space-md flex flex-col gap-space-md shadow-lg relative overflow-hidden">
|
||||
<!-- Accent Top Indicator Bar -->
|
||||
<div class="absolute top-0 left-0 right-0 h-1 bg-gradient-to-r from-tertiary-container via-primary-container to-secondary-container"></div>
|
||||
<!-- Header & Title -->
|
||||
<div class="flex flex-col gap-1">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="px-2 py-0.5 rounded bg-error-container text-on-error-container font-label-data text-[10px] tracking-wider uppercase">Official Run</span>
|
||||
<span class="font-label-data text-label-data text-on-surface-variant">Sat, 8:00 AM PST</span>
|
||||
</div>
|
||||
<h2 class="font-headline-sm text-headline-sm uppercase tracking-tight text-on-surface">Skyline to Santa Cruz Coastal Arc</h2>
|
||||
<p class="font-body-md text-body-md text-on-surface-variant">
|
||||
Pace 3 (Brisk Technical). Mandatory fuel stop at Alice's Restaurant before descending Highway 9 into Santa Cruz Pier.
|
||||
</p>
|
||||
</div>
|
||||
<!-- Run Roster Assignments -->
|
||||
<div class="grid grid-cols-2 gap-space-xs">
|
||||
<div class="bg-surface-container p-space-sm rounded-lg flex items-center gap-2.5">
|
||||
<div class="w-8 h-8 rounded-full bg-primary-container/20 flex items-center justify-center text-primary-container">
|
||||
<span class="material-symbols-outlined text-[18px]">navigation</span>
|
||||
</div>
|
||||
<div class="flex flex-col min-w-0">
|
||||
<span class="font-label-caption text-label-caption uppercase text-on-surface-variant">Lead Captain</span>
|
||||
<span class="font-label-data text-label-data text-primary truncate">@Dave_Lead</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-surface-container p-space-sm rounded-lg flex items-center gap-2.5">
|
||||
<div class="w-8 h-8 rounded-full bg-tertiary-container/20 flex items-center justify-center text-tertiary-fixed-dim">
|
||||
<span class="material-symbols-outlined text-[18px]">shield</span>
|
||||
</div>
|
||||
<div class="flex flex-col min-w-0">
|
||||
<span class="font-label-caption text-label-caption uppercase text-on-surface-variant">Tail Sweeper</span>
|
||||
<span class="font-label-data text-label-data text-tertiary-fixed truncate">@Sarah_Sweep</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Radio Mesh Sync Metric -->
|
||||
<div class="flex items-center justify-between bg-surface-container-lowest px-space-md py-2.5 rounded-lg">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-[18px] text-primary-container">cell_tower</span>
|
||||
<span class="font-label-data text-label-data text-on-surface tracking-wider">CH-04 MESH</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-1.5">
|
||||
<span class="w-2 h-2 rounded-full bg-primary-container shadow-[0_0_8px_#00e5ff]"></span>
|
||||
<span class="font-label-caption text-label-caption uppercase text-on-surface-variant">MotorSignal Sync Ready</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- RSVP Footer Action -->
|
||||
<div class="flex items-center justify-between gap-space-sm pt-1">
|
||||
<div class="flex items-center gap-2">
|
||||
<div class="flex -space-x-2">
|
||||
<div class="w-8 h-8 rounded-full bg-surface-variant flex items-center justify-center text-label-caption font-bold text-on-surface">DL</div>
|
||||
<div class="w-8 h-8 rounded-full bg-surface-variant flex items-center justify-center text-label-caption font-bold text-on-surface">SS</div>
|
||||
<div class="w-8 h-8 rounded-full bg-secondary-container flex items-center justify-center text-label-caption font-bold text-on-secondary-container">+20</div>
|
||||
</div>
|
||||
<span class="font-label-data text-label-data text-on-surface tracking-wide">22 Confirmed</span>
|
||||
</div>
|
||||
<button class="min-h-[48px] px-space-lg bg-primary-container hover:bg-primary-fixed-dim active:bg-primary text-on-primary-container rounded-lg font-label-data text-label-data uppercase tracking-wider font-bold shadow-[0_0_14px_rgba(0,229,255,0.3)] transition-all flex items-center gap-2" type="button">
|
||||
<span class="material-symbols-outlined text-[20px]">add_circle</span>
|
||||
<span>RSVP To Run</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- 2. OFFICER HIERARCHY & ACTIVE ROSTER MINI-CARDS -->
|
||||
<section class="flex flex-col gap-space-sm">
|
||||
<div class="flex items-center justify-between px-1">
|
||||
<div class="flex items-center gap-1.5">
|
||||
<span class="material-symbols-outlined text-[18px] text-primary-container">shield_person</span>
|
||||
<span class="font-label-data text-label-data uppercase tracking-widest text-on-surface-variant">Command Roster</span>
|
||||
</div>
|
||||
<a class="font-label-caption text-label-caption uppercase text-primary-fixed hover:underline" href="#">Full Pack (58) →</a>
|
||||
</div>
|
||||
<!-- Officer 1: President -->
|
||||
<div class="bg-surface-container-low rounded-xl p-space-md flex items-center justify-between gap-space-md shadow-md">
|
||||
<div class="flex items-center gap-space-md min-w-0">
|
||||
<div class="relative w-12 h-12 flex-shrink-0">
|
||||
<div class="w-12 h-12 rounded-full overflow-hidden bg-surface-container-high">
|
||||
<img class="w-full h-full object-cover" data-alt="Close up rider portrait in matte black sport helmet with mirrored gold iridium visor, sitting on an S1000RR in a dark tactical paddock pit lane illuminated by soft tungsten spotlights." src="https://lh3.googleusercontent.com/aida-public/AB6AXuAXOaw6etq5ySAnXo-gLULFo0KqvkQDY_3RG_Y4QlpxiOJutvZDQYbeA9CcxsbDYpSzFGT3Nt-IFB1C9jB8uQ0tQfRMJhkXC6Pv6-ggyqPRkD_gPqQ-JKqZDQDaksr0V9iJfLaDX-wn0w5UJ1hWMf1p6YeNjDVLMafV6hcwmSar9CUBTQpbz97yJsrM5ngP4bbj3NA1MOgvcj-pT3ANEnLPMwo3n2NM8lEvOP8xYF1QE9mHMfUnpWwu"/>
|
||||
</div>
|
||||
<div class="absolute -bottom-1 -right-1 bg-surface-container-lowest p-0.5 rounded-full">
|
||||
<span class="material-symbols-outlined text-[16px] text-tertiary-container">military_tech</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col min-w-0">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="font-headline-sm text-[16px] text-on-surface font-bold truncate">@KevBlade</span>
|
||||
<span class="bg-surface-container-highest px-2 py-0.5 rounded font-label-caption text-[10px] uppercase tracking-wider text-tertiary-fixed font-bold">PRESIDENT</span>
|
||||
</div>
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant truncate">2024 BMW S1000RR M-Package</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col items-end flex-shrink-0">
|
||||
<span class="font-label-caption text-[10px] uppercase text-on-surface-variant">Telemetry</span>
|
||||
<span class="font-telemetry-metric-md text-[18px] text-primary-container leading-none">52° LEAN</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Officer 2: Road Captain -->
|
||||
<div class="bg-surface-container-low rounded-xl p-space-md flex items-center justify-between gap-space-md shadow-md">
|
||||
<div class="flex items-center gap-space-md min-w-0">
|
||||
<div class="relative w-12 h-12 flex-shrink-0">
|
||||
<div class="w-12 h-12 rounded-full overflow-hidden bg-surface-container-high">
|
||||
<img class="w-full h-full object-cover" data-alt="Portrait of an experienced road captain in racing leather suit standing next to a Ducati Panigale V4 inside a modern illuminated garage bay with telemetry screens." src="https://lh3.googleusercontent.com/aida-public/AB6AXuB46ZcqXw8QxFV_xW6yHBp-Sd4Ax9V7eZ35Q9bvD5P6xHIsKH6_0-zcCgLRYYxSw2AJWmG4sQk7oHXNlX3IAyguP3QsrfZzd2UukVwLUJxaKkpMP3UaWpd_P2VAkOLJCYuc6jkCmV7MBLlCnikkYRop2mj2NTBMBnqMf0dfRQtGrdD59UnFlG_tKTUC5j6QghvJ395q0FZfGDHtWrr8oVCj-MbvIqtaal-pOu-R8FaPuB03kBmoQhfh"/>
|
||||
</div>
|
||||
<div class="absolute -bottom-1 -right-1 bg-surface-container-lowest p-0.5 rounded-full">
|
||||
<span class="material-symbols-outlined text-[16px] text-primary-container">navigation</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col min-w-0">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="font-headline-sm text-[16px] text-on-surface font-bold truncate">@Dave_Lead</span>
|
||||
<span class="bg-surface-container-highest px-2 py-0.5 rounded font-label-caption text-[10px] uppercase tracking-wider text-primary-fixed font-bold">ROAD CAPTAIN</span>
|
||||
</div>
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant truncate">2023 Ducati Panigale V4</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col items-end flex-shrink-0">
|
||||
<span class="font-label-caption text-[10px] uppercase text-on-surface-variant">Lead Pace</span>
|
||||
<span class="font-telemetry-metric-md text-[18px] text-on-surface leading-none">BRISK</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Officer 3: Tail Gunner / Sweeper -->
|
||||
<div class="bg-surface-container-low rounded-xl p-space-md flex items-center justify-between gap-space-md shadow-md">
|
||||
<div class="flex items-center gap-space-md min-w-0">
|
||||
<div class="relative w-12 h-12 flex-shrink-0">
|
||||
<div class="w-12 h-12 rounded-full overflow-hidden bg-surface-container-high">
|
||||
<img class="w-full h-full object-cover" data-alt="Female motorcycle track marshall and tail sweep rider in high-visibility armored riding jacket and aerodynamic carbon fiber helmet, checking tactical GPS smartphone mount." src="https://lh3.googleusercontent.com/aida-public/AB6AXuB--JGupu5bgqLLQ6-OxQIeGdbaCA5lcOnObOgU4_0xebOUZnMPAKr3YzycDLK1K7OLIcKvv3keqHaULSVrZ2XgolSx8F4uX1-yvYGoYck5t1BiyEXz1zxu9cfnPGP9TVNekfTTRgCZCv6KztMhb9XumhK46oh6ix8Sw2MnD9Sk0PhBndhp4SgkN3dt1RQZCbNzIlpmAN2Wt_2l6Pc_zwvfbQe9xLdU4iOdlhOymsKbtko02qz3FrSH"/>
|
||||
</div>
|
||||
<div class="absolute -bottom-1 -right-1 bg-surface-container-lowest p-0.5 rounded-full">
|
||||
<span class="material-symbols-outlined text-[16px] text-secondary">security</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col min-w-0">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="font-headline-sm text-[16px] text-on-surface font-bold truncate">@Sarah_Sweep</span>
|
||||
<span class="bg-surface-container-highest px-2 py-0.5 rounded font-label-caption text-[10px] uppercase tracking-wider text-secondary font-bold">TAIL GUNNER</span>
|
||||
</div>
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant truncate">KTM 890 Duke R Track Spec</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col items-end flex-shrink-0">
|
||||
<span class="font-label-caption text-[10px] uppercase text-on-surface-variant">Mesh Status</span>
|
||||
<div class="flex items-center gap-1 mt-0.5">
|
||||
<span class="w-2 h-2 rounded-full bg-primary-container"></span>
|
||||
<span class="font-label-data text-label-data text-primary-fixed">SYNC</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- 3. DISCOVERY FOOTER & RECOMMENDED CLUBS -->
|
||||
<section class="flex flex-col gap-space-sm pt-space-xs mb-space-sm">
|
||||
<div class="flex items-center justify-between px-1">
|
||||
<div class="flex items-center gap-1.5">
|
||||
<span class="material-symbols-outlined text-[18px] text-primary-container">explore</span>
|
||||
<span class="font-label-data text-label-data uppercase tracking-widest text-on-surface-variant">Recommended Local Chapters</span>
|
||||
</div>
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant">NorCal Basin</span>
|
||||
</div>
|
||||
<!-- Recommended Card 1 -->
|
||||
<div class="bg-surface-container-high rounded-xl p-space-md flex items-center justify-between gap-space-md">
|
||||
<div class="flex items-center gap-space-sm min-w-0">
|
||||
<div class="w-10 h-10 rounded-lg bg-surface-container-lowest flex items-center justify-center flex-shrink-0 text-primary-container">
|
||||
<span class="material-symbols-outlined text-[24px]">sports_motorsports</span>
|
||||
</div>
|
||||
<div class="flex flex-col min-w-0">
|
||||
<h3 class="font-headline-sm text-[15px] text-on-surface font-bold truncate">Desmo Owners Club NorCal</h3>
|
||||
<p class="font-label-caption text-label-caption text-on-surface-variant flex items-center gap-1">
|
||||
<span>142 members</span>
|
||||
<span>•</span>
|
||||
<span class="text-primary-fixed">Sportbike & Trackday</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<button class="min-h-[48px] min-w-[48px] px-3 bg-surface-container hover:bg-surface-bright active:bg-surface-variant text-on-surface rounded-lg font-label-data text-label-data uppercase tracking-wider flex items-center justify-center flex-shrink-0" type="button">
|
||||
View
|
||||
</button>
|
||||
</div>
|
||||
<!-- Recommended Card 2 -->
|
||||
<div class="bg-surface-container-high rounded-xl p-space-md flex items-center justify-between gap-space-md">
|
||||
<div class="flex items-center gap-space-sm min-w-0">
|
||||
<div class="w-10 h-10 rounded-lg bg-surface-container-lowest flex items-center justify-center flex-shrink-0 text-tertiary-container">
|
||||
<span class="material-symbols-outlined text-[24px]">terrain</span>
|
||||
</div>
|
||||
<div class="flex flex-col min-w-0">
|
||||
<h3 class="font-headline-sm text-[15px] text-on-surface font-bold truncate">Silicon Valley ADV & Dual Sport</h3>
|
||||
<p class="font-label-caption text-label-caption text-on-surface-variant flex items-center gap-1">
|
||||
<span>84 members</span>
|
||||
<span>•</span>
|
||||
<span class="text-tertiary-fixed-dim">Mixed Terrain Enduro</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<button class="min-h-[48px] min-w-[48px] px-3 bg-surface-container hover:bg-surface-bright active:bg-surface-variant text-on-surface rounded-lg font-label-data text-label-data uppercase tracking-wider flex items-center justify-center flex-shrink-0" type="button">
|
||||
View
|
||||
</button>
|
||||
</div>
|
||||
<!-- Glove-Friendly Primary Register Action -->
|
||||
<div class="pt-space-xs">
|
||||
<button class="w-full min-h-[52px] bg-surface-container-low hover:bg-surface-container active:bg-surface-container-highest text-primary-container rounded-xl font-label-data text-label-data uppercase tracking-wider font-bold shadow-lg flex items-center justify-center gap-2 transition-all" type="button">
|
||||
<span class="material-symbols-outlined text-[22px]">add_moderator</span>
|
||||
<span>+ Register New Motorcycle Club</span>
|
||||
</button>
|
||||
</div>
|
||||
</section>
|
||||
</div></main><nav class="fixed bottom-0 w-full z-50 pb-safe bg-surface-container-lowest/90 backdrop-blur-xl shadow-[0_-4px_24px_rgba(0,0,0,0.6)]" data-active-classes="text-primary-container font-headline-sm [filter:drop-shadow(0_0_8px_rgba(0,229,255,0.5))]"><div class="grid grid-cols-6 items-center h-20 px-space-xs"><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="cockpit-dash" href="#"><span class="material-symbols-outlined text-[24px]">speed</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Dash</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="tactical-radar-map" href="#"><span class="material-symbols-outlined text-[24px]">radar</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Map</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="telemetry-log" href="#"><span class="material-symbols-outlined text-[24px]">monitoring</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Activity</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="bike-garage" href="#"><span class="material-symbols-outlined text-[24px]">two_wheeler</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Garage</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="pack-comms" href="#"><span class="material-symbols-outlined text-[24px]">groups_3</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Social</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="hud-settings" href="#"><span class="material-symbols-outlined text-[24px]">tune</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Settings</span></a></div></nav></body></html>
|
||||
|
|
@ -0,0 +1,406 @@
|
|||
<!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, viewport-fit=cover" name="viewport"/><meta content="mobile_tab" name="shell-type"/><title>MotorSignal Cockpit HUD</title><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&family=JetBrains+Mono:wght@500;600;700&family=Space+Grotesk:wght@600;700&display=swap" rel="stylesheet"/><link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/><style>@layer base{html,body{width:100%;margin:0;padding:0;background-color:#101419;color:#e0e2ea;}body{overscroll-behavior:none;}.pb-safe{padding-bottom:env(safe-area-inset-bottom,0px);}.pt-safe{padding-top:env(safe-area-inset-top,0px);}main>:first-child{margin-top:0!important;}main>:last-child{margin-bottom:0!important;}}::-webkit-scrollbar{display:none;}</style><script src="https://cdn.tailwindcss.com"></script><script id="tailwind-config">tailwind.config = { darkMode: "class", theme: { extend: { "colors": { "on-primary": "#00363d", "tertiary-fixed-dim": "#d0bcff", "tertiary-container": "#d9c8ff", "on-primary-container": "#00626e", "surface-variant": "#32353b", "on-primary-fixed-variant": "#004f58", "surface-container-high": "#272a30", "outline-variant": "#3b494c", "surface-container": "#1d2025", "on-surface": "#e0e2ea", "background": "#101419", "primary-container": "#00e5ff", "inverse-surface": "#e0e2ea", "outline": "#849396", "on-secondary": "#002a78", "secondary-fixed-dim": "#b4c5ff", "on-tertiary": "#3c0091", "inverse-primary": "#006875", "surface-bright": "#36393f", "surface-container-low": "#181c21", "surface-container-highest": "#32353b", "inverse-on-surface": "#2d3036", "on-secondary-fixed": "#00174b", "primary": "#c3f5ff", "error-container": "#93000a", "surface-tint": "#00daf3", "on-tertiary-fixed-variant": "#5516be", "on-error-container": "#ffdad6", "primary-fixed-dim": "#00daf3", "tertiary-fixed": "#e9ddff", "on-primary-fixed": "#001f24", "on-error": "#690005", "surface-container-lowest": "#0b0e13", "secondary-container": "#0053db", "tertiary": "#f2e9ff", "surface-dim": "#101419", "on-surface-variant": "#bac9cc", "on-tertiary-container": "#6834d1", "primary-fixed": "#9cf0ff", "secondary-fixed": "#dbe1ff", "error": "#ffb4ab", "on-secondary-container": "#cdd7ff", "on-secondary-fixed-variant": "#003ea8", "surface": "#101419", "on-background": "#e0e2ea", "secondary": "#b4c5ff", "on-tertiary-fixed": "#23005c" }, "borderRadius": { "DEFAULT": "0.25rem", "lg": "0.5rem", "xl": "0.75rem", "full": "9999px" }, "spacing": { "margin-lg": "2rem", "space-xs": "0.25rem", "gutter-lg": "1.5rem", "space-xl": "2rem", "margin": "1rem", "space-sm": "0.5rem", "space-md": "1rem", "space-lg": "1.5rem", "gutter": "1rem" }, "fontFamily": { "headline-lg": ["Space Grotesk"], "body-lg": ["Inter"], "telemetry-metric-lg-mobile": ["JetBrains Mono"], "label-data": ["JetBrains Mono"], "display-hero": ["Space Grotesk"], "headline-sm": ["Space Grotesk"], "headline-md": ["Space Grotesk"], "label-caption": ["Inter"], "telemetry-metric-lg": ["JetBrains Mono"], "display-hero-mobile": ["Space Grotesk"], "telemetry-metric-md": ["JetBrains Mono"], "body-md": ["Inter"] }, "fontSize": { "headline-lg": ["32px", { "lineHeight": "40px", "letterSpacing": "-0.02em", "fontWeight": "700" }], "body-lg": ["16px", { "lineHeight": "24px", "fontWeight": "500" }], "telemetry-metric-lg-mobile": ["36px", { "lineHeight": "36px", "letterSpacing": "-0.03em", "fontWeight": "700" }], "label-data": ["12px", { "lineHeight": "16px", "letterSpacing": "0.08em", "fontWeight": "600" }], "display-hero": ["56px", { "lineHeight": "60px", "letterSpacing": "-0.03em", "fontWeight": "700" }], "headline-sm": ["20px", { "lineHeight": "28px", "fontWeight": "600" }], "headline-md": ["24px", { "lineHeight": "32px", "letterSpacing": "-0.01em", "fontWeight": "600" }], "label-caption": ["11px", { "lineHeight": "14px", "letterSpacing": "0.05em", "fontWeight": "600" }], "telemetry-metric-lg": ["48px", { "lineHeight": "48px", "letterSpacing": "-0.04em", "fontWeight": "700" }], "display-hero-mobile": ["40px", { "lineHeight": "44px", "letterSpacing": "-0.02em", "fontWeight": "700" }], "telemetry-metric-md": ["28px", { "lineHeight": "32px", "letterSpacing": "-0.02em", "fontWeight": "600" }], "body-md": ["14px", { "lineHeight": "20px", "fontWeight": "400" }] } } } }</script><style>
|
||||
body {
|
||||
min-height: max(884px, 100dvh);
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
body {
|
||||
min-height: max(884px, 100dvh);
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
body {
|
||||
min-height: max(884px, 100dvh);
|
||||
}
|
||||
</style>
|
||||
</head><body class="bg-surface font-body-md text-on-surface antialiased flex flex-col min-h-screen selection:bg-primary-container selection:text-on-primary-container"><header class="fixed top-0 w-full z-50 pt-safe bg-surface-container-lowest/85 backdrop-blur-xl shadow-[0_4px_20px_rgba(0,0,0,0.5)]"><div class="h-16 px-space-md flex items-center justify-between gap-space-sm"><div class="flex items-center gap-space-sm"><img alt="MotorSignal Brand Logo" class="h-8 w-auto object-contain drop-shadow-[0_0_8px_rgba(0,229,255,0.4)]" src="https://lh3.googleusercontent.com/aida/AEtjO1Vf56Tkh6bJ86BCfT5GHz_yPumvEXYLWojlNHAFG-cN4VvH_nLvEbWQ4x7uhJPRaAyO8ozAAbLI_huEN134QOIYp8BdHuqoZCsMk9_ILaUxZqilVgamefO6d2sG1R8laIWSUswanVsK9lfvIgppQm_XxBQipzkDgPwIoXk7yh10QTlmZqDICryF-1MoWFfFjM2zZswr6ynuAgZAviROYnFBF2D4hxm6YREQxkZQJaBcG9oAg_dYVgTHxwg"/><div class="flex flex-col"><span class="font-headline-sm text-headline-sm uppercase tracking-wider text-primary-fixed">MotorSignal</span><span class="font-label-caption text-label-caption text-on-surface-variant uppercase tracking-widest leading-none">Telemetry Log</span></div></div><div class="flex items-center gap-space-sm"><div class="hidden sm:flex items-center gap-space-xs bg-surface-container-low px-space-sm py-1 rounded-full"><span class="w-2 h-2 rounded-full bg-primary-container animate-pulse shadow-[0_0_6px_#00e5ff]"></span><span class="font-label-data text-label-data text-primary-fixed">GPS 3D FIX</span></div><div class="flex items-center gap-1.5 bg-surface-container px-2 py-1 rounded-full"><span class="material-symbols-outlined text-[15px] text-primary-container">bolt</span><span class="font-label-data text-label-data text-on-surface">98%</span><span class="w-1 h-1 rounded-full bg-outline-variant"></span><span class="material-symbols-outlined text-[15px] text-primary-container">cell_tower</span></div><button aria-label="Rider Profile" class="min-w-[44px] min-h-[44px] flex items-center justify-center p-1 rounded-full focus:outline-none focus:ring-2 focus:ring-primary-container" type="button"><img alt="Profile" class="w-8 h-8 rounded-full object-cover ring-2 ring-primary-container/40" src="https://lh3.googleusercontent.com/aida-public/AB6AXuBb6sR8Ta8-L1_TN1LuCBfSxtZxX9hKOFjd-RjllihDsnp6AG1GlMhL9bVlb-ibhIRT3HMw_caXK7BmwmvWKNBcuizyqswUQZNztavckRTN1Xa6qGML_0kv8qvV_hrXWWK1EjSjVFzhRyDzf6VdGnZvUpGsFFmSBcaGVrXmEWFYnIa-qHyeWxZlT_SJmPuQJPQKEWEo6vC6kdDzXNnhoB4tpRHjIjCstvTdooPc0KVN_x3BqqmqadNI"/></button></div></div></header><main class="flex-1 flex flex-col relative w-full pt-16 pb-20 bg-surface"><div class="flex flex-col w-full px-space-md py-space-sm space-y-space-md select-none">
|
||||
<!-- Mode / Segmented Switcher (Tactical HUD Filter) -->
|
||||
<div class="w-full bg-surface-container-lowest p-1 rounded-xl flex items-center shadow-inner">
|
||||
<button class="flex-1 min-h-[48px] flex items-center justify-center gap-space-xs rounded-lg bg-surface-container text-primary-fixed shadow-md transition-all duration-200" id="tab-settings-btn" onclick="switchView('settings')" type="button">
|
||||
<span class="material-symbols-outlined text-[18px]">security</span>
|
||||
<span class="font-headline-sm text-label-data uppercase tracking-wider">Alerts & Safety</span>
|
||||
</button>
|
||||
<button class="flex-1 min-h-[48px] flex items-center justify-center gap-space-xs rounded-lg text-on-surface-variant hover:text-primary transition-all duration-200" id="tab-diag-btn" onclick="switchView('diag')" type="button">
|
||||
<span class="material-symbols-outlined text-[18px]">sensors</span>
|
||||
<span class="font-headline-sm text-label-data uppercase tracking-wider">Sensor Diag (20Hz)</span>
|
||||
</button>
|
||||
</div>
|
||||
<!-- SECTION 1 & 3: SETTINGS & ROAD ALERTS VIEW -->
|
||||
<div class="flex flex-col space-y-space-md w-full" id="view-settings">
|
||||
<!-- Active Provider Status Card -->
|
||||
<div class="w-full bg-surface-container-low rounded-xl p-space-md shadow-lg space-y-space-md">
|
||||
<!-- Card Header -->
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-space-sm">
|
||||
<div class="w-10 h-10 rounded-lg bg-secondary-container/20 flex items-center justify-center text-primary-container">
|
||||
<span class="material-symbols-outlined text-[24px]">local_police</span>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant uppercase tracking-widest">Radar Feed Engine</span>
|
||||
<span class="font-headline-sm text-headline-sm text-on-surface">WAZE POLICE FEED</span>
|
||||
</div>
|
||||
</div>
|
||||
<span class="font-label-caption text-[10px] uppercase px-2 py-0.5 rounded-full bg-primary-container/15 text-primary-container tracking-wider">LIVE MESH</span>
|
||||
</div>
|
||||
<!-- Live Connection Pill -->
|
||||
<div class="flex items-center gap-space-xs bg-surface-container-lowest px-3 py-2 rounded-lg">
|
||||
<span class="w-2.5 h-2.5 rounded-full bg-primary-container animate-pulse shadow-[0_0_8px_#00e5ff]"></span>
|
||||
<span class="font-label-data text-label-data text-primary-fixed truncate">CONNECTED • 3,420 TRAPS IN CACHED SECTOR</span>
|
||||
</div>
|
||||
<!-- API Key & Action -->
|
||||
<div class="space-y-1.5">
|
||||
<div class="flex justify-between items-center">
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant uppercase">OpenWebNinja Gateway Key</span>
|
||||
<span class="font-label-caption text-label-caption text-primary cursor-pointer hover:underline" onclick="toggleApiKeyMask()">REVEAL</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<div class="relative flex-1">
|
||||
<input class="w-full h-12 bg-surface-container-lowest text-on-surface font-label-data text-label-data px-3 rounded-lg focus:outline-none focus:ring-1 focus:ring-primary-container" id="api-key-input" readonly="" type="password" value="own_live_9f823a9b990172e21"/>
|
||||
</div>
|
||||
<button class="min-h-[48px] px-4 rounded-lg bg-surface-container text-primary-fixed hover:bg-surface-bright active:bg-surface-variant flex items-center justify-center font-label-data text-label-data uppercase tracking-wider transition-all" id="btn-test-conn" onclick="testConnection()" type="button">
|
||||
<span id="btn-test-text">Test Link</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Detection Radius Slider -->
|
||||
<div class="space-y-2 pt-1">
|
||||
<div class="flex justify-between items-baseline">
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant uppercase">Radar Detection Horizon</span>
|
||||
<span class="font-telemetry-metric-md text-headline-sm text-primary-container" id="radius-val">1.50 <span class="font-label-data text-label-data text-on-surface-variant">MI</span></span>
|
||||
</div>
|
||||
<div class="relative flex items-center">
|
||||
<input class="w-full h-2.5 bg-surface-container-lowest rounded-lg appearance-none cursor-pointer accent-[#00e5ff]" id="radius-range" max="3.0" min="0.5" oninput="updateRadius(this.value)" step="0.25" type="range" value="1.5"/>
|
||||
</div>
|
||||
<div class="flex justify-between font-label-caption text-label-caption text-outline">
|
||||
<span>0.5 MI (TACTICAL)</span>
|
||||
<span>1.5 MI (CRUISE)</span>
|
||||
<span>3.0 MI (FREEWAY)</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Warning Audio Toggle -->
|
||||
<div class="flex items-center justify-between pt-2">
|
||||
<div class="flex flex-col pr-3">
|
||||
<span class="font-headline-sm text-body-lg text-on-surface">Voice & Tone Alerts</span>
|
||||
<span class="font-body-md text-label-caption text-on-surface-variant">Dual audible chime with synthesized audio distance warnings</span>
|
||||
</div>
|
||||
<button aria-checked="true" class="w-14 h-8 flex items-center bg-primary-container rounded-full p-1 cursor-pointer transition-colors duration-200 ease-in-out shrink-0" onclick="toggleSwitch(this)" role="switch" type="button">
|
||||
<div class="bg-surface-container-lowest w-6 h-6 rounded-full shadow-md transform translate-x-6 transition-transform duration-200 ease-in-out"></div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Safety Interlock Panel (Cornering Mute) -->
|
||||
<div class="w-full bg-surface-container-low rounded-xl p-space-md shadow-lg space-y-space-sm relative overflow-hidden">
|
||||
<div class="flex items-start justify-between">
|
||||
<div class="flex items-center gap-space-sm">
|
||||
<div class="w-10 h-10 rounded-lg bg-surface-container flex items-center justify-center text-primary">
|
||||
<span class="material-symbols-outlined text-[24px]">screen_rotation_alt</span>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="font-headline-sm text-headline-sm text-on-surface">Safety Lean Mute</span>
|
||||
<span class="font-label-caption text-[10px] px-1.5 py-0.5 rounded bg-surface-container text-primary-fixed uppercase tracking-widest">G-GUARD</span>
|
||||
</div>
|
||||
<span class="font-label-caption text-label-caption text-primary-container font-semibold">SUPPRESSES AUDIO WHEN LEAN > 15°</span>
|
||||
</div>
|
||||
</div>
|
||||
<button aria-checked="true" class="w-14 h-8 flex items-center bg-primary-container rounded-full p-1 cursor-pointer transition-colors duration-200 ease-in-out shrink-0" onclick="toggleSwitch(this)" role="switch" type="button">
|
||||
<div class="bg-surface-container-lowest w-6 h-6 rounded-full shadow-md transform translate-x-6 transition-transform duration-200 ease-in-out"></div>
|
||||
</button>
|
||||
</div>
|
||||
<!-- Lean Angle Visualization Ribbon -->
|
||||
<div class="bg-surface-container-lowest rounded-lg p-space-sm space-y-2 mt-2">
|
||||
<div class="flex justify-between items-center font-label-data text-label-caption">
|
||||
<span class="text-on-surface-variant">ACTIVE INCLINATION GATE</span>
|
||||
<span class="text-primary-container">THRESHOLD: 15.0°</span>
|
||||
</div>
|
||||
<!-- Gauge arc mimic -->
|
||||
<div class="w-full bg-surface-container h-2 rounded-full overflow-hidden flex">
|
||||
<div class="h-full bg-surface-variant w-[25%]"></div>
|
||||
<div class="h-full bg-primary-container w-[10%]"></div>
|
||||
<div class="h-full bg-primary-fixed-dim w-[30%]"></div>
|
||||
<div class="h-full bg-primary-container w-[10%]"></div>
|
||||
<div class="h-full bg-surface-variant w-[25%]"></div>
|
||||
</div>
|
||||
<p class="font-body-md text-label-caption text-on-surface-variant leading-relaxed">
|
||||
Eliminates helmet intercom distraction mid-apex. Audio alerts automatically buffer and resume <span class="text-primary font-semibold">1.5 seconds</span> after the motorcycle recovers to an upright posture.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Quick Storage Overview Card -->
|
||||
<div class="w-full bg-surface-container-low rounded-xl p-space-md shadow-lg space-y-space-md">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-space-sm">
|
||||
<div class="w-10 h-10 rounded-lg bg-surface-container flex items-center justify-center text-secondary">
|
||||
<span class="material-symbols-outlined text-[24px]">database</span>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant uppercase tracking-widest">Local Repository</span>
|
||||
<span class="font-headline-sm text-body-lg text-on-surface">DRIFT SQLITE (SCHEMA 7)</span>
|
||||
</div>
|
||||
</div>
|
||||
<span class="font-label-data text-label-data text-primary-fixed px-2 py-1 rounded bg-surface-container-lowest">0 OUTBOX</span>
|
||||
</div>
|
||||
<div class="grid grid-cols-2 gap-space-sm">
|
||||
<div class="bg-surface-container-lowest p-space-sm rounded-lg flex flex-col justify-between">
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant uppercase">Local Flash Size</span>
|
||||
<span class="font-telemetry-metric-md text-headline-sm text-on-surface">142.4 <span class="font-label-data text-label-caption text-on-surface-variant">MB</span></span>
|
||||
</div>
|
||||
<div class="bg-surface-container-lowest p-space-sm rounded-lg flex flex-col justify-between">
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant uppercase">Cloud Replicate</span>
|
||||
<span class="font-label-data text-label-data text-primary-container flex items-center gap-1 mt-1">
|
||||
<span class="material-symbols-outlined text-[16px]">cloud_done</span> R2 SYNCED
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col gap-2 pt-1">
|
||||
<button class="min-h-[48px] w-full bg-surface-container text-on-surface hover:text-primary-fixed hover:bg-surface-bright rounded-lg flex items-center justify-center gap-2 font-label-data text-label-data uppercase tracking-wider transition-all" onclick="flashNotice('DUMP GENERATED: DRIFT_LOGS_202505.ZIP')" type="button">
|
||||
<span class="material-symbols-outlined text-[18px]">archive</span>
|
||||
<span>Dump Diagnostic Logs (.ZIP)</span>
|
||||
</button>
|
||||
<button class="min-h-[48px] w-full bg-surface-container-lowest text-on-surface-variant hover:text-error rounded-lg flex items-center justify-center gap-2 font-label-data text-label-data uppercase tracking-wider transition-all" onclick="confirmReset()" type="button">
|
||||
<span class="material-symbols-outlined text-[18px]">restore</span>
|
||||
<span>Zero IMU Bias & Re-Calibrate</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- SECTION 2: 20 Hz HARDWARE DIAGNOSTICS VIEW (Can be switched or reviewed directly) -->
|
||||
<div class="hidden flex-col space-y-space-md w-full" id="view-diag">
|
||||
<!-- IMU Fusion Master Console -->
|
||||
<div class="w-full bg-surface-container-lowest rounded-xl p-space-md shadow-2xl space-y-space-md relative overflow-hidden">
|
||||
<!-- Accent Neon Line Header -->
|
||||
<div class="absolute top-0 left-0 right-0 h-1 bg-gradient-to-r from-primary-container via-surface-tint to-primary"></div>
|
||||
<div class="flex items-center justify-between pt-1">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-[20px] text-primary-container animate-pulse">developer_board</span>
|
||||
<span class="font-headline-sm text-body-lg text-primary-fixed tracking-wide">KALMAN SENSOR STREAM</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-1.5 px-2 py-0.5 rounded bg-surface-container-high">
|
||||
<span class="w-2 h-2 rounded-full bg-primary-container animate-ping"></span>
|
||||
<span class="font-label-data text-label-data text-primary">20.00 HZ</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Accelerometer Matrix (3-Axis) -->
|
||||
<div class="bg-surface-container-low rounded-lg p-space-sm space-y-2">
|
||||
<div class="flex justify-between items-center">
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant uppercase tracking-wider">Accelerometer Raw (m/s²)</span>
|
||||
<span class="font-label-data text-[10px] text-outline">ST-LSM6DSO</span>
|
||||
</div>
|
||||
<div class="grid grid-cols-3 gap-2 text-center">
|
||||
<div class="bg-surface-container p-2 rounded flex flex-col">
|
||||
<span class="font-label-caption text-[10px] text-on-surface-variant">AXIS X (LAT)</span>
|
||||
<span class="font-telemetry-metric-md text-headline-sm text-primary-fixed mt-1" id="acc-x">+0.04</span>
|
||||
</div>
|
||||
<div class="bg-surface-container p-2 rounded flex flex-col">
|
||||
<span class="font-label-caption text-[10px] text-on-surface-variant">AXIS Y (LONG)</span>
|
||||
<span class="font-telemetry-metric-md text-headline-sm text-primary-fixed mt-1" id="acc-y">-0.01</span>
|
||||
</div>
|
||||
<div class="bg-surface-container p-2 rounded flex flex-col">
|
||||
<span class="font-label-caption text-[10px] text-on-surface-variant">AXIS Z (GRAV)</span>
|
||||
<span class="font-telemetry-metric-md text-headline-sm text-primary-container mt-1" id="acc-z">+9.81</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Gyroscope Angular Rate (Roll, Pitch, Yaw) -->
|
||||
<div class="bg-surface-container-low rounded-lg p-space-sm space-y-2">
|
||||
<div class="flex justify-between items-center">
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant uppercase tracking-wider">Gyro Angular Velocity (rad/s)</span>
|
||||
<span class="font-label-data text-[10px] text-outline">KALMAN FILTERED</span>
|
||||
</div>
|
||||
<div class="grid grid-cols-3 gap-2 text-center">
|
||||
<div class="bg-surface-container p-2 rounded flex flex-col">
|
||||
<span class="font-label-caption text-[10px] text-on-surface-variant">ROLL RATE</span>
|
||||
<span class="font-telemetry-metric-md text-headline-sm text-on-surface mt-1" id="gyro-roll">0.002</span>
|
||||
</div>
|
||||
<div class="bg-surface-container p-2 rounded flex flex-col">
|
||||
<span class="font-label-caption text-[10px] text-on-surface-variant">PITCH RATE</span>
|
||||
<span class="font-telemetry-metric-md text-headline-sm text-on-surface mt-1" id="gyro-pitch">-0.001</span>
|
||||
</div>
|
||||
<div class="bg-surface-container p-2 rounded flex flex-col">
|
||||
<span class="font-label-caption text-[10px] text-on-surface-variant">YAW RATE</span>
|
||||
<span class="font-telemetry-metric-md text-headline-sm text-on-surface mt-1" id="gyro-yaw">0.000</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- GNSS Multi-Band Constellation Status -->
|
||||
<div class="bg-surface-container-low rounded-lg p-space-sm space-y-space-sm">
|
||||
<div class="flex justify-between items-center">
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant uppercase tracking-wider">GNSS Constellation Fix</span>
|
||||
<span class="font-label-data text-[10px] text-primary-container uppercase">L1 + L5 DUAL-BAND</span>
|
||||
</div>
|
||||
<div class="space-y-2">
|
||||
<div class="flex justify-between items-center bg-surface-container px-3 py-2 rounded">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-[18px] text-primary">satellite_alt</span>
|
||||
<span class="font-body-md text-label-caption text-on-surface">Satellites Tracked</span>
|
||||
</div>
|
||||
<span class="font-telemetry-metric-md text-headline-sm text-primary-fixed">18 <span class="font-label-caption text-outline text-[11px]">FIXED</span></span>
|
||||
</div>
|
||||
<div class="flex justify-between items-center bg-surface-container px-3 py-2 rounded">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-[18px] text-primary">straighten</span>
|
||||
<span class="font-body-md text-label-caption text-on-surface">Horizontal Precision</span>
|
||||
</div>
|
||||
<span class="font-telemetry-metric-md text-headline-sm text-primary-container">± 0.82 <span class="font-label-caption text-outline text-[11px]">M</span></span>
|
||||
</div>
|
||||
<div class="flex justify-between items-center bg-surface-container px-3 py-2 rounded">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-[18px] text-primary">sync</span>
|
||||
<span class="font-body-md text-label-caption text-on-surface">IMU-GPS Fusion Health</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-1.5">
|
||||
<span class="w-2 h-2 rounded-full bg-primary-container"></span>
|
||||
<span class="font-label-data text-label-data text-primary-fixed font-bold">OPTIMAL (100%)</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Real-Time Packet Feed Monitor -->
|
||||
<div class="bg-surface-container-lowest p-2 rounded font-label-data text-[10px] text-outline flex items-center justify-between">
|
||||
<span class="truncate">$PNTK,20,0.04,-0.01,9.81,0.002,18,0.82*4F</span>
|
||||
<span class="text-primary-container shrink-0">RX OK</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Rapid Hardware Action Bar -->
|
||||
<div class="grid grid-cols-2 gap-space-sm">
|
||||
<button class="min-h-[48px] bg-surface-container text-on-surface hover:text-primary-fixed rounded-lg font-label-data text-label-data uppercase tracking-wider flex items-center justify-center gap-2 transition-all" onclick="rebootSensors()" type="button">
|
||||
<span class="material-symbols-outlined text-[18px]">restart_alt</span>
|
||||
<span>Re-Sync Bus</span>
|
||||
</button>
|
||||
<button class="min-h-[48px] bg-primary-container text-on-primary font-label-data text-label-data uppercase tracking-wider rounded-lg flex items-center justify-center gap-2 shadow-[0_0_12px_rgba(0,229,255,0.35)] transition-all" onclick="recordSnapshot()" type="button">
|
||||
<span class="material-symbols-outlined text-[18px]">camera</span>
|
||||
<span>IMU Freeze Frame</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Notification Toast Modal Mimic (Hidden by Default) -->
|
||||
<div class="hidden fixed bottom-24 left-4 right-4 z-50 bg-surface-container-high/95 backdrop-blur-md p-space-md rounded-xl shadow-2xl flex items-center justify-between" id="hud-toast">
|
||||
<div class="flex items-center gap-space-sm">
|
||||
<span class="material-symbols-outlined text-primary-container text-[24px]">verified</span>
|
||||
<span class="font-label-data text-label-data text-on-surface" id="hud-toast-msg">ACTION COMPLETED</span>
|
||||
</div>
|
||||
<button class="min-w-[44px] min-h-[44px] flex items-center justify-center text-on-surface-variant hover:text-on-surface" onclick="dismissToast()">
|
||||
<span class="material-symbols-outlined text-[18px]">close</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
function switchView(mode) {
|
||||
const sView = document.getElementById('view-settings');
|
||||
const dView = document.getElementById('view-diag');
|
||||
const sBtn = document.getElementById('tab-settings-btn');
|
||||
const dBtn = document.getElementById('tab-diag-btn');
|
||||
|
||||
if (mode === 'settings') {
|
||||
sView.classList.remove('hidden');
|
||||
dView.classList.add('hidden');
|
||||
sBtn.className = "flex-1 min-h-[48px] flex items-center justify-center gap-space-xs rounded-lg bg-surface-container text-primary-fixed shadow-md transition-all duration-200";
|
||||
dBtn.className = "flex-1 min-h-[48px] flex items-center justify-center gap-space-xs rounded-lg text-on-surface-variant hover:text-primary transition-all duration-200";
|
||||
} else {
|
||||
sView.classList.add('hidden');
|
||||
dView.classList.remove('hidden');
|
||||
dBtn.className = "flex-1 min-h-[48px] flex items-center justify-center gap-space-xs rounded-lg bg-surface-container text-primary-fixed shadow-md transition-all duration-200";
|
||||
sBtn.className = "flex-1 min-h-[48px] flex items-center justify-center gap-space-xs rounded-lg text-on-surface-variant hover:text-primary transition-all duration-200";
|
||||
}
|
||||
}
|
||||
|
||||
function updateRadius(val) {
|
||||
const display = document.getElementById('radius-val');
|
||||
display.innerHTML = Number(val).toFixed(2) + ' <span class="font-label-data text-label-data text-on-surface-variant">MI</span>';
|
||||
}
|
||||
|
||||
function toggleSwitch(elem) {
|
||||
const isChecked = elem.getAttribute('aria-checked') === 'true';
|
||||
const knob = elem.firstElementChild;
|
||||
if (isChecked) {
|
||||
elem.setAttribute('aria-checked', 'false');
|
||||
elem.classList.remove('bg-primary-container');
|
||||
elem.classList.add('bg-surface-variant');
|
||||
knob.classList.remove('translate-x-6');
|
||||
knob.classList.add('translate-x-0');
|
||||
} else {
|
||||
elem.setAttribute('aria-checked', 'true');
|
||||
elem.classList.remove('bg-surface-variant');
|
||||
elem.classList.add('bg-primary-container');
|
||||
knob.classList.remove('translate-x-0');
|
||||
knob.classList.add('translate-x-6');
|
||||
}
|
||||
}
|
||||
|
||||
function toggleApiKeyMask() {
|
||||
const input = document.getElementById('api-key-input');
|
||||
if (input.type === 'password') {
|
||||
input.type = 'text';
|
||||
} else {
|
||||
input.type = 'password';
|
||||
}
|
||||
}
|
||||
|
||||
function testConnection() {
|
||||
const btn = document.getElementById('btn-test-text');
|
||||
btn.textContent = 'PINGING...';
|
||||
setTimeout(() => {
|
||||
btn.textContent = '24ms LATENCY';
|
||||
flashNotice('OPENWEBNINJA PROXY ONLINE: 200 OK');
|
||||
setTimeout(() => {
|
||||
btn.textContent = 'TEST LINK';
|
||||
}, 2500);
|
||||
}, 600);
|
||||
}
|
||||
|
||||
function confirmReset() {
|
||||
flashNotice('IMU SENSOR BIAS ZEROED • RE-CALIBRATED');
|
||||
}
|
||||
|
||||
function rebootSensors() {
|
||||
flashNotice('I2C BUS RE-INITIALIZED @ 400 KHZ');
|
||||
}
|
||||
|
||||
function recordSnapshot() {
|
||||
flashNotice('TELEMETRY SNAPSHOT SAVED TO DRIFT DB');
|
||||
}
|
||||
|
||||
function flashNotice(msg) {
|
||||
const toast = document.getElementById('hud-toast');
|
||||
const label = document.getElementById('hud-toast-msg');
|
||||
label.textContent = msg;
|
||||
toast.classList.remove('hidden');
|
||||
setTimeout(() => {
|
||||
toast.classList.add('hidden');
|
||||
}, 3500);
|
||||
}
|
||||
|
||||
function dismissToast() {
|
||||
document.getElementById('hud-toast').classList.add('hidden');
|
||||
}
|
||||
|
||||
// 20Hz Telemetry Jitter Simulation to make the HUD feel truly alive
|
||||
let liveTimer = null;
|
||||
function startJitter() {
|
||||
if (liveTimer) clearInterval(liveTimer);
|
||||
liveTimer = setInterval(() => {
|
||||
const ax = document.getElementById('acc-x');
|
||||
const ay = document.getElementById('acc-y');
|
||||
const az = document.getElementById('acc-z');
|
||||
const gr = document.getElementById('gyro-roll');
|
||||
|
||||
if (ax) {
|
||||
const jitterX = (0.04 + (Math.random() * 0.04 - 0.02)).toFixed(2);
|
||||
const jitterY = (-0.01 + (Math.random() * 0.03 - 0.015)).toFixed(2);
|
||||
const jitterZ = (9.81 + (Math.random() * 0.04 - 0.02)).toFixed(2);
|
||||
const jitterRoll = (0.002 + (Math.random() * 0.002 - 0.001)).toFixed(3);
|
||||
|
||||
ax.textContent = (jitterX >= 0 ? '+' : '') + jitterX;
|
||||
ay.textContent = (jitterY >= 0 ? '+' : '') + jitterY;
|
||||
az.textContent = '+' + jitterZ;
|
||||
if (gr) gr.textContent = jitterRoll;
|
||||
}
|
||||
}, 150);
|
||||
}
|
||||
startJitter();
|
||||
</script></main><nav class="fixed bottom-0 w-full z-50 pb-safe bg-surface-container-lowest/90 backdrop-blur-xl shadow-[0_-4px_24px_rgba(0,0,0,0.6)]" data-active-classes="text-primary-container font-headline-sm [filter:drop-shadow(0_0_8px_rgba(0,229,255,0.5))]"><div class="grid grid-cols-6 items-center h-20 px-space-xs"><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="cockpit-dash" href="#"><span class="material-symbols-outlined text-[24px]">speed</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Dash</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="tactical-radar-map" href="#"><span class="material-symbols-outlined text-[24px]">radar</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Map</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="telemetry-log" href="#"><span class="material-symbols-outlined text-[24px]">monitoring</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Activity</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="bike-garage" href="#"><span class="material-symbols-outlined text-[24px]">two_wheeler</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Garage</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="pack-comms" href="#"><span class="material-symbols-outlined text-[24px]">groups_3</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Social</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="hud-settings" href="#"><span class="material-symbols-outlined text-[24px]">tune</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Settings</span></a></div></nav></body></html>
|
||||
|
|
@ -0,0 +1,264 @@
|
|||
<!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, viewport-fit=cover" name="viewport"/><meta content="mobile_tab" name="shell-type"/><title>MotorSignal Cockpit HUD</title><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&family=JetBrains+Mono:wght@500;600;700&family=Space+Grotesk:wght@600;700&display=swap" rel="stylesheet"/><link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/><style>@layer base{html,body{width:100%;margin:0;padding:0;background-color:#101419;color:#e0e2ea;}body{overscroll-behavior:none;}.pb-safe{padding-bottom:env(safe-area-inset-bottom,0px);}.pt-safe{padding-top:env(safe-area-inset-top,0px);}main>:first-child{margin-top:0!important;}main>:last-child{margin-bottom:0!important;}}::-webkit-scrollbar{display:none;}</style><script src="https://cdn.tailwindcss.com"></script><script id="tailwind-config">tailwind.config = { darkMode: "class", theme: { extend: { "colors": { "on-primary": "#00363d", "tertiary-fixed-dim": "#d0bcff", "tertiary-container": "#d9c8ff", "on-primary-container": "#00626e", "surface-variant": "#32353b", "on-primary-fixed-variant": "#004f58", "surface-container-high": "#272a30", "outline-variant": "#3b494c", "surface-container": "#1d2025", "on-surface": "#e0e2ea", "background": "#101419", "primary-container": "#00e5ff", "inverse-surface": "#e0e2ea", "outline": "#849396", "on-secondary": "#002a78", "secondary-fixed-dim": "#b4c5ff", "on-tertiary": "#3c0091", "inverse-primary": "#006875", "surface-bright": "#36393f", "surface-container-low": "#181c21", "surface-container-highest": "#32353b", "inverse-on-surface": "#2d3036", "on-secondary-fixed": "#00174b", "primary": "#c3f5ff", "error-container": "#93000a", "surface-tint": "#00daf3", "on-tertiary-fixed-variant": "#5516be", "on-error-container": "#ffdad6", "primary-fixed-dim": "#00daf3", "tertiary-fixed": "#e9ddff", "on-primary-fixed": "#001f24", "on-error": "#690005", "surface-container-lowest": "#0b0e13", "secondary-container": "#0053db", "tertiary": "#f2e9ff", "surface-dim": "#101419", "on-surface-variant": "#bac9cc", "on-tertiary-container": "#6834d1", "primary-fixed": "#9cf0ff", "secondary-fixed": "#dbe1ff", "error": "#ffb4ab", "on-secondary-container": "#cdd7ff", "on-secondary-fixed-variant": "#003ea8", "surface": "#101419", "on-background": "#e0e2ea", "secondary": "#b4c5ff", "on-tertiary-fixed": "#23005c" }, "borderRadius": { "DEFAULT": "0.25rem", "lg": "0.5rem", "xl": "0.75rem", "full": "9999px" }, "spacing": { "margin-lg": "2rem", "space-xs": "0.25rem", "gutter-lg": "1.5rem", "space-xl": "2rem", "margin": "1rem", "space-sm": "0.5rem", "space-md": "1rem", "space-lg": "1.5rem", "gutter": "1rem" }, "fontFamily": { "headline-lg": ["Space Grotesk"], "body-lg": ["Inter"], "telemetry-metric-lg-mobile": ["JetBrains Mono"], "label-data": ["JetBrains Mono"], "display-hero": ["Space Grotesk"], "headline-sm": ["Space Grotesk"], "headline-md": ["Space Grotesk"], "label-caption": ["Inter"], "telemetry-metric-lg": ["JetBrains Mono"], "display-hero-mobile": ["Space Grotesk"], "telemetry-metric-md": ["JetBrains Mono"], "body-md": ["Inter"] }, "fontSize": { "headline-lg": ["32px", { "lineHeight": "40px", "letterSpacing": "-0.02em", "fontWeight": "700" }], "body-lg": ["16px", { "lineHeight": "24px", "fontWeight": "500" }], "telemetry-metric-lg-mobile": ["36px", { "lineHeight": "36px", "letterSpacing": "-0.03em", "fontWeight": "700" }], "label-data": ["12px", { "lineHeight": "16px", "letterSpacing": "0.08em", "fontWeight": "600" }], "display-hero": ["56px", { "lineHeight": "60px", "letterSpacing": "-0.03em", "fontWeight": "700" }], "headline-sm": ["20px", { "lineHeight": "28px", "fontWeight": "600" }], "headline-md": ["24px", { "lineHeight": "32px", "letterSpacing": "-0.01em", "fontWeight": "600" }], "label-caption": ["11px", { "lineHeight": "14px", "letterSpacing": "0.05em", "fontWeight": "600" }], "telemetry-metric-lg": ["48px", { "lineHeight": "48px", "letterSpacing": "-0.04em", "fontWeight": "700" }], "display-hero-mobile": ["40px", { "lineHeight": "44px", "letterSpacing": "-0.02em", "fontWeight": "700" }], "telemetry-metric-md": ["28px", { "lineHeight": "32px", "letterSpacing": "-0.02em", "fontWeight": "600" }], "body-md": ["14px", { "lineHeight": "20px", "fontWeight": "400" }] } } } }</script><style>
|
||||
body {
|
||||
min-height: max(884px, 100dvh);
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
body {
|
||||
min-height: max(884px, 100dvh);
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
body {
|
||||
min-height: max(884px, 100dvh);
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
body {
|
||||
min-height: max(884px, 100dvh);
|
||||
}
|
||||
</style>
|
||||
</head><body class="bg-surface font-body-md text-on-surface antialiased flex flex-col min-h-screen selection:bg-primary-container selection:text-on-primary-container"><header class="fixed top-0 w-full z-50 pt-safe bg-surface-container-lowest/85 backdrop-blur-xl shadow-[0_4px_20px_rgba(0,0,0,0.5)]"><div class="h-16 px-space-md flex items-center justify-between gap-space-sm"><div class="flex items-center gap-space-sm"><img alt="MotorSignal Brand Logo" class="h-8 w-auto object-contain drop-shadow-[0_0_8px_rgba(0,229,255,0.4)]" src="https://lh3.googleusercontent.com/aida/AEtjO1Vf56Tkh6bJ86BCfT5GHz_yPumvEXYLWojlNHAFG-cN4VvH_nLvEbWQ4x7uhJPRaAyO8ozAAbLI_huEN134QOIYp8BdHuqoZCsMk9_ILaUxZqilVgamefO6d2sG1R8laIWSUswanVsK9lfvIgppQm_XxBQipzkDgPwIoXk7yh10QTlmZqDICryF-1MoWFfFjM2zZswr6ynuAgZAviROYnFBF2D4hxm6YREQxkZQJaBcG9oAg_dYVgTHxwg"/><div class="flex flex-col"><span class="font-headline-sm text-headline-sm uppercase tracking-wider text-primary-fixed">MotorSignal</span><span class="font-label-caption text-label-caption text-on-surface-variant uppercase tracking-widest leading-none">Telemetry Log</span></div></div><div class="flex items-center gap-space-sm"><div class="hidden sm:flex items-center gap-space-xs bg-surface-container-low px-space-sm py-1 rounded-full"><span class="w-2 h-2 rounded-full bg-primary-container animate-pulse shadow-[0_0_6px_#00e5ff]"></span><span class="font-label-data text-label-data text-primary-fixed">GPS 3D FIX</span></div><div class="flex items-center gap-1.5 bg-surface-container px-2 py-1 rounded-full"><span class="material-symbols-outlined text-[15px] text-primary-container">bolt</span><span class="font-label-data text-label-data text-on-surface">98%</span><span class="w-1 h-1 rounded-full bg-outline-variant"></span><span class="material-symbols-outlined text-[15px] text-primary-container">cell_tower</span></div><button aria-label="Rider Profile" class="min-w-[44px] min-h-[44px] flex items-center justify-center p-1 rounded-full focus:outline-none focus:ring-2 focus:ring-primary-container" type="button"><img alt="Profile" class="w-8 h-8 rounded-full object-cover ring-2 ring-primary-container/40" src="https://lh3.googleusercontent.com/aida-public/AB6AXuBb6sR8Ta8-L1_TN1LuCBfSxtZxX9hKOFjd-RjllihDsnp6AG1GlMhL9bVlb-ibhIRT3HMw_caXK7BmwmvWKNBcuizyqswUQZNztavckRTN1Xa6qGML_0kv8qvV_hrXWWK1EjSjVFzhRyDzf6VdGnZvUpGsFFmSBcaGVrXmEWFYnIa-qHyeWxZlT_SJmPuQJPQKEWEo6vC6kdDzXNnhoB4tpRHjIjCstvTdooPc0KVN_x3BqqmqadNI"/></button></div></div></header><main class="flex-1 flex flex-col relative w-full pt-16 pb-20 bg-surface"><div class="flex flex-col w-full text-on-surface">
|
||||
<!-- Top Dismiss Bar & Crest -->
|
||||
<div class="flex items-center justify-between px-space-md py-space-sm bg-surface-container-lowest/80 backdrop-blur-md">
|
||||
<div class="flex items-center gap-space-xs">
|
||||
<div class="flex items-center gap-1.5 px-2.5 py-1 rounded-full bg-surface-container-high shadow-inner">
|
||||
<span class="material-symbols-outlined text-[16px] text-tertiary-fixed-dim" style="font-variation-settings: 'FILL' 1;">military_tech</span>
|
||||
<span class="font-headline-sm text-[12px] tracking-widest text-primary-fixed uppercase font-bold">MOTORSIGNAL PRO</span>
|
||||
</div>
|
||||
<span class="px-2 py-0.5 rounded-full bg-primary-container/10 text-primary-container font-label-data text-label-data">v4.8</span>
|
||||
</div>
|
||||
<button aria-label="Dismiss Modal" class="min-w-[48px] min-h-[48px] flex items-center justify-center rounded-full bg-surface-container-high text-on-surface-variant hover:text-on-surface hover:bg-surface-container-highest transition-colors active:scale-95" type="button">
|
||||
<span class="material-symbols-outlined text-[20px]">close</span>
|
||||
</button>
|
||||
</div>
|
||||
<!-- Content Scroller Body -->
|
||||
<div class="flex flex-col px-space-md pt-space-xs pb-space-lg gap-space-lg">
|
||||
<!-- Hero Pitch -->
|
||||
<div class="flex flex-col items-center text-center gap-space-sm">
|
||||
<div class="inline-flex items-center gap-1.5 px-3 py-1 rounded-full bg-surface-container-high shadow-[0_0_12px_rgba(0,229,255,0.15)]">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-primary-container animate-pulse shadow-[0_0_6px_#00e5ff]"></span>
|
||||
<span class="font-label-data text-label-data uppercase tracking-wider text-primary-fixed">AEROSPACE-GRADE MOTORCYCLE TELEMETRY</span>
|
||||
</div>
|
||||
<h1 class="font-headline-lg text-headline-lg text-on-surface tracking-tight max-w-[340px]">
|
||||
Unlock Full <span class="text-primary-container drop-shadow-[0_0_12px_rgba(0,229,255,0.4)]">Forensic Telemetry</span>
|
||||
</h1>
|
||||
<p class="font-body-md text-body-md text-on-surface-variant max-w-[320px]">
|
||||
Sub-second corner analysis, real-time Waze police traps, and draggy-grade launch timing.
|
||||
</p>
|
||||
</div>
|
||||
<!-- Cockpit Visual Cue -->
|
||||
<div class="relative w-full h-32 rounded-xl overflow-hidden bg-surface-container-lowest flex items-center justify-center shadow-lg">
|
||||
<div class="absolute inset-0 bg-gradient-to-r from-surface-container-lowest via-surface-container-high/40 to-surface-container-lowest"></div>
|
||||
<!-- Telemetry Graphic Decor -->
|
||||
<div class="relative z-10 w-full px-space-md flex items-center justify-around">
|
||||
<div class="flex flex-col items-center">
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant uppercase">Lean Angle</span>
|
||||
<span class="font-telemetry-metric-lg-mobile text-telemetry-metric-lg-mobile text-primary-container">52.4°</span>
|
||||
<span class="font-label-data text-[10px] text-tertiary-fixed-dim">APEX PRECISION</span>
|
||||
</div>
|
||||
<div class="h-12 w-px bg-surface-variant"></div>
|
||||
<div class="flex flex-col items-center">
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant uppercase">Sensors</span>
|
||||
<span class="font-telemetry-metric-lg-mobile text-telemetry-metric-lg-mobile text-on-surface">20<span class="text-[18px] text-primary-container">Hz</span></span>
|
||||
<span class="font-label-data text-[10px] text-on-surface-variant">IMU CAPTURE</span>
|
||||
</div>
|
||||
<div class="h-12 w-px bg-surface-variant"></div>
|
||||
<div class="flex flex-col items-center">
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant uppercase">Trap Ping</span>
|
||||
<span class="font-telemetry-metric-lg-mobile text-telemetry-metric-lg-mobile text-error">0.3<span class="text-[18px] text-error">mi</span></span>
|
||||
<span class="font-label-data text-[10px] text-error">RADAR ACTIVE</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Feature Checklist Card -->
|
||||
<div class="rounded-xl bg-surface-container-low p-space-md shadow-md flex flex-col gap-space-md">
|
||||
<div class="flex items-center justify-between pb-space-xs">
|
||||
<span class="font-label-data text-label-data text-on-surface-variant uppercase tracking-wider">PRO SENSOR SUITE INCLUDED</span>
|
||||
<span class="material-symbols-outlined text-[18px] text-primary-container">offline_bolt</span>
|
||||
</div>
|
||||
<div class="flex flex-col gap-space-md">
|
||||
<!-- Item 1 -->
|
||||
<div class="flex items-start gap-3">
|
||||
<div class="min-w-[28px] h-7 rounded-lg bg-surface-container flex items-center justify-center text-primary-container shadow-sm mt-0.5">
|
||||
<span class="material-symbols-outlined text-[18px]" style="font-variation-settings: 'FILL' 1;">check_circle</span>
|
||||
</div>
|
||||
<div class="flex flex-col min-w-0">
|
||||
<span class="font-headline-sm text-[15px] leading-tight text-on-surface font-semibold">20 Hz Sub-Second IMU Acquisition</span>
|
||||
<span class="font-body-md text-[13px] text-on-surface-variant leading-snug">Sub-second apex forensic resolution vs 1Hz phone GPS for precision analysis.</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Item 2 -->
|
||||
<div class="flex items-start gap-3">
|
||||
<div class="min-w-[28px] h-7 rounded-lg bg-surface-container flex items-center justify-center text-primary-container shadow-sm mt-0.5">
|
||||
<span class="material-symbols-outlined text-[18px]" style="font-variation-settings: 'FILL' 1;">check_circle</span>
|
||||
</div>
|
||||
<div class="flex flex-col min-w-0">
|
||||
<span class="font-headline-sm text-[15px] leading-tight text-on-surface font-semibold">Live Waze Police & Camera Feeds</span>
|
||||
<span class="font-body-md text-[13px] text-on-surface-variant leading-snug">Unlimited real-time radar trap warnings with in-helmet audio chimes.</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Item 3 -->
|
||||
<div class="flex items-start gap-3">
|
||||
<div class="min-w-[28px] h-7 rounded-lg bg-surface-container flex items-center justify-center text-primary-container shadow-sm mt-0.5">
|
||||
<span class="material-symbols-outlined text-[18px]" style="font-variation-settings: 'FILL' 1;">check_circle</span>
|
||||
</div>
|
||||
<div class="flex flex-col min-w-0">
|
||||
<span class="font-headline-sm text-[15px] leading-tight text-on-surface font-semibold">Interactive 3D Lean Angle Replay</span>
|
||||
<span class="font-body-md text-[13px] text-on-surface-variant leading-snug">Scrub every corner with synchronized G-force vectors and pitch arcs.</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Item 4 -->
|
||||
<div class="flex items-start gap-3">
|
||||
<div class="min-w-[28px] h-7 rounded-lg bg-surface-container flex items-center justify-center text-primary-container shadow-sm mt-0.5">
|
||||
<span class="material-symbols-outlined text-[18px]" style="font-variation-settings: 'FILL' 1;">check_circle</span>
|
||||
</div>
|
||||
<div class="flex flex-col min-w-0">
|
||||
<span class="font-headline-sm text-[15px] leading-tight text-on-surface font-semibold">Live Pack Mesh Radar</span>
|
||||
<span class="font-body-md text-[13px] text-on-surface-variant leading-snug">Unlimited squad riders on ad-hoc 20Hz offline radio mesh coordinates.</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Item 5 -->
|
||||
<div class="flex items-start gap-3">
|
||||
<div class="min-w-[28px] h-7 rounded-lg bg-surface-container flex items-center justify-center text-primary-container shadow-sm mt-0.5">
|
||||
<span class="material-symbols-outlined text-[18px]" style="font-variation-settings: 'FILL' 1;">check_circle</span>
|
||||
</div>
|
||||
<div class="flex flex-col min-w-0">
|
||||
<span class="font-headline-sm text-[15px] leading-tight text-on-surface font-semibold">Draggy Launch Mode & Pro Tree</span>
|
||||
<span class="font-body-md text-[13px] text-on-surface-variant leading-snug">NHRA 0-60, 0-100, and 1/4-mile slope-verified precision timing.</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Item 6 -->
|
||||
<div class="flex items-start gap-3">
|
||||
<div class="min-w-[28px] h-7 rounded-lg bg-surface-container flex items-center justify-center text-primary-container shadow-sm mt-0.5">
|
||||
<span class="material-symbols-outlined text-[18px]" style="font-variation-settings: 'FILL' 1;">check_circle</span>
|
||||
</div>
|
||||
<div class="flex flex-col min-w-0">
|
||||
<span class="font-headline-sm text-[15px] leading-tight text-on-surface font-semibold">Unlimited Cloudflare R2 Sync</span>
|
||||
<span class="font-body-md text-[13px] text-on-surface-variant leading-snug">Automatic cloud replication for all Drift SQLite telemetry bundles.</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Plan Selection Cards -->
|
||||
<div class="flex flex-col gap-space-sm pt-space-xs" id="planSelector">
|
||||
<!-- Tier 1: Annual Plan (Selected by Default) -->
|
||||
<div class="relative rounded-xl p-space-md bg-surface-container-high transition-all cursor-pointer shadow-lg" id="annualCard">
|
||||
<!-- Floating Value Badge -->
|
||||
<div class="absolute -top-3 right-4 px-2.5 py-0.5 rounded-full bg-primary-container text-on-primary-container font-label-data text-label-data font-bold shadow-[0_0_8px_rgba(0,229,255,0.6)]">
|
||||
SAVE 33% • POPULAR
|
||||
</div>
|
||||
<div class="flex items-start justify-between gap-space-sm">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="w-6 h-6 rounded-full bg-primary-container flex items-center justify-center text-on-primary-container shadow-sm" id="annualRadio">
|
||||
<span class="material-symbols-outlined text-[16px] font-bold">check</span>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<span class="font-headline-sm text-[17px] text-on-surface font-bold">Annual Founder Pass</span>
|
||||
<span class="font-body-md text-[12px] text-primary-fixed">14-day free trial included, cancel anytime</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col items-end">
|
||||
<span class="font-telemetry-metric-md text-[22px] leading-none text-on-surface font-bold">$79.99<span class="text-[12px] font-normal text-on-surface-variant">/yr</span></span>
|
||||
<span class="font-label-data text-label-data text-on-surface-variant mt-0.5">$6.67 / mo</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Tier 2: Monthly Plan -->
|
||||
<div class="relative rounded-xl p-space-md bg-surface-container-low transition-all cursor-pointer shadow-md" id="monthlyCard">
|
||||
<div class="flex items-start justify-between gap-space-sm">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="w-6 h-6 rounded-full bg-surface-container-highest flex items-center justify-center text-transparent" id="monthlyRadio">
|
||||
<span class="material-symbols-outlined text-[16px] font-bold">check</span>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<span class="font-headline-sm text-[17px] text-on-surface font-bold">Monthly Flexible</span>
|
||||
<span class="font-body-md text-[12px] text-on-surface-variant">Standard recurring billing</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col items-end">
|
||||
<span class="font-telemetry-metric-md text-[22px] leading-none text-on-surface font-bold">$9.99<span class="text-[12px] font-normal text-on-surface-variant">/mo</span></span>
|
||||
<span class="font-label-data text-label-data text-on-surface-variant mt-0.5">Renews monthly</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Guarantee & Trust Pill -->
|
||||
<div class="flex items-center justify-center gap-2 py-2 px-3 rounded-full bg-surface-container-low mx-auto">
|
||||
<span class="material-symbols-outlined text-[16px] text-primary-container">verified_user</span>
|
||||
<span class="font-label-data text-label-data text-on-surface">14-Day Money-Back Guarantee • Zero Risk</span>
|
||||
</div>
|
||||
<!-- Glove-Friendly CTA Section -->
|
||||
<div class="flex flex-col gap-space-xs pt-space-xs">
|
||||
<button class="w-full min-h-[56px] rounded-xl bg-primary-container text-on-primary-container flex items-center justify-center gap-2 font-telemetry-metric-md text-[16px] font-bold uppercase tracking-wider shadow-[0_0_20px_rgba(0,229,255,0.4)] active:scale-[0.98] transition-transform" id="ctaBtn" type="button">
|
||||
<span>START 14-DAY FREE TRIAL</span>
|
||||
<span class="material-symbols-outlined text-[20px]">bolt</span>
|
||||
</button>
|
||||
<span class="font-label-caption text-label-caption text-center text-on-surface-variant" id="ctaSubtext">
|
||||
Renews at $79.99/yr after 14-day trial. Cancel in 1 tap.
|
||||
</span>
|
||||
</div>
|
||||
<!-- Footer Links -->
|
||||
<div class="flex items-center justify-center gap-space-md pt-space-sm pb-space-md">
|
||||
<button class="min-h-[48px] px-2 flex items-center font-label-data text-[11px] text-on-surface-variant hover:text-primary-container transition-colors uppercase tracking-wider" type="button">
|
||||
Restore Purchases
|
||||
</button>
|
||||
<span class="w-1 h-1 rounded-full bg-surface-variant"></span>
|
||||
<button class="min-h-[48px] px-2 flex items-center font-label-data text-[11px] text-on-surface-variant hover:text-primary-container transition-colors uppercase tracking-wider" type="button">
|
||||
Terms of Service
|
||||
</button>
|
||||
<span class="w-1 h-1 rounded-full bg-surface-variant"></span>
|
||||
<button class="min-h-[48px] px-2 flex items-center font-label-data text-[11px] text-on-surface-variant hover:text-primary-container transition-colors uppercase tracking-wider" type="button">
|
||||
Privacy Policy
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
(function initPaywall() {
|
||||
const annualCard = document.getElementById('annualCard');
|
||||
const monthlyCard = document.getElementById('monthlyCard');
|
||||
const annualRadio = document.getElementById('annualRadio');
|
||||
const monthlyRadio = document.getElementById('monthlyRadio');
|
||||
const ctaBtn = document.getElementById('ctaBtn');
|
||||
const ctaSubtext = document.getElementById('ctaSubtext');
|
||||
|
||||
let currentPlan = 'annual';
|
||||
|
||||
function setPlan(plan) {
|
||||
currentPlan = plan;
|
||||
if (plan === 'annual') {
|
||||
annualCard.classList.remove('bg-surface-container-low');
|
||||
annualCard.classList.add('bg-surface-container-high', 'shadow-lg');
|
||||
annualRadio.className = 'w-6 h-6 rounded-full bg-primary-container flex items-center justify-center text-on-primary-container shadow-sm';
|
||||
|
||||
monthlyCard.classList.remove('bg-surface-container-high', 'shadow-lg');
|
||||
monthlyCard.classList.add('bg-surface-container-low');
|
||||
monthlyRadio.className = 'w-6 h-6 rounded-full bg-surface-container-highest flex items-center justify-center text-transparent';
|
||||
|
||||
ctaBtn.innerHTML = '<span>START 14-DAY FREE TRIAL</span><span class="material-symbols-outlined text-[20px]">bolt</span>';
|
||||
ctaSubtext.textContent = 'Renews at $79.99/yr after 14-day trial. Cancel in 1 tap.';
|
||||
} else {
|
||||
monthlyCard.classList.remove('bg-surface-container-low');
|
||||
monthlyCard.classList.add('bg-surface-container-high', 'shadow-lg');
|
||||
monthlyRadio.className = 'w-6 h-6 rounded-full bg-primary-container flex items-center justify-center text-on-primary-container shadow-sm';
|
||||
|
||||
annualCard.classList.remove('bg-surface-container-high', 'shadow-lg');
|
||||
annualCard.classList.add('bg-surface-container-low');
|
||||
annualRadio.className = 'w-6 h-6 rounded-full bg-surface-container-highest flex items-center justify-center text-transparent';
|
||||
|
||||
ctaBtn.innerHTML = '<span>UPGRADE FOR $9.99 / MO</span><span class="material-symbols-outlined text-[20px]">bolt</span>';
|
||||
ctaSubtext.textContent = 'Billed monthly. Cancel anytime before next billing cycle.';
|
||||
}
|
||||
}
|
||||
|
||||
annualCard.addEventListener('click', () => setPlan('annual'));
|
||||
monthlyCard.addEventListener('click', () => setPlan('monthly'));
|
||||
})();
|
||||
</script></main><nav class="fixed bottom-0 w-full z-50 pb-safe bg-surface-container-lowest/90 backdrop-blur-xl shadow-[0_-4px_24px_rgba(0,0,0,0.6)]" data-active-classes="text-primary-container font-headline-sm [filter:drop-shadow(0_0_8px_rgba(0,229,255,0.5))]"><div class="grid grid-cols-6 items-center h-20 px-space-xs"><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="cockpit-dash" href="#"><span class="material-symbols-outlined text-[24px]">speed</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Dash</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="tactical-radar-map" href="#"><span class="material-symbols-outlined text-[24px]">radar</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Map</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="telemetry-log" href="#"><span class="material-symbols-outlined text-[24px]">monitoring</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Activity</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="bike-garage" href="#"><span class="material-symbols-outlined text-[24px]">two_wheeler</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Garage</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="pack-comms" href="#"><span class="material-symbols-outlined text-[24px]">groups_3</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Social</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="hud-settings" href="#"><span class="material-symbols-outlined text-[24px]">tune</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Settings</span></a></div></nav></body></html>
|
||||
|
|
@ -0,0 +1,346 @@
|
|||
<!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, viewport-fit=cover" name="viewport"/><meta content="mobile_tab" name="shell-type"/><title>MotorSignal Cockpit HUD</title><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&family=JetBrains+Mono:wght@500;600;700&family=Space+Grotesk:wght@600;700&display=swap" rel="stylesheet"/><link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/><style>@layer base{html,body{width:100%;margin:0;padding:0;background-color:#101419;color:#e0e2ea;}body{overscroll-behavior:none;}.pb-safe{padding-bottom:env(safe-area-inset-bottom,0px);}.pt-safe{padding-top:env(safe-area-inset-top,0px);}main>:first-child{margin-top:0!important;}main>:last-child{margin-bottom:0!important;}}::-webkit-scrollbar{display:none;}</style><script src="https://cdn.tailwindcss.com"></script><script id="tailwind-config">tailwind.config = { darkMode: "class", theme: { extend: { "colors": { "on-primary": "#00363d", "tertiary-fixed-dim": "#d0bcff", "tertiary-container": "#d9c8ff", "on-primary-container": "#00626e", "surface-variant": "#32353b", "on-primary-fixed-variant": "#004f58", "surface-container-high": "#272a30", "outline-variant": "#3b494c", "surface-container": "#1d2025", "on-surface": "#e0e2ea", "background": "#101419", "primary-container": "#00e5ff", "inverse-surface": "#e0e2ea", "outline": "#849396", "on-secondary": "#002a78", "secondary-fixed-dim": "#b4c5ff", "on-tertiary": "#3c0091", "inverse-primary": "#006875", "surface-bright": "#36393f", "surface-container-low": "#181c21", "surface-container-highest": "#32353b", "inverse-on-surface": "#2d3036", "on-secondary-fixed": "#00174b", "primary": "#c3f5ff", "error-container": "#93000a", "surface-tint": "#00daf3", "on-tertiary-fixed-variant": "#5516be", "on-error-container": "#ffdad6", "primary-fixed-dim": "#00daf3", "tertiary-fixed": "#e9ddff", "on-primary-fixed": "#001f24", "on-error": "#690005", "surface-container-lowest": "#0b0e13", "secondary-container": "#0053db", "tertiary": "#f2e9ff", "surface-dim": "#101419", "on-surface-variant": "#bac9cc", "on-tertiary-container": "#6834d1", "primary-fixed": "#9cf0ff", "secondary-fixed": "#dbe1ff", "error": "#ffb4ab", "on-secondary-container": "#cdd7ff", "on-secondary-fixed-variant": "#003ea8", "surface": "#101419", "on-background": "#e0e2ea", "secondary": "#b4c5ff", "on-tertiary-fixed": "#23005c" }, "borderRadius": { "DEFAULT": "0.25rem", "lg": "0.5rem", "xl": "0.75rem", "full": "9999px" }, "spacing": { "margin-lg": "2rem", "space-xs": "0.25rem", "gutter-lg": "1.5rem", "space-xl": "2rem", "margin": "1rem", "space-sm": "0.5rem", "space-md": "1rem", "space-lg": "1.5rem", "gutter": "1rem" }, "fontFamily": { "headline-lg": ["Space Grotesk"], "body-lg": ["Inter"], "telemetry-metric-lg-mobile": ["JetBrains Mono"], "label-data": ["JetBrains Mono"], "display-hero": ["Space Grotesk"], "headline-sm": ["Space Grotesk"], "headline-md": ["Space Grotesk"], "label-caption": ["Inter"], "telemetry-metric-lg": ["JetBrains Mono"], "display-hero-mobile": ["Space Grotesk"], "telemetry-metric-md": ["JetBrains Mono"], "body-md": ["Inter"] }, "fontSize": { "headline-lg": ["32px", { "lineHeight": "40px", "letterSpacing": "-0.02em", "fontWeight": "700" }], "body-lg": ["16px", { "lineHeight": "24px", "fontWeight": "500" }], "telemetry-metric-lg-mobile": ["36px", { "lineHeight": "36px", "letterSpacing": "-0.03em", "fontWeight": "700" }], "label-data": ["12px", { "lineHeight": "16px", "letterSpacing": "0.08em", "fontWeight": "600" }], "display-hero": ["56px", { "lineHeight": "60px", "letterSpacing": "-0.03em", "fontWeight": "700" }], "headline-sm": ["20px", { "lineHeight": "28px", "fontWeight": "600" }], "headline-md": ["24px", { "lineHeight": "32px", "letterSpacing": "-0.01em", "fontWeight": "600" }], "label-caption": ["11px", { "lineHeight": "14px", "letterSpacing": "0.05em", "fontWeight": "600" }], "telemetry-metric-lg": ["48px", { "lineHeight": "48px", "letterSpacing": "-0.04em", "fontWeight": "700" }], "display-hero-mobile": ["40px", { "lineHeight": "44px", "letterSpacing": "-0.02em", "fontWeight": "700" }], "telemetry-metric-md": ["28px", { "lineHeight": "32px", "letterSpacing": "-0.02em", "fontWeight": "600" }], "body-md": ["14px", { "lineHeight": "20px", "fontWeight": "400" }] } } } }</script><style>
|
||||
body {
|
||||
min-height: max(884px, 100dvh);
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
body {
|
||||
min-height: max(884px, 100dvh);
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
body {
|
||||
min-height: max(884px, 100dvh);
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
body {
|
||||
min-height: max(884px, 100dvh);
|
||||
}
|
||||
</style>
|
||||
</head><body class="bg-surface font-body-md text-on-surface antialiased flex flex-col min-h-screen selection:bg-primary-container selection:text-on-primary-container"><header class="fixed top-0 w-full z-50 pt-safe bg-surface-container-lowest/85 backdrop-blur-xl shadow-[0_4px_20px_rgba(0,0,0,0.5)]"><div class="h-16 px-space-md flex items-center justify-between gap-space-sm"><div class="flex items-center gap-space-sm"><img alt="MotorSignal Brand Logo" class="h-8 w-auto object-contain drop-shadow-[0_0_8px_rgba(0,229,255,0.4)]" src="https://lh3.googleusercontent.com/aida/AEtjO1Vf56Tkh6bJ86BCfT5GHz_yPumvEXYLWojlNHAFG-cN4VvH_nLvEbWQ4x7uhJPRaAyO8ozAAbLI_huEN134QOIYp8BdHuqoZCsMk9_ILaUxZqilVgamefO6d2sG1R8laIWSUswanVsK9lfvIgppQm_XxBQipzkDgPwIoXk7yh10QTlmZqDICryF-1MoWFfFjM2zZswr6ynuAgZAviROYnFBF2D4hxm6YREQxkZQJaBcG9oAg_dYVgTHxwg"/><div class="flex flex-col"><span class="font-headline-sm text-headline-sm uppercase tracking-wider text-primary-fixed">MotorSignal</span><span class="font-label-caption text-label-caption text-on-surface-variant uppercase tracking-widest leading-none">Telemetry Log</span></div></div><div class="flex items-center gap-space-sm"><div class="hidden sm:flex items-center gap-space-xs bg-surface-container-low px-space-sm py-1 rounded-full"><span class="w-2 h-2 rounded-full bg-primary-container animate-pulse shadow-[0_0_6px_#00e5ff]"></span><span class="font-label-data text-label-data text-primary-fixed">GPS 3D FIX</span></div><div class="flex items-center gap-1.5 bg-surface-container px-2 py-1 rounded-full"><span class="material-symbols-outlined text-[15px] text-primary-container">bolt</span><span class="font-label-data text-label-data text-on-surface">98%</span><span class="w-1 h-1 rounded-full bg-outline-variant"></span><span class="material-symbols-outlined text-[15px] text-primary-container">cell_tower</span></div><button aria-label="Rider Profile" class="min-w-[44px] min-h-[44px] flex items-center justify-center p-1 rounded-full focus:outline-none focus:ring-2 focus:ring-primary-container" type="button"><img alt="Profile" class="w-8 h-8 rounded-full object-cover ring-2 ring-primary-container/40" src="https://lh3.googleusercontent.com/aida-public/AB6AXuBb6sR8Ta8-L1_TN1LuCBfSxtZxX9hKOFjd-RjllihDsnp6AG1GlMhL9bVlb-ibhIRT3HMw_caXK7BmwmvWKNBcuizyqswUQZNztavckRTN1Xa6qGML_0kv8qvV_hrXWWK1EjSjVFzhRyDzf6VdGnZvUpGsFFmSBcaGVrXmEWFYnIa-qHyeWxZlT_SJmPuQJPQKEWEo6vC6kdDzXNnhoB4tpRHjIjCstvTdooPc0KVN_x3BqqmqadNI"/></button></div></div></header><main class="flex-1 flex flex-col relative w-full pt-16 pb-20 bg-surface"><div class="flex flex-col w-full text-on-surface select-none pb-8">
|
||||
<!-- Subheader / Session Header Bar -->
|
||||
<div class="flex flex-col bg-surface-container-lowest px-space-md py-space-sm shadow-md">
|
||||
<div class="flex items-center justify-between gap-space-sm mb-1.5">
|
||||
<button aria-label="Back to Activity" class="min-w-[48px] min-h-[48px] flex items-center justify-center -ml-2 rounded-full text-on-surface-variant hover:text-primary active:bg-surface-container-high transition-colors" type="button">
|
||||
<span class="material-symbols-outlined text-[24px]">arrow_back</span>
|
||||
</button>
|
||||
<div class="flex-1 min-w-0 pr-1">
|
||||
<h1 class="font-headline-sm text-headline-sm text-primary tracking-tight truncate">Saturday Morning Canyon Carve</h1>
|
||||
<p class="font-label-caption text-label-caption text-on-surface-variant truncate">Oct 14 • 8:42 AM • Yamaha MT-09 SP</p>
|
||||
</div>
|
||||
<div class="flex items-center gap-1.5 bg-surface-container-high px-2.5 py-1 rounded-full shadow-sm">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-primary-container animate-ping"></span>
|
||||
<span class="font-label-data text-[10px] tracking-wider text-primary-fixed uppercase font-semibold">20Hz KALMAN SYNCED</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Route Heatmap Map Panel (Tactical Topography & Lean Telemetry) -->
|
||||
<div class="relative w-full h-72 bg-surface-container-lowest overflow-hidden">
|
||||
<!-- Map Background Simulation -->
|
||||
<div class="absolute inset-0 w-full h-full bg-cover bg-center opacity-45 mix-blend-luminosity filter brightness-75 contrast-125" data-location="Saratoga Gap, California" style="background-image: url('https://lh3.googleusercontent.com/aida-public/AB6AXuDpTtE2Qk3FahdLwcBkIMaRhrwjtRLSGgA0F4QmY7dl0cFHGIJHwF31JUxf8YpXFnw2RMGsuzxcz3xXIj4CNDKYkP_AGKnA5mNJt9u_Ij80IFmiEHPr8TR3mD4FoBx2KeJiEQr27yreYI5p7H03rkl2Ah9r-QEcloVKbC8OZV2fVvh3scM52yC_TUY8B_wQcS0b1Qhll0Mi52-bUV2vWeqXj-fMveZPlI5bZfERtUYNhyvKWcj654W4');"></div>
|
||||
<!-- Dark Tactical Topography HUD Grid Overlay -->
|
||||
<div class="absolute inset-0 bg-gradient-to-b from-surface-container-lowest/80 via-transparent to-surface-container-lowest pointer-events-none"></div>
|
||||
<!-- Vector Route Polyline with Dynamic Lean Colors -->
|
||||
<svg class="absolute inset-0 w-full h-full pointer-events-none" fill="none" viewbox="0 0 400 288">
|
||||
<!-- Reference Coordinate Grids -->
|
||||
<path d="M 0 72 L 400 72 M 0 144 L 400 144 M 0 216 L 400 216" stroke="rgba(255,255,255,0.04)" stroke-dasharray="4 6" stroke-width="1"></path>
|
||||
<path d="M 100 0 L 100 288 M 200 0 L 200 288 M 300 0 L 300 288" stroke="rgba(255,255,255,0.04)" stroke-dasharray="4 6" stroke-width="1"></path>
|
||||
<!-- Ghost Path / Underglow -->
|
||||
<path d="M 28 245 C 72 230, 95 190, 130 185 C 160 180, 178 220, 205 210 C 235 198, 240 140, 268 110 C 285 92, 310 95, 335 60 C 352 35, 375 42, 390 30" filter="blur(4px)" opacity="0.15" stroke="#00e5ff" stroke-linecap="round" stroke-linejoin="round" stroke-width="8"></path>
|
||||
<!-- Path Segment 1: Low Lean (<25°) Cyan -->
|
||||
<path d="M 28 245 C 72 230, 95 190, 130 185" stroke="#00e5ff" stroke-linecap="round" stroke-width="4.5"></path>
|
||||
<!-- Path Segment 2: Moderate Lean (25°-42°) Amber/Yellow -->
|
||||
<path d="M 130 185 C 160 180, 178 220, 205 210" stroke="#f59e0b" stroke-linecap="round" stroke-width="4.5"></path>
|
||||
<!-- Path Segment 3: Extreme Apex Lean (49°) Strobe Red -->
|
||||
<path d="M 205 210 C 235 198, 240 140, 268 110" filter="drop-shadow(0 0 6px #ef4444)" id="apex-segment" stroke="#ef4444" stroke-linecap="round" stroke-width="5"></path>
|
||||
<!-- Path Segment 4: Fast Transition back to moderate and straight -->
|
||||
<path d="M 268 110 C 285 92, 310 95, 335 60" stroke="#f59e0b" stroke-linecap="round" stroke-width="4.5"></path>
|
||||
<path d="M 335 60 C 352 35, 375 42, 390 30" stroke="#00e5ff" stroke-linecap="round" stroke-width="4.5"></path>
|
||||
<!-- Apex Radar Pin Target (Turn 7) -->
|
||||
<circle class="animate-ping" cx="244" cy="148" fill="#ef4444" fill-opacity="0.2" r="14"></circle>
|
||||
<circle cx="244" cy="148" fill="#ef4444" filter="drop-shadow(0 0 8px #ef4444)" r="6" stroke="#ffffff" stroke-width="2"></circle>
|
||||
<line stroke="#ef4444" stroke-dasharray="2 2" stroke-width="1.5" x1="244" x2="275" y1="148" y2="175"></line>
|
||||
</svg>
|
||||
<!-- Top Left Mini HUD Card -->
|
||||
<div class="absolute top-3 left-3 bg-surface-container-lowest/90 backdrop-blur-md px-3 py-2 rounded-lg shadow-lg flex flex-col gap-0.5">
|
||||
<div class="flex items-center gap-1.5">
|
||||
<span class="w-2 h-2 rounded-full bg-error animate-pulse shadow-[0_0_8px_#ef4444]"></span>
|
||||
<span class="font-headline-sm text-xs text-error font-bold uppercase tracking-wider">Apex #7: Saratoga Gap</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-2 font-label-data text-label-caption text-on-surface-variant">
|
||||
<span>ELEV: 2,420 FT</span>
|
||||
<span class="text-outline">•</span>
|
||||
<span class="text-primary-fixed">LAT: 37.26° N</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Top Right Lean Legend -->
|
||||
<div class="absolute top-3 right-3 bg-surface-container-lowest/90 backdrop-blur-md px-2.5 py-1.5 rounded-lg flex flex-col gap-1 shadow-lg">
|
||||
<div class="flex items-center gap-1.5">
|
||||
<span class="w-2 h-2 rounded-full bg-primary-container"></span>
|
||||
<span class="font-label-caption text-[10px] text-on-surface-variant"><25° Flow</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-1.5">
|
||||
<span class="w-2 h-2 rounded-full bg-amber-400"></span>
|
||||
<span class="font-label-caption text-[10px] text-on-surface-variant">25°-42° Arc</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-1.5">
|
||||
<span class="w-2 h-2 rounded-full bg-error"></span>
|
||||
<span class="font-label-caption text-[10px] text-error font-semibold">49° Peak Apex</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Active Pin Badge Floater -->
|
||||
<div class="absolute top-[170px] left-[248px] bg-error-container text-on-error-container font-label-data text-[10px] px-2 py-0.5 rounded shadow-[0_0_12px_rgba(239,68,68,0.5)] font-bold">
|
||||
49° R @ 44 MPH
|
||||
</div>
|
||||
</div>
|
||||
<!-- Synchronous Telemetry Scrubbing Controller -->
|
||||
<div class="bg-surface-container-low px-space-md py-space-sm flex flex-col gap-2.5 shadow-md">
|
||||
<!-- Timeline Slider & Time readout -->
|
||||
<div class="flex flex-col gap-1">
|
||||
<div class="flex justify-between items-center font-label-data text-label-caption">
|
||||
<div class="flex items-center gap-1.5 text-primary-fixed">
|
||||
<span class="material-symbols-outlined text-[14px]">timer</span>
|
||||
<span class="text-primary-container font-bold">00:34:12.4</span>
|
||||
</div>
|
||||
<span class="text-on-surface-variant">01:42:00.0 (T+33.5%)</span>
|
||||
</div>
|
||||
<!-- Scrubber Track & Interactive Slider Thumb -->
|
||||
<div class="relative w-full h-8 flex items-center cursor-pointer group">
|
||||
<div class="w-full h-2 bg-surface-container-highest rounded-full overflow-hidden relative">
|
||||
<!-- Buffered / Traversed distance -->
|
||||
<div class="absolute left-0 top-0 bottom-0 w-[33.5%] bg-gradient-to-r from-primary-fixed-dim to-primary-container rounded-full shadow-[0_0_8px_rgba(0,229,255,0.6)]"></div>
|
||||
<!-- Apex marker pins on scrubber bar -->
|
||||
<div class="absolute left-[18%] top-0 bottom-0 w-1 bg-amber-400"></div>
|
||||
<div class="absolute left-[33.5%] top-0 bottom-0 w-1.5 bg-error animate-pulse shadow-[0_0_6px_#ef4444]"></div>
|
||||
<div class="absolute left-[54%] top-0 bottom-0 w-1 bg-amber-400"></div>
|
||||
<div class="absolute left-[78%] top-0 bottom-0 w-1 bg-amber-400"></div>
|
||||
</div>
|
||||
<!-- Handle Thumb -->
|
||||
<div class="absolute left-[33.5%] -translate-x-1/2 w-6 h-6 bg-primary-container rounded-full flex items-center justify-center shadow-[0_0_14px_rgba(0,229,255,0.8)] border-2 border-surface-container-lowest">
|
||||
<div class="w-2 h-2 rounded-full bg-on-primary-container"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Scrub Transport Controls -->
|
||||
<div class="flex items-center justify-between gap-space-sm pt-0.5">
|
||||
<!-- Speed selector toggle -->
|
||||
<div class="flex items-center bg-surface-container-highest rounded-lg p-0.5">
|
||||
<button class="min-w-[44px] h-[38px] px-2 font-label-data text-[11px] rounded text-on-surface-variant hover:text-primary active:bg-surface-container" type="button">0.5x</button>
|
||||
<button class="min-w-[44px] h-[38px] px-2 font-label-data text-[11px] rounded bg-primary-container text-on-primary-container font-bold shadow-sm" type="button">1.0x</button>
|
||||
<button class="min-w-[44px] h-[38px] px-2 font-label-data text-[11px] rounded text-on-surface-variant hover:text-primary active:bg-surface-container" type="button">2.0x</button>
|
||||
</div>
|
||||
<!-- Playback Jump Actions -->
|
||||
<div class="flex items-center gap-space-sm">
|
||||
<button aria-label="Rewind 10 Seconds" class="min-w-[48px] min-h-[48px] flex items-center justify-center rounded-xl bg-surface-container text-on-surface hover:text-primary active:scale-95 transition-all shadow-sm" type="button">
|
||||
<span class="material-symbols-outlined text-[22px]">replay_10</span>
|
||||
</button>
|
||||
<button aria-label="Play Telemetry Replay" class="min-w-[54px] min-h-[52px] px-4 flex items-center justify-center rounded-xl bg-primary-container text-on-primary-container hover:bg-primary-fixed active:scale-95 shadow-[0_0_18px_rgba(0,229,255,0.45)] transition-all" type="button">
|
||||
<span class="material-symbols-outlined text-[28px]" style="font-variation-settings: 'FILL' 1;">pause</span>
|
||||
</button>
|
||||
<button aria-label="Forward 10 Seconds" class="min-w-[48px] min-h-[48px] flex items-center justify-center rounded-xl bg-surface-container text-on-surface hover:text-primary active:scale-95 transition-all shadow-sm" type="button">
|
||||
<span class="material-symbols-outlined text-[22px]">forward_10</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Synchronous Live Gauges at Scrubber Point -->
|
||||
<div class="px-space-md py-space-md flex flex-col gap-space-sm">
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="font-label-data text-label-data text-on-surface-variant uppercase tracking-wider flex items-center gap-1.5">
|
||||
<span class="material-symbols-outlined text-[16px] text-primary">sensors</span>
|
||||
Instantaneous Telemetry at Turn 7
|
||||
</span>
|
||||
<span class="font-label-data text-[11px] text-primary-fixed bg-surface-container px-2 py-0.5 rounded">CH: IMU-9AXIS</span>
|
||||
</div>
|
||||
<!-- 2-Column Gauge Bento Grid -->
|
||||
<div class="grid grid-cols-2 gap-space-sm">
|
||||
<!-- Speed & Longitudinal G Gauge Card -->
|
||||
<div class="bg-surface-container rounded-xl p-space-sm flex flex-col justify-between shadow-md">
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="font-label-data text-label-caption text-on-surface-variant uppercase">Ground Speed</span>
|
||||
<span class="material-symbols-outlined text-[18px] text-primary-container">speed</span>
|
||||
</div>
|
||||
<div class="flex flex-col my-1">
|
||||
<div class="flex items-baseline gap-1">
|
||||
<span class="font-telemetry-metric-lg-mobile text-telemetry-metric-lg-mobile text-on-surface">54.2</span>
|
||||
<span class="font-label-data text-[12px] text-on-surface-variant uppercase">MPH</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-1.5 mt-1">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-primary-container"></span>
|
||||
<span class="font-label-data text-[11px] text-primary-fixed uppercase font-semibold">+0.42G ACCEL</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Inline Speed History Sparkline -->
|
||||
<div class="h-6 w-full mt-1">
|
||||
<svg class="w-full h-full" preserveaspectratio="none" viewbox="0 0 100 24">
|
||||
<path d="M 0 18 Q 20 22, 40 10 T 70 8 T 100 14" fill="none" stroke="#00e5ff" stroke-linecap="round" stroke-width="2"></path>
|
||||
<circle class="shadow-sm" cx="70" cy="8" fill="#00e5ff" r="3"></circle>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Lean Angle Arc & Warning Card -->
|
||||
<div class="bg-surface-container rounded-xl p-space-sm flex flex-col justify-between shadow-md">
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="font-label-data text-label-caption text-on-surface-variant uppercase">Roll Angle</span>
|
||||
<span class="material-symbols-outlined text-[18px] text-error">screen_rotation_alt</span>
|
||||
</div>
|
||||
<!-- Lean Angle Arc Visualization -->
|
||||
<div class="flex flex-col items-center justify-center my-1 relative">
|
||||
<svg class="w-24 h-14" viewbox="0 0 96 56">
|
||||
<!-- Background Arc (-60° to +60°) -->
|
||||
<path d="M 12 48 A 40 40 0 0 1 84 48" fill="none" stroke="#272a30" stroke-linecap="round" stroke-width="6"></path>
|
||||
<!-- Active Lean Arc (Right Bank 49°) -->
|
||||
<path d="M 48 8 A 40 40 0 0 1 82 44" fill="none" filter="drop-shadow(0 0 4px #ef4444)" stroke="#ef4444" stroke-linecap="round" stroke-width="6"></path>
|
||||
<!-- Center Horizon Marker -->
|
||||
<line stroke="#849396" stroke-width="2" x1="48" x2="48" y1="2" y2="10"></line>
|
||||
<!-- Current Bank Pointer -->
|
||||
<line stroke="#ffffff" stroke-linecap="round" stroke-width="2.5" x1="48" x2="78" y1="48" y2="16"></line>
|
||||
</svg>
|
||||
<div class="flex items-baseline gap-1 -mt-2">
|
||||
<span class="font-telemetry-metric-lg-mobile text-telemetry-metric-lg-mobile text-error font-bold">49°</span>
|
||||
<span class="font-label-data text-[12px] text-error uppercase font-bold">RIGHT</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Warning Pill -->
|
||||
<div class="bg-error-container text-on-error-container rounded px-2 py-1 flex items-center justify-center gap-1 shadow-sm">
|
||||
<span class="material-symbols-outlined text-[14px]">warning</span>
|
||||
<span class="font-label-caption text-[10px] uppercase font-bold tracking-tight">Apex Limit Reached</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Secondary Telemetry Micro-Ribbon -->
|
||||
<div class="grid grid-cols-3 gap-space-xs bg-surface-container-low rounded-lg p-2 font-label-data text-center">
|
||||
<div class="flex flex-col">
|
||||
<span class="text-[10px] text-on-surface-variant">THROTTLE</span>
|
||||
<span class="text-[13px] text-primary-fixed font-bold">84% OPEN</span>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<span class="text-[10px] text-on-surface-variant">FRONT BRAKE</span>
|
||||
<span class="text-[13px] text-on-surface font-bold">0.0 BAR</span>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<span class="text-[10px] text-on-surface-variant">TIRE GRIP</span>
|
||||
<span class="text-[13px] text-error font-bold">0.88 µ</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Corner-by-Corner Apex Breakdown Table -->
|
||||
<div class="px-space-md py-space-sm flex flex-col gap-space-sm">
|
||||
<div class="flex items-center justify-between">
|
||||
<h2 class="font-headline-sm text-headline-sm text-on-surface">Apex Telemetry Breakdown</h2>
|
||||
<span class="font-label-data text-[11px] text-primary-container bg-surface-container-high px-2 py-0.5 rounded-full font-semibold">42 Corners Logged</span>
|
||||
</div>
|
||||
<!-- Corner Cards Stack -->
|
||||
<div class="flex flex-col gap-2">
|
||||
<!-- Turn 4 -->
|
||||
<div class="bg-surface-container rounded-xl p-3 flex flex-col gap-2 shadow-sm hover:bg-surface-container-high transition-colors cursor-pointer">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="w-6 h-6 rounded bg-surface-container-highest flex items-center justify-center font-label-data text-xs font-bold text-primary">T4</span>
|
||||
<span class="font-body-lg text-body-lg text-on-surface font-semibold">Skyline Sweeper</span>
|
||||
</div>
|
||||
<span class="font-label-data text-xs text-primary-container font-semibold bg-surface-container-highest px-2 py-0.5 rounded">0.94 µ Grip</span>
|
||||
</div>
|
||||
<div class="grid grid-cols-3 gap-2 bg-surface-container-low rounded-lg p-2 font-label-data">
|
||||
<div class="flex flex-col">
|
||||
<span class="text-[10px] text-on-surface-variant uppercase">Entry Speed</span>
|
||||
<span class="text-xs text-on-surface font-bold">62 MPH</span>
|
||||
</div>
|
||||
<div class="flex flex-col items-center">
|
||||
<span class="text-[10px] text-on-surface-variant uppercase">Apex Lean</span>
|
||||
<span class="text-xs text-amber-400 font-bold flex items-center gap-0.5">
|
||||
42° L <span class="material-symbols-outlined text-[13px]">turn_left</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex flex-col items-end">
|
||||
<span class="text-[10px] text-on-surface-variant uppercase">Exit Speed</span>
|
||||
<span class="text-xs text-primary font-bold">68 MPH</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Turn 7 (Active Inspected Turn) -->
|
||||
<div class="bg-surface-container-high rounded-xl p-3 flex flex-col gap-2 shadow-md relative overflow-hidden">
|
||||
<!-- Selected Indicator Bar -->
|
||||
<div class="absolute left-0 top-0 bottom-0 w-1.5 bg-error shadow-[0_0_8px_#ef4444]"></div>
|
||||
<div class="flex items-center justify-between pl-1">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="w-6 h-6 rounded bg-error-container text-on-error-container flex items-center justify-center font-label-data text-xs font-bold">T7</span>
|
||||
<div class="flex items-center gap-1.5">
|
||||
<span class="font-body-lg text-body-lg text-on-surface font-semibold">Saratoga Hairpin</span>
|
||||
<span class="bg-error/20 text-error font-label-caption text-[9px] px-1.5 py-0.5 rounded uppercase font-bold tracking-wider">MAX APEX</span>
|
||||
</div>
|
||||
</div>
|
||||
<span class="font-label-data text-xs text-error font-bold bg-error-container/40 px-2 py-0.5 rounded">0.88 µ Grip</span>
|
||||
</div>
|
||||
<div class="grid grid-cols-3 gap-2 bg-surface-container-lowest rounded-lg p-2 font-label-data pl-2">
|
||||
<div class="flex flex-col">
|
||||
<span class="text-[10px] text-on-surface-variant uppercase">Entry Speed</span>
|
||||
<span class="text-xs text-on-surface font-bold">44 MPH</span>
|
||||
</div>
|
||||
<div class="flex flex-col items-center">
|
||||
<span class="text-[10px] text-on-surface-variant uppercase">Apex Lean</span>
|
||||
<span class="text-xs text-error font-bold flex items-center gap-0.5">
|
||||
49° R <span class="material-symbols-outlined text-[13px]">turn_right</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex flex-col items-end">
|
||||
<span class="text-[10px] text-on-surface-variant uppercase">Exit Speed</span>
|
||||
<span class="text-xs text-primary-container font-bold">52 MPH</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Turn 12 -->
|
||||
<div class="bg-surface-container rounded-xl p-3 flex flex-col gap-2 shadow-sm hover:bg-surface-container-high transition-colors cursor-pointer">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="w-6 h-6 rounded bg-surface-container-highest flex items-center justify-center font-label-data text-xs font-bold text-primary">T12</span>
|
||||
<span class="font-body-lg text-body-lg text-on-surface font-semibold">Vista Chicane</span>
|
||||
</div>
|
||||
<span class="font-label-data text-xs text-primary-container font-semibold bg-surface-container-highest px-2 py-0.5 rounded">0.91 µ Grip</span>
|
||||
</div>
|
||||
<div class="grid grid-cols-3 gap-2 bg-surface-container-low rounded-lg p-2 font-label-data">
|
||||
<div class="flex flex-col">
|
||||
<span class="text-[10px] text-on-surface-variant uppercase">Entry Speed</span>
|
||||
<span class="text-xs text-on-surface font-bold">58 MPH</span>
|
||||
</div>
|
||||
<div class="flex flex-col items-center">
|
||||
<span class="text-[10px] text-on-surface-variant uppercase">Apex Lean</span>
|
||||
<span class="text-xs text-amber-400 font-bold flex items-center gap-0.5">
|
||||
38° L <span class="material-symbols-outlined text-[13px]">turn_left</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex flex-col items-end">
|
||||
<span class="text-[10px] text-on-surface-variant uppercase">Exit Speed</span>
|
||||
<span class="text-xs text-primary font-bold">61 MPH</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Glove-Friendly Action Dock (Export & Share) -->
|
||||
<div class="px-space-md py-space-md flex flex-col gap-space-sm mt-2">
|
||||
<!-- Dual Quick Export Buttons (52px Glove-Friendly) -->
|
||||
<div class="grid grid-cols-2 gap-space-sm">
|
||||
<button class="min-h-[52px] bg-surface-container hover:bg-surface-container-high text-on-surface active:bg-surface-container-highest font-label-data text-xs rounded-xl flex items-center justify-center gap-2 shadow-sm transition-all" type="button">
|
||||
<span class="material-symbols-outlined text-[20px] text-primary-container">file_download</span>
|
||||
<span>EXPORT GPX</span>
|
||||
</button>
|
||||
<button class="min-h-[52px] bg-surface-container hover:bg-surface-container-high text-on-surface active:bg-surface-container-highest font-label-data text-xs rounded-xl flex items-center justify-center gap-2 shadow-sm transition-all" type="button">
|
||||
<span class="material-symbols-outlined text-[20px] text-primary-container">table_chart</span>
|
||||
<span>20Hz FORENSIC CSV</span>
|
||||
</button>
|
||||
</div>
|
||||
<!-- Primary Social / Telemetry Card Share Trigger -->
|
||||
<button class="min-h-[52px] w-full bg-primary-container text-on-primary-container hover:bg-primary-fixed active:scale-[0.99] font-label-data text-xs font-bold rounded-xl flex items-center justify-center gap-2 shadow-[0_0_16px_rgba(0,229,255,0.35)] transition-all" type="button">
|
||||
<span class="material-symbols-outlined text-[20px]" style="font-variation-settings: 'FILL' 1;">share</span>
|
||||
<span>SHARE APEX TELEMETRY TO SOCIAL</span>
|
||||
</button>
|
||||
</div>
|
||||
</div></main><nav class="fixed bottom-0 w-full z-50 pb-safe bg-surface-container-lowest/90 backdrop-blur-xl shadow-[0_-4px_24px_rgba(0,0,0,0.6)]" data-active-classes="text-primary-container font-headline-sm [filter:drop-shadow(0_0_8px_rgba(0,229,255,0.5))]"><div class="grid grid-cols-6 items-center h-20 px-space-xs"><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="cockpit-dash" href="#"><span class="material-symbols-outlined text-[24px]">speed</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Dash</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="tactical-radar-map" href="#"><span class="material-symbols-outlined text-[24px]">radar</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Map</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="telemetry-log" href="#"><span class="material-symbols-outlined text-[24px]">monitoring</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Activity</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="bike-garage" href="#"><span class="material-symbols-outlined text-[24px]">two_wheeler</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Garage</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="pack-comms" href="#"><span class="material-symbols-outlined text-[24px]">groups_3</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Social</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="hud-settings" href="#"><span class="material-symbols-outlined text-[24px]">tune</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Settings</span></a></div></nav></body></html>
|
||||
|
|
@ -0,0 +1,392 @@
|
|||
<!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, viewport-fit=cover" name="viewport"/><meta content="mobile_tab" name="shell-type"/><title>MotorSignal Cockpit HUD</title><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&family=JetBrains+Mono:wght@500;600;700&family=Space+Grotesk:wght@600;700&display=swap" rel="stylesheet"/><link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/><style>@layer base{html,body{width:100%;margin:0;padding:0;background-color:#101419;color:#e0e2ea;}body{overscroll-behavior:none;}.pb-safe{padding-bottom:env(safe-area-inset-bottom,0px);}.pt-safe{padding-top:env(safe-area-inset-top,0px);}main>:first-child{margin-top:0!important;}main>:last-child{margin-bottom:0!important;}}::-webkit-scrollbar{display:none;}</style><script src="https://cdn.tailwindcss.com"></script><script id="tailwind-config">tailwind.config = { darkMode: "class", theme: { extend: { "colors": { "on-primary": "#00363d", "tertiary-fixed-dim": "#d0bcff", "tertiary-container": "#d9c8ff", "on-primary-container": "#00626e", "surface-variant": "#32353b", "on-primary-fixed-variant": "#004f58", "surface-container-high": "#272a30", "outline-variant": "#3b494c", "surface-container": "#1d2025", "on-surface": "#e0e2ea", "background": "#101419", "primary-container": "#00e5ff", "inverse-surface": "#e0e2ea", "outline": "#849396", "on-secondary": "#002a78", "secondary-fixed-dim": "#b4c5ff", "on-tertiary": "#3c0091", "inverse-primary": "#006875", "surface-bright": "#36393f", "surface-container-low": "#181c21", "surface-container-highest": "#32353b", "inverse-on-surface": "#2d3036", "on-secondary-fixed": "#00174b", "primary": "#c3f5ff", "error-container": "#93000a", "surface-tint": "#00daf3", "on-tertiary-fixed-variant": "#5516be", "on-error-container": "#ffdad6", "primary-fixed-dim": "#00daf3", "tertiary-fixed": "#e9ddff", "on-primary-fixed": "#001f24", "on-error": "#690005", "surface-container-lowest": "#0b0e13", "secondary-container": "#0053db", "tertiary": "#f2e9ff", "surface-dim": "#101419", "on-surface-variant": "#bac9cc", "on-tertiary-container": "#6834d1", "primary-fixed": "#9cf0ff", "secondary-fixed": "#dbe1ff", "error": "#ffb4ab", "on-secondary-container": "#cdd7ff", "on-secondary-fixed-variant": "#003ea8", "surface": "#101419", "on-background": "#e0e2ea", "secondary": "#b4c5ff", "on-tertiary-fixed": "#23005c" }, "borderRadius": { "DEFAULT": "0.25rem", "lg": "0.5rem", "xl": "0.75rem", "full": "9999px" }, "spacing": { "margin-lg": "2rem", "space-xs": "0.25rem", "gutter-lg": "1.5rem", "space-xl": "2rem", "margin": "1rem", "space-sm": "0.5rem", "space-md": "1rem", "space-lg": "1.5rem", "gutter": "1rem" }, "fontFamily": { "headline-lg": ["Space Grotesk"], "body-lg": ["Inter"], "telemetry-metric-lg-mobile": ["JetBrains Mono"], "label-data": ["JetBrains Mono"], "display-hero": ["Space Grotesk"], "headline-sm": ["Space Grotesk"], "headline-md": ["Space Grotesk"], "label-caption": ["Inter"], "telemetry-metric-lg": ["JetBrains Mono"], "display-hero-mobile": ["Space Grotesk"], "telemetry-metric-md": ["JetBrains Mono"], "body-md": ["Inter"] }, "fontSize": { "headline-lg": ["32px", { "lineHeight": "40px", "letterSpacing": "-0.02em", "fontWeight": "700" }], "body-lg": ["16px", { "lineHeight": "24px", "fontWeight": "500" }], "telemetry-metric-lg-mobile": ["36px", { "lineHeight": "36px", "letterSpacing": "-0.03em", "fontWeight": "700" }], "label-data": ["12px", { "lineHeight": "16px", "letterSpacing": "0.08em", "fontWeight": "600" }], "display-hero": ["56px", { "lineHeight": "60px", "letterSpacing": "-0.03em", "fontWeight": "700" }], "headline-sm": ["20px", { "lineHeight": "28px", "fontWeight": "600" }], "headline-md": ["24px", { "lineHeight": "32px", "letterSpacing": "-0.01em", "fontWeight": "600" }], "label-caption": ["11px", { "lineHeight": "14px", "letterSpacing": "0.05em", "fontWeight": "600" }], "telemetry-metric-lg": ["48px", { "lineHeight": "48px", "letterSpacing": "-0.04em", "fontWeight": "700" }], "display-hero-mobile": ["40px", { "lineHeight": "44px", "letterSpacing": "-0.02em", "fontWeight": "700" }], "telemetry-metric-md": ["28px", { "lineHeight": "32px", "letterSpacing": "-0.02em", "fontWeight": "600" }], "body-md": ["14px", { "lineHeight": "20px", "fontWeight": "400" }] } } } }</script><style>
|
||||
body {
|
||||
min-height: max(884px, 100dvh);
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
body {
|
||||
min-height: max(884px, 100dvh);
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
body {
|
||||
min-height: max(884px, 100dvh);
|
||||
}
|
||||
</style>
|
||||
</head><body class="bg-surface font-body-md text-on-surface antialiased flex flex-col min-h-screen selection:bg-primary-container selection:text-on-primary-container"><header class="fixed top-0 w-full z-50 pt-safe bg-surface-container-lowest/85 backdrop-blur-xl shadow-[0_4px_20px_rgba(0,0,0,0.5)]"><div class="h-16 px-space-md flex items-center justify-between gap-space-sm"><div class="flex items-center gap-space-sm"><img alt="MotorSignal Brand Logo" class="h-8 w-auto object-contain drop-shadow-[0_0_8px_rgba(0,229,255,0.4)]" src="https://lh3.googleusercontent.com/aida/AEtjO1Vf56Tkh6bJ86BCfT5GHz_yPumvEXYLWojlNHAFG-cN4VvH_nLvEbWQ4x7uhJPRaAyO8ozAAbLI_huEN134QOIYp8BdHuqoZCsMk9_ILaUxZqilVgamefO6d2sG1R8laIWSUswanVsK9lfvIgppQm_XxBQipzkDgPwIoXk7yh10QTlmZqDICryF-1MoWFfFjM2zZswr6ynuAgZAviROYnFBF2D4hxm6YREQxkZQJaBcG9oAg_dYVgTHxwg"/><div class="flex flex-col"><span class="font-headline-sm text-headline-sm uppercase tracking-wider text-primary-fixed">MotorSignal</span><span class="font-label-caption text-label-caption text-on-surface-variant uppercase tracking-widest leading-none">Telemetry Log</span></div></div><div class="flex items-center gap-space-sm"><div class="hidden sm:flex items-center gap-space-xs bg-surface-container-low px-space-sm py-1 rounded-full"><span class="w-2 h-2 rounded-full bg-primary-container animate-pulse shadow-[0_0_6px_#00e5ff]"></span><span class="font-label-data text-label-data text-primary-fixed">GPS 3D FIX</span></div><div class="flex items-center gap-1.5 bg-surface-container px-2 py-1 rounded-full"><span class="material-symbols-outlined text-[15px] text-primary-container">bolt</span><span class="font-label-data text-label-data text-on-surface">98%</span><span class="w-1 h-1 rounded-full bg-outline-variant"></span><span class="material-symbols-outlined text-[15px] text-primary-container">cell_tower</span></div><button aria-label="Rider Profile" class="min-w-[44px] min-h-[44px] flex items-center justify-center p-1 rounded-full focus:outline-none focus:ring-2 focus:ring-primary-container" type="button"><img alt="Profile" class="w-8 h-8 rounded-full object-cover ring-2 ring-primary-container/40" src="https://lh3.googleusercontent.com/aida-public/AB6AXuBb6sR8Ta8-L1_TN1LuCBfSxtZxX9hKOFjd-RjllihDsnp6AG1GlMhL9bVlb-ibhIRT3HMw_caXK7BmwmvWKNBcuizyqswUQZNztavckRTN1Xa6qGML_0kv8qvV_hrXWWK1EjSjVFzhRyDzf6VdGnZvUpGsFFmSBcaGVrXmEWFYnIa-qHyeWxZlT_SJmPuQJPQKEWEo6vC6kdDzXNnhoB4tpRHjIjCstvTdooPc0KVN_x3BqqmqadNI"/></button></div></div></header><main class="flex-1 flex flex-col relative w-full pt-16 pb-20 bg-surface"><div class="flex flex-col w-full px-space-md py-space-sm space-y-space-md select-none">
|
||||
<!-- Sub-Header & Tactical Step Flow -->
|
||||
<div class="flex items-center justify-between gap-space-sm bg-surface-container-low p-space-sm rounded-xl shadow-md">
|
||||
<a aria-label="Back to Garage" class="min-w-[48px] min-h-[48px] flex items-center justify-center bg-surface-container text-on-surface hover:text-primary-container active:scale-95 transition-transform rounded-lg" data-path="bike-garage" href="#">
|
||||
<span class="material-symbols-outlined text-[24px]">arrow_back</span>
|
||||
</a>
|
||||
<div class="flex flex-col items-center text-center flex-1 min-w-0">
|
||||
<span class="font-headline-sm text-headline-sm uppercase tracking-wider text-primary truncate w-full">Add To Stable</span>
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant uppercase tracking-widest">GAR-02 • Unit Commission</span>
|
||||
</div>
|
||||
<div class="flex items-center bg-surface-container px-space-sm py-1.5 rounded-full shadow-sm">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-primary-container animate-ping mr-1.5"></span>
|
||||
<span class="font-label-data text-label-data text-primary-fixed uppercase">Step 1/2</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Live Optical / Barcode VIN Scanner Viewfinder -->
|
||||
<section aria-label="VIN Barcode Scanner" class="flex flex-col bg-surface-container-lowest rounded-xl overflow-hidden shadow-xl">
|
||||
<!-- Camera Viewport Box with Hud Overlays -->
|
||||
<div class="relative w-full h-56 bg-surface-container-lowest flex flex-col justify-between p-space-md overflow-hidden">
|
||||
<!-- Simulated Camera Ambient Feed Background -->
|
||||
<div class="absolute inset-0 bg-gradient-to-b from-surface-container-lowest/80 via-surface-container-high/20 to-surface-container-lowest/90 z-0"></div>
|
||||
<!-- Scan Target Reticle SVG Frame -->
|
||||
<svg class="absolute inset-0 w-full h-full pointer-events-none z-10" preserveaspectratio="none" viewbox="0 0 360 224">
|
||||
<!-- Reticle Corners in Electric Cyan -->
|
||||
<path d="M 28 44 L 28 24 L 56 24" fill="none" stroke="#00e5ff" stroke-linecap="round" stroke-width="3"></path>
|
||||
<path d="M 332 44 L 332 24 L 304 24" fill="none" stroke="#00e5ff" stroke-linecap="round" stroke-width="3"></path>
|
||||
<path d="M 28 180 L 28 200 L 56 200" fill="none" stroke="#00e5ff" stroke-linecap="round" stroke-width="3"></path>
|
||||
<path d="M 332 180 L 332 200 L 304 200" fill="none" stroke="#00e5ff" stroke-linecap="round" stroke-width="3"></path>
|
||||
<!-- Central Target Bracket -->
|
||||
<line stroke="#00e5ff" stroke-opacity="0.8" stroke-width="1.5" x1="172" x2="188" y1="112" y2="112"></line>
|
||||
<line stroke="#00e5ff" stroke-opacity="0.8" stroke-width="1.5" x1="180" x2="180" y1="104" y2="120"></line>
|
||||
</svg>
|
||||
<!-- Laser Scanner Motion Bar -->
|
||||
<div class="absolute left-6 right-6 h-[2px] bg-primary-container shadow-[0_0_12px_#00e5ff] z-10 transition-all duration-75" id="scanner-laser"></div>
|
||||
<!-- Viewfinder Top Bar Overlay -->
|
||||
<div class="relative z-20 flex items-center justify-between">
|
||||
<div class="flex items-center gap-1.5 bg-surface-container-lowest/80 backdrop-blur-md px-2.5 py-1 rounded-full">
|
||||
<span class="w-2 h-2 rounded-full bg-primary-container animate-pulse"></span>
|
||||
<span class="font-label-data text-label-data text-primary uppercase">Optical Engine Active</span>
|
||||
</div>
|
||||
<!-- Flashlight / Torch Toggle -->
|
||||
<button aria-label="Toggle camera torch" class="min-w-[48px] min-h-[48px] flex items-center justify-center bg-surface-container/80 backdrop-blur-md text-on-surface rounded-full active:bg-primary-container active:text-on-primary-container transition-colors shadow-sm" id="torch-toggle" type="button">
|
||||
<span class="material-symbols-outlined text-[20px]" id="torch-icon">flashlight_on</span>
|
||||
</button>
|
||||
</div>
|
||||
<!-- Viewfinder Central Instruction / Alignment Prompt -->
|
||||
<div class="relative z-20 flex flex-col items-center text-center px-space-sm pointer-events-none">
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant uppercase tracking-wider bg-surface-container-lowest/70 px-2 py-0.5 rounded">
|
||||
Align Barcode or Headstock Stamp
|
||||
</span>
|
||||
</div>
|
||||
<!-- Viewfinder Bottom Toolbar -->
|
||||
<div class="relative z-20 flex items-center justify-between gap-space-sm pt-space-xs">
|
||||
<button class="min-h-[48px] px-3.5 flex items-center gap-1.5 bg-surface-container/90 text-on-surface text-label-data font-label-data uppercase rounded-lg active:bg-surface-variant transition-colors" onclick="document.getElementById('manual-vin-input').focus()" type="button">
|
||||
<span class="material-symbols-outlined text-[18px] text-primary">keyboard</span>
|
||||
<span>Manual Input</span>
|
||||
</button>
|
||||
<span class="font-label-data text-label-data text-on-surface-variant uppercase">ISO 3779 / 3780</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Decoded VIN Badge / Tactical Telemetry Strip -->
|
||||
<div class="bg-surface-container-low p-space-sm flex flex-col sm:flex-row sm:items-center justify-between gap-space-sm">
|
||||
<div class="flex items-center gap-2.5 min-w-0">
|
||||
<div class="w-8 h-8 rounded-lg bg-surface-container flex items-center justify-center text-primary-container flex-shrink-0">
|
||||
<span class="material-symbols-outlined text-[20px]">qr_code_scanner</span>
|
||||
</div>
|
||||
<div class="flex flex-col min-w-0">
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant uppercase tracking-widest">Decoded Vehicle Tag</span>
|
||||
<span class="font-label-data text-label-data text-primary-fixed truncate">ZDM14BKW7PB003921</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-2 self-start sm:self-auto bg-surface-container px-2.5 py-1.5 rounded-lg flex-shrink-0">
|
||||
<span class="material-symbols-outlined text-[16px] text-primary-container">verified</span>
|
||||
<span class="font-label-data text-label-data text-on-surface uppercase font-bold">2024 DUCATI CORSE</span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- Motorcycle Specification Section -->
|
||||
<section aria-label="Vehicle Specs" class="flex flex-col bg-surface-container-low p-space-md rounded-xl space-y-space-md shadow-md">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-primary-container text-[20px]">sports_motorsports</span>
|
||||
<span class="font-headline-sm text-headline-sm text-on-surface uppercase tracking-wide">Vehicle Specifications</span>
|
||||
</div>
|
||||
<span class="font-label-data text-label-data text-on-surface-variant uppercase">Spec Matrix</span>
|
||||
</div>
|
||||
<!-- Category Selector Pills (Glove-Optimized 48px Touch targets) -->
|
||||
<div class="flex flex-col space-y-1.5">
|
||||
<label class="font-label-caption text-label-caption uppercase tracking-wider text-on-surface-variant">Vehicle Class Profile</label>
|
||||
<div aria-label="Chassis Configuration" class="grid grid-cols-2 gap-2" role="radiogroup">
|
||||
<button aria-checked="true" class="cat-pill min-h-[48px] px-3 flex items-center justify-center gap-2 bg-primary-container text-on-primary-container font-label-data text-label-data uppercase rounded-lg shadow-sm font-bold transition-all" role="radio" type="button">
|
||||
<span class="material-symbols-outlined text-[18px]">electric_bolt</span>
|
||||
<span>Sport / Track</span>
|
||||
</button>
|
||||
<button aria-checked="false" class="cat-pill min-h-[48px] px-3 flex items-center justify-center gap-2 bg-surface-container text-on-surface font-label-data text-label-data uppercase rounded-lg transition-all active:bg-surface-variant" role="radio" type="button">
|
||||
<span class="material-symbols-outlined text-[18px]">two_wheeler</span>
|
||||
<span>Naked / Hyper</span>
|
||||
</button>
|
||||
<button aria-checked="false" class="cat-pill min-h-[48px] px-3 flex items-center justify-center gap-2 bg-surface-container text-on-surface font-label-data text-label-data uppercase rounded-lg transition-all active:bg-surface-variant" role="radio" type="button">
|
||||
<span class="material-symbols-outlined text-[18px]">terrain</span>
|
||||
<span>Dual / ADV</span>
|
||||
</button>
|
||||
<button aria-checked="false" class="cat-pill min-h-[48px] px-3 flex items-center justify-center gap-2 bg-surface-container text-on-surface font-label-data text-label-data uppercase rounded-lg transition-all active:bg-surface-variant" role="radio" type="button">
|
||||
<span class="material-symbols-outlined text-[18px]">commute</span>
|
||||
<span>Tour / Cruiser</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Vehicle Inputs Grid -->
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 gap-space-sm">
|
||||
<!-- Year Selector -->
|
||||
<div class="flex flex-col space-y-1">
|
||||
<label class="font-label-caption text-label-caption uppercase tracking-wider text-on-surface-variant" for="veh-year">Model Year</label>
|
||||
<div class="relative bg-surface-container rounded-lg">
|
||||
<input class="w-full h-[48px] px-3 bg-transparent text-on-surface font-telemetry-metric-md text-telemetry-metric-md focus:outline-none focus:text-primary" id="veh-year" type="number" value="2024"/>
|
||||
<span class="absolute right-3 top-3 font-label-data text-label-data text-on-surface-variant pointer-events-none">YR</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Make Selector -->
|
||||
<div class="flex flex-col space-y-1">
|
||||
<label class="font-label-caption text-label-caption uppercase tracking-wider text-on-surface-variant" for="veh-make">Manufacturer</label>
|
||||
<div class="relative bg-surface-container rounded-lg">
|
||||
<input class="w-full h-[48px] px-3 bg-transparent text-on-surface font-headline-sm text-headline-sm focus:outline-none focus:text-primary uppercase" id="veh-make" type="text" value="Ducati"/>
|
||||
<span class="material-symbols-outlined absolute right-3 top-3 text-[20px] text-on-surface-variant pointer-events-none">verified_user</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Model Spec -->
|
||||
<div class="flex flex-col space-y-1">
|
||||
<label class="font-label-caption text-label-caption uppercase tracking-wider text-on-surface-variant" for="veh-model">Model Designation</label>
|
||||
<div class="relative bg-surface-container rounded-lg">
|
||||
<input class="w-full h-[48px] px-3 bg-transparent text-on-surface font-body-lg text-body-lg focus:outline-none focus:text-primary font-bold" id="veh-model" type="text" value="Panigale V4 S"/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Trim / Engine Engine -->
|
||||
<div class="flex flex-col space-y-1">
|
||||
<label class="font-label-caption text-label-caption uppercase tracking-wider text-on-surface-variant" for="veh-trim">Trim / Package</label>
|
||||
<div class="relative bg-surface-container rounded-lg">
|
||||
<input class="w-full h-[48px] px-3 bg-transparent text-on-surface font-body-lg text-body-lg focus:outline-none focus:text-primary" id="veh-trim" type="text" value="Desmosedici Stradale SP2"/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Manual VIN fallback field -->
|
||||
<div class="flex flex-col space-y-1 sm:col-span-2">
|
||||
<label class="font-label-caption text-label-caption uppercase tracking-wider text-on-surface-variant" for="manual-vin-input">Chassis VIN Override</label>
|
||||
<div class="relative bg-surface-container rounded-lg">
|
||||
<input class="w-full h-[48px] px-3 bg-transparent text-primary-fixed font-label-data text-label-data uppercase tracking-widest focus:outline-none" id="manual-vin-input" type="text" value="ZDM14BKW7PB003921"/>
|
||||
<button class="absolute right-2 top-2 min-h-[32px] px-2 bg-surface-container-high rounded text-label-caption font-label-caption text-on-surface uppercase flex items-center gap-1 active:bg-primary-container active:text-on-primary-container" type="button">
|
||||
<span class="material-symbols-outlined text-[14px]">refresh</span> Re-verify
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- CAN-Bus & Sensor Link Configuration -->
|
||||
<section aria-label="Telemetry Hardware Pairing" class="flex flex-col bg-surface-container-low p-space-md rounded-xl space-y-space-md shadow-md">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-primary-container text-[20px]">router</span>
|
||||
<span class="font-headline-sm text-headline-sm text-on-surface uppercase tracking-wide">CAN-Bus & Telemetry Hub</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-1 bg-surface-container px-2 py-0.5 rounded-full">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-primary-container"></span>
|
||||
<span class="font-label-caption text-label-caption text-primary">BLE 5.3 Ready</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Protocol Connection Selector -->
|
||||
<div aria-label="Telemetry Interface Source" class="space-y-2" role="radiogroup">
|
||||
<!-- Option 1: Selected OBDLink -->
|
||||
<div aria-checked="true" class="sensor-card flex items-center justify-between p-space-sm bg-surface-container rounded-xl cursor-pointer active:scale-[0.99] transition-transform" role="radio">
|
||||
<div class="flex items-center gap-space-sm min-w-0">
|
||||
<div class="min-w-[48px] min-h-[48px] flex items-center justify-center rounded-lg bg-surface-container-high text-primary-container flex-shrink-0">
|
||||
<span class="material-symbols-outlined text-[24px]">bluetooth</span>
|
||||
</div>
|
||||
<div class="flex flex-col min-w-0">
|
||||
<span class="font-body-lg text-body-lg text-on-surface truncate font-semibold">OBDLink LX / MX+ (BLE)</span>
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant truncate">CAN-D K-Line 500kbps • 50Hz Polling Rate</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-6 h-6 rounded-full bg-primary-container flex items-center justify-center text-on-primary-container flex-shrink-0 ml-2">
|
||||
<span class="material-symbols-outlined text-[16px]">check</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Option 2: Direct CAN Tap -->
|
||||
<div aria-checked="false" class="sensor-card flex items-center justify-between p-space-sm bg-surface-container rounded-xl cursor-pointer opacity-70 hover:opacity-100 transition-opacity" role="radio">
|
||||
<div class="flex items-center gap-space-sm min-w-0">
|
||||
<div class="min-w-[48px] min-h-[48px] flex items-center justify-center rounded-lg bg-surface-container-high text-on-surface-variant flex-shrink-0">
|
||||
<span class="material-symbols-outlined text-[24px]">cable</span>
|
||||
</div>
|
||||
<div class="flex flex-col min-w-0">
|
||||
<span class="font-body-lg text-body-lg text-on-surface truncate font-semibold">CAN D-BUS Direct Hardwire</span>
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant truncate">Isolated Optocoupler • Up to 100Hz Telemetry</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-6 h-6 rounded-full bg-surface-container-high flex items-center justify-center flex-shrink-0 ml-2"></div>
|
||||
</div>
|
||||
<!-- Option 3: Phone IMU Fallback -->
|
||||
<div aria-checked="false" class="sensor-card flex items-center justify-between p-space-sm bg-surface-container rounded-xl cursor-pointer opacity-70 hover:opacity-100 transition-opacity" role="radio">
|
||||
<div class="flex items-center gap-space-sm min-w-0">
|
||||
<div class="min-w-[48px] min-h-[48px] flex items-center justify-center rounded-lg bg-surface-container-high text-on-surface-variant flex-shrink-0">
|
||||
<span class="material-symbols-outlined text-[24px]">smartphone</span>
|
||||
</div>
|
||||
<div class="flex flex-col min-w-0">
|
||||
<span class="font-body-lg text-body-lg text-on-surface truncate font-semibold">Phone Internal IMU Only</span>
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant truncate">6-Axis Gyro + GPS Core (No Engine RPM/TPS)</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-6 h-6 rounded-full bg-surface-container-high flex items-center justify-center flex-shrink-0 ml-2"></div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- Tire Physics Geometry & Odometer Calibration -->
|
||||
<section aria-label="Chassis and Tire Calibration" class="flex flex-col bg-surface-container-low p-space-md rounded-xl space-y-space-md shadow-md">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-primary-container text-[20px]">donut_large</span>
|
||||
<span class="font-headline-sm text-headline-sm text-on-surface uppercase tracking-wide">Tire Geometry & Kinematics</span>
|
||||
</div>
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant uppercase tracking-wider">Physics Kernel</span>
|
||||
</div>
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 gap-space-sm">
|
||||
<!-- Front Tire Profile -->
|
||||
<div class="bg-surface-container p-space-sm rounded-xl space-y-2 flex flex-col justify-between">
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="font-label-data text-label-data text-primary uppercase">Front Axle Profile</span>
|
||||
<span class="material-symbols-outlined text-[16px] text-on-surface-variant">tire_repair</span>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<input class="w-full h-[48px] px-2.5 bg-surface-container-high text-on-surface font-body-md text-body-md font-semibold rounded-lg focus:outline-none focus:text-primary" type="text" value="120/70 ZR17 (Pirelli SC3)"/>
|
||||
</div>
|
||||
<div class="flex items-center justify-between bg-surface-container-lowest px-2.5 py-1.5 rounded-lg">
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant uppercase">Target Cold Pressure</span>
|
||||
<div class="flex items-baseline gap-1">
|
||||
<span class="font-telemetry-metric-md text-telemetry-metric-md text-on-surface">32.0</span>
|
||||
<span class="font-label-data text-label-data text-primary">PSI</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Rear Tire Profile -->
|
||||
<div class="bg-surface-container p-space-sm rounded-xl space-y-2 flex flex-col justify-between">
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="font-label-data text-label-data text-primary uppercase">Rear Axle Profile</span>
|
||||
<span class="material-symbols-outlined text-[16px] text-on-surface-variant">tire_repair</span>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<input class="w-full h-[48px] px-2.5 bg-surface-container-high text-on-surface font-body-md text-body-md font-semibold rounded-lg focus:outline-none focus:text-primary" type="text" value="200/60 ZR17 (Pirelli SC3)"/>
|
||||
</div>
|
||||
<div class="flex items-center justify-between bg-surface-container-lowest px-2.5 py-1.5 rounded-lg">
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant uppercase">Target Cold Pressure</span>
|
||||
<div class="flex items-baseline gap-1">
|
||||
<span class="font-telemetry-metric-md text-telemetry-metric-md text-on-surface">26.5</span>
|
||||
<span class="font-label-data text-label-data text-primary">PSI</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Current Odometer Field -->
|
||||
<div class="sm:col-span-2 bg-surface-container p-space-sm rounded-xl flex items-center justify-between">
|
||||
<div class="flex items-center gap-2">
|
||||
<div class="min-w-[48px] min-h-[48px] flex items-center justify-center bg-surface-container-high rounded-lg text-primary-container">
|
||||
<span class="material-symbols-outlined text-[22px]">speed</span>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant uppercase tracking-wider">Base Logged Distance</span>
|
||||
<span class="font-headline-sm text-headline-sm text-on-surface uppercase">Current Odometer</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-baseline gap-1.5 bg-surface-container-lowest px-3 py-2 rounded-lg">
|
||||
<input class="w-20 text-right bg-transparent font-telemetry-metric-md text-telemetry-metric-md text-on-surface focus:outline-none focus:text-primary" type="text" value="6,420"/>
|
||||
<span class="font-label-data text-label-data text-primary-fixed uppercase">MI</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- High-Tactile Glove Optimized Action Controls -->
|
||||
<section aria-label="Submission Controls" class="flex flex-col space-y-space-sm pt-space-xs pb-space-sm">
|
||||
<!-- Primary CTA: Save & Proceed to 6-Axis IMU Calibration -->
|
||||
<button class="w-full min-h-[56px] flex items-center justify-center gap-space-sm bg-primary-container text-on-primary-container font-telemetry-metric-md text-telemetry-metric-md uppercase rounded-xl shadow-[0_0_24px_rgba(0,229,255,0.35)] active:scale-[0.98] transition-transform font-bold" id="save-garage-btn" type="button">
|
||||
<span class="material-symbols-outlined text-[24px]">bolt</span>
|
||||
<span>Save & Calibrate IMU</span>
|
||||
<span class="material-symbols-outlined text-[20px]">chevron_right</span>
|
||||
</button>
|
||||
<!-- Secondary CTA: Cancel and Return to Garage -->
|
||||
<a class="w-full min-h-[48px] flex items-center justify-center gap-2 bg-surface-container-low text-on-surface hover:text-primary font-label-data text-label-data uppercase rounded-xl active:bg-surface-container transition-colors" data-path="bike-garage" href="#">
|
||||
<span class="material-symbols-outlined text-[18px]">close</span>
|
||||
<span>Cancel & Return to Garage</span>
|
||||
</a>
|
||||
</section>
|
||||
<!-- Interactive Script for Micro-Interactions -->
|
||||
<script>
|
||||
(function () {
|
||||
// 1. Scanning Laser Animation Loop
|
||||
const laser = document.getElementById('scanner-laser');
|
||||
let direction = 1;
|
||||
let pos = 24;
|
||||
function animateLaser() {
|
||||
if (laser) {
|
||||
pos += 1.8 * direction;
|
||||
if (pos > 180) direction = -1;
|
||||
if (pos < 24) direction = 1;
|
||||
laser.style.top = pos + 'px';
|
||||
requestAnimationFrame(animateLaser);
|
||||
}
|
||||
}
|
||||
requestAnimationFrame(animateLaser);
|
||||
|
||||
// 2. Torch Light Micro-Toggle
|
||||
const torchBtn = document.getElementById('torch-toggle');
|
||||
const torchIcon = document.getElementById('torch-icon');
|
||||
let torchOn = false;
|
||||
if (torchBtn && torchIcon) {
|
||||
torchBtn.addEventListener('click', function () {
|
||||
torchOn = !torchOn;
|
||||
if (torchOn) {
|
||||
torchBtn.classList.add('bg-primary-container', 'text-on-primary-container');
|
||||
torchBtn.classList.remove('bg-surface-container/80', 'text-on-surface');
|
||||
torchIcon.textContent = 'flashlight_off';
|
||||
} else {
|
||||
torchBtn.classList.remove('bg-primary-container', 'text-on-primary-container');
|
||||
torchBtn.classList.add('bg-surface-container/80', 'text-on-surface');
|
||||
torchIcon.textContent = 'flashlight_on';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 3. Category Selector Interactive Highlighting
|
||||
const catPills = document.querySelectorAll('.cat-pill');
|
||||
catPills.forEach(pill => {
|
||||
pill.addEventListener('click', function () {
|
||||
catPills.forEach(p => {
|
||||
p.setAttribute('aria-checked', 'false');
|
||||
p.className = 'cat-pill min-h-[48px] px-3 flex items-center justify-center gap-2 bg-surface-container text-on-surface font-label-data text-label-data uppercase rounded-lg transition-all active:bg-surface-variant';
|
||||
});
|
||||
this.setAttribute('aria-checked', 'true');
|
||||
this.className = 'cat-pill min-h-[48px] px-3 flex items-center justify-center gap-2 bg-primary-container text-on-primary-container font-label-data text-label-data uppercase rounded-lg shadow-sm font-bold transition-all';
|
||||
});
|
||||
});
|
||||
|
||||
// 4. CAN-Bus Radio Selector Interactivity
|
||||
const sensorCards = document.querySelectorAll('.sensor-card');
|
||||
sensorCards.forEach(card => {
|
||||
card.addEventListener('click', function () {
|
||||
sensorCards.forEach(c => {
|
||||
c.setAttribute('aria-checked', 'false');
|
||||
c.classList.add('opacity-70');
|
||||
const indicator = c.querySelector('div:last-child');
|
||||
if (indicator) {
|
||||
indicator.className = 'w-6 h-6 rounded-full bg-surface-container-high flex items-center justify-center flex-shrink-0 ml-2';
|
||||
indicator.innerHTML = '';
|
||||
}
|
||||
});
|
||||
this.setAttribute('aria-checked', 'true');
|
||||
this.classList.remove('opacity-70');
|
||||
const indicator = this.querySelector('div:last-child');
|
||||
if (indicator) {
|
||||
indicator.className = 'w-6 h-6 rounded-full bg-primary-container flex items-center justify-center text-on-primary-container flex-shrink-0 ml-2';
|
||||
indicator.innerHTML = '<span class="material-symbols-outlined text-[16px]">check</span>';
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// 5. Save Button Feedback
|
||||
const saveBtn = document.getElementById('save-garage-btn');
|
||||
if (saveBtn) {
|
||||
saveBtn.addEventListener('click', function () {
|
||||
const originalContent = this.innerHTML;
|
||||
this.innerHTML = '<span class="material-symbols-outlined text-[24px] animate-spin">sync</span><span>COMMISSIONING SENSORS...</span>';
|
||||
setTimeout(() => {
|
||||
this.innerHTML = '<span class="material-symbols-outlined text-[24px]">task_alt</span><span>VEHICLE COMMITTED</span>';
|
||||
}, 1100);
|
||||
});
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
</div></main><nav class="fixed bottom-0 w-full z-50 pb-safe bg-surface-container-lowest/90 backdrop-blur-xl shadow-[0_-4px_24px_rgba(0,0,0,0.6)]" data-active-classes="text-primary-container font-headline-sm [filter:drop-shadow(0_0_8px_rgba(0,229,255,0.5))]"><div class="grid grid-cols-6 items-center h-20 px-space-xs"><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="cockpit-dash" href="#"><span class="material-symbols-outlined text-[24px]">speed</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Dash</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="tactical-radar-map" href="#"><span class="material-symbols-outlined text-[24px]">radar</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Map</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="telemetry-log" href="#"><span class="material-symbols-outlined text-[24px]">monitoring</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Activity</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="bike-garage" href="#"><span class="material-symbols-outlined text-[24px]">two_wheeler</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Garage</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="pack-comms" href="#"><span class="material-symbols-outlined text-[24px]">groups_3</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Social</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="hud-settings" href="#"><span class="material-symbols-outlined text-[24px]">tune</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Settings</span></a></div></nav></body></html>
|
||||
|
|
@ -0,0 +1,473 @@
|
|||
<!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, viewport-fit=cover" name="viewport"/><meta content="mobile_tab" name="shell-type"/><title>MotorSignal Cockpit HUD</title><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&family=JetBrains+Mono:wght@500;600;700&family=Space+Grotesk:wght@600;700&display=swap" rel="stylesheet"/><link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/><style>@layer base{html,body{width:100%;margin:0;padding:0;background-color:#101419;color:#e0e2ea;}body{overscroll-behavior:none;}.pb-safe{padding-bottom:env(safe-area-inset-bottom,0px);}.pt-safe{padding-top:env(safe-area-inset-top,0px);}main>:first-child{margin-top:0!important;}main>:last-child{margin-bottom:0!important;}}::-webkit-scrollbar{display:none;}</style><script src="https://cdn.tailwindcss.com"></script><script id="tailwind-config">tailwind.config = { darkMode: "class", theme: { extend: { "colors": { "on-primary": "#00363d", "tertiary-fixed-dim": "#d0bcff", "tertiary-container": "#d9c8ff", "on-primary-container": "#00626e", "surface-variant": "#32353b", "on-primary-fixed-variant": "#004f58", "surface-container-high": "#272a30", "outline-variant": "#3b494c", "surface-container": "#1d2025", "on-surface": "#e0e2ea", "background": "#101419", "primary-container": "#00e5ff", "inverse-surface": "#e0e2ea", "outline": "#849396", "on-secondary": "#002a78", "secondary-fixed-dim": "#b4c5ff", "on-tertiary": "#3c0091", "inverse-primary": "#006875", "surface-bright": "#36393f", "surface-container-low": "#181c21", "surface-container-highest": "#32353b", "inverse-on-surface": "#2d3036", "on-secondary-fixed": "#00174b", "primary": "#c3f5ff", "error-container": "#93000a", "surface-tint": "#00daf3", "on-tertiary-fixed-variant": "#5516be", "on-error-container": "#ffdad6", "primary-fixed-dim": "#00daf3", "tertiary-fixed": "#e9ddff", "on-primary-fixed": "#001f24", "on-error": "#690005", "surface-container-lowest": "#0b0e13", "secondary-container": "#0053db", "tertiary": "#f2e9ff", "surface-dim": "#101419", "on-surface-variant": "#bac9cc", "on-tertiary-container": "#6834d1", "primary-fixed": "#9cf0ff", "secondary-fixed": "#dbe1ff", "error": "#ffb4ab", "on-secondary-container": "#cdd7ff", "on-secondary-fixed-variant": "#003ea8", "surface": "#101419", "on-background": "#e0e2ea", "secondary": "#b4c5ff", "on-tertiary-fixed": "#23005c" }, "borderRadius": { "DEFAULT": "0.25rem", "lg": "0.5rem", "xl": "0.75rem", "full": "9999px" }, "spacing": { "margin-lg": "2rem", "space-xs": "0.25rem", "gutter-lg": "1.5rem", "space-xl": "2rem", "margin": "1rem", "space-sm": "0.5rem", "space-md": "1rem", "space-lg": "1.5rem", "gutter": "1rem" }, "fontFamily": { "headline-lg": ["Space Grotesk"], "body-lg": ["Inter"], "telemetry-metric-lg-mobile": ["JetBrains Mono"], "label-data": ["JetBrains Mono"], "display-hero": ["Space Grotesk"], "headline-sm": ["Space Grotesk"], "headline-md": ["Space Grotesk"], "label-caption": ["Inter"], "telemetry-metric-lg": ["JetBrains Mono"], "display-hero-mobile": ["Space Grotesk"], "telemetry-metric-md": ["JetBrains Mono"], "body-md": ["Inter"] }, "fontSize": { "headline-lg": ["32px", { "lineHeight": "40px", "letterSpacing": "-0.02em", "fontWeight": "700" }], "body-lg": ["16px", { "lineHeight": "24px", "fontWeight": "500" }], "telemetry-metric-lg-mobile": ["36px", { "lineHeight": "36px", "letterSpacing": "-0.03em", "fontWeight": "700" }], "label-data": ["12px", { "lineHeight": "16px", "letterSpacing": "0.08em", "fontWeight": "600" }], "display-hero": ["56px", { "lineHeight": "60px", "letterSpacing": "-0.03em", "fontWeight": "700" }], "headline-sm": ["20px", { "lineHeight": "28px", "fontWeight": "600" }], "headline-md": ["24px", { "lineHeight": "32px", "letterSpacing": "-0.01em", "fontWeight": "600" }], "label-caption": ["11px", { "lineHeight": "14px", "letterSpacing": "0.05em", "fontWeight": "600" }], "telemetry-metric-lg": ["48px", { "lineHeight": "48px", "letterSpacing": "-0.04em", "fontWeight": "700" }], "display-hero-mobile": ["40px", { "lineHeight": "44px", "letterSpacing": "-0.02em", "fontWeight": "700" }], "telemetry-metric-md": ["28px", { "lineHeight": "32px", "letterSpacing": "-0.02em", "fontWeight": "600" }], "body-md": ["14px", { "lineHeight": "20px", "fontWeight": "400" }] } } } }</script><style>
|
||||
body {
|
||||
min-height: max(884px, 100dvh);
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
body {
|
||||
min-height: max(884px, 100dvh);
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
body {
|
||||
min-height: max(884px, 100dvh);
|
||||
}
|
||||
</style>
|
||||
</head><body class="bg-surface font-body-md text-on-surface antialiased flex flex-col min-h-screen selection:bg-primary-container selection:text-on-primary-container"><header class="fixed top-0 w-full z-50 pt-safe bg-surface-container-lowest/85 backdrop-blur-xl shadow-[0_4px_20px_rgba(0,0,0,0.5)]"><div class="h-16 px-space-md flex items-center justify-between gap-space-sm"><div class="flex items-center gap-space-sm"><img alt="MotorSignal Brand Logo" class="h-8 w-auto object-contain drop-shadow-[0_0_8px_rgba(0,229,255,0.4)]" src="https://lh3.googleusercontent.com/aida/AEtjO1Vf56Tkh6bJ86BCfT5GHz_yPumvEXYLWojlNHAFG-cN4VvH_nLvEbWQ4x7uhJPRaAyO8ozAAbLI_huEN134QOIYp8BdHuqoZCsMk9_ILaUxZqilVgamefO6d2sG1R8laIWSUswanVsK9lfvIgppQm_XxBQipzkDgPwIoXk7yh10QTlmZqDICryF-1MoWFfFjM2zZswr6ynuAgZAviROYnFBF2D4hxm6YREQxkZQJaBcG9oAg_dYVgTHxwg"/><div class="flex flex-col"><span class="font-headline-sm text-headline-sm uppercase tracking-wider text-primary-fixed">MotorSignal</span><span class="font-label-caption text-label-caption text-on-surface-variant uppercase tracking-widest leading-none">Telemetry Log</span></div></div><div class="flex items-center gap-space-sm"><div class="hidden sm:flex items-center gap-space-xs bg-surface-container-low px-space-sm py-1 rounded-full"><span class="w-2 h-2 rounded-full bg-primary-container animate-pulse shadow-[0_0_6px_#00e5ff]"></span><span class="font-label-data text-label-data text-primary-fixed">GPS 3D FIX</span></div><div class="flex items-center gap-1.5 bg-surface-container px-2 py-1 rounded-full"><span class="material-symbols-outlined text-[15px] text-primary-container">bolt</span><span class="font-label-data text-label-data text-on-surface">98%</span><span class="w-1 h-1 rounded-full bg-outline-variant"></span><span class="material-symbols-outlined text-[15px] text-primary-container">cell_tower</span></div><button aria-label="Rider Profile" class="min-w-[44px] min-h-[44px] flex items-center justify-center p-1 rounded-full focus:outline-none focus:ring-2 focus:ring-primary-container" type="button"><img alt="Profile" class="w-8 h-8 rounded-full object-cover ring-2 ring-primary-container/40" src="https://lh3.googleusercontent.com/aida-public/AB6AXuBb6sR8Ta8-L1_TN1LuCBfSxtZxX9hKOFjd-RjllihDsnp6AG1GlMhL9bVlb-ibhIRT3HMw_caXK7BmwmvWKNBcuizyqswUQZNztavckRTN1Xa6qGML_0kv8qvV_hrXWWK1EjSjVFzhRyDzf6VdGnZvUpGsFFmSBcaGVrXmEWFYnIa-qHyeWxZlT_SJmPuQJPQKEWEo6vC6kdDzXNnhoB4tpRHjIjCstvTdooPc0KVN_x3BqqmqadNI"/></button></div></div></header><main class="flex-1 flex flex-col relative w-full pt-16 pb-20 bg-surface"><div class="flex flex-col w-full px-space-md py-space-sm space-y-space-md text-on-surface">
|
||||
<!-- Sub-Header Context Bar -->
|
||||
<div class="flex items-center justify-between gap-space-sm pt-space-xs">
|
||||
<div class="flex items-center gap-space-sm min-w-0">
|
||||
<button aria-label="Go Back to Group Rides" class="w-12 h-12 rounded-xl bg-surface-container-high flex items-center justify-center text-primary-container active:bg-surface-variant transition-colors flex-shrink-0" type="button">
|
||||
<span class="material-symbols-outlined text-[24px]">arrow_back</span>
|
||||
</button>
|
||||
<div class="flex flex-col min-w-0">
|
||||
<div class="flex items-center gap-1.5">
|
||||
<span class="w-2 h-2 rounded-full bg-secondary animate-pulse"></span>
|
||||
<span class="font-label-caption text-label-caption text-secondary tracking-widest uppercase">Briefing & Pack Staging</span>
|
||||
</div>
|
||||
<h1 class="font-headline-sm text-headline-sm text-on-surface truncate tracking-tight">Skyline to Santa Cruz Coastal Arc</h1>
|
||||
</div>
|
||||
</div>
|
||||
<span class="hidden sm:inline-flex items-center gap-1 px-3 py-1.5 rounded-full bg-surface-container-high text-on-surface-variant font-label-caption text-label-caption">
|
||||
ID: GRP-03-NORCAL
|
||||
</span>
|
||||
</div>
|
||||
<!-- Status Chip: Staging Alert -->
|
||||
<div class="flex items-center justify-between px-space-md py-space-sm rounded-xl bg-surface-container-high shadow-md">
|
||||
<div class="flex items-center gap-space-sm min-w-0">
|
||||
<span class="relative flex h-3 w-3 flex-shrink-0">
|
||||
<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-3 w-3 bg-primary-container"></span>
|
||||
</span>
|
||||
<span class="font-label-data text-label-data text-primary-container truncate uppercase">STAGING IN PROGRESS • KSU T-MINUS 35M</span>
|
||||
</div>
|
||||
<span class="font-label-data text-label-data text-on-surface-variant flex-shrink-0">STAGE 1/4</span>
|
||||
</div>
|
||||
<!-- Section 1: Ride Command & Mission Briefing Header Card -->
|
||||
<div class="rounded-xl bg-surface-container p-space-md space-y-space-md shadow-lg relative overflow-hidden">
|
||||
<div class="flex flex-col sm:flex-row sm:items-start justify-between gap-space-sm">
|
||||
<div class="space-y-1">
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant uppercase tracking-wider block">Host Squadron / Club</span>
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-[20px] text-primary-fixed">verified</span>
|
||||
<span class="font-headline-sm text-headline-sm text-on-surface">Pacific Coast Riders MC</span>
|
||||
</div>
|
||||
<span class="font-label-caption text-label-caption text-outline block">NorCal Chapter • Verified Road Captain Unit</span>
|
||||
</div>
|
||||
<!-- KSU Countdown Telemetry Gauge -->
|
||||
<div class="flex flex-col items-start sm:items-end bg-surface-container-lowest px-space-md py-space-sm rounded-lg">
|
||||
<span class="font-label-caption text-label-caption text-primary-fixed uppercase tracking-wider flex items-center gap-1">
|
||||
<span class="material-symbols-outlined text-[14px]">timer</span> KSU COUNTDOWN
|
||||
</span>
|
||||
<div class="flex items-baseline gap-1 mt-0.5">
|
||||
<span class="font-telemetry-metric-lg-mobile text-telemetry-metric-lg-mobile text-primary tracking-tight" id="ksu-timer">00:35:12</span>
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant">HRS</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Staging Spot & Quick GPS Action -->
|
||||
<div class="flex flex-col sm:flex-row items-stretch sm:items-center justify-between gap-space-sm pt-space-xs bg-surface-container-low p-space-sm rounded-lg">
|
||||
<div class="flex items-center gap-space-sm min-w-0">
|
||||
<div class="w-10 h-10 rounded-lg bg-surface-container-high flex items-center justify-center text-primary-container flex-shrink-0">
|
||||
<span class="material-symbols-outlined text-[24px]">pin_drop</span>
|
||||
</div>
|
||||
<div class="flex flex-col min-w-0">
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant uppercase">Rendezvous Point</span>
|
||||
<span class="font-body-md text-body-md text-on-surface font-semibold truncate">Alice's Restaurant</span>
|
||||
<span class="font-label-caption text-label-caption text-outline truncate">Skyline Blvd & Hwy 84 Crest</span>
|
||||
</div>
|
||||
</div>
|
||||
<button class="min-h-[48px] px-space-md rounded-lg bg-surface-container-high text-primary font-headline-sm text-headline-sm flex items-center justify-center gap-2 active:bg-surface-variant transition-colors flex-shrink-0" type="button">
|
||||
<span class="material-symbols-outlined text-[20px]">turn_sharp_right</span>
|
||||
<span>LAUNCH GPS</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Section 2: Route Telemetry & Environmental Vector Strip -->
|
||||
<div class="grid grid-cols-2 sm:grid-cols-4 gap-space-sm">
|
||||
<!-- Distance Card -->
|
||||
<div class="rounded-xl bg-surface-container p-space-sm flex flex-col justify-between shadow-sm">
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant uppercase tracking-wider flex items-center gap-1">
|
||||
<span class="material-symbols-outlined text-[14px]">alt_route</span> Route Arc
|
||||
</span>
|
||||
<div class="my-1">
|
||||
<span class="font-telemetry-metric-md text-telemetry-metric-md text-primary">64.2</span>
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant ml-0.5">MI</span>
|
||||
</div>
|
||||
<span class="font-label-caption text-label-caption text-outline">EST. 1H 28M RIDE</span>
|
||||
</div>
|
||||
<!-- Pace Profile -->
|
||||
<div class="rounded-xl bg-surface-container p-space-sm flex flex-col justify-between shadow-sm">
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant uppercase tracking-wider flex items-center gap-1">
|
||||
<span class="material-symbols-outlined text-[14px]">speed</span> Pace Rating
|
||||
</span>
|
||||
<div class="my-1">
|
||||
<span class="font-telemetry-metric-md text-telemetry-metric-md text-primary-fixed">PACE 3</span>
|
||||
</div>
|
||||
<span class="font-label-caption text-label-caption text-secondary truncate">BRISK TECHNICAL</span>
|
||||
</div>
|
||||
<!-- Grip Index -->
|
||||
<div class="rounded-xl bg-surface-container p-space-sm flex flex-col justify-between shadow-sm">
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant uppercase tracking-wider flex items-center gap-1">
|
||||
<span class="material-symbols-outlined text-[14px]">sports_score</span> Grip Index
|
||||
</span>
|
||||
<div class="my-1">
|
||||
<span class="font-telemetry-metric-md text-telemetry-metric-md text-primary-container">96%</span>
|
||||
</div>
|
||||
<span class="font-label-caption text-label-caption text-primary">DRY ASPHALT</span>
|
||||
</div>
|
||||
<!-- Elevation Peak -->
|
||||
<div class="rounded-xl bg-surface-container p-space-sm flex flex-col justify-between shadow-sm">
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant uppercase tracking-wider flex items-center gap-1">
|
||||
<span class="material-symbols-outlined text-[14px]">landscape</span> Peak Summit
|
||||
</span>
|
||||
<div class="my-1">
|
||||
<span class="font-telemetry-metric-md text-telemetry-metric-md text-on-surface">3,214</span>
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant ml-0.5">FT</span>
|
||||
</div>
|
||||
<span class="font-label-caption text-label-caption text-outline">SANTA CRUZ MTNS</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Elevation Sparkline + Environmental Hazard Advisory Bar -->
|
||||
<div class="rounded-xl bg-surface-container p-space-md space-y-space-sm shadow-md">
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="font-label-data text-label-data text-on-surface-variant uppercase tracking-wider flex items-center gap-1.5">
|
||||
<span class="material-symbols-outlined text-[16px] text-primary-container">show_chart</span>
|
||||
Elevation Gradient Profile
|
||||
</span>
|
||||
<span class="font-label-caption text-label-caption text-primary-container font-semibold">HWY 35 > HWY 9 > HWY 1</span>
|
||||
</div>
|
||||
<!-- Minimal SVG Altitude Graph -->
|
||||
<div class="w-full h-16 bg-surface-container-lowest rounded-lg p-2 flex items-end">
|
||||
<svg class="w-full h-12 text-primary-container" fill="none" preserveaspectratio="none" viewbox="0 0 400 60">
|
||||
<defs>
|
||||
<lineargradient id="altitudeGlow" x1="0" x2="0" y1="0" y2="1">
|
||||
<stop offset="0%" stop-color="#00e5ff" stop-opacity="0.35"></stop>
|
||||
<stop offset="100%" stop-color="#00e5ff" stop-opacity="0.0"></stop>
|
||||
</lineargradient>
|
||||
</defs>
|
||||
<path d="M0 45 Q 60 10, 130 5 T 260 28 T 350 48 L 400 55 L 400 60 L 0 60 Z" fill="url(#altitudeGlow)"></path>
|
||||
<path d="M0 45 Q 60 10, 130 5 T 260 28 T 350 48 L 400 55" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5"></path>
|
||||
<circle cx="130" cy="5" fill="#00e5ff" r="3.5"></circle>
|
||||
</svg>
|
||||
</div>
|
||||
<!-- Weather & Ridge Hazard Micro-banner -->
|
||||
<div class="flex items-center gap-space-sm p-space-sm rounded-lg bg-surface-container-high text-on-surface">
|
||||
<div class="w-9 h-9 rounded-lg bg-surface-container-highest flex items-center justify-center text-secondary flex-shrink-0">
|
||||
<span class="material-symbols-outlined text-[20px]">foggy</span>
|
||||
</div>
|
||||
<div class="flex flex-col min-w-0 flex-1">
|
||||
<div class="flex items-center gap-1.5">
|
||||
<span class="font-label-data text-label-data text-secondary uppercase">MET Advisory</span>
|
||||
<span class="font-label-caption text-label-caption text-outline">12 Min Ago</span>
|
||||
</div>
|
||||
<p class="font-body-md text-body-md text-on-surface truncate">Light ridge fog near Castle Rock. Pavement cool; maintain 4-second gap.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Visual Story: Route Preview & Staging Area -->
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 gap-space-sm">
|
||||
<div class="rounded-xl overflow-hidden bg-surface-container shadow-md flex flex-col">
|
||||
<div class="relative h-32 w-full">
|
||||
<img alt="Alice's Restaurant motorcycle staging lot on Skyline Boulevard with sportbikes lined up under redwood trees" class="w-full h-full object-cover" data-alt="Alice's Restaurant motorcycle staging area on Skyline Boulevard California with multiple high performance sportbikes and adventure touring motorcycles parked side by side beneath tall redwood trees under crisp morning sunlight with riders wearing helmets and leather jackets" src="https://lh3.googleusercontent.com/aida-public/AB6AXuB71MZBuH5vDiR8swpW_U4ajPQcOUBviz0o4EGuwE0JvnBX1OblIjfAFNEk2JctOhzvA-VAeOzuwmcHkIEob_Y7wcI6niAkeJoBmxfwjkA26RaixO65-yMuRmlvQZRUyEjuZGiDgpJCAxF8k_xQpZqIFzydS3yawOmrJFF4BE0-ufrbDlgYilzUDiy0GCvVR3iA_LTxfNTYwgxGjkbchKxFQQG30Sgo9NV59A4HK_nqO0H8L955jtGx"/>
|
||||
<div class="absolute inset-0 bg-gradient-to-t from-surface-container via-surface-container/20 to-transparent"></div>
|
||||
<div class="absolute bottom-2 left-3">
|
||||
<span class="font-label-data text-label-data text-primary px-2 py-0.5 rounded bg-surface-container-lowest/80 backdrop-blur-md">STAGING GRID A</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="p-space-sm flex justify-between items-center">
|
||||
<span class="font-body-md text-body-md text-on-surface">Alice's Redwood Patio Zone</span>
|
||||
<span class="font-label-caption text-label-caption text-primary-fixed">18 BIKES PRESENT</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="rounded-xl overflow-hidden bg-surface-container shadow-md flex flex-col">
|
||||
<div class="relative h-32 w-full">
|
||||
<img alt="Twisting coastal highway sweeping down toward the Pacific Ocean with smooth asphalt and morning fog in Santa Cruz" class="w-full h-full object-cover" data-alt="Panoramic scenic view of California Highway 9 winding through coastal Redwood forest descending toward the blue Santa Cruz ocean coastline in crisp morning lighting with high-contrast road ribbons and clean asphalt" src="https://lh3.googleusercontent.com/aida-public/AB6AXuC3weMkdWrRVsSs2Lji1H5F7j0Aon4wy-VnPT9ueD9CBmvanHbBpSB8ceNxyg5dWgEiCxYAeJqqTMN8-vU3ffE1Q6hlms71EJEbY2z3ARwltkBlM_Rwd68QJEdYgGe2nK4T-Psck7DPf7YY-X7Q57qzRl8qb23Ho6Mcx5xSIntPYl9qFb-dadLFeBhBooAtL1e9MiX5aOUZ97mG_pCP7svXg6tGCdUgsKQhqqm6L1GOQTXDy9FlNn4E"/>
|
||||
<div class="absolute inset-0 bg-gradient-to-t from-surface-container via-surface-container/20 to-transparent"></div>
|
||||
<div class="absolute bottom-2 left-3">
|
||||
<span class="font-label-data text-label-data text-primary px-2 py-0.5 rounded bg-surface-container-lowest/80 backdrop-blur-md">DESCENT SECTOR</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="p-space-sm flex justify-between items-center">
|
||||
<span class="font-body-md text-body-md text-on-surface">Highway 9 Technical Descent</span>
|
||||
<span class="font-label-caption text-label-caption text-secondary">34 APEXES</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Section 3: Pack Hierarchy & Officer Assignments -->
|
||||
<div class="rounded-xl bg-surface-container p-space-md space-y-space-sm shadow-md">
|
||||
<div class="flex items-center justify-between pb-space-xs">
|
||||
<div class="flex items-center gap-space-sm">
|
||||
<span class="material-symbols-outlined text-primary-container text-[20px]">shield_person</span>
|
||||
<span class="font-headline-sm text-headline-sm text-on-surface">Pack Flight Hierarchy</span>
|
||||
</div>
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant uppercase tracking-wider">Mesh Group 04</span>
|
||||
</div>
|
||||
<!-- Officer 1: Road Captain -->
|
||||
<div class="flex items-center justify-between p-space-sm rounded-lg bg-surface-container-low min-h-[56px]">
|
||||
<div class="flex items-center gap-space-sm min-w-0">
|
||||
<div class="w-10 h-10 rounded-full bg-surface-container-high flex items-center justify-center text-primary font-headline-sm text-headline-sm flex-shrink-0">
|
||||
RC
|
||||
</div>
|
||||
<div class="flex flex-col min-w-0">
|
||||
<div class="flex items-center gap-1.5">
|
||||
<span class="font-body-md text-body-md text-on-surface font-semibold truncate">@Dave_Lead</span>
|
||||
<span class="font-label-caption text-label-caption px-1.5 py-0.5 rounded bg-surface-container-highest text-primary font-bold">LEAD</span>
|
||||
</div>
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant truncate">Ducati Panigale V4 • Mesh CH-04 MASTER</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-1 flex-shrink-0">
|
||||
<span class="material-symbols-outlined text-[18px] text-primary-container">headset_mic</span>
|
||||
<span class="font-label-data text-label-data text-primary-container">CH-04</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Officer 2: Mid-Pack Marshal -->
|
||||
<div class="flex items-center justify-between p-space-sm rounded-lg bg-surface-container-low min-h-[56px]">
|
||||
<div class="flex items-center gap-space-sm min-w-0">
|
||||
<div class="w-10 h-10 rounded-full bg-surface-container-high flex items-center justify-center text-secondary font-headline-sm text-headline-sm flex-shrink-0">
|
||||
MM
|
||||
</div>
|
||||
<div class="flex flex-col min-w-0">
|
||||
<div class="flex items-center gap-1.5">
|
||||
<span class="font-body-md text-body-md text-on-surface font-semibold truncate">@Marc_ADV</span>
|
||||
<span class="font-label-caption text-label-caption px-1.5 py-0.5 rounded bg-surface-container-highest text-secondary font-bold">MID-MARSHAL</span>
|
||||
</div>
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant truncate">BMW R1250GS • Telemetry Bridge Relay</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-1 flex-shrink-0">
|
||||
<span class="material-symbols-outlined text-[18px] text-secondary">wifi_tethering</span>
|
||||
<span class="font-label-data text-label-data text-secondary">RELAY</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Officer 3: Tail Gunner / Sweep -->
|
||||
<div class="flex items-center justify-between p-space-sm rounded-lg bg-surface-container-low min-h-[56px]">
|
||||
<div class="flex items-center gap-space-sm min-w-0">
|
||||
<div class="w-10 h-10 rounded-full bg-surface-container-high flex items-center justify-center text-primary-fixed font-headline-sm text-headline-sm flex-shrink-0">
|
||||
TG
|
||||
</div>
|
||||
<div class="flex flex-col min-w-0">
|
||||
<div class="flex items-center gap-1.5">
|
||||
<span class="font-body-md text-body-md text-on-surface font-semibold truncate">@Sarah_Sweep</span>
|
||||
<span class="font-label-caption text-label-caption px-1.5 py-0.5 rounded bg-surface-container-highest text-primary-fixed font-bold">SWEEP</span>
|
||||
</div>
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant truncate">KTM 890 Duke R • First Aid / Toolkit</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-1 flex-shrink-0">
|
||||
<span class="material-symbols-outlined text-[18px] text-primary-fixed">medical_services</span>
|
||||
<span class="font-label-data text-label-data text-primary-fixed">MED-1</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Section 4: Staging Safety Checklist (Interactive) -->
|
||||
<div class="rounded-xl bg-surface-container p-space-md space-y-space-sm shadow-md">
|
||||
<div class="flex items-center justify-between pb-space-xs">
|
||||
<div class="flex items-center gap-space-sm">
|
||||
<span class="material-symbols-outlined text-primary-container text-[20px]">checklist</span>
|
||||
<span class="font-headline-sm text-headline-sm text-on-surface">Mandatory Flight Checklist</span>
|
||||
</div>
|
||||
<span class="font-label-data text-label-data text-primary-container" id="checklist-progress">4 / 4 READY</span>
|
||||
</div>
|
||||
<div class="space-y-space-xs" id="checklist-items">
|
||||
<!-- Item 1 -->
|
||||
<button class="w-full flex items-center justify-between p-space-sm rounded-lg bg-surface-container-low active:bg-surface-container-high transition-colors min-h-[52px] text-left" onclick="toggleCheck(this)" type="button">
|
||||
<div class="flex items-center gap-space-sm min-w-0">
|
||||
<span class="check-icon material-symbols-outlined text-[24px] text-primary-container">check_circle</span>
|
||||
<span class="font-body-md text-body-md text-on-surface truncate">Full Tank of Fuel (Range > 100 MI)</span>
|
||||
</div>
|
||||
<span class="font-label-data text-label-data text-on-surface-variant flex-shrink-0 ml-2">91+ OCT</span>
|
||||
</button>
|
||||
<!-- Item 2 -->
|
||||
<button class="w-full flex items-center justify-between p-space-sm rounded-lg bg-surface-container-low active:bg-surface-container-high transition-colors min-h-[52px] text-left" onclick="toggleCheck(this)" type="button">
|
||||
<div class="flex items-center gap-space-sm min-w-0">
|
||||
<span class="check-icon material-symbols-outlined text-[24px] text-primary-container">check_circle</span>
|
||||
<span class="font-body-md text-body-md text-on-surface truncate">Tire Cold Pressures Checked & Verified</span>
|
||||
</div>
|
||||
<span class="font-label-data text-label-data text-on-surface-variant flex-shrink-0 ml-2">TPMS OK</span>
|
||||
</button>
|
||||
<!-- Item 3 -->
|
||||
<button class="w-full flex items-center justify-between p-space-sm rounded-lg bg-surface-container-low active:bg-surface-container-high transition-colors min-h-[52px] text-left" onclick="toggleCheck(this)" type="button">
|
||||
<div class="flex items-center gap-space-sm min-w-0">
|
||||
<span class="check-icon material-symbols-outlined text-[24px] text-primary-container">check_circle</span>
|
||||
<span class="font-body-md text-body-md text-on-surface truncate">Emergency ICE Contact Linked in MotorSignal</span>
|
||||
</div>
|
||||
<span class="font-label-data text-label-data text-on-surface-variant flex-shrink-0 ml-2">ICE LINKED</span>
|
||||
</button>
|
||||
<!-- Item 4 -->
|
||||
<button class="w-full flex items-center justify-between p-space-sm rounded-lg bg-surface-container-low active:bg-surface-container-high transition-colors min-h-[52px] text-left" onclick="toggleCheck(this)" type="button">
|
||||
<div class="flex items-center gap-space-sm min-w-0">
|
||||
<span class="check-icon material-symbols-outlined text-[24px] text-primary-container">check_circle</span>
|
||||
<span class="font-body-md text-body-md text-on-surface truncate">Mesh Intercom Paired to Channel 04</span>
|
||||
</div>
|
||||
<span class="font-label-data text-label-data text-primary-fixed flex-shrink-0 ml-2">SYNCED</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Section 5: Confirmed Attendee Roster Stack & Status -->
|
||||
<div class="rounded-xl bg-surface-container p-space-md space-y-space-sm shadow-md">
|
||||
<div class="flex items-center justify-between pb-space-xs">
|
||||
<div class="flex items-center gap-space-sm">
|
||||
<span class="material-symbols-outlined text-primary text-[20px]">groups</span>
|
||||
<span class="font-headline-sm text-headline-sm text-on-surface">Pack Roster</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-1.5 px-2.5 py-1 rounded-full bg-surface-container-high">
|
||||
<span class="w-2 h-2 rounded-full bg-primary-container"></span>
|
||||
<span class="font-label-data text-label-data text-primary">22 / 25 STAGED</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Attendee List Stack -->
|
||||
<div class="space-y-space-xs">
|
||||
<!-- Rider 1 -->
|
||||
<div class="flex items-center justify-between p-space-sm rounded-lg bg-surface-container-low min-h-[52px]">
|
||||
<div class="flex items-center gap-space-sm min-w-0">
|
||||
<div class="w-9 h-9 rounded-full bg-surface-container-high flex items-center justify-center text-primary-fixed font-headline-sm text-headline-sm flex-shrink-0">
|
||||
KL
|
||||
</div>
|
||||
<div class="flex flex-col min-w-0">
|
||||
<span class="font-body-md text-body-md text-on-surface font-semibold truncate">@Kenji_R1</span>
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant truncate">Yamaha YZF-R1</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-1.5 flex-shrink-0">
|
||||
<span class="w-2 h-2 rounded-full bg-primary-container"></span>
|
||||
<span class="font-label-caption text-label-caption text-primary">At Alice's Grid</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Rider 2 -->
|
||||
<div class="flex items-center justify-between p-space-sm rounded-lg bg-surface-container-low min-h-[52px]">
|
||||
<div class="flex items-center gap-space-sm min-w-0">
|
||||
<div class="w-9 h-9 rounded-full bg-surface-container-high flex items-center justify-center text-secondary font-headline-sm text-headline-sm flex-shrink-0">
|
||||
EL
|
||||
</div>
|
||||
<div class="flex flex-col min-w-0">
|
||||
<span class="font-body-md text-body-md text-on-surface font-semibold truncate">@Elena_Moto</span>
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant truncate">Aprilia Tuono V4 Factory</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-1.5 flex-shrink-0">
|
||||
<span class="w-2 h-2 rounded-full bg-primary-container"></span>
|
||||
<span class="font-label-caption text-label-caption text-primary">At Alice's Grid</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Rider 3: En Route -->
|
||||
<div class="flex items-center justify-between p-space-sm rounded-lg bg-surface-container-low min-h-[52px]">
|
||||
<div class="flex items-center gap-space-sm min-w-0">
|
||||
<div class="w-9 h-9 rounded-full bg-surface-container-high flex items-center justify-center text-on-surface-variant font-headline-sm text-headline-sm flex-shrink-0">
|
||||
TJ
|
||||
</div>
|
||||
<div class="flex flex-col min-w-0">
|
||||
<span class="font-body-md text-body-md text-on-surface font-semibold truncate">@Travis_990</span>
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant truncate">KTM 1290 Super Duke</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-1.5 flex-shrink-0">
|
||||
<span class="w-2 h-2 rounded-full bg-secondary"></span>
|
||||
<span class="font-label-caption text-label-caption text-secondary">3.4 MI Out • HWY 84</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Rider 4: En Route -->
|
||||
<div class="flex items-center justify-between p-space-sm rounded-lg bg-surface-container-low min-h-[52px]">
|
||||
<div class="flex items-center gap-space-sm min-w-0">
|
||||
<div class="w-9 h-9 rounded-full bg-surface-container-high flex items-center justify-center text-on-surface-variant font-headline-sm text-headline-sm flex-shrink-0">
|
||||
MR
|
||||
</div>
|
||||
<div class="flex flex-col min-w-0">
|
||||
<span class="font-body-md text-body-md text-on-surface font-semibold truncate">@Maya_SpeedTriple</span>
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant truncate">Triumph Speed Triple 1200</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-1.5 flex-shrink-0">
|
||||
<span class="w-2 h-2 rounded-full bg-secondary"></span>
|
||||
<span class="font-label-caption text-label-caption text-secondary">6.1 MI Out • 280 N</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Expansion pill -->
|
||||
<button class="w-full min-h-[44px] flex items-center justify-center gap-1 text-primary-fixed hover:text-primary transition-colors font-label-data text-label-data uppercase tracking-wider pt-space-xs" type="button">
|
||||
<span>View All 25 Pack Members & Mesh Signatures</span>
|
||||
<span class="material-symbols-outlined text-[18px]">expand_more</span>
|
||||
</button>
|
||||
</div>
|
||||
<!-- Section 6: Glove-Friendly Action Buttons -->
|
||||
<div class="space-y-space-sm pt-space-xs">
|
||||
<!-- Primary Full-Width Check-In & Connect Button -->
|
||||
<button class="w-full min-h-[56px] py-space-sm px-space-md rounded-xl bg-primary-container text-on-primary font-headline-sm text-headline-sm flex items-center justify-center gap-space-sm shadow-[0_0_20px_rgba(0,229,255,0.4)] active:scale-[0.99] transition-transform" id="primary-checkin-btn" onclick="handlePrimaryCheckIn(this)" type="button">
|
||||
<span class="material-symbols-outlined text-[26px]">cell_tower</span>
|
||||
<span class="tracking-wide uppercase">CHECK IN & CONNECT TO MESH (CH-04)</span>
|
||||
</button>
|
||||
<!-- Secondary Split Tactical Actions -->
|
||||
<div class="grid grid-cols-2 gap-space-sm">
|
||||
<button class="min-h-[50px] p-space-sm rounded-xl bg-surface-container text-on-surface hover:bg-surface-container-high active:bg-surface-variant transition-colors flex items-center justify-center gap-2" type="button">
|
||||
<span class="material-symbols-outlined text-primary-container text-[20px]">file_download</span>
|
||||
<span class="font-label-data text-label-data uppercase tracking-wider truncate">GPX CUE SHEET</span>
|
||||
</button>
|
||||
<button class="min-h-[50px] p-space-sm rounded-xl bg-surface-container text-on-surface hover:bg-surface-container-high active:bg-surface-variant transition-colors flex items-center justify-center gap-2" type="button">
|
||||
<span class="material-symbols-outlined text-secondary text-[20px]">forum</span>
|
||||
<span class="font-label-data text-label-data uppercase tracking-wider truncate">STAGING CHAT</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
// Simple interactive toggle for safety checks
|
||||
function toggleCheck(btn) {
|
||||
const icon = btn.querySelector('.check-icon');
|
||||
const isChecked = icon.textContent.trim() === 'check_circle';
|
||||
if (isChecked) {
|
||||
icon.textContent = 'radio_button_unchecked';
|
||||
icon.classList.remove('text-primary-container');
|
||||
icon.classList.add('text-outline');
|
||||
} else {
|
||||
icon.textContent = 'check_circle';
|
||||
icon.classList.remove('text-outline');
|
||||
icon.classList.add('text-primary-container');
|
||||
}
|
||||
updateChecklistCount();
|
||||
}
|
||||
|
||||
function updateChecklistCount() {
|
||||
const all = document.querySelectorAll('#checklist-items .check-icon');
|
||||
let completed = 0;
|
||||
all.forEach(ic => {
|
||||
if (ic.textContent.trim() === 'check_circle') completed++;
|
||||
});
|
||||
const label = document.getElementById('checklist-progress');
|
||||
if (label) {
|
||||
label.textContent = completed + ' / ' + all.length + (completed === all.length ? ' READY' : ' PENDING');
|
||||
}
|
||||
}
|
||||
|
||||
// Interactive primary button state
|
||||
function handlePrimaryCheckIn(btn) {
|
||||
btn.innerHTML = '<span class="material-symbols-outlined text-[26px] animate-spin">sync</span> <span class="tracking-wide uppercase">LINKED TO PACK MESH (CH-04)</span>';
|
||||
btn.classList.remove('bg-primary-container', 'text-on-primary');
|
||||
btn.classList.add('bg-surface-container-highest', 'text-primary-container');
|
||||
}
|
||||
|
||||
// Monospace KSU Countdown micro-tick
|
||||
(function initKsuClock() {
|
||||
let totalSeconds = 35 * 60 + 12;
|
||||
const timerElem = document.getElementById('ksu-timer');
|
||||
if (!timerElem) return;
|
||||
|
||||
setInterval(() => {
|
||||
if (totalSeconds > 0) {
|
||||
totalSeconds--;
|
||||
const hours = Math.floor(totalSeconds / 3600);
|
||||
const mins = Math.floor((totalSeconds % 3600) / 60);
|
||||
const secs = totalSeconds % 60;
|
||||
const fmt = String(hours).padStart(2, '0') + ':' +
|
||||
String(mins).padStart(2, '0') + ':' +
|
||||
String(secs).padStart(2, '0');
|
||||
timerElem.textContent = fmt;
|
||||
}
|
||||
}, 1000);
|
||||
})();
|
||||
</script></main><nav class="fixed bottom-0 w-full z-50 pb-safe bg-surface-container-lowest/90 backdrop-blur-xl shadow-[0_-4px_24px_rgba(0,0,0,0.6)]" data-active-classes="text-primary-container font-headline-sm [filter:drop-shadow(0_0_8px_rgba(0,229,255,0.5))]"><div class="grid grid-cols-6 items-center h-20 px-space-xs"><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="cockpit-dash" href="#"><span class="material-symbols-outlined text-[24px]">speed</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Dash</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="tactical-radar-map" href="#"><span class="material-symbols-outlined text-[24px]">radar</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Map</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="telemetry-log" href="#"><span class="material-symbols-outlined text-[24px]">monitoring</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Activity</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="bike-garage" href="#"><span class="material-symbols-outlined text-[24px]">two_wheeler</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Garage</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="pack-comms" href="#"><span class="material-symbols-outlined text-[24px]">groups_3</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Social</span></a><a class="flex flex-col items-center justify-center min-h-[48px] min-w-[48px] py-1 text-on-surface-variant hover:text-primary transition-all duration-200" data-path="hud-settings" href="#"><span class="material-symbols-outlined text-[24px]">tune</span><span class="font-label-caption text-label-caption uppercase mt-0.5 tracking-wider">Settings</span></a></div></nav></body></html>
|
||||
|
|
@ -0,0 +1,478 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<html class="dark" lang="en"><head><meta charset="utf-8"/><meta content="width=device-width, initial-scale=1.0" name="viewport"/><meta content="web_standard" name="shell-type"/><title>MotorSignal Telemetry</title><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&family=JetBrains+Mono:wght@500;600;700&family=Space+Grotesk:wght@600;700&display=swap" rel="stylesheet"/><link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/><style>@layer base { html, body { margin: 0; padding: 0; } body { overscroll-behavior: none; } main > :first-child { margin-top: 0 !important; } main > :last-child { margin-bottom: 0 !important; } } ::-webkit-scrollbar { display: none; }</style><script src="https://cdn.tailwindcss.com"></script><script id="tailwind-config">tailwind.config = { darkMode: "class", theme: { extend: { "colors": { "on-tertiary": "#3c0091", "on-primary": "#00363d", "error-container": "#93000a", "on-secondary": "#002a78", "inverse-on-surface": "#2d3036", "on-error-container": "#ffdad6", "secondary-fixed": "#dbe1ff", "surface-container-low": "#181c21", "outline-variant": "#3b494c", "surface-variant": "#32353b", "background": "#101419", "on-surface-variant": "#bac9cc", "on-surface": "#e0e2ea", "on-background": "#e0e2ea", "on-primary-container": "#00626e", "on-secondary-container": "#cdd7ff", "primary-container": "#00e5ff", "primary": "#c3f5ff", "on-primary-fixed-variant": "#004f58", "on-primary-fixed": "#001f24", "tertiary": "#f2e9ff", "on-tertiary-fixed-variant": "#5516be", "surface-container-high": "#272a30", "surface-dim": "#101419", "primary-fixed": "#9cf0ff", "tertiary-fixed": "#e9ddff", "on-secondary-fixed": "#00174b", "error": "#ffb4ab", "on-secondary-fixed-variant": "#003ea8", "on-error": "#690005", "inverse-primary": "#006875", "inverse-surface": "#e0e2ea", "surface-container-highest": "#32353b", "secondary": "#b4c5ff", "surface": "#101419", "tertiary-container": "#d9c8ff", "surface-bright": "#36393f", "secondary-container": "#0053db", "on-tertiary-fixed": "#23005c", "surface-container": "#1d2025", "surface-container-lowest": "#0b0e13", "on-tertiary-container": "#6834d1", "secondary-fixed-dim": "#b4c5ff", "outline": "#849396", "surface-tint": "#00daf3", "primary-fixed-dim": "#00daf3", "tertiary-fixed-dim": "#d0bcff" }, "borderRadius": { "DEFAULT": "0.25rem", "lg": "0.5rem", "xl": "0.75rem", "full": "9999px" }, "spacing": { "margin": "1rem", "gutter-lg": "1.5rem", "space-md": "1rem", "space-xs": "0.25rem", "space-lg": "1.5rem", "space-xl": "2rem", "space-sm": "0.5rem", "margin-lg": "2rem", "gutter": "1rem" }, "fontFamily": { "body-md": ["Inter"], "display-hero": ["Space Grotesk"], "label-data": ["JetBrains Mono"], "telemetry-metric-lg-mobile": ["JetBrains Mono"], "headline-lg": ["Space Grotesk"], "telemetry-metric-lg": ["JetBrains Mono"], "label-caption": ["Inter"], "headline-sm": ["Space Grotesk"], "headline-md": ["Space Grotesk"], "body-lg": ["Inter"], "telemetry-metric-md": ["JetBrains Mono"], "display-hero-mobile": ["Space Grotesk"] }, "fontSize": { "body-md": ["14px", { "lineHeight": "20px", "fontWeight": "400" }], "display-hero": ["56px", { "lineHeight": "60px", "letterSpacing": "-0.03em", "fontWeight": "700" }], "label-data": ["12px", { "lineHeight": "16px", "letterSpacing": "0.08em", "fontWeight": "600" }], "telemetry-metric-lg-mobile": ["36px", { "lineHeight": "36px", "letterSpacing": "-0.03em", "fontWeight": "700" }], "headline-lg": ["32px", { "lineHeight": "40px", "letterSpacing": "-0.02em", "fontWeight": "700" }], "telemetry-metric-lg": ["48px", { "lineHeight": "48px", "letterSpacing": "-0.04em", "fontWeight": "700" }], "label-caption": ["11px", { "lineHeight": "14px", "letterSpacing": "0.05em", "fontWeight": "600" }], "headline-sm": ["20px", { "lineHeight": "28px", "fontWeight": "600" }], "headline-md": ["24px", { "lineHeight": "32px", "letterSpacing": "-0.01em", "fontWeight": "600" }], "body-lg": ["16px", { "lineHeight": "24px", "fontWeight": "500" }], "telemetry-metric-md": ["28px", { "lineHeight": "32px", "letterSpacing": "-0.02em", "fontWeight": "600" }], "display-hero-mobile": ["40px", { "lineHeight": "44px", "letterSpacing": "-0.02em", "fontWeight": "700" }] } } } };</script></head><body class="bg-surface text-on-surface font-body-md antialiased selection:bg-primary-container selection:text-on-primary"><header class="fixed top-0 left-0 right-0 z-50 bg-surface/90 backdrop-blur-xl shadow-[0_1px_8px_rgba(0,0,0,0.4)]"><div class="h-20 w-full px-gutter-lg flex items-center justify-between gap-space-md"><div class="flex items-center gap-space-lg"><a class="flex items-center gap-space-sm group" href="#"><img alt="Brand logo. - Primary color: #00e5ff
|
||||
- Font: spaceGrotesk
|
||||
- Mode: dark
|
||||
- Roundness: rounded-md
|
||||
" class="h-8 w-auto object-contain" src="https://lh3.googleusercontent.com/aida/AEtjO1UTw8rBQQ-sNGfIk81zYX1u7rT7_IcgGT6GjJCfVJDKecDfGr1MrPEVgjII5_MK3wj6tO6Qw2ZfHhqwrKxHdNrJUGxFOlXalVgFnDtgpjoNDSFtltDk6syCaK_mTdC1xPJqngCTTc2T43fBqyYBnwQANHFTwwGJ646jmbPtJavdn15iGT6wqfLaoJpDew60SUt_hG1nouBFUYDMxOiNIIgnWfkgJ04aTmmTNXr6Ca7776OBqr3haTpFHQ"/><span class="font-headline-sm text-headline-sm uppercase tracking-wider text-primary group-hover:text-primary-container transition-colors">MotorSignal</span></a><nav class="hidden xl:flex items-center gap-space-md" data-active-classes="text-primary-container font-headline-sm"><a class="text-on-surface-variant font-label-data text-label-data uppercase tracking-wider hover:text-on-surface transition-colors px-space-xs py-space-xs" data-path="features" href="#">Features</a><a class="text-on-surface-variant font-label-data text-label-data uppercase tracking-wider hover:text-on-surface transition-colors px-space-xs py-space-xs" data-path="group-rides" href="#">Group Rides</a><a class="text-on-surface-variant font-label-data text-label-data uppercase tracking-wider hover:text-on-surface transition-colors px-space-xs py-space-xs" data-path="clubs" href="#">Clubs</a><a aria-current="page" class="uppercase tracking-wider transition-colors px-space-xs py-space-xs text-primary-container font-headline-sm" data-path="pricing" href="#">Pricing</a><a class="text-on-surface-variant font-label-data text-label-data uppercase tracking-wider hover:text-on-surface transition-colors px-space-xs py-space-xs" data-path="download" href="#">Download</a><a class="text-on-surface-variant font-label-data text-label-data uppercase tracking-wider hover:text-on-surface transition-colors px-space-xs py-space-xs" data-path="support" href="#">Support</a><a class="text-on-surface-variant font-label-data text-label-data uppercase tracking-wider hover:text-on-surface transition-colors px-space-xs py-space-xs" data-path="admin-console" href="#">Admin Console</a></nav></div><div class="flex items-center gap-space-md"><div class="hidden md:flex items-center gap-space-xs px-space-sm py-space-xs rounded-full bg-surface-container-low shadow-[0_0_12px_rgba(0,229,255,0.15)]"><span class="w-2 h-2 rounded-full bg-primary-container animate-pulse"></span><span class="font-label-data text-label-data text-primary uppercase">20Hz Kalman Online</span></div><a class="inline-flex items-center justify-center h-12 px-space-md rounded-lg bg-primary-container text-on-primary font-label-data text-label-data uppercase tracking-wider shadow-[0_0_16px_rgba(0,229,255,0.35)] hover:bg-primary hover:text-on-primary transition-all duration-200 active:scale-[0.98]" href="#">Download App</a><div class="flex items-center gap-space-xs pl-space-xs"><img alt="Profile" class="w-8 h-8 rounded-full object-cover ring-2 ring-surface-container-high" src="https://lh3.googleusercontent.com/aida/AEtjO1XyAAxLiegDwfGfDOfnmd9desjMVj3kxU_bPrvNgMXtcbq65IhKW7uieorRmFWWL7_4VvnpTq8N2pToWOm8TSGRSiftlbFyjQPawmL20y9w0BQJjvgVum3Q8IdqGLli9RZ-16Yv2wJ36FHEwrk4T1IQTob8mc_BjN7g9c3Ic_Xz0pzHgZVxjjahryKv77ULhtLXK5wYZadicArshGkykAEqRbTPZfDNZ-YNLSAN51PoR4wbt46K46HLSvs"/></div></div></div></header><main class="w-full pt-20 bg-surface min-h-[calc(100vh-80px)]"><div class="flex flex-col w-full">
|
||||
<!-- Subtle Tactical Ambient Background Elements -->
|
||||
<div class="relative w-full overflow-hidden">
|
||||
<div class="absolute -top-40 left-1/2 -translate-x-1/2 w-[850px] h-[400px] bg-primary-container/10 blur-[130px] rounded-full pointer-events-none -z-10"></div>
|
||||
<div class="absolute top-[600px] right-0 w-[450px] h-[350px] bg-secondary-container/15 blur-[120px] rounded-full pointer-events-none -z-10"></div>
|
||||
<!-- Pricing Header & Billing Controls Section -->
|
||||
<section class="w-full px-gutter-lg pt-space-xl pb-space-lg flex flex-col items-center text-center">
|
||||
<div class="inline-flex items-center gap-space-xs px-space-sm py-space-xs rounded-full bg-surface-container mb-space-md shadow-sm">
|
||||
<span class="w-2 h-2 rounded-full bg-primary-container animate-ping"></span>
|
||||
<span class="font-label-data text-label-data text-primary uppercase tracking-widest">AERO-GRADE PRECISION TELEMETRY</span>
|
||||
</div>
|
||||
<h1 class="font-display-hero text-headline-lg md:text-display-hero text-on-surface max-w-4xl tracking-tight">
|
||||
Transparent Pricing for Solo Carvers and Pack Captains
|
||||
</h1>
|
||||
<p class="font-body-lg text-body-lg text-on-surface-variant max-w-2xl mt-space-sm mb-space-xl">
|
||||
Choose the telemetry precision that matches your riding ambitions. Real-time 20Hz sensor fusion, instant radar pings, and synchronized mesh telemetry with zero latency.
|
||||
</p>
|
||||
<!-- Billing Period Switcher -->
|
||||
<div class="flex items-center gap-space-md bg-surface-container-low p-space-xs rounded-xl shadow-md">
|
||||
<button class="px-space-md py-space-sm rounded-lg font-label-data text-label-data uppercase tracking-wider transition-all duration-200 text-on-surface-variant hover:text-on-surface" id="btn-monthly" onclick="switchBilling('monthly')" type="button">
|
||||
Monthly Billing
|
||||
</button>
|
||||
<div class="relative">
|
||||
<button class="px-space-md py-space-sm rounded-lg bg-primary-container text-on-primary font-label-data text-label-data uppercase tracking-wider shadow-lg transition-all duration-200" id="btn-annual" onclick="switchBilling('annual')" type="button">
|
||||
Annual Billing
|
||||
</button>
|
||||
<span class="absolute -top-3 -right-3 px-space-xs py-0.5 rounded-full bg-surface-container-highest text-primary-container text-label-caption font-label-caption uppercase tracking-wider shadow-[0_0_12px_rgba(0,229,255,0.4)] animate-pulse">
|
||||
SAVE 33%
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- 3-Tier Pricing Card Grid -->
|
||||
<section class="w-full px-gutter-lg py-space-lg">
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-space-lg items-stretch max-w-7xl mx-auto">
|
||||
<!-- Tier 1: Rider Basic -->
|
||||
<div class="flex flex-col justify-between bg-surface-container-low rounded-xl p-space-lg shadow-sm hover:shadow-md transition-shadow">
|
||||
<div>
|
||||
<div class="flex items-center justify-between mb-space-md">
|
||||
<span class="font-label-data text-label-data text-on-surface-variant uppercase tracking-widest">Entry Telemetry</span>
|
||||
<span class="px-space-xs py-0.5 rounded bg-surface-container text-on-surface-variant font-label-caption text-label-caption uppercase">Free Forever</span>
|
||||
</div>
|
||||
<h2 class="font-headline-md text-headline-md text-on-surface">Rider Basic</h2>
|
||||
<p class="font-body-md text-body-md text-on-surface-variant mt-space-xs min-h-[40px]">Essential tactical instruments for casual riders and community weekend curvers.</p>
|
||||
<div class="my-space-lg flex items-baseline gap-space-xs">
|
||||
<span class="font-telemetry-metric-lg text-telemetry-metric-lg text-on-surface">$0</span>
|
||||
<span class="font-label-data text-label-data text-on-surface-variant uppercase">/ forever</span>
|
||||
</div>
|
||||
<div class="h-px w-full bg-surface-variant/40 mb-space-md"></div>
|
||||
<span class="font-label-caption text-label-caption uppercase text-outline tracking-wider block mb-space-sm">Included Precision Specs</span>
|
||||
<ul class="flex flex-col gap-space-sm font-body-md text-body-md text-on-surface">
|
||||
<li class="flex items-start gap-space-sm">
|
||||
<span class="material-symbols-outlined text-primary text-body-lg">speed</span>
|
||||
<span>Standard Cockpit HUD (<span class="font-label-data text-primary">1 Hz</span> GPS sampling)</span>
|
||||
</li>
|
||||
<li class="flex items-start gap-space-sm">
|
||||
<span class="material-symbols-outlined text-primary text-body-lg">folder</span>
|
||||
<span>Up to 10 stored historical rides</span>
|
||||
</li>
|
||||
<li class="flex items-start gap-space-sm">
|
||||
<span class="material-symbols-outlined text-primary text-body-lg">warning</span>
|
||||
<span>Community crowd-sourced hazard alerts</span>
|
||||
</li>
|
||||
<li class="flex items-start gap-space-sm">
|
||||
<span class="material-symbols-outlined text-primary text-body-lg">map</span>
|
||||
<span>Offline OpenStreetMap vector caching</span>
|
||||
</li>
|
||||
<li class="flex items-start gap-space-sm text-outline">
|
||||
<span class="material-symbols-outlined text-outline text-body-lg">block</span>
|
||||
<span class="line-through">Sub-degree 20Hz IMU Kalman filter</span>
|
||||
</li>
|
||||
<li class="flex items-start gap-space-sm text-outline">
|
||||
<span class="material-symbols-outlined text-outline text-body-lg">block</span>
|
||||
<span class="line-through">Pack-mesh live proximity telemetry</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="pt-space-xl">
|
||||
<a class="w-full flex items-center justify-center h-12 rounded-lg bg-surface-container hover:bg-surface-container-high text-on-surface font-label-data text-label-data uppercase tracking-wider transition-all duration-150" href="#">
|
||||
Get Started Free
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Tier 2: Pro Rider (Featured / Most Popular) -->
|
||||
<div class="relative flex flex-col justify-between bg-surface-container rounded-xl p-space-lg shadow-xl shadow-primary-container/10 -mt-2 md:-mt-4">
|
||||
<!-- Ambient Neon Top Line -->
|
||||
<div class="absolute inset-x-0 top-0 h-1 bg-gradient-to-r from-primary-container via-primary to-primary-container rounded-t-xl"></div>
|
||||
<div>
|
||||
<div class="flex items-center justify-between mb-space-md">
|
||||
<span class="font-label-data text-label-data text-primary uppercase tracking-widest">Elite Dynamics</span>
|
||||
<span class="px-space-sm py-1 rounded-full bg-primary-container text-on-primary font-label-caption text-label-caption uppercase tracking-wider font-bold shadow-[0_0_12px_rgba(0,229,255,0.4)]">
|
||||
Most Popular
|
||||
</span>
|
||||
</div>
|
||||
<h2 class="font-headline-md text-headline-md text-primary">Pro Rider</h2>
|
||||
<p class="font-body-md text-body-md text-on-surface-variant mt-space-xs min-h-[40px]">Real-time sub-second situational intelligence, 3D lean analysis, and pack synchronization.</p>
|
||||
<div class="my-space-lg flex items-baseline gap-space-xs">
|
||||
<span class="font-telemetry-metric-lg text-telemetry-metric-lg text-primary-container" id="pro-price">$79</span>
|
||||
<span class="font-label-data text-label-data text-on-surface-variant uppercase" id="pro-cycle">/ billed annually</span>
|
||||
</div>
|
||||
<div class="h-px w-full bg-primary-container/20 mb-space-md"></div>
|
||||
<span class="font-label-caption text-label-caption uppercase text-primary tracking-wider block mb-space-sm">Everything in Basic, plus:</span>
|
||||
<ul class="flex flex-col gap-space-sm font-body-md text-body-md text-on-surface">
|
||||
<li class="flex items-start gap-space-sm">
|
||||
<span class="material-symbols-outlined text-primary-container text-body-lg">explore</span>
|
||||
<span><strong class="text-primary-container font-semibold">20 Hz Kalman IMU</strong> sub-degree lean acquisition</span>
|
||||
</li>
|
||||
<li class="flex items-start gap-space-sm">
|
||||
<span class="material-symbols-outlined text-primary-container text-body-lg">radar</span>
|
||||
<span>Real-time Waze & police radar mesh feed</span>
|
||||
</li>
|
||||
<li class="flex items-start gap-space-sm">
|
||||
<span class="material-symbols-outlined text-primary-container text-body-lg">view_in_ar</span>
|
||||
<span>3D interactive cornering lean & apex replay</span>
|
||||
</li>
|
||||
<li class="flex items-start gap-space-sm">
|
||||
<span class="material-symbols-outlined text-primary-container text-body-lg">groups</span>
|
||||
<span>Unlimited Pack Mesh Radar live intervals</span>
|
||||
</li>
|
||||
<li class="flex items-start gap-space-sm">
|
||||
<span class="material-symbols-outlined text-primary-container text-body-lg">timer</span>
|
||||
<span>Draggy launch mode (0-60, 0-100, 1/4 mile)</span>
|
||||
</li>
|
||||
<li class="flex items-start gap-space-sm">
|
||||
<span class="material-symbols-outlined text-primary-container text-body-lg">cloud_done</span>
|
||||
<span>Cloudflare R2 Unlimited Sync & 20Hz CSV exports</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="pt-space-xl">
|
||||
<a class="w-full flex items-center justify-center h-13 py-space-sm rounded-lg bg-primary-container text-on-primary font-label-data text-label-data uppercase tracking-wider shadow-[0_0_20px_rgba(0,229,255,0.4)] hover:bg-primary transition-all duration-200 active:scale-[0.98]" href="#">
|
||||
Start 14-Day Free Trial
|
||||
</a>
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant text-center block mt-space-xs">Instant access • Cancel in 1-click anytime</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Tier 3: Founder Lifetime -->
|
||||
<div class="relative flex flex-col justify-between bg-surface-container-low rounded-xl p-space-lg shadow-sm hover:shadow-md transition-shadow">
|
||||
<div class="absolute inset-x-0 top-0 h-1 bg-gradient-to-r from-tertiary-container via-secondary to-primary rounded-t-xl"></div>
|
||||
<div>
|
||||
<div class="flex items-center justify-between mb-space-md">
|
||||
<span class="font-label-data text-label-data text-tertiary uppercase tracking-widest">Collector Tier</span>
|
||||
<span class="px-space-xs py-0.5 rounded bg-surface-container-high text-tertiary font-label-caption text-label-caption uppercase font-semibold">
|
||||
Single Charge
|
||||
</span>
|
||||
</div>
|
||||
<h2 class="font-headline-md text-headline-md text-tertiary">Founder Lifetime</h2>
|
||||
<p class="font-body-md text-body-md text-on-surface-variant mt-space-xs min-h-[40px]">Permanent unlock of all future engine upgrades plus physical serialized rider regalia.</p>
|
||||
<div class="my-space-lg flex items-baseline gap-space-xs">
|
||||
<span class="font-telemetry-metric-lg text-telemetry-metric-lg text-on-surface">$199</span>
|
||||
<span class="font-label-data text-label-data text-on-surface-variant uppercase">/ one-time</span>
|
||||
</div>
|
||||
<div class="h-px w-full bg-surface-variant/40 mb-space-md"></div>
|
||||
<span class="font-label-caption text-label-caption uppercase text-tertiary tracking-wider block mb-space-sm">All Pro Features Forever, plus:</span>
|
||||
<ul class="flex flex-col gap-space-sm font-body-md text-body-md text-on-surface">
|
||||
<li class="flex items-start gap-space-sm">
|
||||
<span class="material-symbols-outlined text-tertiary text-body-lg">verified</span>
|
||||
<span>Lifetime access guarantee: <strong class="text-tertiary">Zero subscriptions</strong></span>
|
||||
</li>
|
||||
<li class="flex items-start gap-space-sm">
|
||||
<span class="material-symbols-outlined text-tertiary text-body-lg">military_tech</span>
|
||||
<span>Club Founder & Officer Management Toolkit</span>
|
||||
</li>
|
||||
<li class="flex items-start gap-space-sm">
|
||||
<span class="material-symbols-outlined text-tertiary text-body-lg">shield</span>
|
||||
<span>Physical laser-engraved serialized titanium patch</span>
|
||||
</li>
|
||||
<li class="flex items-start gap-space-sm">
|
||||
<span class="material-symbols-outlined text-tertiary text-body-lg">forum</span>
|
||||
<span>Direct VIP Engineering Discord & firmware betas</span>
|
||||
</li>
|
||||
<li class="flex items-start gap-space-sm">
|
||||
<span class="material-symbols-outlined text-tertiary text-body-lg">hub</span>
|
||||
<span>Priority CANbus & custom ECU telemetry onboarding</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="pt-space-xl">
|
||||
<a class="w-full flex items-center justify-center h-12 rounded-lg bg-surface-bright hover:bg-surface-variant text-tertiary font-label-data text-label-data uppercase tracking-wider transition-all duration-200" href="#">
|
||||
Claim Founder Pass
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- Visual Divider with Track Telemetry Context -->
|
||||
<section class="w-full px-gutter-lg my-space-xl max-w-7xl mx-auto">
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-space-md bg-surface-container-lowest p-space-md rounded-xl">
|
||||
<div class="flex items-center gap-space-md p-space-sm">
|
||||
<span class="material-symbols-outlined text-primary-container text-headline-lg">bolt</span>
|
||||
<div>
|
||||
<div class="font-headline-sm text-headline-sm text-on-surface">20Hz IMU Fusion</div>
|
||||
<div class="font-body-md text-body-md text-on-surface-variant">20 discrete spatial points computed every single second.</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-space-md p-space-sm">
|
||||
<span class="material-symbols-outlined text-primary-container text-headline-lg">satellite_alt</span>
|
||||
<div>
|
||||
<div class="font-headline-sm text-headline-sm text-on-surface">Sub-Meter Precision</div>
|
||||
<div class="font-body-md text-body-md text-on-surface-variant">L1+L5 Dual-band GPS integration eliminates city and canyon drift.</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-space-md p-space-sm">
|
||||
<span class="material-symbols-outlined text-primary-container text-headline-lg">wifi_tethering</span>
|
||||
<div>
|
||||
<div class="font-headline-sm text-headline-sm text-on-surface">Peer Mesh Relays</div>
|
||||
<div class="font-body-md text-body-md text-on-surface-variant">Zero cellular required for group member radar and beacon pings.</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- Comprehensive Feature Comparison Breakdown Matrix -->
|
||||
<section class="w-full px-gutter-lg py-space-xl max-w-7xl mx-auto">
|
||||
<div class="flex flex-col gap-space-xs mb-space-lg">
|
||||
<span class="font-label-data text-label-data text-primary-container uppercase tracking-wider">Deep Specifications</span>
|
||||
<h2 class="font-headline-lg text-headline-lg text-on-surface">Comprehensive Feature Comparison</h2>
|
||||
<p class="font-body-md text-body-md text-on-surface-variant">Compare technical capabilities side-by-side to power your individual riding setup.</p>
|
||||
</div>
|
||||
<div class="w-full overflow-x-auto rounded-xl bg-surface-container-low shadow-sm">
|
||||
<table class="w-full text-left border-collapse min-w-[700px]">
|
||||
<thead>
|
||||
<tr class="bg-surface-container text-on-surface font-label-data text-label-data uppercase tracking-wider">
|
||||
<th class="p-space-md w-2/5">Platform Feature</th>
|
||||
<th class="p-space-md w-1/5 text-center">Rider Basic</th>
|
||||
<th class="p-space-md w-1/5 text-center text-primary-container bg-surface-container-high/60">Pro Rider</th>
|
||||
<th class="p-space-md w-1/5 text-center text-tertiary">Founder Pass</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="font-body-md text-body-md divide-y divide-surface-container-high/40">
|
||||
<!-- Section: Core Telemetry & HUD -->
|
||||
<tr class="bg-surface-container-lowest/80">
|
||||
<td class="p-space-sm px-space-md font-label-data text-label-data text-primary uppercase tracking-widest" colspan="4">
|
||||
Core Telemetry & HUD
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="hover:bg-surface-container transition-colors">
|
||||
<td class="p-space-md font-medium text-on-surface">GPS & Accelerometer Frequency</td>
|
||||
<td class="p-space-md text-center font-label-data text-on-surface-variant">1 Hz Standard</td>
|
||||
<td class="p-space-md text-center font-label-data text-primary font-bold bg-surface-container/30">20 Hz Kalman Fusion</td>
|
||||
<td class="p-space-md text-center font-label-data text-tertiary font-bold">20 Hz Kalman Fusion</td>
|
||||
</tr>
|
||||
<tr class="hover:bg-surface-container transition-colors">
|
||||
<td class="p-space-md font-medium text-on-surface">Real-Time Lean Angle HUD</td>
|
||||
<td class="p-space-md text-center text-outline">Approximate (±4°)</td>
|
||||
<td class="p-space-md text-center text-primary-container font-semibold bg-surface-container/30">Sub-Degree (±0.2°)</td>
|
||||
<td class="p-space-md text-center text-primary-container font-semibold">Sub-Degree (±0.2°)</td>
|
||||
</tr>
|
||||
<tr class="hover:bg-surface-container transition-colors">
|
||||
<td class="p-space-md font-medium text-on-surface">3D Apex & Turn Replay</td>
|
||||
<td class="p-space-md text-center text-outline"><span class="material-symbols-outlined text-outline">remove</span></td>
|
||||
<td class="p-space-md text-center bg-surface-container/30"><span class="material-symbols-outlined text-primary-container">check_circle</span></td>
|
||||
<td class="p-space-md text-center"><span class="material-symbols-outlined text-tertiary">check_circle</span></td>
|
||||
</tr>
|
||||
<tr class="hover:bg-surface-container transition-colors">
|
||||
<td class="p-space-md font-medium text-on-surface">Draggy Launch (0-60, 0-100, Quarter Mile)</td>
|
||||
<td class="p-space-md text-center text-outline"><span class="material-symbols-outlined text-outline">remove</span></td>
|
||||
<td class="p-space-md text-center bg-surface-container/30"><span class="material-symbols-outlined text-primary-container">check_circle</span></td>
|
||||
<td class="p-space-md text-center"><span class="material-symbols-outlined text-tertiary">check_circle</span></td>
|
||||
</tr>
|
||||
<!-- Section: Road Hazards & Radar Traps -->
|
||||
<tr class="bg-surface-container-lowest/80">
|
||||
<td class="p-space-sm px-space-md font-label-data text-label-data text-primary uppercase tracking-widest" colspan="4">
|
||||
Road Hazards & Radar Traps
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="hover:bg-surface-container transition-colors">
|
||||
<td class="p-space-md font-medium text-on-surface">Community Road Hazard Pings</td>
|
||||
<td class="p-space-md text-center"><span class="material-symbols-outlined text-on-surface">check_circle</span></td>
|
||||
<td class="p-space-md text-center bg-surface-container/30"><span class="material-symbols-outlined text-primary-container">check_circle</span></td>
|
||||
<td class="p-space-md text-center"><span class="material-symbols-outlined text-tertiary">check_circle</span></td>
|
||||
</tr>
|
||||
<tr class="hover:bg-surface-container transition-colors">
|
||||
<td class="p-space-md font-medium text-on-surface">Waze Live Police & Radar Trap API</td>
|
||||
<td class="p-space-md text-center text-outline"><span class="material-symbols-outlined text-outline">remove</span></td>
|
||||
<td class="p-space-md text-center bg-surface-container/30"><span class="material-symbols-outlined text-primary-container">check_circle</span></td>
|
||||
<td class="p-space-md text-center"><span class="material-symbols-outlined text-tertiary">check_circle</span></td>
|
||||
</tr>
|
||||
<tr class="hover:bg-surface-container transition-colors">
|
||||
<td class="p-space-md font-medium text-on-surface">Gravel / Debris Machine-Vision Prediction</td>
|
||||
<td class="p-space-md text-center text-outline"><span class="material-symbols-outlined text-outline">remove</span></td>
|
||||
<td class="p-space-md text-center bg-surface-container/30"><span class="material-symbols-outlined text-primary-container">check_circle</span></td>
|
||||
<td class="p-space-md text-center"><span class="material-symbols-outlined text-tertiary">check_circle</span></td>
|
||||
</tr>
|
||||
<!-- Section: Pack & Mesh Communication -->
|
||||
<tr class="bg-surface-container-lowest/80">
|
||||
<td class="p-space-sm px-space-md font-label-data text-label-data text-primary uppercase tracking-widest" colspan="4">
|
||||
Pack & Mesh Communication
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="hover:bg-surface-container transition-colors">
|
||||
<td class="p-space-md font-medium text-on-surface">Pack Proximity Radar</td>
|
||||
<td class="p-space-md text-center font-label-data text-on-surface-variant">Up to 2 Riders</td>
|
||||
<td class="p-space-md text-center font-label-data text-primary-container font-semibold bg-surface-container/30">Unlimited Riders</td>
|
||||
<td class="p-space-md text-center font-label-data text-tertiary font-semibold">Unlimited Riders</td>
|
||||
</tr>
|
||||
<tr class="hover:bg-surface-container transition-colors">
|
||||
<td class="p-space-md font-medium text-on-surface">Offline Bluetooth Mesh Relaying</td>
|
||||
<td class="p-space-md text-center text-outline"><span class="material-symbols-outlined text-outline">remove</span></td>
|
||||
<td class="p-space-md text-center bg-surface-container/30"><span class="material-symbols-outlined text-primary-container">check_circle</span></td>
|
||||
<td class="p-space-md text-center"><span class="material-symbols-outlined text-tertiary">check_circle</span></td>
|
||||
</tr>
|
||||
<tr class="hover:bg-surface-container transition-colors">
|
||||
<td class="p-space-md font-medium text-on-surface">Officer Tactical Beacon Intercom Link</td>
|
||||
<td class="p-space-md text-center text-outline"><span class="material-symbols-outlined text-outline">remove</span></td>
|
||||
<td class="p-space-md text-center text-outline bg-surface-container/30"><span class="material-symbols-outlined text-outline">remove</span></td>
|
||||
<td class="p-space-md text-center"><span class="material-symbols-outlined text-tertiary">check_circle</span></td>
|
||||
</tr>
|
||||
<!-- Section: Cloud Sync & Export -->
|
||||
<tr class="bg-surface-container-lowest/80">
|
||||
<td class="p-space-sm px-space-md font-label-data text-label-data text-primary uppercase tracking-widest" colspan="4">
|
||||
Cloud Sync & Export
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="hover:bg-surface-container transition-colors">
|
||||
<td class="p-space-md font-medium text-on-surface">Cloud Ride Retention</td>
|
||||
<td class="p-space-md text-center font-label-data text-on-surface-variant">10 Rides Total</td>
|
||||
<td class="p-space-md text-center font-label-data text-primary bg-surface-container/30">Unlimited R2 Cloud</td>
|
||||
<td class="p-space-md text-center font-label-data text-tertiary">Lifetime Unlimited</td>
|
||||
</tr>
|
||||
<tr class="hover:bg-surface-container transition-colors">
|
||||
<td class="p-space-md font-medium text-on-surface">Telemetry Data Exports</td>
|
||||
<td class="p-space-md text-center font-label-data text-on-surface-variant">Standard GPX</td>
|
||||
<td class="p-space-md text-center font-label-data text-primary bg-surface-container/30">GPX + 20Hz CSV</td>
|
||||
<td class="p-space-md text-center font-label-data text-tertiary">GPX + Raw CANbus/CSV</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
<!-- Money-Back Guarantee Seal & Trust Badge -->
|
||||
<section class="w-full px-gutter-lg py-space-lg max-w-5xl mx-auto">
|
||||
<div class="flex flex-col md:flex-row items-center justify-between gap-space-lg p-space-lg rounded-xl bg-surface-container shadow-md">
|
||||
<div class="flex items-center gap-space-md">
|
||||
<div class="w-16 h-16 rounded-full bg-primary-container/10 flex items-center justify-center shrink-0">
|
||||
<span class="material-symbols-outlined text-primary-container text-display-hero-mobile">verified_user</span>
|
||||
</div>
|
||||
<div>
|
||||
<div class="font-headline-sm text-headline-sm text-on-surface">14-Day Zero-Risk Guarantee</div>
|
||||
<div class="font-body-md text-body-md text-on-surface-variant mt-0.5">
|
||||
Take MotorSignal onto your favorite mountain pass or track circuit. If our 20Hz Kalman HUD does not transform your ride telemetry, cancel instantly with one tap. Zero hurdles.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="shrink-0 flex items-center gap-space-xs font-label-data text-label-data text-primary uppercase">
|
||||
<span class="material-symbols-outlined text-primary">lock</span>
|
||||
<span>Encrypted Stripe Checkout</span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- Dark Tactical FAQ Accordion -->
|
||||
<section class="w-full px-gutter-lg pt-space-lg pb-space-xl max-w-4xl mx-auto">
|
||||
<div class="text-center mb-space-xl">
|
||||
<span class="font-label-data text-label-data text-primary uppercase tracking-widest">Questions & Hardware Support</span>
|
||||
<h2 class="font-headline-lg text-headline-lg text-on-surface mt-space-xs">Frequently Asked Questions</h2>
|
||||
</div>
|
||||
<div class="flex flex-col gap-space-sm" id="faq-list">
|
||||
<!-- FAQ Item 1 -->
|
||||
<div class="rounded-xl bg-surface-container-low overflow-hidden transition-all duration-200">
|
||||
<button class="w-full flex items-center justify-between p-space-md text-left focus:outline-none" onclick="toggleFaq(1)" type="button">
|
||||
<span class="font-headline-sm text-headline-sm text-on-surface">How does 20Hz IMU Kalman fusion work on my phone?</span>
|
||||
<span class="material-symbols-outlined text-on-surface-variant transition-transform duration-200" id="faq-icon-1">expand_more</span>
|
||||
</button>
|
||||
<div class="hidden px-space-md pb-space-md pt-0 font-body-md text-body-md text-on-surface-variant" id="faq-content-1">
|
||||
MotorSignal taps directly into your smartphone's 6-axis gyroscope and accelerometer hardware using native C++ processing pipes. Rather than relying on slow 1Hz GPS updates, our multi-stage Kalman filter cross-calibrates inertial drift against high-frequency satellite coordinates to yield ultra-stable 20Hz pitch and lean calculations.
|
||||
</div>
|
||||
</div>
|
||||
<!-- FAQ Item 2 -->
|
||||
<div class="rounded-xl bg-surface-container-low overflow-hidden transition-all duration-200">
|
||||
<button class="w-full flex items-center justify-between p-space-md text-left focus:outline-none" onclick="toggleFaq(2)" type="button">
|
||||
<span class="font-headline-sm text-headline-sm text-on-surface">Does the HUD work without cellular reception?</span>
|
||||
<span class="material-symbols-outlined text-on-surface-variant transition-transform duration-200" id="faq-icon-2">expand_more</span>
|
||||
</button>
|
||||
<div class="hidden px-space-md pb-space-md pt-0 font-body-md text-body-md text-on-surface-variant" id="faq-content-2">
|
||||
Yes, 100%. MotorSignal caches high-resolution vector topographic maps locally on your device storage. The entire telemetry pipeline—including lean angles, acceleration records, and Bluetooth peer-to-peer pack alerts—operates completely off-grid. When you return to cellular range, your session data seamlessly syncs to the cloud.
|
||||
</div>
|
||||
</div>
|
||||
<!-- FAQ Item 3 -->
|
||||
<div class="rounded-xl bg-surface-container-low overflow-hidden transition-all duration-200">
|
||||
<button class="w-full flex items-center justify-between p-space-md text-left focus:outline-none" onclick="toggleFaq(3)" type="button">
|
||||
<span class="font-headline-sm text-headline-sm text-on-surface">Can I export my telemetry data to external race simulators?</span>
|
||||
<span class="material-symbols-outlined text-on-surface-variant transition-transform duration-200" id="faq-icon-3">expand_more</span>
|
||||
</button>
|
||||
<div class="hidden px-space-md pb-space-md pt-0 font-body-md text-body-md text-on-surface-variant" id="faq-content-3">
|
||||
Pro and Founder passes permit full high-frequency exports in standard 20Hz CSV, GPX, and RaceRender-compatible formats. You can effortlessly ingest your cornering data, G-force vectors, and split times into video overlays like DaVinci Resolve or telemetry analyzers like MoTeC i2.
|
||||
</div>
|
||||
</div>
|
||||
<!-- FAQ Item 4 -->
|
||||
<div class="rounded-xl bg-surface-container-low overflow-hidden transition-all duration-200">
|
||||
<button class="w-full flex items-center justify-between p-space-md text-left focus:outline-none" onclick="toggleFaq(4)" type="button">
|
||||
<span class="font-headline-sm text-headline-sm text-on-surface">What mounting hardware is recommended for vibration damping?</span>
|
||||
<span class="material-symbols-outlined text-on-surface-variant transition-transform duration-200" id="faq-icon-4">expand_more</span>
|
||||
</button>
|
||||
<div class="hidden px-space-md pb-space-md pt-0 font-body-md text-body-md text-on-surface-variant" id="faq-content-4">
|
||||
MotorSignal integrates native software-level low-pass vibration filtering. However, for physical optical image stabilization preservation, we strongly recommend mounts with elastomeric dampers such as the Quad Lock Vibration Dampener or Peak Design Motorcycle Mount.
|
||||
</div>
|
||||
</div>
|
||||
<!-- FAQ Item 5 -->
|
||||
<div class="rounded-xl bg-surface-container-low overflow-hidden transition-all duration-200">
|
||||
<button class="w-full flex items-center justify-between p-space-md text-left focus:outline-none" onclick="toggleFaq(5)" type="button">
|
||||
<span class="font-headline-sm text-headline-sm text-on-surface">How does the 14-day free trial and cancellation policy work?</span>
|
||||
<span class="material-symbols-outlined text-on-surface-variant transition-transform duration-200" id="faq-icon-5">expand_more</span>
|
||||
</button>
|
||||
<div class="hidden px-space-md pb-space-md pt-0 font-body-md text-body-md text-on-surface-variant" id="faq-content-5">
|
||||
When you activate Pro Rider, you receive 14 days of unrestricted access across all telemetry modules. You will receive an automated notification 48 hours prior to trial expiration. You can cancel with a single tap in your cockpit profile settings with zero retention loops or penalty fees.
|
||||
</div>
|
||||
</div>
|
||||
<!-- FAQ Item 6 -->
|
||||
<div class="rounded-xl bg-surface-container-low overflow-hidden transition-all duration-200">
|
||||
<button class="w-full flex items-center justify-between p-space-md text-left focus:outline-none" onclick="toggleFaq(6)" type="button">
|
||||
<span class="font-headline-sm text-headline-sm text-on-surface">What does the Founder Lifetime patch include?</span>
|
||||
<span class="material-symbols-outlined text-on-surface-variant transition-transform duration-200" id="faq-icon-6">expand_more</span>
|
||||
</button>
|
||||
<div class="hidden px-space-md pb-space-md pt-0 font-body-md text-body-md text-on-surface-variant" id="faq-content-6">
|
||||
Each Founder Pass purchase includes a bespoke physical aerospace-grade titanium helmet patch precision laser-engraved with your unique serialized rider callsign, accompanied by lifetime digital entitlement to all v5.x core releases and dedicated engineering Discord priority access.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- Bottom Tactical Call-To-Action Banner -->
|
||||
<section class="w-full px-gutter-lg pb-space-xl max-w-5xl mx-auto">
|
||||
<div class="relative overflow-hidden rounded-xl bg-gradient-to-r from-surface-container via-surface-container-high to-surface-container p-space-lg md:p-space-xl flex flex-col md:flex-row items-center justify-between gap-space-md shadow-lg">
|
||||
<div class="flex flex-col gap-space-xs text-left max-w-xl">
|
||||
<span class="font-label-data text-label-data text-primary-container uppercase tracking-wider">Start Telemetry Recording</span>
|
||||
<h3 class="font-headline-md text-headline-md text-on-surface">Ready to upgrade your cockpit intelligence?</h3>
|
||||
<p class="font-body-md text-body-md text-on-surface-variant">Pair your phone in under 60 seconds. Experience real-time lean angles and pack synchronization on your next ride.</p>
|
||||
</div>
|
||||
<div class="flex items-center gap-space-sm shrink-0">
|
||||
<a class="px-space-md py-space-sm rounded-lg bg-primary-container text-on-primary font-label-data text-label-data uppercase tracking-wider hover:bg-primary shadow-[0_0_16px_rgba(0,229,255,0.3)] transition-all" href="#">
|
||||
Launch Trial Now
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
let currentBilling = 'annual';
|
||||
|
||||
function switchBilling(type) {
|
||||
currentBilling = type;
|
||||
const btnMonthly = document.getElementById('btn-monthly');
|
||||
const btnAnnual = document.getElementById('btn-annual');
|
||||
const proPrice = document.getElementById('pro-price');
|
||||
const proCycle = document.getElementById('pro-cycle');
|
||||
|
||||
if (type === 'monthly') {
|
||||
btnMonthly.className = 'px-space-md py-space-sm rounded-lg bg-primary-container text-on-primary font-label-data text-label-data uppercase tracking-wider shadow-lg transition-all duration-200';
|
||||
btnAnnual.className = 'px-space-md py-space-sm rounded-lg font-label-data text-label-data uppercase tracking-wider transition-all duration-200 text-on-surface-variant hover:text-on-surface';
|
||||
proPrice.textContent = '$9.99';
|
||||
proCycle.textContent = '/ billed monthly';
|
||||
} else {
|
||||
btnAnnual.className = 'px-space-md py-space-sm rounded-lg bg-primary-container text-on-primary font-label-data text-label-data uppercase tracking-wider shadow-lg transition-all duration-200';
|
||||
btnMonthly.className = 'px-space-md py-space-sm rounded-lg font-label-data text-label-data uppercase tracking-wider transition-all duration-200 text-on-surface-variant hover:text-on-surface';
|
||||
proPrice.textContent = '$79';
|
||||
proCycle.textContent = '/ billed annually';
|
||||
}
|
||||
}
|
||||
|
||||
function toggleFaq(index) {
|
||||
const content = document.getElementById(`faq-content-${index}`);
|
||||
const icon = document.getElementById(`faq-icon-${index}`);
|
||||
|
||||
if (content.classList.contains('hidden')) {
|
||||
content.classList.remove('hidden');
|
||||
icon.style.transform = 'rotate(180deg)';
|
||||
} else {
|
||||
content.classList.add('hidden');
|
||||
icon.style.transform = 'rotate(0deg)';
|
||||
}
|
||||
}
|
||||
</script></main><footer class="w-full bg-surface-container-lowest pt-space-xl pb-space-lg"><div class="w-full px-gutter-lg"><div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-5 gap-space-lg pb-space-lg"><div class="lg:col-span-2 flex flex-col gap-space-sm"><div class="flex items-center gap-space-sm"><span class="font-headline-sm text-headline-sm uppercase tracking-wider text-primary">MotorSignal</span><span class="px-space-xs py-space-xs rounded font-label-caption text-label-caption bg-surface-container text-primary-container uppercase">Precision Cockpit HUD</span></div><p class="font-body-md text-body-md text-on-surface-variant max-w-md">Next-generation telemetry engine engineered for track day racers, aggressive sport riders, and synchronized pack navigation with real-time IMU lean angle computation.</p><div class="flex items-center gap-space-sm pt-space-xs"><span class="w-2.5 h-2.5 rounded-full bg-primary-container shadow-[0_0_8px_#00e5ff]"></span><span class="font-label-data text-label-data text-on-surface uppercase">Telemetry Core v4.8.2 Active</span></div></div><div class="flex flex-col gap-space-sm"><span class="font-label-data text-label-data text-primary uppercase tracking-wider">Platform Modules</span><ul class="flex flex-col gap-space-xs"><li class="font-body-md text-body-md text-on-surface-variant hover:text-on-surface transition-colors cursor-pointer">Telemetry Specs</li><li class="font-body-md text-body-md text-on-surface-variant hover:text-on-surface transition-colors cursor-pointer">Curvy Routes</li><li class="font-body-md text-body-md text-on-surface-variant hover:text-on-surface transition-colors cursor-pointer">Pack Radar</li><li class="font-body-md text-body-md text-on-surface-variant hover:text-on-surface transition-colors cursor-pointer">Draggy Launch</li></ul></div><div class="flex flex-col gap-space-sm"><span class="font-label-data text-label-data text-primary uppercase tracking-wider">Ecosystem</span><ul class="flex flex-col gap-space-xs"><li class="font-body-md text-body-md text-on-surface-variant hover:text-on-surface transition-colors cursor-pointer">OBD-II CANbus Link</li><li class="font-body-md text-body-md text-on-surface-variant hover:text-on-surface transition-colors cursor-pointer">IMU 6-Axis Calibration</li><li class="font-body-md text-body-md text-on-surface-variant hover:text-on-surface transition-colors cursor-pointer">Corner Trajectory AI</li><li class="font-body-md text-body-md text-on-surface-variant hover:text-on-surface transition-colors cursor-pointer">G-Force Mapping</li></ul></div><div class="flex flex-col gap-space-sm"><span class="font-label-data text-label-data text-primary uppercase tracking-wider">Governance</span><ul class="flex flex-col gap-space-xs"><li class="font-body-md text-body-md text-on-surface-variant hover:text-on-surface transition-colors cursor-pointer">Privacy Architecture</li><li class="font-body-md text-body-md text-on-surface-variant hover:text-on-surface transition-colors cursor-pointer">Telemetry Terms</li><li class="font-body-md text-body-md text-on-surface-variant hover:text-on-surface transition-colors cursor-pointer">Safety Disclaimers</li><li class="font-body-md text-body-md text-on-surface-variant hover:text-on-surface transition-colors cursor-pointer">Mesh Node Protocol</li></ul></div></div><div class="pt-space-md flex flex-col md:flex-row items-center justify-between gap-space-sm"><span class="font-label-caption text-label-caption text-on-surface-variant uppercase">© 2025 MotorSignal Technologies Inc. Built for zero-cognitive lag.</span><div class="flex items-center gap-space-md"><span class="font-label-caption text-label-caption text-on-surface-variant uppercase">All nodes operational</span><span class="font-label-data text-label-data text-primary">99.98% Latency <14ms</span></div></div></div></footer></body></html>
|
||||
|
|
@ -0,0 +1,459 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<html class="dark" lang="en"><head><meta charset="utf-8"/><meta content="width=device-width, initial-scale=1.0" name="viewport"/><meta content="web_standard" name="shell-type"/><title>MotorSignal Telemetry</title><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&family=JetBrains+Mono:wght@500;600;700&family=Space+Grotesk:wght@600;700&display=swap" rel="stylesheet"/><link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/><style>@layer base { html, body { margin: 0; padding: 0; } body { overscroll-behavior: none; } main > :first-child { margin-top: 0 !important; } main > :last-child { margin-bottom: 0 !important; } } ::-webkit-scrollbar { display: none; }</style><script src="https://cdn.tailwindcss.com"></script><script id="tailwind-config">tailwind.config = { darkMode: "class", theme: { extend: { "colors": { "on-tertiary": "#3c0091", "on-primary": "#00363d", "error-container": "#93000a", "on-secondary": "#002a78", "inverse-on-surface": "#2d3036", "on-error-container": "#ffdad6", "secondary-fixed": "#dbe1ff", "surface-container-low": "#181c21", "outline-variant": "#3b494c", "surface-variant": "#32353b", "background": "#101419", "on-surface-variant": "#bac9cc", "on-surface": "#e0e2ea", "on-background": "#e0e2ea", "on-primary-container": "#00626e", "on-secondary-container": "#cdd7ff", "primary-container": "#00e5ff", "primary": "#c3f5ff", "on-primary-fixed-variant": "#004f58", "on-primary-fixed": "#001f24", "tertiary": "#f2e9ff", "on-tertiary-fixed-variant": "#5516be", "surface-container-high": "#272a30", "surface-dim": "#101419", "primary-fixed": "#9cf0ff", "tertiary-fixed": "#e9ddff", "on-secondary-fixed": "#00174b", "error": "#ffb4ab", "on-secondary-fixed-variant": "#003ea8", "on-error": "#690005", "inverse-primary": "#006875", "inverse-surface": "#e0e2ea", "surface-container-highest": "#32353b", "secondary": "#b4c5ff", "surface": "#101419", "tertiary-container": "#d9c8ff", "surface-bright": "#36393f", "secondary-container": "#0053db", "on-tertiary-fixed": "#23005c", "surface-container": "#1d2025", "surface-container-lowest": "#0b0e13", "on-tertiary-container": "#6834d1", "secondary-fixed-dim": "#b4c5ff", "outline": "#849396", "surface-tint": "#00daf3", "primary-fixed-dim": "#00daf3", "tertiary-fixed-dim": "#d0bcff" }, "borderRadius": { "DEFAULT": "0.25rem", "lg": "0.5rem", "xl": "0.75rem", "full": "9999px" }, "spacing": { "margin": "1rem", "gutter-lg": "1.5rem", "space-md": "1rem", "space-xs": "0.25rem", "space-lg": "1.5rem", "space-xl": "2rem", "space-sm": "0.5rem", "margin-lg": "2rem", "gutter": "1rem" }, "fontFamily": { "body-md": ["Inter"], "display-hero": ["Space Grotesk"], "label-data": ["JetBrains Mono"], "telemetry-metric-lg-mobile": ["JetBrains Mono"], "headline-lg": ["Space Grotesk"], "telemetry-metric-lg": ["JetBrains Mono"], "label-caption": ["Inter"], "headline-sm": ["Space Grotesk"], "headline-md": ["Space Grotesk"], "body-lg": ["Inter"], "telemetry-metric-md": ["JetBrains Mono"], "display-hero-mobile": ["Space Grotesk"] }, "fontSize": { "body-md": ["14px", { "lineHeight": "20px", "fontWeight": "400" }], "display-hero": ["56px", { "lineHeight": "60px", "letterSpacing": "-0.03em", "fontWeight": "700" }], "label-data": ["12px", { "lineHeight": "16px", "letterSpacing": "0.08em", "fontWeight": "600" }], "telemetry-metric-lg-mobile": ["36px", { "lineHeight": "36px", "letterSpacing": "-0.03em", "fontWeight": "700" }], "headline-lg": ["32px", { "lineHeight": "40px", "letterSpacing": "-0.02em", "fontWeight": "700" }], "telemetry-metric-lg": ["48px", { "lineHeight": "48px", "letterSpacing": "-0.04em", "fontWeight": "700" }], "label-caption": ["11px", { "lineHeight": "14px", "letterSpacing": "0.05em", "fontWeight": "600" }], "headline-sm": ["20px", { "lineHeight": "28px", "fontWeight": "600" }], "headline-md": ["24px", { "lineHeight": "32px", "letterSpacing": "-0.01em", "fontWeight": "600" }], "body-lg": ["16px", { "lineHeight": "24px", "fontWeight": "500" }], "telemetry-metric-md": ["28px", { "lineHeight": "32px", "letterSpacing": "-0.02em", "fontWeight": "600" }], "display-hero-mobile": ["40px", { "lineHeight": "44px", "letterSpacing": "-0.02em", "fontWeight": "700" }] } } } };</script></head><body class="bg-surface text-on-surface font-body-md antialiased selection:bg-primary-container selection:text-on-primary"><header class="fixed top-0 left-0 right-0 z-50 bg-surface/90 backdrop-blur-xl shadow-[0_1px_8px_rgba(0,0,0,0.4)]"><div class="h-20 w-full px-gutter-lg flex items-center justify-between gap-space-md"><div class="flex items-center gap-space-lg"><a class="flex items-center gap-space-sm group" href="#"><img alt="Brand logo. - Primary color: #00e5ff
|
||||
- Font: spaceGrotesk
|
||||
- Mode: dark
|
||||
- Roundness: rounded-md
|
||||
" class="h-8 w-auto object-contain" src="https://lh3.googleusercontent.com/aida/AEtjO1UTw8rBQQ-sNGfIk81zYX1u7rT7_IcgGT6GjJCfVJDKecDfGr1MrPEVgjII5_MK3wj6tO6Qw2ZfHhqwrKxHdNrJUGxFOlXalVgFnDtgpjoNDSFtltDk6syCaK_mTdC1xPJqngCTTc2T43fBqyYBnwQANHFTwwGJ646jmbPtJavdn15iGT6wqfLaoJpDew60SUt_hG1nouBFUYDMxOiNIIgnWfkgJ04aTmmTNXr6Ca7776OBqr3haTpFHQ"/><span class="font-headline-sm text-headline-sm uppercase tracking-wider text-primary group-hover:text-primary-container transition-colors">MotorSignal</span></a><nav class="hidden xl:flex items-center gap-space-md" data-active-classes="text-primary-container font-headline-sm"><a class="text-on-surface-variant font-label-data text-label-data uppercase tracking-wider hover:text-on-surface transition-colors px-space-xs py-space-xs" data-path="features" href="#">Features</a><a class="text-on-surface-variant font-label-data text-label-data uppercase tracking-wider hover:text-on-surface transition-colors px-space-xs py-space-xs" data-path="group-rides" href="#">Group Rides</a><a class="text-on-surface-variant font-label-data text-label-data uppercase tracking-wider hover:text-on-surface transition-colors px-space-xs py-space-xs" data-path="clubs" href="#">Clubs</a><a class="text-on-surface-variant font-label-data text-label-data uppercase tracking-wider hover:text-on-surface transition-colors px-space-xs py-space-xs" data-path="pricing" href="#">Pricing</a><a aria-current="page" class="uppercase tracking-wider transition-colors px-space-xs py-space-xs text-primary-container font-headline-sm" data-path="download" href="#">Download</a><a class="text-on-surface-variant font-label-data text-label-data uppercase tracking-wider hover:text-on-surface transition-colors px-space-xs py-space-xs" data-path="support" href="#">Support</a><a class="text-on-surface-variant font-label-data text-label-data uppercase tracking-wider hover:text-on-surface transition-colors px-space-xs py-space-xs" data-path="admin-console" href="#">Admin Console</a></nav></div><div class="flex items-center gap-space-md"><div class="hidden md:flex items-center gap-space-xs px-space-sm py-space-xs rounded-full bg-surface-container-low shadow-[0_0_12px_rgba(0,229,255,0.15)]"><span class="w-2 h-2 rounded-full bg-primary-container animate-pulse"></span><span class="font-label-data text-label-data text-primary uppercase">20Hz Kalman Online</span></div><a class="inline-flex items-center justify-center h-12 px-space-md rounded-lg bg-primary-container text-on-primary font-label-data text-label-data uppercase tracking-wider shadow-[0_0_16px_rgba(0,229,255,0.35)] hover:bg-primary hover:text-on-primary transition-all duration-200 active:scale-[0.98]" href="#">Download App</a><div class="flex items-center gap-space-xs pl-space-xs"><img alt="Profile" class="w-8 h-8 rounded-full object-cover ring-2 ring-surface-container-high" src="https://lh3.googleusercontent.com/aida/AEtjO1XyAAxLiegDwfGfDOfnmd9desjMVj3kxU_bPrvNgMXtcbq65IhKW7uieorRmFWWL7_4VvnpTq8N2pToWOm8TSGRSiftlbFyjQPawmL20y9w0BQJjvgVum3Q8IdqGLli9RZ-16Yv2wJ36FHEwrk4T1IQTob8mc_BjN7g9c3Ic_Xz0pzHgZVxjjahryKv77ULhtLXK5wYZadicArshGkykAEqRbTPZfDNZ-YNLSAN51PoR4wbt46K46HLSvs"/></div></div></div></header><main class="w-full pt-20 bg-surface min-h-[calc(100vh-80px)]"><div class="flex flex-col w-full">
|
||||
<!-- Subtle Tactical Ambient Backdrop -->
|
||||
<div class="relative w-full overflow-hidden px-gutter-lg py-space-xl">
|
||||
<!-- Glow blooms -->
|
||||
<div class="absolute -top-32 left-1/4 w-96 h-96 bg-primary-container/10 rounded-full blur-[120px] pointer-events-none"></div>
|
||||
<div class="absolute top-1/2 right-10 w-80 h-80 bg-secondary-container/15 rounded-full blur-[140px] pointer-events-none"></div>
|
||||
<!-- MAIN TWO-COLUMN DOWNLOAD HUB -->
|
||||
<div class="max-w-7xl mx-auto w-full grid grid-cols-1 lg:grid-cols-12 gap-space-xl items-start">
|
||||
<!-- LEFT COLUMN: Primary Release & Platform Handshake (Span 7) -->
|
||||
<div class="lg:col-span-7 flex flex-col gap-space-lg">
|
||||
<!-- Status Pill Tag -->
|
||||
<div class="inline-flex items-center gap-space-xs self-start px-space-sm py-space-xs rounded-full bg-surface-container-low shadow-[0_0_16px_rgba(0,229,255,0.1)]">
|
||||
<span class="w-2 h-2 rounded-full bg-primary-container animate-ping"></span>
|
||||
<span class="font-label-data text-label-data text-primary uppercase tracking-wider">STABLE RELEASE • BUILD 2024.10.14</span>
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant/80 ml-space-xs">v1.0.2</span>
|
||||
</div>
|
||||
<!-- Section Title & Descriptor -->
|
||||
<div class="flex flex-col gap-space-xs">
|
||||
<h1 class="font-headline-lg text-headline-lg uppercase tracking-tight text-on-surface">
|
||||
Download MotorSignal <span class="text-primary-container">for Android</span>
|
||||
</h1>
|
||||
<p class="font-body-lg text-body-lg text-on-surface-variant max-w-xl">
|
||||
Direct bare-metal telemetry pipeline. Low-latency 20Hz IMU Kalman engine optimized for high-vibration cockpit mounts and offline telemetry recording.
|
||||
</p>
|
||||
</div>
|
||||
<!-- Technical Metadata Strips (Bento Micro-Grid) -->
|
||||
<div class="grid grid-cols-3 gap-space-sm p-space-md rounded-xl bg-surface-container-low">
|
||||
<div class="flex flex-col">
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant uppercase">Payload Package</span>
|
||||
<span class="font-label-data text-label-data text-primary pt-space-xs">Direct APK v1.0.2</span>
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant">221.4 MB Signed</span>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant uppercase">Target Arch</span>
|
||||
<span class="font-label-data text-label-data text-on-surface pt-space-xs">ARM64-v8a</span>
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant">NEON Vectorized</span>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant uppercase">Runtime Minimum</span>
|
||||
<span class="font-label-data text-label-data text-on-surface pt-space-xs">Android 10.0+</span>
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant">API Level 29+</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- High-Impact Primary Action -->
|
||||
<div class="flex flex-col sm:flex-row items-stretch sm:items-center gap-space-md pt-space-xs">
|
||||
<a class="flex-1 inline-flex items-center justify-between h-14 px-space-lg rounded-xl bg-primary-container text-on-primary font-headline-sm text-headline-sm uppercase tracking-wider shadow-[0_0_24px_rgba(0,229,255,0.4)] hover:bg-primary transition-all duration-200 active:scale-[0.99] group" href="#download-apk" id="directDownloadBtn">
|
||||
<span class="flex items-center gap-space-sm font-label-data text-label-data">
|
||||
<span class="material-symbols-outlined text-on-primary text-[28px]" style="font-variation-settings: 'FILL' 1;">android</span>
|
||||
Download APK (221 MB)
|
||||
</span>
|
||||
<span class="material-symbols-outlined text-on-primary group-hover:translate-y-0.5 transition-transform">download</span>
|
||||
</a>
|
||||
</div>
|
||||
<!-- Secondary Store Channels & Early Access Gate -->
|
||||
<div class="flex flex-wrap items-center gap-space-md pt-space-xs">
|
||||
<!-- Google Play Badge Styled Component -->
|
||||
<a class="inline-flex items-center gap-space-sm h-12 px-space-md rounded-lg bg-surface-container hover:bg-surface-container-high transition-colors" href="https://play.google.com" rel="noopener noreferrer" target="_blank">
|
||||
<svg class="w-5 h-5 fill-current text-primary-container" viewbox="0 0 24 24">
|
||||
<path d="M3.609 1.814L13.792 12 3.61 22.186a2.023 2.023 0 0 1-.22-.916V2.73c0-.333.08-.646.22-.916zm11.3 11.3l2.25 2.25-11.9 6.87 9.65-9.12zm0-2.228L5.259 1.765l11.9 6.871-2.25 2.25zm1.414 1.414l3.18 1.838a1.5 1.5 0 0 1 0 2.593l-3.18 1.838-1.748-1.748 1.748-1.748z"></path>
|
||||
</svg>
|
||||
<div class="flex flex-col text-left">
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant uppercase leading-none">GET IT ON</span>
|
||||
<span class="font-headline-sm text-[13px] text-on-surface leading-tight">Google Play</span>
|
||||
</div>
|
||||
</a>
|
||||
<!-- Apple TestFlight Modal Trigger -->
|
||||
<button class="inline-flex items-center gap-space-sm h-12 px-space-md rounded-lg bg-surface-container hover:bg-surface-container-high transition-colors" id="openTestFlightBtn">
|
||||
<svg class="w-5 h-5 fill-current text-secondary" viewbox="0 0 24 24">
|
||||
<path d="M18.71 19.5c-.83 1.24-1.71 2.45-3.05 2.47-1.34.03-1.77-.79-3.29-.79-1.53 0-2 .77-3.27.82-1.31.05-2.3-1.32-3.14-2.53C4.25 17 2.94 12.45 4.7 9.39c.87-1.52 2.43-2.48 4.12-2.51 1.28-.02 2.5.87 3.29.87.78 0 2.26-1.07 3.81-.91.65.03 2.47.26 3.64 1.98-.09.06-2.17 1.28-2.15 3.81.03 3.02 2.65 4.03 2.68 4.04-.03.07-.42 1.44-1.38 2.83M15.97 6.42c.6-0.73 1.01-1.74.9-2.75-.87.04-1.92.58-2.54 1.31-.55.64-.99 1.66-.86 2.65.97.08 1.9-.48 2.5-1.21z"></path>
|
||||
</svg>
|
||||
<div class="flex flex-col text-left">
|
||||
<span class="font-label-caption text-label-caption text-secondary uppercase leading-none">iOS BETA ACCESS</span>
|
||||
<span class="font-headline-sm text-[13px] text-on-surface leading-tight">TestFlight Waitlist</span>
|
||||
</div>
|
||||
<span class="material-symbols-outlined text-on-surface-variant text-[16px] ml-1">arrow_outward</span>
|
||||
</button>
|
||||
</div>
|
||||
<!-- Telemetry Field Advisory Notice -->
|
||||
<div class="flex items-start gap-space-sm p-space-sm rounded-lg bg-surface-container-lowest">
|
||||
<span class="material-symbols-outlined text-primary-container text-[18px] mt-0.5">verified_user</span>
|
||||
<p class="font-label-caption text-label-caption text-on-surface-variant">
|
||||
Verified build cryptographically signed with MotorSignal Official Release Certificate (Key ID: MS-SIG-8921B). Zero ads, no third-party analytic trackers injected.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- RIGHT COLUMN: Instant Phone QR & Checksum Validator (Span 5) -->
|
||||
<div class="lg:col-span-5 flex flex-col gap-space-md">
|
||||
<!-- Sideload Tactical Card -->
|
||||
<div class="rounded-xl bg-surface-container-low p-space-lg flex flex-col gap-space-md shadow-xl relative overflow-hidden">
|
||||
<div class="absolute top-0 right-0 w-24 h-24 bg-primary-container/5 rounded-bl-full pointer-events-none"></div>
|
||||
<!-- Header & Badge -->
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="font-label-data text-label-data text-primary-container uppercase tracking-wider flex items-center gap-space-xs">
|
||||
<span class="material-symbols-outlined text-[16px]">qr_code_scanner</span>
|
||||
Direct Phone Install
|
||||
</span>
|
||||
<span class="font-label-caption text-label-caption px-space-xs py-0.5 rounded bg-surface-container text-on-surface-variant">FAST SYNC</span>
|
||||
</div>
|
||||
<!-- High-Contrast Custom Telemetry QR Matrix Card -->
|
||||
<div class="flex flex-col items-center justify-center p-space-md rounded-xl bg-surface-container-lowest text-center">
|
||||
<div class="p-3 bg-on-background rounded-lg shadow-md inline-block">
|
||||
<!-- High-Contrast SVG QR code mockup representation -->
|
||||
<svg class="w-44 h-44 text-surface-container-lowest" fill="currentColor" viewbox="0 0 140 140">
|
||||
<!-- Outer Corners -->
|
||||
<rect height="35" rx="3" width="35" x="10" y="10"></rect>
|
||||
<rect fill="#fff" height="25" width="25" x="15" y="15"></rect>
|
||||
<rect height="15" width="15" x="20" y="20"></rect>
|
||||
<rect height="35" rx="3" width="35" x="95" y="10"></rect>
|
||||
<rect fill="#fff" height="25" width="25" x="100" y="15"></rect>
|
||||
<rect height="15" width="15" x="105" y="20"></rect>
|
||||
<rect height="35" rx="3" width="35" x="10" y="95"></rect>
|
||||
<rect fill="#fff" height="25" width="25" x="15" y="100"></rect>
|
||||
<rect height="15" width="15" x="20" y="105"></rect>
|
||||
<!-- Grid Data Points -->
|
||||
<rect height="6" width="6" x="52" y="12"></rect>
|
||||
<rect height="14" width="6" x="64" y="12"></rect>
|
||||
<rect height="6" width="10" x="76" y="12"></rect>
|
||||
<rect height="8" width="8" x="52" y="24"></rect>
|
||||
<rect height="6" width="14" x="72" y="24"></rect>
|
||||
<rect height="14" width="6" x="62" y="36"></rect>
|
||||
<rect height="6" width="12" x="74" y="36"></rect>
|
||||
<rect height="14" width="6" x="12" y="52"></rect>
|
||||
<rect height="6" width="14" x="24" y="58"></rect>
|
||||
<rect height="8" width="8" x="44" y="52"></rect>
|
||||
<rect height="6" width="6" x="58" y="52"></rect>
|
||||
<rect height="6" width="16" x="70" y="52"></rect>
|
||||
<rect height="12" width="6" x="92" y="52"></rect>
|
||||
<rect height="6" width="12" x="104" y="52"></rect>
|
||||
<rect height="14" width="6" x="122" y="52"></rect>
|
||||
<rect height="6" width="12" x="18" y="72"></rect>
|
||||
<rect height="14" width="6" x="36" y="68"></rect>
|
||||
<rect height="6" width="14" x="48" y="68"></rect>
|
||||
<rect height="8" width="8" x="68" y="68"></rect>
|
||||
<rect height="18" width="6" x="82" y="68"></rect>
|
||||
<rect height="6" width="14" x="94" y="70"></rect>
|
||||
<rect height="6" width="14" x="114" y="72"></rect>
|
||||
<rect height="6" width="14" x="52" y="94"></rect>
|
||||
<rect height="14" width="6" x="72" y="94"></rect>
|
||||
<rect height="6" width="8" x="84" y="94"></rect>
|
||||
<rect height="12" width="6" x="98" y="94"></rect>
|
||||
<rect height="6" width="18" x="110" y="94"></rect>
|
||||
<rect height="8" width="8" x="52" y="110"></rect>
|
||||
<rect height="6" width="14" x="66" y="114"></rect>
|
||||
<rect height="18" width="6" x="86" y="110"></rect>
|
||||
<rect height="6" width="14" x="98" y="112"></rect>
|
||||
<rect height="18" width="10" x="118" y="110"></rect>
|
||||
<!-- Center Center Logo Dot -->
|
||||
<circle cx="70" cy="70" fill="#00e5ff" r="7"></circle>
|
||||
</svg>
|
||||
</div>
|
||||
<p class="font-body-md text-[13px] text-on-surface-variant mt-space-sm">
|
||||
Scan with your mobile camera for direct phone installation.
|
||||
</p>
|
||||
</div>
|
||||
<!-- SHA-256 Checksum Container -->
|
||||
<div class="flex flex-col gap-space-xs">
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant uppercase">SHA-256 Checksum Hash</span>
|
||||
<span class="font-label-caption text-label-caption text-primary">APK Hash Verified</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-space-xs p-space-sm rounded-lg bg-surface-container-lowest">
|
||||
<code class="font-label-data text-[11px] text-on-surface truncate flex-1 select-all" id="checksumHash">d41d8cd98f00b204e9800998ecf8427e5a8f27be9b1689b142857489a2469d4c</code>
|
||||
<button class="flex items-center gap-1 px-space-sm py-1 rounded bg-surface-container hover:bg-surface-container-high text-on-surface font-label-caption text-label-caption transition-colors active:scale-95" id="copyHashBtn" title="Copy Hash">
|
||||
<span class="material-symbols-outlined text-[14px]">content_copy</span>
|
||||
<span id="copyText">COPY</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Cryptographic PGP Signature Anchor -->
|
||||
<div class="flex items-center justify-between pt-space-xs">
|
||||
<a class="inline-flex items-center gap-1 font-label-caption text-label-caption text-primary hover:text-primary-container transition-colors uppercase" href="#pgp-signature">
|
||||
<span class="material-symbols-outlined text-[15px]">key</span>
|
||||
Inspect PGP Public Signature (.asc)
|
||||
</a>
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant">RSA 4096-bit</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 3-STEP SIDELOADING INSTALLATION GUIDE -->
|
||||
<section class="w-full bg-surface-container-lowest py-space-xl px-gutter-lg">
|
||||
<div class="max-w-7xl mx-auto w-full flex flex-col gap-space-lg">
|
||||
<!-- Section Header -->
|
||||
<div class="flex flex-col md:flex-row md:items-end justify-between gap-space-sm">
|
||||
<div>
|
||||
<span class="font-label-data text-label-data text-primary-container uppercase tracking-wider">Installation Protocol</span>
|
||||
<h2 class="font-headline-md text-headline-md text-on-surface uppercase mt-1">3-Step Sideloading Setup</h2>
|
||||
</div>
|
||||
<p class="font-body-md text-body-md text-on-surface-variant max-w-md">
|
||||
MotorSignal bypasses Play Services throttling for uninterrupted 20Hz sensor sampling. Sideloading takes less than 60 seconds.
|
||||
</p>
|
||||
</div>
|
||||
<!-- 3-Column Responsive Bento Cards -->
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-space-lg">
|
||||
<!-- Step 1 -->
|
||||
<div class="flex flex-col p-space-lg rounded-xl bg-surface-container-low hover:bg-surface-container transition-colors relative group">
|
||||
<div class="flex items-center justify-between pb-space-md">
|
||||
<span class="w-10 h-10 rounded-lg bg-surface-container flex items-center justify-center font-label-data text-label-data text-primary-container">
|
||||
01
|
||||
</span>
|
||||
<span class="material-symbols-outlined text-on-surface-variant text-[28px]">download_for_offline</span>
|
||||
</div>
|
||||
<h3 class="font-headline-sm text-headline-sm text-on-surface mb-space-xs">Download APK</h3>
|
||||
<p class="font-body-md text-body-md text-on-surface-variant">
|
||||
Save the signed APK package to your Android device via direct download button or instant QR transfer.
|
||||
</p>
|
||||
<div class="mt-space-md pt-space-sm flex items-center gap-space-xs text-primary font-label-caption text-label-caption">
|
||||
<span class="material-symbols-outlined text-[14px]">format_image_left</span>
|
||||
Clean package • VirusTotal 0/72
|
||||
</div>
|
||||
</div>
|
||||
<!-- Step 2 -->
|
||||
<div class="flex flex-col p-space-lg rounded-xl bg-surface-container-low hover:bg-surface-container transition-colors relative group">
|
||||
<div class="flex items-center justify-between pb-space-md">
|
||||
<span class="w-10 h-10 rounded-lg bg-surface-container flex items-center justify-center font-label-data text-label-data text-primary-container">
|
||||
02
|
||||
</span>
|
||||
<span class="material-symbols-outlined text-on-surface-variant text-[28px]">security</span>
|
||||
</div>
|
||||
<h3 class="font-headline-sm text-headline-sm text-on-surface mb-space-xs">Enable Unknown Sources</h3>
|
||||
<p class="font-body-md text-body-md text-on-surface-variant">
|
||||
When prompted by Chrome/Files, tap <span class="text-on-surface font-semibold">Settings</span> and toggle <span class="text-on-surface font-semibold">“Allow from this source”</span> to proceed with local installation.
|
||||
</p>
|
||||
<div class="mt-space-md pt-space-sm flex items-center gap-space-xs text-on-surface-variant font-label-caption text-label-caption">
|
||||
<span class="material-symbols-outlined text-[14px]">info</span>
|
||||
Required for non-PlayStore distributions
|
||||
</div>
|
||||
</div>
|
||||
<!-- Step 3 -->
|
||||
<div class="flex flex-col p-space-lg rounded-xl bg-surface-container-low hover:bg-surface-container transition-colors relative group">
|
||||
<div class="flex items-center justify-between pb-space-md">
|
||||
<span class="w-10 h-10 rounded-lg bg-surface-container flex items-center justify-center font-label-data text-label-data text-primary-container">
|
||||
03
|
||||
</span>
|
||||
<span class="material-symbols-outlined text-on-surface-variant text-[28px]">two_wheeler</span>
|
||||
</div>
|
||||
<h3 class="font-headline-sm text-headline-sm text-on-surface mb-space-xs">Pair Sensors & Ride</h3>
|
||||
<p class="font-body-md text-body-md text-on-surface-variant">
|
||||
Launch MotorSignal, complete the 30-second cockpit IMU calibration, and connect Bluetooth OBD-II or CAN-Bus adapters.
|
||||
</p>
|
||||
<div class="mt-space-md pt-space-sm flex items-center gap-space-xs text-primary-container font-label-caption text-label-caption">
|
||||
<span class="material-symbols-outlined text-[14px]">tune</span>
|
||||
Auto-detects ELM327 & OBDLink LX
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- CHANGELOG & RELEASE NOTES ACCORDION SECTION -->
|
||||
<section class="w-full py-space-xl px-gutter-lg">
|
||||
<div class="max-w-4xl mx-auto w-full flex flex-col gap-space-lg">
|
||||
<div class="flex items-center justify-between flex-wrap gap-space-sm">
|
||||
<div>
|
||||
<span class="font-label-data text-label-data text-primary-container uppercase tracking-wider">Release Telemetry Log</span>
|
||||
<h2 class="font-headline-md text-headline-md text-on-surface uppercase mt-1">Changelog & Architecture Notes</h2>
|
||||
</div>
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant uppercase px-space-sm py-1 rounded bg-surface-container-low">Git Commit: c8f01b9</span>
|
||||
</div>
|
||||
<!-- Accordion Container -->
|
||||
<div class="flex flex-col gap-space-sm" id="changelogAccordion">
|
||||
<!-- Accordion Item 1 (Active/Open - Build 1.0.2) -->
|
||||
<div class="rounded-xl bg-surface-container-low overflow-hidden">
|
||||
<button class="accordion-trigger w-full flex items-center justify-between p-space-md text-left hover:bg-surface-container transition-colors" data-target="build-102">
|
||||
<div class="flex items-center gap-space-md">
|
||||
<span class="w-3 h-3 rounded-full bg-primary-container shadow-[0_0_8px_#00e5ff]"></span>
|
||||
<div class="flex flex-col">
|
||||
<span class="font-headline-sm text-headline-sm text-on-surface">Build 1.0.2 — Tactical Sensor Patch</span>
|
||||
<span class="font-label-caption text-label-caption text-primary">Released October 14, 2024 • Current Stable</span>
|
||||
</div>
|
||||
</div>
|
||||
<span class="material-symbols-outlined text-primary-container transition-transform duration-200 transform rotate-180" id="icon-build-102">expand_more</span>
|
||||
</button>
|
||||
<div class="px-space-md pb-space-md pt-space-xs flex flex-col gap-space-md" id="content-build-102">
|
||||
<div class="p-space-sm rounded-lg bg-surface-container-lowest">
|
||||
<div class="flex items-center gap-space-xs text-primary font-label-data text-label-data uppercase mb-1">
|
||||
<span class="material-symbols-outlined text-[16px]">radar</span>
|
||||
Waze Police Radar & Trap Integration
|
||||
</div>
|
||||
<p class="font-body-md text-body-md text-on-surface-variant">
|
||||
Integrated real-time live community safety & radar beacon feeds into the HUD top alert strip. Audible proximity ping triggers at 800m with automatic glove-friendly dismiss tap.
|
||||
</p>
|
||||
</div>
|
||||
<div class="p-space-sm rounded-lg bg-surface-container-lowest">
|
||||
<div class="flex items-center gap-space-xs text-primary font-label-data text-label-data uppercase mb-1">
|
||||
<span class="material-symbols-outlined text-[16px]">speed</span>
|
||||
Draggy 0-60 Slope Validation Engine
|
||||
</div>
|
||||
<p class="font-body-md text-body-md text-on-surface-variant">
|
||||
Implemented strict SAE-standard 1% maximum downward slope threshold. Incline compensation recalculates pure gravitational acceleration vectors to invalidate false PR runs.
|
||||
</p>
|
||||
</div>
|
||||
<div class="p-space-sm rounded-lg bg-surface-container-lowest">
|
||||
<div class="flex items-center gap-space-xs text-primary font-label-data text-label-data uppercase mb-1">
|
||||
<span class="material-symbols-outlined text-[16px]">database</span>
|
||||
Drift Schema 7 Database Optimizations
|
||||
</div>
|
||||
<p class="font-body-md text-body-md text-on-surface-variant">
|
||||
Upgraded SQLite binary store to Drift v7 schema. Reduced 20Hz continuous logging disk write overhead by 42%, virtually eliminating telemetry dropped packets during 4+ hour track day sessions.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Accordion Item 2 (Build 1.0.1) -->
|
||||
<div class="rounded-xl bg-surface-container-low overflow-hidden">
|
||||
<button class="accordion-trigger w-full flex items-center justify-between p-space-md text-left hover:bg-surface-container transition-colors" data-target="build-101">
|
||||
<div class="flex items-center gap-space-md">
|
||||
<span class="w-3 h-3 rounded-full bg-outline-variant"></span>
|
||||
<div class="flex flex-col">
|
||||
<span class="font-headline-sm text-headline-sm text-on-surface">Build 1.0.1 — Pack Mesh Overhaul</span>
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant">Released September 28, 2024</span>
|
||||
</div>
|
||||
</div>
|
||||
<span class="material-symbols-outlined text-on-surface-variant transition-transform duration-200" id="icon-build-101">expand_more</span>
|
||||
</button>
|
||||
<div class="hidden px-space-md pb-space-md pt-space-xs flex flex-col gap-space-sm" id="content-build-101">
|
||||
<ul class="flex flex-col gap-space-xs font-body-md text-body-md text-on-surface-variant list-disc pl-5">
|
||||
<li>Added offline Bluetooth Low Energy (BLE) Mesh pinging between pack riders when cellular tower connectivity drops out in canyons.</li>
|
||||
<li>Expanded lean angle gyro range support to 68 degrees for supermoto and MotoGP track riders.</li>
|
||||
<li>Fixed battery thermal throttling safety cutoffs on Samsung Galaxy S23/S24 Ultra units mounted on direct-sun handlebar clamps.</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Accordion Item 3 (Build 1.0.0) -->
|
||||
<div class="rounded-xl bg-surface-container-low overflow-hidden">
|
||||
<button class="accordion-trigger w-full flex items-center justify-between p-space-md text-left hover:bg-surface-container transition-colors" data-target="build-100">
|
||||
<div class="flex items-center gap-space-md">
|
||||
<span class="w-3 h-3 rounded-full bg-outline-variant"></span>
|
||||
<div class="flex flex-col">
|
||||
<span class="font-headline-sm text-headline-sm text-on-surface">Build 1.0.0 — Genesis Release</span>
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant">Released September 10, 2024</span>
|
||||
</div>
|
||||
</div>
|
||||
<span class="material-symbols-outlined text-on-surface-variant transition-transform duration-200" id="icon-build-100">expand_more</span>
|
||||
</button>
|
||||
<div class="hidden px-space-md pb-space-md pt-space-xs flex flex-col gap-space-sm" id="content-build-100">
|
||||
<ul class="flex flex-col gap-space-xs font-body-md text-body-md text-on-surface-variant list-disc pl-5">
|
||||
<li>Initial public launch of MotorSignal Telemetry Engine.</li>
|
||||
<li>Real-time HUD featuring 100km/h glanceable high-contrast speedometer, dynamic G-force circle, and corner apex trajectory analysis.</li>
|
||||
<li>Full CAN-Bus OBD-II PID telemetry scanner for Kawasaki, Yamaha, Ducati, and BMW Motorrad.</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- TESTFLIGHT WAITLIST MODAL DIALOG -->
|
||||
<div class="fixed inset-0 z-50 flex items-center justify-center p-space-md bg-surface-container-lowest/80 backdrop-blur-md hidden transition-opacity duration-200" id="testflightModal">
|
||||
<div class="max-w-md w-full rounded-xl bg-surface-container-high p-space-lg shadow-2xl flex flex-col gap-space-md relative">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-space-xs">
|
||||
<span class="material-symbols-outlined text-secondary">flight_takeoff</span>
|
||||
<span class="font-headline-sm text-headline-sm text-on-surface uppercase">iOS TestFlight Waitlist</span>
|
||||
</div>
|
||||
<button class="w-8 h-8 rounded-lg bg-surface-container flex items-center justify-center text-on-surface hover:text-primary transition-colors" id="closeTestFlightBtn">
|
||||
<span class="material-symbols-outlined text-[18px]">close</span>
|
||||
</button>
|
||||
</div>
|
||||
<p class="font-body-md text-body-md text-on-surface-variant">
|
||||
Due to Apple CoreMotion IMU high-rate sensor sandboxing limits, we are slowly onboarding riders by invitation to guarantee telemetry accuracy.
|
||||
</p>
|
||||
<form class="flex flex-col gap-space-sm" id="waitlistForm" onsubmit="event.preventDefault(); submitWaitlist();">
|
||||
<div class="flex flex-col gap-1">
|
||||
<label class="font-label-caption text-label-caption text-on-surface-variant uppercase" for="riderEmail">Apple ID Email</label>
|
||||
<input class="h-12 px-space-md rounded-lg bg-surface-container-lowest text-on-surface font-body-md focus:outline-none focus:ring-1 focus:ring-primary-container placeholder:text-outline" id="riderEmail" placeholder="rider@icloud.com" required="" type="email"/>
|
||||
</div>
|
||||
<div class="flex flex-col gap-1">
|
||||
<label class="font-label-caption text-label-caption text-on-surface-variant uppercase" for="motorcycleModel">Primary Bike (Make, Model, Year)</label>
|
||||
<input class="h-12 px-space-md rounded-lg bg-surface-container-lowest text-on-surface font-body-md focus:outline-none focus:ring-1 focus:ring-primary-container placeholder:text-outline" id="motorcycleModel" placeholder="e.g. 2023 Yamaha YZF-R7" required="" type="text"/>
|
||||
</div>
|
||||
<button class="h-12 mt-space-sm rounded-lg bg-secondary text-on-secondary font-label-data text-label-data uppercase tracking-wider hover:bg-secondary-fixed transition-colors flex items-center justify-center gap-2" type="submit">
|
||||
<span>Request Beta Slot</span>
|
||||
<span class="material-symbols-outlined text-[18px]">send</span>
|
||||
</button>
|
||||
</form>
|
||||
<div class="hidden font-label-data text-label-data text-primary text-center p-space-sm rounded bg-surface-container-lowest" id="waitlistFeedback">
|
||||
Slot requested! Check your Apple ID inbox within 48h.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- INLINE CLIENT INTERACTION LOGIC -->
|
||||
<script>
|
||||
// Copy Checksum Hash
|
||||
const copyHashBtn = document.getElementById('copyHashBtn');
|
||||
const checksumHash = document.getElementById('checksumHash');
|
||||
const copyText = document.getElementById('copyText');
|
||||
|
||||
if (copyHashBtn && checksumHash) {
|
||||
copyHashBtn.addEventListener('click', () => {
|
||||
navigator.clipboard.writeText(checksumHash.textContent.trim()).then(() => {
|
||||
copyText.textContent = 'COPIED!';
|
||||
copyHashBtn.classList.add('text-primary');
|
||||
setTimeout(() => {
|
||||
copyText.textContent = 'COPY';
|
||||
copyHashBtn.classList.remove('text-primary');
|
||||
}, 2000);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Changelog Accordion Toggle
|
||||
const triggers = document.querySelectorAll('.accordion-trigger');
|
||||
triggers.forEach(trigger => {
|
||||
trigger.addEventListener('click', () => {
|
||||
const targetId = trigger.getAttribute('data-target');
|
||||
const content = document.getElementById('content-' + targetId);
|
||||
const icon = document.getElementById('icon-' + targetId);
|
||||
|
||||
if (content.classList.contains('hidden')) {
|
||||
content.classList.remove('hidden');
|
||||
icon.classList.add('rotate-180');
|
||||
} else {
|
||||
content.classList.add('hidden');
|
||||
icon.classList.remove('rotate-180');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// TestFlight Modal Controls
|
||||
const testFlightModal = document.getElementById('testflightModal');
|
||||
const openTestFlightBtn = document.getElementById('openTestFlightBtn');
|
||||
const closeTestFlightBtn = document.getElementById('closeTestFlightBtn');
|
||||
|
||||
if (openTestFlightBtn && testFlightModal && closeTestFlightBtn) {
|
||||
openTestFlightBtn.addEventListener('click', () => {
|
||||
testFlightModal.classList.remove('hidden');
|
||||
});
|
||||
closeTestFlightBtn.addEventListener('click', () => {
|
||||
testFlightModal.classList.add('hidden');
|
||||
});
|
||||
testFlightModal.addEventListener('click', (e) => {
|
||||
if (e.target === testFlightModal) {
|
||||
testFlightModal.classList.add('hidden');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Modal Waitlist Submit Simulation
|
||||
function submitWaitlist() {
|
||||
const feedback = document.getElementById('waitlistFeedback');
|
||||
const form = document.getElementById('waitlistForm');
|
||||
if (feedback && form) {
|
||||
feedback.classList.remove('hidden');
|
||||
form.reset();
|
||||
setTimeout(() => {
|
||||
feedback.classList.add('hidden');
|
||||
testFlightModal.classList.add('hidden');
|
||||
}, 2200);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</div></main><footer class="w-full bg-surface-container-lowest pt-space-xl pb-space-lg"><div class="w-full px-gutter-lg"><div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-5 gap-space-lg pb-space-lg"><div class="lg:col-span-2 flex flex-col gap-space-sm"><div class="flex items-center gap-space-sm"><span class="font-headline-sm text-headline-sm uppercase tracking-wider text-primary">MotorSignal</span><span class="px-space-xs py-space-xs rounded font-label-caption text-label-caption bg-surface-container text-primary-container uppercase">Precision Cockpit HUD</span></div><p class="font-body-md text-body-md text-on-surface-variant max-w-md">Next-generation telemetry engine engineered for track day racers, aggressive sport riders, and synchronized pack navigation with real-time IMU lean angle computation.</p><div class="flex items-center gap-space-sm pt-space-xs"><span class="w-2.5 h-2.5 rounded-full bg-primary-container shadow-[0_0_8px_#00e5ff]"></span><span class="font-label-data text-label-data text-on-surface uppercase">Telemetry Core v4.8.2 Active</span></div></div><div class="flex flex-col gap-space-sm"><span class="font-label-data text-label-data text-primary uppercase tracking-wider">Platform Modules</span><ul class="flex flex-col gap-space-xs"><li class="font-body-md text-body-md text-on-surface-variant hover:text-on-surface transition-colors cursor-pointer">Telemetry Specs</li><li class="font-body-md text-body-md text-on-surface-variant hover:text-on-surface transition-colors cursor-pointer">Curvy Routes</li><li class="font-body-md text-body-md text-on-surface-variant hover:text-on-surface transition-colors cursor-pointer">Pack Radar</li><li class="font-body-md text-body-md text-on-surface-variant hover:text-on-surface transition-colors cursor-pointer">Draggy Launch</li></ul></div><div class="flex flex-col gap-space-sm"><span class="font-label-data text-label-data text-primary uppercase tracking-wider">Ecosystem</span><ul class="flex flex-col gap-space-xs"><li class="font-body-md text-body-md text-on-surface-variant hover:text-on-surface transition-colors cursor-pointer">OBD-II CANbus Link</li><li class="font-body-md text-body-md text-on-surface-variant hover:text-on-surface transition-colors cursor-pointer">IMU 6-Axis Calibration</li><li class="font-body-md text-body-md text-on-surface-variant hover:text-on-surface transition-colors cursor-pointer">Corner Trajectory AI</li><li class="font-body-md text-body-md text-on-surface-variant hover:text-on-surface transition-colors cursor-pointer">G-Force Mapping</li></ul></div><div class="flex flex-col gap-space-sm"><span class="font-label-data text-label-data text-primary uppercase tracking-wider">Governance</span><ul class="flex flex-col gap-space-xs"><li class="font-body-md text-body-md text-on-surface-variant hover:text-on-surface transition-colors cursor-pointer">Privacy Architecture</li><li class="font-body-md text-body-md text-on-surface-variant hover:text-on-surface transition-colors cursor-pointer">Telemetry Terms</li><li class="font-body-md text-body-md text-on-surface-variant hover:text-on-surface transition-colors cursor-pointer">Safety Disclaimers</li><li class="font-body-md text-body-md text-on-surface-variant hover:text-on-surface transition-colors cursor-pointer">Mesh Node Protocol</li></ul></div></div><div class="pt-space-md flex flex-col md:flex-row items-center justify-between gap-space-sm"><span class="font-label-caption text-label-caption text-on-surface-variant uppercase">© 2025 MotorSignal Technologies Inc. Built for zero-cognitive lag.</span><div class="flex items-center gap-space-md"><span class="font-label-caption text-label-caption text-on-surface-variant uppercase">All nodes operational</span><span class="font-label-data text-label-data text-primary">99.98% Latency <14ms</span></div></div></div></footer></body></html>
|
||||
|
|
@ -0,0 +1,698 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<html class="dark" lang="en"><head><meta charset="utf-8"/><meta content="width=device-width, initial-scale=1.0" name="viewport"/><meta content="web_standard" name="shell-type"/><title>MotorSignal Telemetry</title><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&family=JetBrains+Mono:wght@500;600;700&family=Space+Grotesk:wght@600;700&display=swap" rel="stylesheet"/><link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/><style>@layer base { html, body { margin: 0; padding: 0; } body { overscroll-behavior: none; } main > :first-child { margin-top: 0 !important; } main > :last-child { margin-bottom: 0 !important; } } ::-webkit-scrollbar { display: none; }</style><script src="https://cdn.tailwindcss.com"></script><script id="tailwind-config">tailwind.config = { darkMode: "class", theme: { extend: { "colors": { "on-tertiary": "#3c0091", "on-primary": "#00363d", "error-container": "#93000a", "on-secondary": "#002a78", "inverse-on-surface": "#2d3036", "on-error-container": "#ffdad6", "secondary-fixed": "#dbe1ff", "surface-container-low": "#181c21", "outline-variant": "#3b494c", "surface-variant": "#32353b", "background": "#101419", "on-surface-variant": "#bac9cc", "on-surface": "#e0e2ea", "on-background": "#e0e2ea", "on-primary-container": "#00626e", "on-secondary-container": "#cdd7ff", "primary-container": "#00e5ff", "primary": "#c3f5ff", "on-primary-fixed-variant": "#004f58", "on-primary-fixed": "#001f24", "tertiary": "#f2e9ff", "on-tertiary-fixed-variant": "#5516be", "surface-container-high": "#272a30", "surface-dim": "#101419", "primary-fixed": "#9cf0ff", "tertiary-fixed": "#e9ddff", "on-secondary-fixed": "#00174b", "error": "#ffb4ab", "on-secondary-fixed-variant": "#003ea8", "on-error": "#690005", "inverse-primary": "#006875", "inverse-surface": "#e0e2ea", "surface-container-highest": "#32353b", "secondary": "#b4c5ff", "surface": "#101419", "tertiary-container": "#d9c8ff", "surface-bright": "#36393f", "secondary-container": "#0053db", "on-tertiary-fixed": "#23005c", "surface-container": "#1d2025", "surface-container-lowest": "#0b0e13", "on-tertiary-container": "#6834d1", "secondary-fixed-dim": "#b4c5ff", "outline": "#849396", "surface-tint": "#00daf3", "primary-fixed-dim": "#00daf3", "tertiary-fixed-dim": "#d0bcff" }, "borderRadius": { "DEFAULT": "0.25rem", "lg": "0.5rem", "xl": "0.75rem", "full": "9999px" }, "spacing": { "margin": "1rem", "gutter-lg": "1.5rem", "space-md": "1rem", "space-xs": "0.25rem", "space-lg": "1.5rem", "space-xl": "2rem", "space-sm": "0.5rem", "margin-lg": "2rem", "gutter": "1rem" }, "fontFamily": { "body-md": ["Inter"], "display-hero": ["Space Grotesk"], "label-data": ["JetBrains Mono"], "telemetry-metric-lg-mobile": ["JetBrains Mono"], "headline-lg": ["Space Grotesk"], "telemetry-metric-lg": ["JetBrains Mono"], "label-caption": ["Inter"], "headline-sm": ["Space Grotesk"], "headline-md": ["Space Grotesk"], "body-lg": ["Inter"], "telemetry-metric-md": ["JetBrains Mono"], "display-hero-mobile": ["Space Grotesk"] }, "fontSize": { "body-md": ["14px", { "lineHeight": "20px", "fontWeight": "400" }], "display-hero": ["56px", { "lineHeight": "60px", "letterSpacing": "-0.03em", "fontWeight": "700" }], "label-data": ["12px", { "lineHeight": "16px", "letterSpacing": "0.08em", "fontWeight": "600" }], "telemetry-metric-lg-mobile": ["36px", { "lineHeight": "36px", "letterSpacing": "-0.03em", "fontWeight": "700" }], "headline-lg": ["32px", { "lineHeight": "40px", "letterSpacing": "-0.02em", "fontWeight": "700" }], "telemetry-metric-lg": ["48px", { "lineHeight": "48px", "letterSpacing": "-0.04em", "fontWeight": "700" }], "label-caption": ["11px", { "lineHeight": "14px", "letterSpacing": "0.05em", "fontWeight": "600" }], "headline-sm": ["20px", { "lineHeight": "28px", "fontWeight": "600" }], "headline-md": ["24px", { "lineHeight": "32px", "letterSpacing": "-0.01em", "fontWeight": "600" }], "body-lg": ["16px", { "lineHeight": "24px", "fontWeight": "500" }], "telemetry-metric-md": ["28px", { "lineHeight": "32px", "letterSpacing": "-0.02em", "fontWeight": "600" }], "display-hero-mobile": ["40px", { "lineHeight": "44px", "letterSpacing": "-0.02em", "fontWeight": "700" }] } } } };</script></head><body class="bg-surface text-on-surface font-body-md antialiased selection:bg-primary-container selection:text-on-primary"><header class="fixed top-0 left-0 right-0 z-50 bg-surface/90 backdrop-blur-xl shadow-[0_1px_8px_rgba(0,0,0,0.4)]"><div class="h-20 w-full px-gutter-lg flex items-center justify-between gap-space-md"><div class="flex items-center gap-space-lg"><a class="flex items-center gap-space-sm group" href="#"><img alt="Brand logo. - Primary color: #00e5ff
|
||||
- Font: spaceGrotesk
|
||||
- Mode: dark
|
||||
- Roundness: rounded-md
|
||||
" class="h-8 w-auto object-contain" src="https://lh3.googleusercontent.com/aida/AEtjO1UTw8rBQQ-sNGfIk81zYX1u7rT7_IcgGT6GjJCfVJDKecDfGr1MrPEVgjII5_MK3wj6tO6Qw2ZfHhqwrKxHdNrJUGxFOlXalVgFnDtgpjoNDSFtltDk6syCaK_mTdC1xPJqngCTTc2T43fBqyYBnwQANHFTwwGJ646jmbPtJavdn15iGT6wqfLaoJpDew60SUt_hG1nouBFUYDMxOiNIIgnWfkgJ04aTmmTNXr6Ca7776OBqr3haTpFHQ"/><span class="font-headline-sm text-headline-sm uppercase tracking-wider text-primary group-hover:text-primary-container transition-colors">MotorSignal</span></a><nav class="hidden xl:flex items-center gap-space-md" data-active-classes="text-primary-container font-headline-sm"><a aria-current="page" class="uppercase tracking-wider transition-colors px-space-xs py-space-xs text-primary-container font-headline-sm" data-path="features" href="#">Features</a><a class="text-on-surface-variant font-label-data text-label-data uppercase tracking-wider hover:text-on-surface transition-colors px-space-xs py-space-xs" data-path="group-rides" href="#">Group Rides</a><a class="text-on-surface-variant font-label-data text-label-data uppercase tracking-wider hover:text-on-surface transition-colors px-space-xs py-space-xs" data-path="clubs" href="#">Clubs</a><a class="text-on-surface-variant font-label-data text-label-data uppercase tracking-wider hover:text-on-surface transition-colors px-space-xs py-space-xs" data-path="pricing" href="#">Pricing</a><a class="text-on-surface-variant font-label-data text-label-data uppercase tracking-wider hover:text-on-surface transition-colors px-space-xs py-space-xs" data-path="download" href="#">Download</a><a class="text-on-surface-variant font-label-data text-label-data uppercase tracking-wider hover:text-on-surface transition-colors px-space-xs py-space-xs" data-path="support" href="#">Support</a><a class="text-on-surface-variant font-label-data text-label-data uppercase tracking-wider hover:text-on-surface transition-colors px-space-xs py-space-xs" data-path="admin-console" href="#">Admin Console</a></nav></div><div class="flex items-center gap-space-md"><div class="hidden md:flex items-center gap-space-xs px-space-sm py-space-xs rounded-full bg-surface-container-low shadow-[0_0_12px_rgba(0,229,255,0.15)]"><span class="w-2 h-2 rounded-full bg-primary-container animate-pulse"></span><span class="font-label-data text-label-data text-primary uppercase">20Hz Kalman Online</span></div><a class="inline-flex items-center justify-center h-12 px-space-md rounded-lg bg-primary-container text-on-primary font-label-data text-label-data uppercase tracking-wider shadow-[0_0_16px_rgba(0,229,255,0.35)] hover:bg-primary hover:text-on-primary transition-all duration-200 active:scale-[0.98]" href="#">Download App</a><div class="flex items-center gap-space-xs pl-space-xs"><img alt="Profile" class="w-8 h-8 rounded-full object-cover ring-2 ring-surface-container-high" src="https://lh3.googleusercontent.com/aida/AEtjO1XyAAxLiegDwfGfDOfnmd9desjMVj3kxU_bPrvNgMXtcbq65IhKW7uieorRmFWWL7_4VvnpTq8N2pToWOm8TSGRSiftlbFyjQPawmL20y9w0BQJjvgVum3Q8IdqGLli9RZ-16Yv2wJ36FHEwrk4T1IQTob8mc_BjN7g9c3Ic_Xz0pzHgZVxjjahryKv77ULhtLXK5wYZadicArshGkykAEqRbTPZfDNZ-YNLSAN51PoR4wbt46K46HLSvs"/></div></div></div></header><main class="w-full pt-20 bg-surface min-h-[calc(100vh-80px)]"><div class="flex flex-col w-full">
|
||||
<!-- Top Technical Header -->
|
||||
<section class="relative w-full px-gutter-lg py-space-xl overflow-hidden bg-surface-container-lowest">
|
||||
<div class="absolute inset-0 bg-gradient-to-r from-primary-container/5 via-transparent to-secondary-container/10 pointer-events-none"></div>
|
||||
<div class="max-w-7xl mx-auto flex flex-col gap-space-md relative z-10">
|
||||
<div class="flex flex-wrap items-center gap-space-sm">
|
||||
<span class="inline-flex items-center gap-1.5 px-3 py-1 rounded bg-surface-container-high text-primary-container font-label-data text-label-data tracking-wider uppercase shadow-inner">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-primary-container animate-ping"></span>
|
||||
AEROSPACE-GRADE SENSOR FUSION & ARCHITECTURE
|
||||
</span>
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant uppercase tracking-widest hidden sm:inline">
|
||||
SPEC REF: MS-ENG-REV4.8
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex flex-col lg:flex-row lg:items-end justify-between gap-space-lg">
|
||||
<div class="max-w-3xl flex flex-col gap-space-xs">
|
||||
<h1 class="font-headline-lg text-headline-lg text-on-surface uppercase tracking-tight">
|
||||
High-Density Telemetry Engineering
|
||||
</h1>
|
||||
<p class="font-body-lg text-body-lg text-on-surface-variant">
|
||||
Sub-second corner forensics, gyroscopic lean mathematics, and fail-safe canyon synchronization engineered for extreme lean thresholds and zero cognitive diversion.
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex flex-wrap items-center gap-space-sm shrink-0">
|
||||
<a class="h-12 px-space-md rounded bg-surface-container-high hover:bg-surface-container text-on-surface font-label-data text-label-data uppercase tracking-wider inline-flex items-center gap-2 transition-all" href="#benchmark">
|
||||
<span class="material-symbols-outlined text-primary text-base">table_chart</span>
|
||||
Hardware Matrix
|
||||
</a>
|
||||
<button class="h-12 px-space-md rounded bg-primary-container text-on-primary font-label-data text-label-data uppercase tracking-wider shadow-[0_0_16px_rgba(0,229,255,0.35)] hover:bg-primary hover:text-on-primary inline-flex items-center gap-2 transition-all active:scale-95" id="btn-download-whitepaper">
|
||||
<span class="material-symbols-outlined text-base">download</span>
|
||||
Download Technical Whitepaper (PDF)
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Quick Metrics Bar -->
|
||||
<div class="grid grid-cols-2 md:grid-cols-4 gap-space-sm pt-space-md">
|
||||
<div class="p-space-sm rounded bg-surface-container-low flex flex-col">
|
||||
<span class="font-label-caption text-label-caption text-outline uppercase tracking-wider">IMU Sampling Rate</span>
|
||||
<span class="font-telemetry-metric-md text-telemetry-metric-md text-primary font-bold">200 Hz</span>
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant">Dual InvenSense MPU-6050 filter</span>
|
||||
</div>
|
||||
<div class="p-space-sm rounded bg-surface-container-low flex flex-col">
|
||||
<span class="font-label-caption text-label-caption text-outline uppercase tracking-wider">Kalman GPS Mesh</span>
|
||||
<span class="font-telemetry-metric-md text-telemetry-metric-md text-primary-container font-bold">20 Hz</span>
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant">10x resolution vs standard GNSS</span>
|
||||
</div>
|
||||
<div class="p-space-sm rounded bg-surface-container-low flex flex-col">
|
||||
<span class="font-label-caption text-label-caption text-outline uppercase tracking-wider">Lean Angle Precision</span>
|
||||
<span class="font-telemetry-metric-md text-telemetry-metric-md text-secondary font-bold">±0.25°</span>
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant">Dynamic roll center auto-zero</span>
|
||||
</div>
|
||||
<div class="p-space-sm rounded bg-surface-container-low flex flex-col">
|
||||
<span class="font-label-caption text-label-caption text-outline uppercase tracking-wider">Offline Sync Quorum</span>
|
||||
<span class="font-telemetry-metric-md text-telemetry-metric-md text-tertiary-container font-bold">100%</span>
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant">Zero packet loss SQLite journal</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- 4 Deep-Dive Alternating Engineering Sections -->
|
||||
<div class="w-full max-w-7xl mx-auto px-gutter-lg py-space-xl flex flex-col gap-24">
|
||||
<!-- MODULE 01: 20 Hz Kalman Sensor Fusion Engine -->
|
||||
<section class="grid grid-cols-1 lg:grid-cols-12 gap-space-lg items-center">
|
||||
<div class="lg:col-span-6 flex flex-col gap-space-md order-2 lg:order-1">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="px-2 py-0.5 rounded bg-surface-container text-primary-container font-label-data text-label-data tracking-wider uppercase">ARCH 01 // FUSION</span>
|
||||
<span class="font-label-caption text-label-caption text-outline uppercase">Sub-Decimeter Spatial Integrity</span>
|
||||
</div>
|
||||
<h2 class="font-headline-lg text-headline-lg text-on-surface uppercase tracking-tight">
|
||||
20 Hz Kalman Sensor Fusion Engine
|
||||
</h2>
|
||||
<p class="font-body-md text-body-md text-on-surface-variant leading-relaxed">
|
||||
Standard consumer smartphones restrict raw GNSS updates to a staggered 1 Hz heartbeat. At 140 km/h on a technical downhill corner, a bike covers nearly 39 meters between GPS stamps, slicing apex points completely in half and smoothing out trail braking signatures.
|
||||
</p>
|
||||
<p class="font-body-md text-body-md text-on-surface-variant leading-relaxed">
|
||||
MotorSignal executes an Extended Kalman Filter (EKF) combining phone multi-frequency GNSS (L1+L5) with a 200 Hz 6-axis IMU accelerometer and gyroscopic stream. The result is a synthesized 20 Hz spatial vector that resolves steering angle adjustments, apex clipping points, and subtle countersteering impulses in razor-sharp resolution.
|
||||
</p>
|
||||
<div class="grid grid-cols-2 gap-space-sm pt-space-xs">
|
||||
<div class="p-space-sm rounded bg-surface-container-low">
|
||||
<span class="font-label-caption text-label-caption text-error uppercase font-semibold">1 Hz Legacy GPS Trap</span>
|
||||
<p class="font-body-md text-body-md text-on-surface-variant mt-1">
|
||||
Misses apex clipping point by up to 28 meters. Chops out mid-corner trajectory oscillations.
|
||||
</p>
|
||||
</div>
|
||||
<div class="p-space-sm rounded bg-surface-container-low">
|
||||
<span class="font-label-caption text-label-caption text-primary-container uppercase font-semibold">MotorSignal 20 Hz EKF</span>
|
||||
<p class="font-body-md text-body-md text-on-surface-variant mt-1">
|
||||
Tracks sub-degree trail-braking transitions and micro-throttle slides at apex center.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Vector Visual / Comparison Chart -->
|
||||
<div class="lg:col-span-6 order-1 lg:order-2">
|
||||
<div class="p-space-md rounded-xl bg-surface-container-low shadow-[0_0_24px_rgba(0,0,0,0.5)] flex flex-col gap-space-sm">
|
||||
<div class="flex items-center justify-between pb-space-xs">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="w-2.5 h-2.5 rounded-full bg-primary-container animate-pulse"></span>
|
||||
<span class="font-label-data text-label-data text-on-surface uppercase tracking-wider">APEX TRAJECTORY FORENSICS (HAIRPIN T6)</span>
|
||||
</div>
|
||||
<span class="font-label-caption text-label-caption text-outline uppercase font-mono">DELTA: +19.4m ACCURACY</span>
|
||||
</div>
|
||||
<!-- Trajectory SVG Visualizer -->
|
||||
<div class="relative w-full h-72 bg-surface-container-lowest rounded-lg p-space-sm flex items-center justify-center overflow-hidden">
|
||||
<svg class="w-full h-full" fill="none" viewbox="0 0 600 300" xmlns="http://www.w3.org/2000/svg">
|
||||
<!-- Grid Backdrop -->
|
||||
<defs>
|
||||
<pattern height="30" id="grid" patternunits="userSpaceOnUse" width="30">
|
||||
<path d="M 30 0 L 0 0 0 30" fill="none" stroke="#1d2025" stroke-width="0.8"></path>
|
||||
</pattern>
|
||||
<lineargradient id="kalmanGlow" x1="0%" x2="100%" y1="0%" y2="100%">
|
||||
<stop offset="0%" stop-color="#00e5ff" stop-opacity="0.8"></stop>
|
||||
<stop offset="50%" stop-color="#c3f5ff" stop-opacity="1"></stop>
|
||||
<stop offset="100%" stop-color="#0053db" stop-opacity="0.7"></stop>
|
||||
</lineargradient>
|
||||
</defs>
|
||||
<rect fill="url(#grid)" height="100%" width="100%"></rect>
|
||||
<!-- Tarmac Track Outline -->
|
||||
<path d="M 40 260 C 180 250 260 220 320 140 C 370 70 470 50 560 60" stroke="#272a30" stroke-linecap="round" stroke-width="34"></path>
|
||||
<path d="M 40 260 C 180 250 260 220 320 140 C 370 70 470 50 560 60" stroke="#101419" stroke-linecap="round" stroke-width="26"></path>
|
||||
<!-- Apex Marker -->
|
||||
<circle cx="342" cy="115" fill="#00e5ff" r="4"></circle>
|
||||
<circle cx="342" cy="115" r="12" stroke="#00e5ff" stroke-opacity="0.4" stroke-width="1.5"></circle>
|
||||
<text class="font-label-caption text-label-caption" fill="#c3f5ff" font-size="10" x="360" y="118">TRUE CORNER APEX</text>
|
||||
<!-- JAGGED 1 Hz PHONE GPS (Stepwise error) -->
|
||||
<path d="M 50 260 L 160 240 L 270 190 L 400 90 L 550 60" fill="none" stroke="#ffb4ab" stroke-dasharray="4 4" stroke-width="2"></path>
|
||||
<!-- Staggered data points -->
|
||||
<circle cx="50" cy="260" fill="#ffb4ab" r="3"></circle>
|
||||
<circle cx="160" cy="240" fill="#ffb4ab" r="3"></circle>
|
||||
<circle cx="270" cy="190" fill="#ffb4ab" r="3"></circle>
|
||||
<circle cx="400" cy="90" fill="#ffb4ab" r="3"></circle>
|
||||
<circle cx="550" cy="60" fill="#ffb4ab" r="3"></circle>
|
||||
<!-- MOTOR SIGNAL 20 Hz KALMAN FILTERED SMOOTH PATH -->
|
||||
<path d="M 50 260 C 190 250 270 210 338 120 C 370 76 460 55 550 60" fill="none" stroke="url(#kalmanGlow)" stroke-linecap="round" stroke-width="3.5"></path>
|
||||
<!-- Micro-corrections along the line -->
|
||||
<g fill="#00e5ff">
|
||||
<circle cx="210" cy="242" r="1.5"></circle>
|
||||
<circle cx="230" cy="235" r="1.5"></circle>
|
||||
<circle cx="250" cy="223" r="1.5"></circle>
|
||||
<circle cx="270" cy="205" r="1.5"></circle>
|
||||
<circle cx="290" cy="180" r="1.5"></circle>
|
||||
<circle cx="310" cy="155" r="1.5"></circle>
|
||||
<circle cx="330" cy="130" r="1.5"></circle>
|
||||
<circle cx="355" cy="100" r="1.5"></circle>
|
||||
<circle cx="380" cy="85" r="1.5"></circle>
|
||||
<circle cx="410" cy="72" r="1.5"></circle>
|
||||
<circle cx="440" cy="64" r="1.5"></circle>
|
||||
<circle cx="475" cy="60" r="1.5"></circle>
|
||||
<circle cx="510" cy="59" r="1.5"></circle>
|
||||
</g>
|
||||
<!-- Annotation box -->
|
||||
<rect fill="#181c21" fill-opacity="0.9" height="54" rx="4" width="200" x="70" y="30"></rect>
|
||||
<text class="font-label-caption text-label-caption" fill="#ffb4ab" font-size="9" x="80" y="48">-- 1 Hz Baseline: Truncates Apex (-19m)</text>
|
||||
<text class="font-label-data text-label-data" fill="#00e5ff" font-size="10" x="80" y="64">__ 20 Hz Kalman: Continuous Arc</text>
|
||||
<text class="font-label-caption text-label-caption" fill="#bac9cc" font-size="8" x="80" y="76">Trail braking & throttle micro-wiggles retained</text>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="flex items-center justify-between text-on-surface-variant font-label-data text-label-data px-1">
|
||||
<span class="text-error flex items-center gap-1.5">
|
||||
<span class="inline-block w-2.5 h-0.5 bg-error"></span> 1 Hz Standard Phone GNSS
|
||||
</span>
|
||||
<span class="text-primary-container flex items-center gap-1.5">
|
||||
<span class="inline-block w-2.5 h-1 bg-primary-container rounded"></span> MotorSignal 20 Hz Kalman Fusion
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- MODULE 02: Gyroscopic Lean Angle Physics & Kinematics -->
|
||||
<section class="grid grid-cols-1 lg:grid-cols-12 gap-space-lg items-center">
|
||||
<!-- Diagram / Vector Graphics Canvas -->
|
||||
<div class="lg:col-span-6">
|
||||
<div class="p-space-md rounded-xl bg-surface-container-low shadow-[0_0_24px_rgba(0,0,0,0.5)] flex flex-col gap-space-sm">
|
||||
<div class="flex items-center justify-between pb-space-xs">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-primary-container text-base">screen_rotation</span>
|
||||
<span class="font-label-data text-label-data text-on-surface uppercase tracking-wider">3-AXIS GYRO & ROLL-CENTER VECTOR</span>
|
||||
</div>
|
||||
<span class="font-label-caption text-label-caption text-secondary uppercase font-mono">θ = 51.4° MAX LEAN</span>
|
||||
</div>
|
||||
<div class="relative w-full h-80 bg-surface-container-lowest rounded-lg p-space-sm flex items-center justify-center overflow-hidden">
|
||||
<svg class="w-full h-full" fill="none" viewbox="0 0 500 320" xmlns="http://www.w3.org/2000/svg">
|
||||
<!-- Ground Plane -->
|
||||
<line stroke="#3b494c" stroke-width="2" x1="20" x2="480" y1="270" y2="270"></line>
|
||||
<text class="font-label-caption text-label-caption" fill="#849396" font-size="10" x="30" y="290">GROUND LEVEL (TARMAC HORIZON)</text>
|
||||
<!-- Center Vertical Reference -->
|
||||
<line stroke="#3b494c" stroke-dasharray="3 3" stroke-width="1.5" x1="250" x2="250" y1="30" y2="270"></line>
|
||||
<text class="font-label-caption text-label-caption" fill="#849396" font-size="9" x="255" y="45">TRUE VERTICAL (GRAVITY VECTOR)</text>
|
||||
<!-- Motorcycle Lean Axis (52 degrees) -->
|
||||
<!-- Pivot point Contact patch at (250, 270) -->
|
||||
<g transform="rotate(-48, 250, 270)">
|
||||
<!-- Motorcycle Chasis Beam Line -->
|
||||
<line stroke="#00e5ff" stroke-width="3" x1="250" x2="250" y1="270" y2="70"></line>
|
||||
<!-- Virtual Center of Mass (CoM) -->
|
||||
<circle cx="250" cy="140" fill="#0053db" fill-opacity="0.8" r="14" stroke="#00e5ff" stroke-width="2"></circle>
|
||||
<text class="font-label-data text-label-data" fill="#c3f5ff" font-size="10" x="270" y="145">CoM (BIKE + RIDER)</text>
|
||||
<!-- Phone Mounting Node Off-Center -->
|
||||
<rect fill="#181c21" height="24" rx="2" stroke="#00e5ff" stroke-width="1.5" width="16" x="242" y="80"></rect>
|
||||
<text class="font-label-caption text-label-caption" fill="#c3f5ff" font-size="8" x="264" y="94">MOUNT NODE (x, y, z)</text>
|
||||
<!-- Tire Contact Patch Oval -->
|
||||
<ellipse cx="250" cy="270" fill="#00e5ff" fill-opacity="0.6" rx="9" ry="5"></ellipse>
|
||||
</g>
|
||||
<!-- Lean Angle Arc -->
|
||||
<path d="M 250 170 A 100 100 0 0 0 176 195" fill="none" stroke="#00e5ff" stroke-dasharray="2 2" stroke-width="2"></path>
|
||||
<text class="font-telemetry-metric-md text-headline-sm font-bold" fill="#00e5ff" x="180" y="160">51.4°</text>
|
||||
<text class="font-label-caption text-label-caption" fill="#bac9cc" font-size="8" x="180" y="174">ROLL ANGLE (θ)</text>
|
||||
<!-- Radial acceleration vector -->
|
||||
<line marker-end="url(#arrow)" stroke="#ffb4ab" stroke-width="2" x1="165" x2="90" y1="180" y2="180"></line>
|
||||
<text class="font-label-data text-label-data" fill="#ffb4ab" font-size="9" x="65" y="172">CENTRIPETAL FORCE (1.42G)</text>
|
||||
<!-- Dynamic Contact Patch Offset shift -->
|
||||
<circle cx="238" cy="270" fill="#00daf3" r="4"></circle>
|
||||
<line stroke="#00daf3" stroke-width="2" x1="250" x2="238" y1="270" y2="270"></line>
|
||||
<text class="font-label-caption text-label-caption" fill="#00daf3" font-size="8" x="150" y="260">PATCH CAMBER DISPLACEMENT (-12mm)</text>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="grid grid-cols-3 gap-space-xs text-center pt-space-xs">
|
||||
<div class="p-space-xs rounded bg-surface-container">
|
||||
<span class="font-label-caption text-label-caption text-outline uppercase block">Roll Axis</span>
|
||||
<span class="font-label-data text-label-data text-primary">Dynamic Offset</span>
|
||||
</div>
|
||||
<div class="p-space-xs rounded bg-surface-container">
|
||||
<span class="font-label-caption text-label-caption text-outline uppercase block">Pitch (Stoppie)</span>
|
||||
<span class="font-label-data text-label-data text-primary">Decel Compensated</span>
|
||||
</div>
|
||||
<div class="p-space-xs rounded bg-surface-container">
|
||||
<span class="font-label-caption text-label-caption text-outline uppercase block">Yaw Slip</span>
|
||||
<span class="font-label-data text-label-data text-primary">CAN-Bus Sync</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="lg:col-span-6 flex flex-col gap-space-md">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="px-2 py-0.5 rounded bg-surface-container text-primary-container font-label-data text-label-data tracking-wider uppercase">ARCH 02 // KINEMATICS</span>
|
||||
<span class="font-label-caption text-label-caption text-outline uppercase">Quaternions & Rigid Body Centroids</span>
|
||||
</div>
|
||||
<h2 class="font-headline-lg text-headline-lg text-on-surface uppercase tracking-tight">
|
||||
Gyroscopic Lean Angle Physics & Kinematics
|
||||
</h2>
|
||||
<p class="font-body-md text-body-md text-on-surface-variant leading-relaxed">
|
||||
Measuring the lean of a two-wheeled vehicle is inherently non-linear. As a motorcycle tips into a fast sweeper, the tire contact patch migrates laterally across the tire profile by up to 25mm, altering the instantaneous roll center and inducing heavy lateral G-forces that falsely trick naive accelerometer tilt algorithms.
|
||||
</p>
|
||||
<p class="font-body-md text-body-md text-on-surface-variant leading-relaxed">
|
||||
MotorSignal solves this via continuous coordinate frame transformations. You can mount your phone anywhere: sideways on a clip-on, flat on the tank, or tucked behind a race fairing. Our 30-second initial roll calibration computes the transformation matrix between device axes and chassis ground vectors, filtering out engine vibration frequencies (70–160 Hz) through a low-pass Butterworth filter.
|
||||
</p>
|
||||
<div class="p-space-sm rounded bg-surface-container-low flex flex-col gap-1">
|
||||
<span class="font-label-data text-label-data text-primary-container uppercase">Zero-Mount Calibration Algorithm</span>
|
||||
<p class="font-body-md text-body-md text-on-surface-variant">
|
||||
Roll, pitch, and yaw are resolved using non-gimbal lock unit quaternions <span class="font-label-data text-label-data text-primary">q = [w, x, y, z]</span>. No matter how crooked your handlebar bracket sits, true chassis lean remains isolated within ±0.25° precision.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- MODULE 03: Safety Lean-Angle Interlock (G-Guard) -->
|
||||
<section class="grid grid-cols-1 lg:grid-cols-12 gap-space-lg items-center">
|
||||
<div class="lg:col-span-6 flex flex-col gap-space-md order-2 lg:order-1">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="px-2 py-0.5 rounded bg-surface-container text-error font-label-data text-label-data tracking-wider uppercase">ARCH 03 // SAFETY HUD</span>
|
||||
<span class="font-label-caption text-label-caption text-outline uppercase">Zero-Cognitive Diversion</span>
|
||||
</div>
|
||||
<h2 class="font-headline-lg text-headline-lg text-on-surface uppercase tracking-tight">
|
||||
Safety Lean-Angle Interlock (G-Guard)
|
||||
</h2>
|
||||
<p class="font-body-md text-body-md text-on-surface-variant leading-relaxed">
|
||||
At full lean inside a 50° blind apex, an unexpected radar ping, navigation reroute, or group rider chime can distract the rider, inducing target fixation or an accidental panic brake grab.
|
||||
</p>
|
||||
<p class="font-body-md text-body-md text-on-surface-variant leading-relaxed">
|
||||
MotorSignal's patent-pending <strong>G-Guard State Machine</strong> dynamically locks out non-critical alerts whenever the roll angle exceeds <strong>15°</strong>. Visual banners are silenced, screen contrast transitions to an ultra-clean high-contrast HUD, and audio cues are buffered into an emergency FIFO stack.
|
||||
</p>
|
||||
<div class="p-space-sm rounded bg-surface-container-low flex flex-col gap-2">
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="font-label-data text-label-data text-primary uppercase">Interlock Release Hysteresis</span>
|
||||
<span class="font-label-data text-label-data text-primary-container">1,500ms Delay Window</span>
|
||||
</div>
|
||||
<p class="font-body-md text-body-md text-on-surface-variant">
|
||||
Alerts remain held until the chassis straightens under <strong>10°</strong> and holds upright stability for a minimum of 1.5 seconds. Only then are low-priority warnings delivered softly into helmet intercoms.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- State Machine Diagram Component -->
|
||||
<div class="lg:col-span-6 order-1 lg:order-2">
|
||||
<div class="p-space-md rounded-xl bg-surface-container-low shadow-[0_0_24px_rgba(0,0,0,0.5)] flex flex-col gap-space-sm">
|
||||
<div class="flex items-center justify-between pb-space-xs">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="w-2.5 h-2.5 rounded-full bg-error animate-pulse"></span>
|
||||
<span class="font-label-data text-label-data text-on-surface uppercase tracking-wider">G-GUARD FINITE STATE MACHINE (FSM)</span>
|
||||
</div>
|
||||
<span class="font-label-caption text-label-caption text-outline uppercase font-mono">STATUS: ACTIVE BUFFER</span>
|
||||
</div>
|
||||
<div class="relative w-full h-80 bg-surface-container-lowest rounded-lg p-space-sm flex flex-col justify-between overflow-hidden">
|
||||
<!-- State 1: Upright -->
|
||||
<div class="flex items-center justify-between p-3 rounded bg-surface-container border-l-4 border-l-primary-container">
|
||||
<div>
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="font-label-data text-label-data text-primary-container font-bold">STATE A: STRAIGHT & LEVEL</span>
|
||||
<span class="px-1.5 py-0.5 rounded text-[10px] bg-primary-container/20 text-primary-container font-mono">ROLL < 15°</span>
|
||||
</div>
|
||||
<p class="font-label-caption text-label-caption text-on-surface-variant mt-1">Normal HUD updates active. Radar, pack radar, and voice guidance deliver at 100% gain.</p>
|
||||
</div>
|
||||
<span class="material-symbols-outlined text-primary-container text-2xl">volume_up</span>
|
||||
</div>
|
||||
<!-- Transition Arrow Down -->
|
||||
<div class="flex items-center justify-center gap-3 text-outline">
|
||||
<span class="font-label-caption text-label-caption text-error font-mono font-bold tracking-wider">ROLL > 15° TRIGGER [SILENCE ENGAGED]</span>
|
||||
<span class="material-symbols-outlined text-error">arrow_downward</span>
|
||||
</div>
|
||||
<!-- State 2: High Lean Lockout -->
|
||||
<div class="flex items-center justify-between p-3 rounded bg-error-container/20 border-l-4 border-l-error">
|
||||
<div>
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="font-label-data text-label-data text-error font-bold">STATE B: APEX INTERLOCK ACTIVE</span>
|
||||
<span class="px-1.5 py-0.5 rounded text-[10px] bg-error/20 text-error font-mono">LEAN LOCKED</span>
|
||||
</div>
|
||||
<p class="font-label-caption text-label-caption text-on-surface-variant mt-1">
|
||||
Audio suppressed immediately. Visual clutter pruned. Pending notifications queued in volatile RAM FIFO stack.
|
||||
</p>
|
||||
</div>
|
||||
<span class="material-symbols-outlined text-error text-2xl animate-pulse">volume_off</span>
|
||||
</div>
|
||||
<!-- Transition Arrow Up -->
|
||||
<div class="flex items-center justify-center gap-3 text-outline">
|
||||
<span class="material-symbols-outlined text-primary">arrow_upward</span>
|
||||
<span class="font-label-caption text-label-caption text-primary font-mono font-bold tracking-wider">ROLL < 10° FOR > 1.5s [HYSTERESIS RELEASE]</span>
|
||||
</div>
|
||||
<!-- State 3: Buffer Drain -->
|
||||
<div class="flex items-center justify-between p-2.5 rounded bg-surface-container-high">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-secondary text-base">restore</span>
|
||||
<span class="font-label-caption text-label-caption text-on-surface">Buffer Flush: Priority alerts delivered chronologically.</span>
|
||||
</div>
|
||||
<span class="font-label-data text-label-data text-secondary">0 Drops</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center justify-between text-on-surface-variant font-label-data text-label-data px-1">
|
||||
<span>Critical Crash SOS is exempt from suppression.</span>
|
||||
<span class="text-primary-container">ISO 26262 ASIL-B Validated</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- MODULE 04: Dual Storage & Offline Canyon Sync -->
|
||||
<section class="grid grid-cols-1 lg:grid-cols-12 gap-space-lg items-center">
|
||||
<!-- Architecture Graphic -->
|
||||
<div class="lg:col-span-6">
|
||||
<div class="p-space-md rounded-xl bg-surface-container-low shadow-[0_0_24px_rgba(0,0,0,0.5)] flex flex-col gap-space-sm">
|
||||
<div class="flex items-center justify-between pb-space-xs">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-tertiary-container text-base">cloud_sync</span>
|
||||
<span class="font-label-data text-label-data text-on-surface uppercase tracking-wider">OFFLINE CANYON JOURNAL (SCHEMA 7)</span>
|
||||
</div>
|
||||
<span class="font-label-caption text-label-caption text-outline uppercase font-mono">ZERO DROP GUARANTEE</span>
|
||||
</div>
|
||||
<!-- Flow Chart Diagram -->
|
||||
<div class="relative w-full h-80 bg-surface-container-lowest rounded-lg p-space-sm flex flex-col justify-around overflow-hidden">
|
||||
<!-- Node 1: IMU/GPS Stream -->
|
||||
<div class="flex items-center gap-3 p-2.5 rounded bg-surface-container">
|
||||
<span class="material-symbols-outlined text-primary text-xl">sensors</span>
|
||||
<div class="flex-1 min-w-0">
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="font-label-data text-label-data text-on-surface font-semibold">200 Hz IMU + 20 Hz GPS Stream</span>
|
||||
<span class="font-label-caption text-label-caption text-primary">In-Memory Ring Buffer</span>
|
||||
</div>
|
||||
<div class="w-full bg-surface-container-highest h-1 rounded-full mt-1.5 overflow-hidden">
|
||||
<div class="bg-primary h-full w-4/5 animate-pulse"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Arrow -->
|
||||
<div class="flex justify-center text-outline">
|
||||
<span class="material-symbols-outlined text-sm">south</span>
|
||||
</div>
|
||||
<!-- Node 2: SQLite Drift Schema 7 -->
|
||||
<div class="flex items-center gap-3 p-2.5 rounded bg-surface-container border-l-4 border-l-tertiary-container">
|
||||
<span class="material-symbols-outlined text-tertiary-container text-xl">database</span>
|
||||
<div class="flex-1 min-w-0">
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="font-label-data text-label-data text-tertiary-container font-semibold">SQLite Drift WAL Engine (Schema 7)</span>
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant font-mono">Local NVMe Storage</span>
|
||||
</div>
|
||||
<p class="font-label-caption text-label-caption text-on-surface-variant mt-0.5">
|
||||
Sub-millisecond writes via Write-Ahead Logging (WAL). 0% frame loss even in unexpected crash shutdown.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Split Flow: Sync Outbox -->
|
||||
<div class="flex justify-center text-outline">
|
||||
<span class="material-symbols-outlined text-sm">fork_right</span>
|
||||
</div>
|
||||
<div class="grid grid-cols-2 gap-space-xs">
|
||||
<div class="p-2 rounded bg-surface-container-high flex flex-col">
|
||||
<div class="flex items-center gap-1.5 text-error">
|
||||
<span class="material-symbols-outlined text-sm">signal_cellular_connected_no_internet_0_bar</span>
|
||||
<span class="font-label-caption text-label-caption font-bold">DEAD CANYON ZONE</span>
|
||||
</div>
|
||||
<p class="font-label-caption text-label-caption text-on-surface-variant mt-1">
|
||||
Batches records into `SyncOutboxQueue`. Exponential backoff heartbeat.
|
||||
</p>
|
||||
</div>
|
||||
<div class="p-2 rounded bg-surface-container-high flex flex-col">
|
||||
<div class="flex items-center gap-1.5 text-primary-container">
|
||||
<span class="material-symbols-outlined text-sm">wifi</span>
|
||||
<span class="font-label-caption text-label-caption font-bold">CELL TOWER LOCK</span>
|
||||
</div>
|
||||
<p class="font-label-caption text-label-caption text-on-surface-variant mt-1">
|
||||
Protobuf payload replication directly to Cloudflare R2 binary storage buckets.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center justify-between text-on-surface-variant font-label-data text-label-data px-1">
|
||||
<span>Protobuf compression ratio: 8.4:1</span>
|
||||
<span class="text-tertiary-container">< 3.2MB per 100km run</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="lg:col-span-6 flex flex-col gap-space-md">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="px-2 py-0.5 rounded bg-surface-container text-tertiary-container font-label-data text-label-data tracking-wider uppercase">ARCH 04 // STORAGE</span>
|
||||
<span class="font-label-caption text-label-caption text-outline uppercase">Resilient Sync Mesh</span>
|
||||
</div>
|
||||
<h2 class="font-headline-lg text-headline-lg text-on-surface uppercase tracking-tight">
|
||||
Dual Storage & Offline Canyon Sync
|
||||
</h2>
|
||||
<p class="font-body-md text-body-md text-on-surface-variant leading-relaxed">
|
||||
The best motorcycle passes—the Tail of the Dragon, Stelvio Pass, and Angeles Crest—are notorious cellular blackouts. Telemetry systems reliant on cloud connections frequently stall, discard corner records, or crash rider sessions completely.
|
||||
</p>
|
||||
<p class="font-body-md text-body-md text-on-surface-variant leading-relaxed">
|
||||
MotorSignal decouples telemetry recording from network state. Sessions commit directly to an embedded <strong>SQLite Drift Schema 7</strong> write-ahead log. When connectivity evaporates, your high-resolution telemetry queues seamlessly in the local SyncOutbox. Once a cellular or Wi-Fi handshake is achieved, compressed binary Protobuf streams sync directly to Cloudflare R2 bucket clusters with sha256 checksum validation.
|
||||
</p>
|
||||
<div class="grid grid-cols-2 gap-space-sm pt-space-xs">
|
||||
<div class="p-space-sm rounded bg-surface-container-low">
|
||||
<span class="font-label-data text-label-data text-on-surface font-semibold">Zero Memory Leaks</span>
|
||||
<p class="font-body-md text-body-md text-on-surface-variant mt-1">
|
||||
Fixed memory footprint (< 85MB RAM) prevents app background termination during 10-hour rides.
|
||||
</p>
|
||||
</div>
|
||||
<div class="p-space-sm rounded bg-surface-container-low">
|
||||
<span class="font-label-data text-label-data text-on-surface font-semibold">R2 Binary Snapshots</span>
|
||||
<p class="font-body-md text-body-md text-on-surface-variant mt-1">
|
||||
Full 4K-resolution GPS & G-force trajectory replays exportable instantly as CSV, GPX, or JSON.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
<!-- Hardware & Sensor Comparative Benchmark Matrix -->
|
||||
<section class="w-full bg-surface-container-lowest py-space-xl px-gutter-lg" id="benchmark">
|
||||
<div class="max-w-7xl mx-auto flex flex-col gap-space-lg">
|
||||
<div class="flex flex-col gap-space-xs">
|
||||
<span class="font-label-data text-label-data text-primary uppercase tracking-wider">BENCHMARK LAB AUDIT</span>
|
||||
<h2 class="font-headline-lg text-headline-lg text-on-surface uppercase tracking-tight">
|
||||
Hardware & Sensor Comparative Matrix
|
||||
</h2>
|
||||
<p class="font-body-md text-body-md text-on-surface-variant max-w-2xl">
|
||||
Empirical testing conducted on Laguna Seca and Mulholland Highway comparing standard consumer navigation software, dedicated motorsport hardware, and the MotorSignal Pro fusion core.
|
||||
</p>
|
||||
</div>
|
||||
<!-- Comparative Table Container -->
|
||||
<div class="w-full overflow-x-auto rounded-xl bg-surface-container-low shadow-[0_0_24px_rgba(0,0,0,0.4)]">
|
||||
<table class="w-full text-left font-body-md text-body-md border-collapse min-w-[720px]">
|
||||
<thead>
|
||||
<tr class="bg-surface-container-high text-on-surface font-label-data text-label-data uppercase tracking-wider">
|
||||
<th class="p-4 pl-6 text-on-surface">Architectural Metric</th>
|
||||
<th class="p-4 text-on-surface-variant">Standard Phone GPS Apps</th>
|
||||
<th class="p-4 text-on-surface-variant">Dedicated Track Hardware ($800+)</th>
|
||||
<th class="p-4 pr-6 text-primary-container bg-surface-container-highest">MotorSignal Pro Core</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y-0">
|
||||
<!-- Row 1 -->
|
||||
<tr class="hover:bg-surface-container/50 transition-colors">
|
||||
<td class="p-4 pl-6 font-label-data text-label-data text-on-surface font-semibold flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-primary text-base">speed</span>
|
||||
Sampling Rate (GPS / IMU)
|
||||
</td>
|
||||
<td class="p-4 text-on-surface-variant font-mono">1 Hz (GPS only)</td>
|
||||
<td class="p-4 text-on-surface-variant font-mono">10 Hz – 25 Hz</td>
|
||||
<td class="p-4 pr-6 text-primary-container font-mono font-bold bg-surface-container-highest/40">20 Hz EKF / 200 Hz IMU</td>
|
||||
</tr>
|
||||
<!-- Row 2 -->
|
||||
<tr class="hover:bg-surface-container/50 transition-colors bg-surface-container-low/50">
|
||||
<td class="p-4 pl-6 font-label-data text-label-data text-on-surface font-semibold flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-primary text-base">architecture</span>
|
||||
Lean Angle Precision
|
||||
</td>
|
||||
<td class="p-4 text-error font-mono">± 8.0° (Estimated)</td>
|
||||
<td class="p-4 text-on-surface-variant font-mono">± 0.5° (Requires gyro box)</td>
|
||||
<td class="p-4 pr-6 text-primary-container font-mono font-bold bg-surface-container-highest/40">± 0.25° (Self-Calibrating)</td>
|
||||
</tr>
|
||||
<!-- Row 3 -->
|
||||
<tr class="hover:bg-surface-container/50 transition-colors">
|
||||
<td class="p-4 pl-6 font-label-data text-label-data text-on-surface font-semibold flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-primary text-base">map</span>
|
||||
Offline Vector Cache
|
||||
</td>
|
||||
<td class="p-4 text-error">Limited / Requires Manual Download</td>
|
||||
<td class="p-4 text-on-surface-variant">Track Maps Only (No Street Routing)</td>
|
||||
<td class="p-4 pr-6 text-primary-container font-semibold bg-surface-container-highest/40">Automated Regional Vector Grid</td>
|
||||
</tr>
|
||||
<!-- Row 4 -->
|
||||
<tr class="hover:bg-surface-container/50 transition-colors bg-surface-container-low/50">
|
||||
<td class="p-4 pl-6 font-label-data text-label-data text-on-surface font-semibold flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-primary text-base">radar</span>
|
||||
Police & Hazard Alert Latency
|
||||
</td>
|
||||
<td class="p-4 text-on-surface-variant font-mono">1,800ms – 4,500ms</td>
|
||||
<td class="p-4 text-error font-mono">N/A (No Network/Radar Link)</td>
|
||||
<td class="p-4 pr-6 text-primary-container font-mono font-bold bg-surface-container-highest/40">< 340ms (Mesh Broadcast)</td>
|
||||
</tr>
|
||||
<!-- Row 5 -->
|
||||
<tr class="hover:bg-surface-container/50 transition-colors">
|
||||
<td class="p-4 pl-6 font-label-data text-label-data text-on-surface font-semibold flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-primary text-base">battery_charging_full</span>
|
||||
Battery Consumption Rate
|
||||
</td>
|
||||
<td class="p-4 text-on-surface-variant font-mono">18% – 24% per hour</td>
|
||||
<td class="p-4 text-on-surface-variant font-mono">Dedicated 12V Bike Tap</td>
|
||||
<td class="p-4 pr-6 text-primary-container font-mono font-bold bg-surface-container-highest/40">7.2% per hour (Vulkan Optimized)</td>
|
||||
</tr>
|
||||
<!-- Row 6 -->
|
||||
<tr class="hover:bg-surface-container/50 transition-colors bg-surface-container-low/50">
|
||||
<td class="p-4 pl-6 font-label-data text-label-data text-on-surface font-semibold flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-primary text-base">cable</span>
|
||||
CAN-Bus OBD-II Link
|
||||
</td>
|
||||
<td class="p-4 text-error">Unsupported</td>
|
||||
<td class="p-4 text-on-surface-variant">Proprietary harness only ($250+)</td>
|
||||
<td class="p-4 pr-6 text-primary-container font-semibold bg-surface-container-highest/40">Universal BLE 5.3 CAN & Kline</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="flex flex-col sm:flex-row items-center justify-between gap-space-sm font-label-caption text-label-caption text-outline">
|
||||
<span>Tested on iPhone 15 Pro / Galaxy S24 Ultra running iOS 17.5 & Android 14 with dual-band GNSS enabled.</span>
|
||||
<span class="text-primary">Independently verified by CalTelemetry Labs</span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- Technical FAQ Accordion Section -->
|
||||
<section class="w-full max-w-5xl mx-auto px-gutter-lg py-space-xl">
|
||||
<div class="flex flex-col gap-space-lg">
|
||||
<div class="text-center flex flex-col gap-space-xs items-center">
|
||||
<span class="font-label-data text-label-data text-primary-container uppercase tracking-wider">ENGINEERING INQUIRIES</span>
|
||||
<h2 class="font-headline-lg text-headline-lg text-on-surface uppercase tracking-tight">
|
||||
Frequently Answered Technical Questions
|
||||
</h2>
|
||||
<p class="font-body-md text-body-md text-on-surface-variant max-w-xl">
|
||||
Everything you need to know about calibration procedures, handlebar mount vibrations, and satellite constellation integrity.
|
||||
</p>
|
||||
</div>
|
||||
<!-- Accordions Container -->
|
||||
<div class="flex flex-col gap-space-sm" id="technical-faq-group">
|
||||
<!-- FAQ Item 1 -->
|
||||
<div class="faq-item rounded-lg bg-surface-container-low overflow-hidden transition-all duration-200">
|
||||
<button aria-expanded="false" class="faq-trigger w-full p-space-md flex items-center justify-between text-left hover:bg-surface-container transition-colors" type="button">
|
||||
<span class="font-headline-sm text-headline-sm text-on-surface text-base sm:text-lg">
|
||||
1. How does MotorSignal calibrate mount orientation if my phone is mounted at an odd angle?
|
||||
</span>
|
||||
<span class="material-symbols-outlined faq-icon text-primary-container transition-transform duration-300">expand_more</span>
|
||||
</button>
|
||||
<div class="faq-content hidden px-space-md pb-space-md pt-0 text-on-surface-variant font-body-md text-body-md">
|
||||
<p>
|
||||
MotorSignal executes a dynamic gravity-vector resolve during the first 30 seconds of rolling motion above 15 km/h. By analyzing the orthogonal relationship between forward longitudinal acceleration (braking and throttle) and downward gravitational force, our algorithm derives the device’s orientation quaternion. This entirely eliminates the need for rigid perpendicular phone placement on your cockpit or clip-ons.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- FAQ Item 2 -->
|
||||
<div class="faq-item rounded-lg bg-surface-container-low overflow-hidden transition-all duration-200">
|
||||
<button aria-expanded="false" class="faq-trigger w-full p-space-md flex items-center justify-between text-left hover:bg-surface-container transition-colors" type="button">
|
||||
<span class="font-headline-sm text-headline-sm text-on-surface text-base sm:text-lg">
|
||||
2. Will high-frequency single-cylinder or V-Twin motorcycle vibrations damage the sensor fusion output?
|
||||
</span>
|
||||
<span class="material-symbols-outlined faq-icon text-primary-container transition-transform duration-300">expand_more</span>
|
||||
</button>
|
||||
<div class="faq-content hidden px-space-md pb-space-md pt-0 text-on-surface-variant font-body-md text-body-md">
|
||||
<p>
|
||||
Single-cylinder thumper motors and big twin engines emit severe harmonic resonance between 70 Hz and 180 Hz that normally saturate smartphone MEMS gyroscopes. MotorSignal routes all raw IMU data through a digital 4th-order low-pass Butterworth filter configured with a sharp 22 Hz cutoff. Engine harmonics and road buzz are discarded before reaching the Kalman trajectory pipeline, ensuring crisp, flutter-free lean angle curves.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- FAQ Item 3 -->
|
||||
<div class="faq-item rounded-lg bg-surface-container-low overflow-hidden transition-all duration-200">
|
||||
<button aria-expanded="false" class="faq-trigger w-full p-space-md flex items-center justify-between text-left hover:bg-surface-container transition-colors" type="button">
|
||||
<span class="font-headline-sm text-headline-sm text-on-surface text-base sm:text-lg">
|
||||
3. Which satellite constellations are utilized, and what happens under heavy forest canopy?
|
||||
</span>
|
||||
<span class="material-symbols-outlined faq-icon text-primary-container transition-transform duration-300">expand_more</span>
|
||||
</button>
|
||||
<div class="faq-content hidden px-space-md pb-space-md pt-0 text-on-surface-variant font-body-md text-body-md">
|
||||
<p>
|
||||
MotorSignal taps into dual-frequency GNSS radios simultaneously tracking GPS (USA L1/L5), GLONASS (Russia G1), Galileo (EU E1/E5a), and BeiDou (China B1/B2a). If tall canyon walls or dense redwood canopies drop satellite lock below 4 birds, our Dead-Reckoning IMU odometry steps in instantaneously, maintaining sub-meter trajectory continuity for up to 45 seconds without drift.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- FAQ Item 4 -->
|
||||
<div class="faq-item rounded-lg bg-surface-container-low overflow-hidden transition-all duration-200">
|
||||
<button aria-expanded="false" class="faq-trigger w-full p-space-md flex items-center justify-between text-left hover:bg-surface-container transition-colors" type="button">
|
||||
<span class="font-headline-sm text-headline-sm text-on-surface text-base sm:text-lg">
|
||||
4. Can MotorSignal integrate with my motorcycle’s factory CAN-Bus or aftermarket OBD-II port?
|
||||
</span>
|
||||
<span class="material-symbols-outlined faq-icon text-primary-container transition-transform duration-300">expand_more</span>
|
||||
</button>
|
||||
<div class="faq-content hidden px-space-md pb-space-md pt-0 text-on-surface-variant font-body-md text-body-md">
|
||||
<p>
|
||||
Yes. Through our certified BLE 5.3 CAN bridge adapter (or standard ELM327 OBD-II dongles), MotorSignal captures throttle position percentage (TPS), front wheel speed vs rear wheel slip, gear indicator, engine RPM, and coolant temperature at up to 50 Hz. This data is matched synchronously with your IMU lean angle to unlock true MotoGP-level telemetry traces.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- FAQ Item 5 -->
|
||||
<div class="faq-item rounded-lg bg-surface-container-low overflow-hidden transition-all duration-200">
|
||||
<button aria-expanded="false" class="faq-trigger w-full p-space-md flex items-center justify-between text-left hover:bg-surface-container transition-colors" type="button">
|
||||
<span class="font-headline-sm text-headline-sm text-on-surface text-base sm:text-lg">
|
||||
5. How is user privacy handled when high-speed track telemetry is synchronized to the cloud?
|
||||
</span>
|
||||
<span class="material-symbols-outlined faq-icon text-primary-container transition-transform duration-300">expand_more</span>
|
||||
</button>
|
||||
<div class="faq-content hidden px-space-md pb-space-md pt-0 text-on-surface-variant font-body-md text-body-md">
|
||||
<p>
|
||||
Telemetry files stored in Cloudflare R2 are client-side encrypted using AES-GCM-256 before transmission. MotorSignal features an automated "Geo-Privacy Scrubber" that masks the first and last 800 meters of any recorded session (protecting home garage locations). Furthermore, speed and acceleration stamps can be stripped prior to sharing routes with community packs.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- Interactive Call To Action -->
|
||||
<section class="w-full bg-surface-container-low py-space-xl px-gutter-lg">
|
||||
<div class="max-w-4xl mx-auto rounded-2xl bg-surface-container p-space-lg text-center flex flex-col items-center gap-space-md shadow-[0_0_32px_rgba(0,229,255,0.15)] relative overflow-hidden">
|
||||
<div class="w-16 h-1 rounded-full bg-primary-container mx-auto"></div>
|
||||
<div class="flex flex-col gap-space-xs">
|
||||
<h3 class="font-headline-lg text-headline-lg text-on-surface uppercase">
|
||||
Ready to benchmark your motorcycle?
|
||||
</h3>
|
||||
<p class="font-body-md text-body-md text-on-surface-variant max-w-lg mx-auto">
|
||||
Equip the cockpit HUD trusted by competitive supersport riders, endurance rally champions, and canyon enthusiasts worldwide.
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex flex-wrap items-center justify-center gap-space-sm pt-space-xs">
|
||||
<a class="h-12 px-space-lg rounded-lg bg-primary-container text-on-primary font-label-data text-label-data uppercase tracking-wider shadow-[0_0_18px_rgba(0,229,255,0.4)] hover:bg-primary inline-flex items-center gap-2 transition-all" href="#">
|
||||
<span class="material-symbols-outlined">rocket_launch</span>
|
||||
Install MotorSignal Pro
|
||||
</a>
|
||||
<a class="h-12 px-space-md rounded-lg bg-surface-container-high text-on-surface font-label-data text-label-data uppercase tracking-wider hover:bg-surface-bright inline-flex items-center gap-2 transition-all" href="#">
|
||||
<span class="material-symbols-outlined">terminal</span>
|
||||
View SDK Documentation
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
<!-- Inline Interactive Script for Accordion & Whitepaper Trigger -->
|
||||
<script>
|
||||
// Accordion Logic
|
||||
document.querySelectorAll('.faq-trigger').forEach((trigger) => {
|
||||
trigger.addEventListener('click', () => {
|
||||
const item = trigger.closest('.faq-item');
|
||||
const content = item.querySelector('.faq-content');
|
||||
const icon = trigger.querySelector('.faq-icon');
|
||||
const isExpanded = trigger.getAttribute('aria-expanded') === 'true';
|
||||
|
||||
// Toggle state
|
||||
if (isExpanded) {
|
||||
content.classList.add('hidden');
|
||||
trigger.setAttribute('aria-expanded', 'false');
|
||||
icon.style.transform = 'rotate(0deg)';
|
||||
} else {
|
||||
content.classList.remove('hidden');
|
||||
trigger.setAttribute('aria-expanded', 'true');
|
||||
icon.style.transform = 'rotate(180deg)';
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Whitepaper Download simulation feedback
|
||||
const whitepaperBtn = document.getElementById('btn-download-whitepaper');
|
||||
if (whitepaperBtn) {
|
||||
whitepaperBtn.addEventListener('click', () => {
|
||||
const originalText = whitepaperBtn.innerHTML;
|
||||
whitepaperBtn.innerHTML = '<span class="material-symbols-outlined text-base animate-spin">refresh</span> PREPARING ARCH-V4.8.PDF...';
|
||||
whitepaperBtn.classList.add('opacity-80');
|
||||
setTimeout(() => {
|
||||
whitepaperBtn.innerHTML = '<span class="material-symbols-outlined text-base">check_circle</span> DOWNLOAD STARTED';
|
||||
setTimeout(() => {
|
||||
whitepaperBtn.innerHTML = originalText;
|
||||
whitepaperBtn.classList.remove('opacity-80');
|
||||
}, 2200);
|
||||
}, 1200);
|
||||
});
|
||||
}
|
||||
</script></main><footer class="w-full bg-surface-container-lowest pt-space-xl pb-space-lg"><div class="w-full px-gutter-lg"><div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-5 gap-space-lg pb-space-lg"><div class="lg:col-span-2 flex flex-col gap-space-sm"><div class="flex items-center gap-space-sm"><span class="font-headline-sm text-headline-sm uppercase tracking-wider text-primary">MotorSignal</span><span class="px-space-xs py-space-xs rounded font-label-caption text-label-caption bg-surface-container text-primary-container uppercase">Precision Cockpit HUD</span></div><p class="font-body-md text-body-md text-on-surface-variant max-w-md">Next-generation telemetry engine engineered for track day racers, aggressive sport riders, and synchronized pack navigation with real-time IMU lean angle computation.</p><div class="flex items-center gap-space-sm pt-space-xs"><span class="w-2.5 h-2.5 rounded-full bg-primary-container shadow-[0_0_8px_#00e5ff]"></span><span class="font-label-data text-label-data text-on-surface uppercase">Telemetry Core v4.8.2 Active</span></div></div><div class="flex flex-col gap-space-sm"><span class="font-label-data text-label-data text-primary uppercase tracking-wider">Platform Modules</span><ul class="flex flex-col gap-space-xs"><li class="font-body-md text-body-md text-on-surface-variant hover:text-on-surface transition-colors cursor-pointer">Telemetry Specs</li><li class="font-body-md text-body-md text-on-surface-variant hover:text-on-surface transition-colors cursor-pointer">Curvy Routes</li><li class="font-body-md text-body-md text-on-surface-variant hover:text-on-surface transition-colors cursor-pointer">Pack Radar</li><li class="font-body-md text-body-md text-on-surface-variant hover:text-on-surface transition-colors cursor-pointer">Draggy Launch</li></ul></div><div class="flex flex-col gap-space-sm"><span class="font-label-data text-label-data text-primary uppercase tracking-wider">Ecosystem</span><ul class="flex flex-col gap-space-xs"><li class="font-body-md text-body-md text-on-surface-variant hover:text-on-surface transition-colors cursor-pointer">OBD-II CANbus Link</li><li class="font-body-md text-body-md text-on-surface-variant hover:text-on-surface transition-colors cursor-pointer">IMU 6-Axis Calibration</li><li class="font-body-md text-body-md text-on-surface-variant hover:text-on-surface transition-colors cursor-pointer">Corner Trajectory AI</li><li class="font-body-md text-body-md text-on-surface-variant hover:text-on-surface transition-colors cursor-pointer">G-Force Mapping</li></ul></div><div class="flex flex-col gap-space-sm"><span class="font-label-data text-label-data text-primary uppercase tracking-wider">Governance</span><ul class="flex flex-col gap-space-xs"><li class="font-body-md text-body-md text-on-surface-variant hover:text-on-surface transition-colors cursor-pointer">Privacy Architecture</li><li class="font-body-md text-body-md text-on-surface-variant hover:text-on-surface transition-colors cursor-pointer">Telemetry Terms</li><li class="font-body-md text-body-md text-on-surface-variant hover:text-on-surface transition-colors cursor-pointer">Safety Disclaimers</li><li class="font-body-md text-body-md text-on-surface-variant hover:text-on-surface transition-colors cursor-pointer">Mesh Node Protocol</li></ul></div></div><div class="pt-space-md flex flex-col md:flex-row items-center justify-between gap-space-sm"><span class="font-label-caption text-label-caption text-on-surface-variant uppercase">© 2025 MotorSignal Technologies Inc. Built for zero-cognitive lag.</span><div class="flex items-center gap-space-md"><span class="font-label-caption text-label-caption text-on-surface-variant uppercase">All nodes operational</span><span class="font-label-data text-label-data text-primary">99.98% Latency <14ms</span></div></div></div></footer></body></html>
|
||||
|
|
@ -0,0 +1,606 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<html class="dark" lang="en"><head><meta charset="utf-8"/><meta content="width=device-width, initial-scale=1.0" name="viewport"/><meta content="web_standard" name="shell-type"/><title>MotorSignal Telemetry</title><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&family=JetBrains+Mono:wght@500;600;700&family=Space+Grotesk:wght@600;700&display=swap" rel="stylesheet"/><link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/><style>@layer base { html, body { margin: 0; padding: 0; } body { overscroll-behavior: none; } main > :first-child { margin-top: 0 !important; } main > :last-child { margin-bottom: 0 !important; } } ::-webkit-scrollbar { display: none; }</style><script src="https://cdn.tailwindcss.com"></script><script id="tailwind-config">tailwind.config = { darkMode: "class", theme: { extend: { "colors": { "on-tertiary": "#3c0091", "on-primary": "#00363d", "error-container": "#93000a", "on-secondary": "#002a78", "inverse-on-surface": "#2d3036", "on-error-container": "#ffdad6", "secondary-fixed": "#dbe1ff", "surface-container-low": "#181c21", "outline-variant": "#3b494c", "surface-variant": "#32353b", "background": "#101419", "on-surface-variant": "#bac9cc", "on-surface": "#e0e2ea", "on-background": "#e0e2ea", "on-primary-container": "#00626e", "on-secondary-container": "#cdd7ff", "primary-container": "#00e5ff", "primary": "#c3f5ff", "on-primary-fixed-variant": "#004f58", "on-primary-fixed": "#001f24", "tertiary": "#f2e9ff", "on-tertiary-fixed-variant": "#5516be", "surface-container-high": "#272a30", "surface-dim": "#101419", "primary-fixed": "#9cf0ff", "tertiary-fixed": "#e9ddff", "on-secondary-fixed": "#00174b", "error": "#ffb4ab", "on-secondary-fixed-variant": "#003ea8", "on-error": "#690005", "inverse-primary": "#006875", "inverse-surface": "#e0e2ea", "surface-container-highest": "#32353b", "secondary": "#b4c5ff", "surface": "#101419", "tertiary-container": "#d9c8ff", "surface-bright": "#36393f", "secondary-container": "#0053db", "on-tertiary-fixed": "#23005c", "surface-container": "#1d2025", "surface-container-lowest": "#0b0e13", "on-tertiary-container": "#6834d1", "secondary-fixed-dim": "#b4c5ff", "outline": "#849396", "surface-tint": "#00daf3", "primary-fixed-dim": "#00daf3", "tertiary-fixed-dim": "#d0bcff" }, "borderRadius": { "DEFAULT": "0.25rem", "lg": "0.5rem", "xl": "0.75rem", "full": "9999px" }, "spacing": { "margin": "1rem", "gutter-lg": "1.5rem", "space-md": "1rem", "space-xs": "0.25rem", "space-lg": "1.5rem", "space-xl": "2rem", "space-sm": "0.5rem", "margin-lg": "2rem", "gutter": "1rem" }, "fontFamily": { "body-md": ["Inter"], "display-hero": ["Space Grotesk"], "label-data": ["JetBrains Mono"], "telemetry-metric-lg-mobile": ["JetBrains Mono"], "headline-lg": ["Space Grotesk"], "telemetry-metric-lg": ["JetBrains Mono"], "label-caption": ["Inter"], "headline-sm": ["Space Grotesk"], "headline-md": ["Space Grotesk"], "body-lg": ["Inter"], "telemetry-metric-md": ["JetBrains Mono"], "display-hero-mobile": ["Space Grotesk"] }, "fontSize": { "body-md": ["14px", { "lineHeight": "20px", "fontWeight": "400" }], "display-hero": ["56px", { "lineHeight": "60px", "letterSpacing": "-0.03em", "fontWeight": "700" }], "label-data": ["12px", { "lineHeight": "16px", "letterSpacing": "0.08em", "fontWeight": "600" }], "telemetry-metric-lg-mobile": ["36px", { "lineHeight": "36px", "letterSpacing": "-0.03em", "fontWeight": "700" }], "headline-lg": ["32px", { "lineHeight": "40px", "letterSpacing": "-0.02em", "fontWeight": "700" }], "telemetry-metric-lg": ["48px", { "lineHeight": "48px", "letterSpacing": "-0.04em", "fontWeight": "700" }], "label-caption": ["11px", { "lineHeight": "14px", "letterSpacing": "0.05em", "fontWeight": "600" }], "headline-sm": ["20px", { "lineHeight": "28px", "fontWeight": "600" }], "headline-md": ["24px", { "lineHeight": "32px", "letterSpacing": "-0.01em", "fontWeight": "600" }], "body-lg": ["16px", { "lineHeight": "24px", "fontWeight": "500" }], "telemetry-metric-md": ["28px", { "lineHeight": "32px", "letterSpacing": "-0.02em", "fontWeight": "600" }], "display-hero-mobile": ["40px", { "lineHeight": "44px", "letterSpacing": "-0.02em", "fontWeight": "700" }] } } } };</script></head><body class="bg-surface text-on-surface font-body-md antialiased selection:bg-primary-container selection:text-on-primary"><header class="fixed top-0 left-0 right-0 z-50 bg-surface/90 backdrop-blur-xl shadow-[0_1px_8px_rgba(0,0,0,0.4)]"><div class="h-20 w-full px-gutter-lg flex items-center justify-between gap-space-md"><div class="flex items-center gap-space-lg"><a class="flex items-center gap-space-sm group" href="#"><img alt="Brand logo. - Primary color: #00e5ff
|
||||
- Font: spaceGrotesk
|
||||
- Mode: dark
|
||||
- Roundness: rounded-md
|
||||
" class="h-8 w-auto object-contain" src="https://lh3.googleusercontent.com/aida/AEtjO1UTw8rBQQ-sNGfIk81zYX1u7rT7_IcgGT6GjJCfVJDKecDfGr1MrPEVgjII5_MK3wj6tO6Qw2ZfHhqwrKxHdNrJUGxFOlXalVgFnDtgpjoNDSFtltDk6syCaK_mTdC1xPJqngCTTc2T43fBqyYBnwQANHFTwwGJ646jmbPtJavdn15iGT6wqfLaoJpDew60SUt_hG1nouBFUYDMxOiNIIgnWfkgJ04aTmmTNXr6Ca7776OBqr3haTpFHQ"/><span class="font-headline-sm text-headline-sm uppercase tracking-wider text-primary group-hover:text-primary-container transition-colors">MotorSignal</span></a><nav class="hidden xl:flex items-center gap-space-md" data-active-classes="text-primary-container font-headline-sm"><a aria-current="page" class="uppercase tracking-wider transition-colors px-space-xs py-space-xs text-primary-container font-headline-sm" data-path="features" href="#">Features</a><a class="text-on-surface-variant font-label-data text-label-data uppercase tracking-wider hover:text-on-surface transition-colors px-space-xs py-space-xs" data-path="group-rides" href="#">Group Rides</a><a class="text-on-surface-variant font-label-data text-label-data uppercase tracking-wider hover:text-on-surface transition-colors px-space-xs py-space-xs" data-path="clubs" href="#">Clubs</a><a class="text-on-surface-variant font-label-data text-label-data uppercase tracking-wider hover:text-on-surface transition-colors px-space-xs py-space-xs" data-path="pricing" href="#">Pricing</a><a class="text-on-surface-variant font-label-data text-label-data uppercase tracking-wider hover:text-on-surface transition-colors px-space-xs py-space-xs" data-path="download" href="#">Download</a><a class="text-on-surface-variant font-label-data text-label-data uppercase tracking-wider hover:text-on-surface transition-colors px-space-xs py-space-xs" data-path="support" href="#">Support</a><a class="text-on-surface-variant font-label-data text-label-data uppercase tracking-wider hover:text-on-surface transition-colors px-space-xs py-space-xs" data-path="admin-console" href="#">Admin Console</a></nav></div><div class="flex items-center gap-space-md"><div class="hidden md:flex items-center gap-space-xs px-space-sm py-space-xs rounded-full bg-surface-container-low shadow-[0_0_12px_rgba(0,229,255,0.15)]"><span class="w-2 h-2 rounded-full bg-primary-container animate-pulse"></span><span class="font-label-data text-label-data text-primary uppercase">20Hz Kalman Online</span></div><a class="inline-flex items-center justify-center h-12 px-space-md rounded-lg bg-primary-container text-on-primary font-label-data text-label-data uppercase tracking-wider shadow-[0_0_16px_rgba(0,229,255,0.35)] hover:bg-primary hover:text-on-primary transition-all duration-200 active:scale-[0.98]" href="#">Download App</a><div class="flex items-center gap-space-xs pl-space-xs"><img alt="Profile" class="w-8 h-8 rounded-full object-cover ring-2 ring-surface-container-high" src="https://lh3.googleusercontent.com/aida/AEtjO1XyAAxLiegDwfGfDOfnmd9desjMVj3kxU_bPrvNgMXtcbq65IhKW7uieorRmFWWL7_4VvnpTq8N2pToWOm8TSGRSiftlbFyjQPawmL20y9w0BQJjvgVum3Q8IdqGLli9RZ-16Yv2wJ36FHEwrk4T1IQTob8mc_BjN7g9c3Ic_Xz0pzHgZVxjjahryKv77ULhtLXK5wYZadicArshGkykAEqRbTPZfDNZ-YNLSAN51PoR4wbt46K46HLSvs"/></div></div></div></header><main class="w-full pt-20 bg-surface min-h-[calc(100vh-80px)]"><div class="flex flex-col w-full">
|
||||
<!-- HERO SECTION -->
|
||||
<section class="relative w-full overflow-hidden px-margin md:px-margin-lg lg:px-gutter-lg pt-space-lg pb-space-xl">
|
||||
<!-- Ambient living background glow -->
|
||||
<div class="absolute -top-32 left-1/4 w-[500px] h-[500px] bg-gradient-to-br from-primary-container/15 via-secondary-container/10 to-transparent blur-3xl pointer-events-none rounded-full"></div>
|
||||
<div class="absolute top-1/2 -right-24 w-[420px] h-[420px] bg-gradient-to-tr from-on-tertiary-container/15 via-primary-container/10 to-transparent blur-3xl pointer-events-none rounded-full"></div>
|
||||
<div class="max-w-7xl mx-auto grid grid-cols-1 lg:grid-cols-12 gap-space-lg lg:gap-space-xl items-center relative z-10">
|
||||
<!-- Left Column: Vision & Primary Calls to Action (7 cols) -->
|
||||
<div class="lg:col-span-7 flex flex-col gap-space-md">
|
||||
<!-- System Status Pill -->
|
||||
<div class="inline-flex items-center gap-space-xs px-space-sm py-space-xs rounded-full bg-surface-container-high w-fit shadow-md">
|
||||
<span class="w-2 h-2 rounded-full bg-primary-container animate-ping"></span>
|
||||
<span class="font-label-data text-label-data text-primary uppercase tracking-wider">AEROSPACE-GRADE MOTORCYCLE TELEMETRY • V1.0.2 STABLE</span>
|
||||
</div>
|
||||
<!-- Headline -->
|
||||
<h1 class="font-display-hero text-display-hero text-on-surface tracking-tight">
|
||||
High-Fidelity Telemetry for <span class="text-transparent bg-clip-text bg-gradient-to-r from-primary via-primary-container to-secondary">Every Corner</span>
|
||||
</h1>
|
||||
<!-- Subtitle -->
|
||||
<p class="font-body-lg text-body-lg text-on-surface-variant max-w-2xl">
|
||||
Experience 20 Hz Kalman sensor fusion, sub-second apex forensic analysis, verified Waze police traps, and offline ad-hoc pack mesh radar engineered for unyielding precision.
|
||||
</p>
|
||||
<!-- CTA Cluster -->
|
||||
<div class="flex flex-wrap items-center gap-space-md pt-space-xs">
|
||||
<a class="inline-flex items-center justify-center gap-space-xs h-[52px] px-space-lg rounded-xl bg-primary-container text-on-primary font-label-data text-label-data uppercase tracking-wider shadow-[0_0_24px_rgba(0,229,255,0.4)] hover:bg-primary transition-all duration-200 active:scale-95" href="#download">
|
||||
<span class="material-symbols-outlined text-lg">download</span>
|
||||
Download Android APK (v1.0.2)
|
||||
</a>
|
||||
<a class="inline-flex items-center justify-center gap-space-xs h-[52px] px-space-lg rounded-xl bg-surface-container-high text-on-surface font-label-data text-label-data uppercase tracking-wider hover:bg-surface-bright transition-all duration-200" href="#specs">
|
||||
<span class="material-symbols-outlined text-lg">terminal</span>
|
||||
Explore Engineering Specs
|
||||
</a>
|
||||
</div>
|
||||
<!-- Ecosystem Platforms Verification -->
|
||||
<div class="flex items-center gap-space-lg pt-space-xs">
|
||||
<div class="flex items-center gap-space-xs">
|
||||
<span class="material-symbols-outlined text-primary-container text-lg">verified</span>
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant uppercase">Google Play Verified</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-space-xs">
|
||||
<span class="material-symbols-outlined text-secondary text-lg">flight_takeoff</span>
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant uppercase">Apple TestFlight Ready</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-space-xs">
|
||||
<span class="material-symbols-outlined text-primary text-lg">speed</span>
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant uppercase">20Hz IMU Precision</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Right Column: 3D Angled Glass Cockpit HUD Phone Mockup (5 cols) -->
|
||||
<div class="lg:col-span-5 relative flex justify-center perspective-[1200px]">
|
||||
<!-- Tactile Cockpit HUD Housing Mockup with dynamic glow -->
|
||||
<div class="w-full max-w-sm rounded-3xl bg-surface-container-lowest p-space-sm shadow-2xl relative transition-all duration-500 hover:rotate-0 rotate-1 md:rotate-2">
|
||||
<!-- Outer Neon Precision Edge -->
|
||||
<div class="rounded-[22px] bg-surface-container-low p-space-md flex flex-col gap-space-sm relative overflow-hidden">
|
||||
<!-- Live Status Ribbon -->
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-space-xs">
|
||||
<span class="w-2 h-2 rounded-full bg-primary-container animate-pulse"></span>
|
||||
<span class="font-label-data text-label-data text-primary uppercase">RADAR LOCK • GPS 20Hz</span>
|
||||
</div>
|
||||
<span class="font-label-data text-label-data text-on-surface-variant uppercase">CANBUS: OK</span>
|
||||
</div>
|
||||
<!-- Urgent Hazard Alert Banner -->
|
||||
<div class="flex items-center gap-space-xs px-space-sm py-space-xs rounded-lg bg-error-container text-on-error-container shadow-[0_0_16px_rgba(239,68,68,0.4)]">
|
||||
<span class="material-symbols-outlined text-base animate-bounce">radar</span>
|
||||
<div class="flex flex-col">
|
||||
<span class="font-label-data text-label-data uppercase font-bold tracking-wider leading-none">POLICE TRAP AHEAD • 350M</span>
|
||||
<span class="font-label-caption text-label-caption opacity-80 uppercase leading-none mt-0.5">Waze Peer Confirmed: Laser Radar</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Central HUD Gauge Module -->
|
||||
<div class="flex flex-col items-center justify-center py-space-md bg-surface-container rounded-xl relative">
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant uppercase tracking-widest">Ground Velocity</span>
|
||||
<div class="flex items-baseline gap-space-xs">
|
||||
<span class="font-telemetry-metric-lg text-telemetry-metric-lg text-primary-container leading-none">68</span>
|
||||
<span class="font-label-data text-label-data text-on-surface-variant">MPH</span>
|
||||
</div>
|
||||
<!-- Subtle dynamic rev counter bar -->
|
||||
<div class="w-4/5 h-1.5 bg-surface-container-highest rounded-full mt-space-xs overflow-hidden flex">
|
||||
<div class="h-full bg-primary-container w-[72%]"></div>
|
||||
<div class="h-full bg-error-container w-[10%]"></div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Lean Arc & G-Force Split Screen -->
|
||||
<div class="grid grid-cols-2 gap-space-sm">
|
||||
<!-- Lean Angle HUD Tile -->
|
||||
<div class="flex flex-col items-center p-space-sm bg-surface-container rounded-xl relative">
|
||||
<div class="flex items-center justify-between w-full">
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant uppercase">Lean Angle</span>
|
||||
<span class="font-label-data text-label-data text-secondary">R-APEX</span>
|
||||
</div>
|
||||
<!-- Dynamic Lean SVG Arc -->
|
||||
<div class="relative w-24 h-16 flex items-center justify-center my-space-xs">
|
||||
<svg class="w-full h-full" viewbox="0 0 100 60">
|
||||
<path class="text-surface-container-highest" d="M 10 50 A 40 40 0 0 1 90 50" fill="none" stroke="currentColor" stroke-linecap="round" stroke-width="6"></path>
|
||||
<path class="text-primary-container" d="M 50 50 A 40 40 0 0 1 88 42" fill="none" stroke="currentColor" stroke-linecap="round" stroke-width="6"></path>
|
||||
<line class="text-primary" stroke="currentColor" stroke-linecap="round" stroke-width="2.5" x1="50" x2="84" y1="50" y2="28"></line>
|
||||
</svg>
|
||||
<span class="absolute bottom-0 font-telemetry-metric-md text-telemetry-metric-md text-on-surface leading-none">49°</span>
|
||||
</div>
|
||||
<span class="font-label-caption text-label-caption text-primary-container uppercase">Optimal Friction</span>
|
||||
</div>
|
||||
<!-- G-Force Friction Circle Tile -->
|
||||
<div class="flex flex-col items-center p-space-sm bg-surface-container rounded-xl">
|
||||
<div class="flex items-center justify-between w-full">
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant uppercase">Friction G</span>
|
||||
<span class="font-label-data text-label-data text-primary-container">0.84G</span>
|
||||
</div>
|
||||
<!-- Mini Friction Target Diagram -->
|
||||
<div class="relative w-20 h-16 flex items-center justify-center my-space-xs">
|
||||
<div class="w-14 h-14 rounded-full bg-surface-container-low flex items-center justify-center relative">
|
||||
<div class="w-8 h-8 rounded-full bg-surface-container-highest flex items-center justify-center">
|
||||
<!-- Active G dot -->
|
||||
<div class="w-2.5 h-2.5 rounded-full bg-primary-container translate-x-2 translate-y-1 shadow-[0_0_8px_#00e5ff]"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant uppercase">Lat: +0.72G • Lon: -0.41G</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Interlock Mode Live Badge -->
|
||||
<div class="flex items-center justify-between px-space-sm py-space-xs rounded-lg bg-surface-container-lowest">
|
||||
<div class="flex items-center gap-space-xs">
|
||||
<span class="material-symbols-outlined text-secondary text-sm">volume_off</span>
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant uppercase">Safety Lean Mute</span>
|
||||
</div>
|
||||
<span class="font-label-data text-label-data text-primary">ACTIVE (>15°)</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- LIVE TELEMETRY METRIC STRIP -->
|
||||
<section class="w-full px-margin md:px-margin-lg lg:px-gutter-lg py-space-lg bg-surface-container-lowest">
|
||||
<div class="max-w-7xl mx-auto">
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-space-md">
|
||||
<!-- Metric Card 1 -->
|
||||
<div class="p-space-md rounded-2xl bg-surface-container flex flex-col gap-space-xs shadow-md transition-all hover:bg-surface-container-high">
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="font-label-data text-label-data text-primary-container uppercase">Kalman Core</span>
|
||||
<span class="material-symbols-outlined text-primary text-base">sensors</span>
|
||||
</div>
|
||||
<div class="flex items-baseline gap-space-xs mt-space-xs">
|
||||
<span class="font-telemetry-metric-md text-telemetry-metric-md text-on-surface">20 Hz</span>
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant">IMU ACQUISITION</span>
|
||||
</div>
|
||||
<p class="font-body-md text-body-md text-on-surface-variant mt-space-xs">
|
||||
20x sample fidelity vs standard 1 Hz phone GPS. Eliminates signal jitter through high-order Kalman sensor fusion.
|
||||
</p>
|
||||
</div>
|
||||
<!-- Metric Card 2 -->
|
||||
<div class="p-space-md rounded-2xl bg-surface-container flex flex-col gap-space-xs shadow-md transition-all hover:bg-surface-container-high">
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="font-label-data text-label-data text-primary-container uppercase">Apex Resolution</span>
|
||||
<span class="material-symbols-outlined text-primary text-base">timer</span>
|
||||
</div>
|
||||
<div class="flex items-baseline gap-space-xs mt-space-xs">
|
||||
<span class="font-telemetry-metric-md text-telemetry-metric-md text-on-surface">0.05s</span>
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant">CADENCE</span>
|
||||
</div>
|
||||
<p class="font-body-md text-body-md text-on-surface-variant mt-space-xs">
|
||||
Forensic millisecond trace recording. Dissect entry speed, trail braking limits, and corner-exit throttle delivery.
|
||||
</p>
|
||||
</div>
|
||||
<!-- Metric Card 3 -->
|
||||
<div class="p-space-md rounded-2xl bg-surface-container flex flex-col gap-space-xs shadow-md transition-all hover:bg-surface-container-high">
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="font-label-data text-label-data text-primary-container uppercase">Storage Engine</span>
|
||||
<span class="material-symbols-outlined text-primary text-base">cloud_off</span>
|
||||
</div>
|
||||
<div class="flex items-baseline gap-space-xs mt-space-xs">
|
||||
<span class="font-telemetry-metric-md text-telemetry-metric-md text-on-surface">100%</span>
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant">OFFLINE DRIFT</span>
|
||||
</div>
|
||||
<p class="font-body-md text-body-md text-on-surface-variant mt-space-xs">
|
||||
Zero cellular dropouts. Embedded SQLite Drift Schema 7 engine logs continuous session vectors deep in canyon dead zones.
|
||||
</p>
|
||||
</div>
|
||||
<!-- Metric Card 4 -->
|
||||
<div class="p-space-md rounded-2xl bg-surface-container flex flex-col gap-space-xs shadow-md transition-all hover:bg-surface-container-high">
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="font-label-data text-label-data text-primary-container uppercase">IMU Friction</span>
|
||||
<span class="material-symbols-outlined text-primary text-base">adjust</span>
|
||||
</div>
|
||||
<div class="flex items-baseline gap-space-xs mt-space-xs">
|
||||
<span class="font-telemetry-metric-md text-telemetry-metric-md text-on-surface">0.01g</span>
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant">LAT ACCURACY</span>
|
||||
</div>
|
||||
<p class="font-body-md text-body-md text-on-surface-variant mt-space-xs">
|
||||
Precise lateral and longitudinal friction circle instrumentation calibrated directly to road camber and bike geometry.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- INTERACTIVE LEAN ANGLE PHYSICS & SAFETY INTERLOCK SECTION -->
|
||||
<section class="w-full px-margin md:px-margin-lg lg:px-gutter-lg py-space-xl" id="specs">
|
||||
<div class="max-w-7xl mx-auto flex flex-col gap-space-lg">
|
||||
<!-- Section Header -->
|
||||
<div class="flex flex-col gap-space-xs max-w-3xl">
|
||||
<div class="inline-flex items-center gap-space-xs">
|
||||
<span class="font-label-data text-label-data text-primary-container uppercase">Dynamic Safety Matrix</span>
|
||||
<span class="w-12 h-[1px] bg-primary-container"></span>
|
||||
</div>
|
||||
<h2 class="font-headline-lg text-headline-lg text-on-surface">
|
||||
Lean Angle Physics & Dynamic Acoustic Interlock
|
||||
</h2>
|
||||
<p class="font-body-lg text-body-lg text-on-surface-variant">
|
||||
Cockpit alerts must adapt to high-risk flight phases. MotorSignal constantly monitors roll dynamics to suppress cognitive clutter at maximum apex commitment.
|
||||
</p>
|
||||
</div>
|
||||
<!-- Main Visualizer Bento Card -->
|
||||
<div class="grid grid-cols-1 lg:grid-cols-12 gap-space-lg items-stretch">
|
||||
<!-- Left: Interactive Banking Angle Visualizer (7 cols) -->
|
||||
<div class="lg:col-span-7 p-space-lg rounded-3xl bg-surface-container-low flex flex-col justify-between shadow-xl">
|
||||
<div>
|
||||
<div class="flex items-center justify-between mb-space-md">
|
||||
<span class="font-label-data text-label-data text-on-surface-variant uppercase">Interactive Angle Simulator</span>
|
||||
<span class="px-space-sm py-space-xs rounded-md bg-surface-container font-label-data text-label-data text-primary-container uppercase" id="lean-category">Aggressive Apex (42°)</span>
|
||||
</div>
|
||||
<!-- Big Interactive Display Gauge -->
|
||||
<div class="flex flex-col items-center justify-center py-space-lg relative">
|
||||
<div class="w-64 h-36 relative flex items-end justify-center overflow-hidden">
|
||||
<!-- Semicircle Guide SVG -->
|
||||
<svg class="w-full h-full" viewbox="0 0 200 110">
|
||||
<path class="text-surface-container-highest" d="M 20 100 A 80 80 0 0 1 180 100" fill="none" stroke="currentColor" stroke-linecap="round" stroke-width="12"></path>
|
||||
<!-- Danger zone (>50) -->
|
||||
<path class="text-error" d="M 155 45 A 80 80 0 0 1 180 100" fill="none" stroke="currentColor" stroke-linecap="round" stroke-width="12"></path>
|
||||
<!-- Active dynamic needle line -->
|
||||
<line class="text-primary-container transition-all duration-150" id="needle" stroke="currentColor" stroke-linecap="round" stroke-width="4" x1="100" x2="160" y1="100" y2="40"></line>
|
||||
<circle class="text-primary-container" cx="100" cy="100" fill="currentColor" r="8"></circle>
|
||||
</svg>
|
||||
</div>
|
||||
<!-- Numeric Telemetry Value -->
|
||||
<div class="flex items-baseline gap-space-xs mt-space-sm">
|
||||
<span class="font-telemetry-metric-lg text-telemetry-metric-lg text-on-surface" id="lean-value">42</span>
|
||||
<span class="font-label-data text-label-data text-primary-container">° DEGREES</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Interactive Slider Input -->
|
||||
<div class="flex flex-col gap-space-xs px-space-md mt-space-md">
|
||||
<div class="flex items-center justify-between font-label-data text-label-data text-on-surface-variant uppercase">
|
||||
<span>0° Upright</span>
|
||||
<span>15° Interlock Active</span>
|
||||
<span>55° Knee Down</span>
|
||||
</div>
|
||||
<input class="w-full h-3 bg-surface-container-highest rounded-lg appearance-none cursor-pointer accent-primary-container focus:outline-none" id="lean-range" max="55" min="0" type="range" value="42"/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Bottom Telemetry State Output -->
|
||||
<div class="grid grid-cols-3 gap-space-sm mt-space-lg pt-space-md bg-surface-container rounded-2xl p-space-sm">
|
||||
<div class="flex flex-col">
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant uppercase">Audio Status</span>
|
||||
<span class="font-label-data text-label-data text-error font-semibold uppercase" id="audio-state">SUPPRESSED</span>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant uppercase">HUD Target</span>
|
||||
<span class="font-label-data text-label-data text-primary uppercase">APEX FOCUSED</span>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant uppercase">Camber Offset</span>
|
||||
<span class="font-label-data text-label-data text-on-surface uppercase">+1.2° COMPENSATED</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Right: Safety Lean Mute Interlock Detail (5 cols) -->
|
||||
<div class="lg:col-span-5 p-space-lg rounded-3xl bg-surface-container flex flex-col justify-between shadow-xl">
|
||||
<div class="flex flex-col gap-space-md">
|
||||
<div class="w-12 h-12 rounded-2xl bg-secondary-container flex items-center justify-center text-on-secondary">
|
||||
<span class="material-symbols-outlined text-2xl">hearing_disabled</span>
|
||||
</div>
|
||||
<h3 class="font-headline-md text-headline-md text-on-surface">
|
||||
Safety Lean Mute Interlock
|
||||
</h3>
|
||||
<p class="font-body-md text-body-md text-on-surface-variant">
|
||||
High banking angles demand complete cognitive bandwidth. MotorSignal's proprietary safety interlock instantaneously suppresses audio notifications, chime streams, and non-critical comms whenever roll exceeds <span class="text-primary font-semibold">15°</span>.
|
||||
</p>
|
||||
<div class="flex flex-col gap-space-sm pt-space-xs">
|
||||
<div class="flex items-start gap-space-sm">
|
||||
<span class="material-symbols-outlined text-primary-container text-lg mt-0.5">check_circle</span>
|
||||
<p class="font-body-md text-body-md text-on-surface">Automatic audio resumption 1.2s after motorcycle vertical re-stabilization (<10°).</p>
|
||||
</div>
|
||||
<div class="flex items-start gap-space-sm">
|
||||
<span class="material-symbols-outlined text-primary-container text-lg mt-0.5">check_circle</span>
|
||||
<p class="font-body-md text-body-md text-on-surface">Emergency red-flag hazard alerts pierce through interlock threshold via high-frequency haptic pulses.</p>
|
||||
</div>
|
||||
<div class="flex items-start gap-space-sm">
|
||||
<span class="material-symbols-outlined text-primary-container text-lg mt-0.5">check_circle</span>
|
||||
<p class="font-body-md text-body-md text-on-surface">Eliminates helmet intercom distractions precisely at apex clipping points.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="p-space-sm rounded-xl bg-surface-container-high mt-space-md flex items-center gap-space-sm">
|
||||
<span class="material-symbols-outlined text-primary-container">shield</span>
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant uppercase">Meets FIM Superbike telemetry latency compliance safety margins.</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- 3 CORE VALUE PILLARS -->
|
||||
<section class="w-full px-margin md:px-margin-lg lg:px-gutter-lg py-space-xl bg-surface-container-lowest">
|
||||
<div class="max-w-7xl mx-auto flex flex-col gap-space-xl">
|
||||
<div class="flex flex-col items-center text-center gap-space-xs max-w-2xl mx-auto">
|
||||
<span class="font-label-data text-label-data text-primary-container uppercase tracking-widest">Engineered Precision</span>
|
||||
<h2 class="font-headline-lg text-headline-lg text-on-surface">Three Foundations of Cockpit Dominance</h2>
|
||||
<p class="font-body-md text-body-md text-on-surface-variant">Built from the ground up for extreme vibration environments, gloved inputs, and zero cellular trust.</p>
|
||||
</div>
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-space-lg">
|
||||
<!-- Pillar 1: Tactical Cockpit HUD -->
|
||||
<div class="p-space-lg rounded-3xl bg-surface-container flex flex-col justify-between gap-space-md hover:bg-surface-container-high transition-all">
|
||||
<div class="flex flex-col gap-space-md">
|
||||
<div class="w-12 h-12 rounded-2xl bg-surface-container-highest flex items-center justify-center text-primary-container">
|
||||
<span class="material-symbols-outlined text-2xl">dashboard</span>
|
||||
</div>
|
||||
<h3 class="font-headline-sm text-headline-sm text-on-surface">Tactical Cockpit HUD</h3>
|
||||
<p class="font-body-md text-body-md text-on-surface-variant">
|
||||
Switch effortlessly between Minimal, Sport, and Touring cockpit dashboards. Oversized 48px hit zones guarantee swift gloved interactions even at triple-digit speeds.
|
||||
</p>
|
||||
</div>
|
||||
<div class="p-space-sm rounded-2xl bg-surface-container-low flex flex-col gap-space-xs">
|
||||
<div class="flex items-center justify-between font-label-caption text-label-caption text-on-surface-variant uppercase">
|
||||
<span>View Mode</span>
|
||||
<span class="text-primary-container">High Sunlight OLED Contrast</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-space-xs pt-1">
|
||||
<span class="px-space-xs py-0.5 rounded bg-surface-container-highest font-label-data text-label-data text-primary">SPORT</span>
|
||||
<span class="px-space-xs py-0.5 rounded bg-surface font-label-data text-label-data text-on-surface-variant">MINIMAL</span>
|
||||
<span class="px-space-xs py-0.5 rounded bg-surface font-label-data text-label-data text-on-surface-variant">TOURING</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Pillar 2: Real-Time Police & Camera Swarm -->
|
||||
<div class="p-space-lg rounded-3xl bg-surface-container flex flex-col justify-between gap-space-md hover:bg-surface-container-high transition-all">
|
||||
<div class="flex flex-col gap-space-md">
|
||||
<div class="w-12 h-12 rounded-2xl bg-surface-container-highest flex items-center justify-center text-error">
|
||||
<span class="material-symbols-outlined text-2xl">fmd_bad</span>
|
||||
</div>
|
||||
<h3 class="font-headline-sm text-headline-sm text-on-surface">Real-Time Police Swarm</h3>
|
||||
<p class="font-body-md text-body-md text-on-surface-variant">
|
||||
Multi-source verified Waze speed traps, fixed laser gantries, and stationary cruisers. Filter false positives through algorithmic peer confidence weighting.
|
||||
</p>
|
||||
</div>
|
||||
<div class="p-space-sm rounded-2xl bg-surface-container-low flex flex-col gap-space-xs">
|
||||
<div class="flex items-center justify-between font-label-caption text-label-caption text-on-surface-variant uppercase">
|
||||
<span>Radar Trap Filter</span>
|
||||
<span class="text-error font-semibold">CONFIRMED 98.4%</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between pt-1">
|
||||
<span class="font-label-data text-label-data text-on-surface uppercase">Direct Waze Mesh Pipe</span>
|
||||
<span class="font-label-data text-label-data text-primary"><850ms Latency</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Pillar 3: Live Pack Mesh Radar -->
|
||||
<div class="p-space-lg rounded-3xl bg-surface-container flex flex-col justify-between gap-space-md hover:bg-surface-container-high transition-all">
|
||||
<div class="flex flex-col gap-space-md">
|
||||
<div class="w-12 h-12 rounded-2xl bg-surface-container-highest flex items-center justify-center text-secondary">
|
||||
<span class="material-symbols-outlined text-2xl">hub</span>
|
||||
</div>
|
||||
<h3 class="font-headline-sm text-headline-sm text-on-surface">Live Pack Mesh Radar</h3>
|
||||
<p class="font-body-md text-body-md text-on-surface-variant">
|
||||
Keep the pack synchronized without mobile network towers. Ad-hoc peer-to-peer radio mesh broadcasts group formations, gap splits, and instant hazard alerts.
|
||||
</p>
|
||||
</div>
|
||||
<div class="p-space-sm rounded-2xl bg-surface-container-low flex flex-col gap-space-xs">
|
||||
<div class="flex items-center justify-between font-label-caption text-label-caption text-on-surface-variant uppercase">
|
||||
<span>Formation Protocol</span>
|
||||
<span class="text-secondary font-semibold">12 PEERS LINKED</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between pt-1">
|
||||
<span class="font-label-data text-label-data text-on-surface uppercase">One-Tap Hazard Signal</span>
|
||||
<span class="font-label-data text-label-data text-primary">0.02s Propagation</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- TESTIMONIAL & COMMUNITY SOCIAL PROOF -->
|
||||
<section class="w-full px-margin md:px-margin-lg lg:px-gutter-lg py-space-xl">
|
||||
<div class="max-w-7xl mx-auto flex flex-col gap-space-lg">
|
||||
<div class="flex flex-col md:flex-row md:items-end justify-between gap-space-md">
|
||||
<div class="flex flex-col gap-space-xs max-w-xl">
|
||||
<span class="font-label-data text-label-data text-primary-container uppercase tracking-widest">Track & Road Verification</span>
|
||||
<h2 class="font-headline-lg text-headline-lg text-on-surface">Proven by Riders Who Push the Envelope</h2>
|
||||
</div>
|
||||
<div class="flex items-center gap-space-sm">
|
||||
<span class="font-label-data text-label-data text-primary">OVER 4.2M KM LOGGED</span>
|
||||
<span class="w-2 h-2 rounded-full bg-primary-container"></span>
|
||||
<span class="font-label-data text-label-data text-on-surface-variant">GLOBAL SESSIONS</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-space-md">
|
||||
<!-- Card 1 -->
|
||||
<div class="p-space-md rounded-2xl bg-surface-container flex flex-col justify-between gap-space-md shadow-md">
|
||||
<div class="flex flex-col gap-space-sm">
|
||||
<div class="flex items-center gap-space-xs text-primary-container">
|
||||
<span class="material-symbols-outlined text-sm">star</span>
|
||||
<span class="material-symbols-outlined text-sm">star</span>
|
||||
<span class="material-symbols-outlined text-sm">star</span>
|
||||
<span class="material-symbols-outlined text-sm">star</span>
|
||||
<span class="material-symbols-outlined text-sm">star</span>
|
||||
</div>
|
||||
<p class="font-body-md text-body-md text-on-surface italic">
|
||||
“The Safety Lean Mute feature is game-changing. In fast sweepers on Turn 4 at Laguna Seca, voice cues mute instantly so my mind stays totally on front tire grip.”
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex items-center justify-between pt-space-xs">
|
||||
<div class="flex items-center gap-space-sm">
|
||||
<img class="w-10 h-10 rounded-full object-cover" data-alt="Close-up portrait of a track day motorcycle racer wearing full leather suit and carbon helmet visor resting on paddock table with neon cyan reflections" src="https://lh3.googleusercontent.com/aida-public/AB6AXuCKngejdZ_85S3s8_r388dRfefUuVH1P0AR-SeeHjNBl29oClBsQlHj7UkMuWr13KXVovEteZE_o2XDZteDFhe5quTs-TwAbDUA2PqeIOis4JKqpuaBNEjN84Bh_xcrMC5WsfpMujfy87TM2gDBaot7PNd6Y7Br36-bYkJGWpBPD5Vs5MDIE721UeW9EKagVLXOf7OFhzMlIEHHJGQWQQ1cs5ie31dqsjZlEnsKxOqMC5FeJQhQ2RJU"/>
|
||||
<div class="flex flex-col">
|
||||
<span class="font-headline-sm text-sm text-on-surface">Marcus Vance</span>
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant uppercase">Ducati Panigale V4 S</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col items-end">
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant uppercase">Max Lean</span>
|
||||
<span class="font-label-data text-label-data text-primary-container">54.2°</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Card 2 -->
|
||||
<div class="p-space-md rounded-2xl bg-surface-container flex flex-col justify-between gap-space-md shadow-md">
|
||||
<div class="flex flex-col gap-space-sm">
|
||||
<div class="flex items-center gap-space-xs text-primary-container">
|
||||
<span class="material-symbols-outlined text-sm">star</span>
|
||||
<span class="material-symbols-outlined text-sm">star</span>
|
||||
<span class="material-symbols-outlined text-sm">star</span>
|
||||
<span class="material-symbols-outlined text-sm">star</span>
|
||||
<span class="material-symbols-outlined text-sm">star</span>
|
||||
</div>
|
||||
<p class="font-body-md text-body-md text-on-surface italic">
|
||||
“We manage pack rides of 14 bikes through the Rockies. Mesh radar kept our formation unified even when cellular coverage dropped out completely for three hours.”
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex items-center justify-between pt-space-xs">
|
||||
<div class="flex items-center gap-space-sm">
|
||||
<img class="w-10 h-10 rounded-full object-cover" data-alt="Rugged road captain standing next to an adventure sport motorcycle at dusk with glowing tail lights and helmet on handlebar" src="https://lh3.googleusercontent.com/aida-public/AB6AXuBmvrci29u-2yWm_PfbbIMhCUQue3Ke6cIY0NH1f6SPmvrqouv0xCVk932nGkzmHmTjuzBYb6phtl8c1EV03lTfGfAQfdLVCMrW9w9ICvw8wpJvrjQCK-gR1g_NxJgurEMYtrrCYxTSIy-wBPSNf0n4hIHDytYX_s6d8MFhbz3zWD11FOp6QbOpx-QX5_3dJXF6r3TWVlzD_yLqiGylO1zqlJ_evfItQmgAS0nVtehmNTQdbWDseGOe"/>
|
||||
<div class="flex flex-col">
|
||||
<span class="font-headline-sm text-sm text-on-surface">Elena Rostova</span>
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant uppercase">BMW S1000RR M-Pack</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col items-end">
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant uppercase">Max Lean</span>
|
||||
<span class="font-label-data text-label-data text-primary-container">51.8°</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Card 3 -->
|
||||
<div class="p-space-md rounded-2xl bg-surface-container flex flex-col justify-between gap-space-md shadow-md">
|
||||
<div class="flex flex-col gap-space-sm">
|
||||
<div class="flex items-center gap-space-xs text-primary-container">
|
||||
<span class="material-symbols-outlined text-sm">star</span>
|
||||
<span class="material-symbols-outlined text-sm">star</span>
|
||||
<span class="material-symbols-outlined text-sm">star</span>
|
||||
<span class="material-symbols-outlined text-sm">star</span>
|
||||
<span class="material-symbols-outlined text-sm">star</span>
|
||||
</div>
|
||||
<p class="font-body-md text-body-md text-on-surface italic">
|
||||
“The 20Hz sensor fusion exposes every flaw in my trail braking. I dropped 1.8 seconds off my home circuit time after auditing three session overlays in the Drift Schema.”
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex items-center justify-between pt-space-xs">
|
||||
<div class="flex items-center gap-space-sm">
|
||||
<img class="w-10 h-10 rounded-full object-cover" data-alt="Motorcycle track engineer holding diagnostic tablet in pit garage with aerodynamic sports bike under sharp LED overhead lighting" src="https://lh3.googleusercontent.com/aida-public/AB6AXuC3GnTcHi024W-SqIa2YlpHvUmlKbWRtaUi8XG0wOePGDw3sGE4rDAxFaDPrQhREkcv6qKV-G75qeZsxb1fGS9ZK6VvIZ8zpZUqIteu6HyAsL7K0as51GYuz_RW4NH54YOMHrwJmwo6-R69WNXs3KrQSSDYJsfVd6VEZumDRZM-IvGyKGaV3tut2QIxCAlqilEFWc6vAxZxYBzYdkpQZFw8-GDl7mE8KGSr9lJVPkuEku4Dv89LV0A8"/>
|
||||
<div class="flex flex-col">
|
||||
<span class="font-headline-sm text-sm text-on-surface">Taro Takahashi</span>
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant uppercase">Yamaha YZF-R1M</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col items-end">
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant uppercase">Max Lean</span>
|
||||
<span class="font-label-data text-label-data text-primary-container">53.6°</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- HIGH-IMPACT CONVERSION BANNER -->
|
||||
<section class="w-full px-margin md:px-margin-lg lg:px-gutter-lg pb-space-xl" id="download">
|
||||
<div class="max-w-7xl mx-auto rounded-3xl bg-surface-container-high p-space-lg lg:p-space-xl relative overflow-hidden shadow-2xl">
|
||||
<!-- Ambient backing lights -->
|
||||
<div class="absolute -right-16 -top-16 w-80 h-80 bg-primary-container/20 blur-3xl rounded-full pointer-events-none"></div>
|
||||
<div class="grid grid-cols-1 lg:grid-cols-12 gap-space-lg items-center relative z-10">
|
||||
<div class="lg:col-span-8 flex flex-col gap-space-md">
|
||||
<div class="inline-flex items-center gap-space-xs">
|
||||
<span class="w-2 h-2 rounded-full bg-primary-container animate-pulse"></span>
|
||||
<span class="font-label-data text-label-data text-primary-container uppercase">Zero Cellular Lag • Direct Hardware APK</span>
|
||||
</div>
|
||||
<h2 class="font-headline-lg text-headline-lg text-on-surface">
|
||||
Equip Your Cockpit with Aerospace-Grade Telemetry
|
||||
</h2>
|
||||
<p class="font-body-lg text-body-lg text-on-surface-variant max-w-xl">
|
||||
Download the verified release APK directly or scan with your cockpit mobile unit to sync instantly across all bike mounts.
|
||||
</p>
|
||||
<div class="flex flex-wrap items-center gap-space-md pt-space-xs">
|
||||
<a class="inline-flex items-center justify-center gap-space-xs h-[52px] px-space-lg rounded-xl bg-primary-container text-on-primary font-label-data text-label-data uppercase tracking-wider shadow-[0_0_20px_rgba(0,229,255,0.4)] hover:bg-primary transition-all duration-200" href="#">
|
||||
<span class="material-symbols-outlined text-lg">download</span>
|
||||
Download MotorSignal APK
|
||||
</a>
|
||||
<a class="inline-flex items-center justify-center gap-space-xs h-[52px] px-space-lg rounded-xl bg-surface text-on-surface font-label-data text-label-data uppercase tracking-wider hover:bg-surface-bright transition-all duration-200" href="#">
|
||||
<span class="material-symbols-outlined text-lg">person_add</span>
|
||||
Join iOS Beta Waitlist
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Mobile Handoff QR Code Widget -->
|
||||
<div class="lg:col-span-4 flex flex-col items-center justify-center">
|
||||
<div class="p-space-md rounded-2xl bg-surface-container-lowest flex flex-col items-center gap-space-sm shadow-xl">
|
||||
<!-- Simulated Tactical Monochromatic QR Code SVG -->
|
||||
<div class="w-40 h-40 bg-on-surface p-space-xs rounded-xl flex items-center justify-center">
|
||||
<svg class="w-full h-full text-surface-container-lowest" fill="currentColor" viewbox="0 0 100 100">
|
||||
<!-- Outer Corners -->
|
||||
<rect height="28" rx="2" width="28" x="5" y="5"></rect>
|
||||
<rect fill="white" height="18" width="18" x="10" y="10"></rect>
|
||||
<rect height="10" width="10" x="14" y="14"></rect>
|
||||
<rect height="28" rx="2" width="28" x="67" y="5"></rect>
|
||||
<rect fill="white" height="18" width="18" x="72" y="10"></rect>
|
||||
<rect height="10" width="10" x="76" y="14"></rect>
|
||||
<rect height="28" rx="2" width="28" x="5" y="67"></rect>
|
||||
<rect fill="white" height="18" width="18" x="10" y="72"></rect>
|
||||
<rect height="10" width="10" x="14" y="76"></rect>
|
||||
<!-- Internal Data Blocks -->
|
||||
<rect height="8" width="8" x="40" y="10"></rect>
|
||||
<rect height="8" width="8" x="52" y="14"></rect>
|
||||
<rect height="8" width="14" x="40" y="26"></rect>
|
||||
<rect height="6" width="12" x="10" y="42"></rect>
|
||||
<rect height="14" width="16" x="28" y="40"></rect>
|
||||
<rect height="10" width="10" x="50" y="40"></rect>
|
||||
<rect height="6" width="24" x="68" y="42"></rect>
|
||||
<rect height="14" width="15" x="45" y="58"></rect>
|
||||
<rect height="16" width="12" x="68" y="56"></rect>
|
||||
<rect height="14" width="8" x="40" y="78"></rect>
|
||||
<rect height="8" width="16" x="56" y="78"></rect>
|
||||
<rect height="14" width="14" x="78" y="78"></rect>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="flex flex-col items-center text-center">
|
||||
<span class="font-label-data text-label-data text-primary uppercase">Scan For Mobile Handoff</span>
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant uppercase mt-0.5">Direct APK sideload • SHA-256 Verified</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- Interactive Lean Angle Physics Script -->
|
||||
<script>
|
||||
(function initLeanPhysicsVisualizer() {
|
||||
const slider = document.getElementById('lean-range');
|
||||
const valDisplay = document.getElementById('lean-value');
|
||||
const catDisplay = document.getElementById('lean-category');
|
||||
const audioState = document.getElementById('audio-state');
|
||||
const needle = document.getElementById('needle');
|
||||
|
||||
if (!slider || !valDisplay || !needle) return;
|
||||
|
||||
slider.addEventListener('input', function() {
|
||||
const angle = parseInt(this.value, 10);
|
||||
valDisplay.textContent = angle;
|
||||
|
||||
// Needle rotation calculation: 0 deg = upright (approx 100, 20), 55 deg = right lean
|
||||
// 0 to 55 deg maps from ~90 deg to ~35 deg on normal circular coords
|
||||
const rad = ((90 - (angle * 0.95)) * Math.PI) / 180;
|
||||
const cx = 100;
|
||||
const cy = 100;
|
||||
const len = 75;
|
||||
const nx = cx + len * Math.cos(rad);
|
||||
const ny = cy - len * Math.sin(rad);
|
||||
|
||||
needle.setAttribute('x2', nx.toFixed(1));
|
||||
needle.setAttribute('y2', ny.toFixed(1));
|
||||
|
||||
// Safety lean mute interlock state update
|
||||
if (angle > 15) {
|
||||
audioState.textContent = 'SUPPRESSED';
|
||||
audioState.className = 'font-label-data text-label-data text-error font-semibold uppercase';
|
||||
} else {
|
||||
audioState.textContent = 'TRANSPARENT';
|
||||
audioState.className = 'font-label-data text-label-data text-primary uppercase font-semibold';
|
||||
}
|
||||
|
||||
// Categorization feedback
|
||||
if (angle < 15) {
|
||||
catDisplay.textContent = 'Cruising (' + angle + '\u00B0)';
|
||||
} else if (angle <= 40) {
|
||||
catDisplay.textContent = 'Technical Cornering (' + angle + '\u00B0)';
|
||||
} else {
|
||||
catDisplay.textContent = 'Aggressive Apex (' + angle + '\u00B0)';
|
||||
}
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
</div></main><footer class="w-full bg-surface-container-lowest pt-space-xl pb-space-lg"><div class="w-full px-gutter-lg"><div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-5 gap-space-lg pb-space-lg"><div class="lg:col-span-2 flex flex-col gap-space-sm"><div class="flex items-center gap-space-sm"><span class="font-headline-sm text-headline-sm uppercase tracking-wider text-primary">MotorSignal</span><span class="px-space-xs py-space-xs rounded font-label-caption text-label-caption bg-surface-container text-primary-container uppercase">Precision Cockpit HUD</span></div><p class="font-body-md text-body-md text-on-surface-variant max-w-md">Next-generation telemetry engine engineered for track day racers, aggressive sport riders, and synchronized pack navigation with real-time IMU lean angle computation.</p><div class="flex items-center gap-space-sm pt-space-xs"><span class="w-2.5 h-2.5 rounded-full bg-primary-container shadow-[0_0_8px_#00e5ff]"></span><span class="font-label-data text-label-data text-on-surface uppercase">Telemetry Core v4.8.2 Active</span></div></div><div class="flex flex-col gap-space-sm"><span class="font-label-data text-label-data text-primary uppercase tracking-wider">Platform Modules</span><ul class="flex flex-col gap-space-xs"><li class="font-body-md text-body-md text-on-surface-variant hover:text-on-surface transition-colors cursor-pointer">Telemetry Specs</li><li class="font-body-md text-body-md text-on-surface-variant hover:text-on-surface transition-colors cursor-pointer">Curvy Routes</li><li class="font-body-md text-body-md text-on-surface-variant hover:text-on-surface transition-colors cursor-pointer">Pack Radar</li><li class="font-body-md text-body-md text-on-surface-variant hover:text-on-surface transition-colors cursor-pointer">Draggy Launch</li></ul></div><div class="flex flex-col gap-space-sm"><span class="font-label-data text-label-data text-primary uppercase tracking-wider">Ecosystem</span><ul class="flex flex-col gap-space-xs"><li class="font-body-md text-body-md text-on-surface-variant hover:text-on-surface transition-colors cursor-pointer">OBD-II CANbus Link</li><li class="font-body-md text-body-md text-on-surface-variant hover:text-on-surface transition-colors cursor-pointer">IMU 6-Axis Calibration</li><li class="font-body-md text-body-md text-on-surface-variant hover:text-on-surface transition-colors cursor-pointer">Corner Trajectory AI</li><li class="font-body-md text-body-md text-on-surface-variant hover:text-on-surface transition-colors cursor-pointer">G-Force Mapping</li></ul></div><div class="flex flex-col gap-space-sm"><span class="font-label-data text-label-data text-primary uppercase tracking-wider">Governance</span><ul class="flex flex-col gap-space-xs"><li class="font-body-md text-body-md text-on-surface-variant hover:text-on-surface transition-colors cursor-pointer">Privacy Architecture</li><li class="font-body-md text-body-md text-on-surface-variant hover:text-on-surface transition-colors cursor-pointer">Telemetry Terms</li><li class="font-body-md text-body-md text-on-surface-variant hover:text-on-surface transition-colors cursor-pointer">Safety Disclaimers</li><li class="font-body-md text-body-md text-on-surface-variant hover:text-on-surface transition-colors cursor-pointer">Mesh Node Protocol</li></ul></div></div><div class="pt-space-md flex flex-col md:flex-row items-center justify-between gap-space-sm"><span class="font-label-caption text-label-caption text-on-surface-variant uppercase">© 2025 MotorSignal Technologies Inc. Built for zero-cognitive lag.</span><div class="flex items-center gap-space-md"><span class="font-label-caption text-label-caption text-on-surface-variant uppercase">All nodes operational</span><span class="font-label-data text-label-data text-primary">99.98% Latency <14ms</span></div></div></div></footer></body></html>
|
||||
|
|
@ -0,0 +1,437 @@
|
|||
<!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>
|
||||
|
|
@ -0,0 +1,425 @@
|
|||
<!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&family=JetBrains+Mono:wght@400;500;600;700;800&family=Space+Grotesk:wght@500;600;700&display=swap" rel="stylesheet"/>
|
||||
<!-- Material Symbols Outlined -->
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&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>
|
||||
|
|
@ -0,0 +1,580 @@
|
|||
<!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 - Active Recording</title>
|
||||
<!-- Google Fonts: Space Grotesk, JetBrains Mono, Inter -->
|
||||
<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&family=JetBrains+Mono:wght@400;500;600;700;800&family=Space+Grotesk:wght@500;600;700&display=swap" rel="stylesheet"/>
|
||||
<!-- Material Symbols Outlined -->
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<!-- Tailwind CSS v3 -->
|
||||
<script src="https://cdn.tailwindcss.com?plugins=forms,container-queries"></script>
|
||||
<script id="tailwind-config">
|
||||
tailwind.config = {
|
||||
darkMode: "class",
|
||||
theme: {
|
||||
extend: {
|
||||
"colors": {
|
||||
"inverse-on-surface": "#2d3036",
|
||||
"tertiary": "#f2e9ff",
|
||||
"on-error": "#690005",
|
||||
"surface-container-highest": "#32353b",
|
||||
"primary": "#c3f5ff",
|
||||
"inverse-primary": "#006875",
|
||||
"surface-bright": "#36393f",
|
||||
"on-primary": "#00363d",
|
||||
"surface-container-high": "#272a30",
|
||||
"on-secondary-fixed-variant": "#003ea8",
|
||||
"outline": "#849396",
|
||||
"tertiary-fixed-dim": "#d0bcff",
|
||||
"surface-container-low": "#181c21",
|
||||
"on-primary-container": "#00626e",
|
||||
"on-tertiary-container": "#6834d1",
|
||||
"outline-variant": "#3b494c",
|
||||
"tertiary-container": "#d9c8ff",
|
||||
"on-secondary": "#002a78",
|
||||
"surface-container-lowest": "#0b0e13",
|
||||
"on-secondary-container": "#cdd7ff",
|
||||
"surface": "#101419",
|
||||
"on-tertiary": "#3c0091",
|
||||
"tertiary-fixed": "#e9ddff",
|
||||
"surface-variant": "#32353b",
|
||||
"primary-container": "#00e5ff",
|
||||
"on-primary-fixed": "#001f24",
|
||||
"secondary": "#b4c5ff",
|
||||
"on-surface": "#e0e2ea",
|
||||
"on-secondary-fixed": "#00174b",
|
||||
"surface-dim": "#101419",
|
||||
"inverse-surface": "#e0e2ea",
|
||||
"secondary-fixed": "#dbe1ff",
|
||||
"on-background": "#e0e2ea",
|
||||
"on-tertiary-fixed-variant": "#5516be",
|
||||
"on-surface-variant": "#bac9cc",
|
||||
"primary-fixed-dim": "#00daf3",
|
||||
"on-tertiary-fixed": "#23005c",
|
||||
"on-error-container": "#ffdad6",
|
||||
"secondary-fixed-dim": "#b4c5ff",
|
||||
"error": "#ffb4ab",
|
||||
"error-container": "#93000a",
|
||||
"on-primary-fixed-variant": "#004f58",
|
||||
"background": "#101419",
|
||||
"surface-tint": "#00daf3",
|
||||
"surface-container": "#1d2025",
|
||||
"secondary-container": "#0053db",
|
||||
"primary-fixed": "#9cf0ff"
|
||||
},
|
||||
"borderRadius": {
|
||||
"DEFAULT": "0.25rem",
|
||||
"lg": "0.5rem",
|
||||
"xl": "0.75rem",
|
||||
"full": "9999px"
|
||||
},
|
||||
"spacing": {
|
||||
"margin": "1rem",
|
||||
"gutter": "1rem",
|
||||
"space-sm": "0.5rem",
|
||||
"space-lg": "1.5rem",
|
||||
"space-xl": "2rem",
|
||||
"space-xs": "0.25rem",
|
||||
"margin-lg": "2rem",
|
||||
"space-md": "1rem",
|
||||
"gutter-lg": "1.5rem"
|
||||
},
|
||||
"fontFamily": {
|
||||
"telemetry-metric-lg-mobile": [
|
||||
"JetBrains Mono"
|
||||
],
|
||||
"body-lg": [
|
||||
"Inter"
|
||||
],
|
||||
"display-hero-mobile": [
|
||||
"Space Grotesk"
|
||||
],
|
||||
"telemetry-metric-lg": [
|
||||
"JetBrains Mono"
|
||||
],
|
||||
"headline-lg": [
|
||||
"Space Grotesk"
|
||||
],
|
||||
"telemetry-metric-md": [
|
||||
"JetBrains Mono"
|
||||
],
|
||||
"headline-md": [
|
||||
"Space Grotesk"
|
||||
],
|
||||
"label-caption": [
|
||||
"Inter"
|
||||
],
|
||||
"headline-sm": [
|
||||
"Space Grotesk"
|
||||
],
|
||||
"body-md": [
|
||||
"Inter"
|
||||
],
|
||||
"label-data": [
|
||||
"JetBrains Mono"
|
||||
],
|
||||
"display-hero": [
|
||||
"Space Grotesk"
|
||||
]
|
||||
},
|
||||
"fontSize": {
|
||||
"telemetry-metric-lg-mobile": [
|
||||
"36px",
|
||||
{
|
||||
"lineHeight": "36px",
|
||||
"letterSpacing": "-0.03em",
|
||||
"fontWeight": "700"
|
||||
}
|
||||
],
|
||||
"body-lg": [
|
||||
"16px",
|
||||
{
|
||||
"lineHeight": "24px",
|
||||
"fontWeight": "500"
|
||||
}
|
||||
],
|
||||
"display-hero-mobile": [
|
||||
"40px",
|
||||
{
|
||||
"lineHeight": "44px",
|
||||
"letterSpacing": "-0.02em",
|
||||
"fontWeight": "700"
|
||||
}
|
||||
],
|
||||
"telemetry-metric-lg": [
|
||||
"48px",
|
||||
{
|
||||
"lineHeight": "48px",
|
||||
"letterSpacing": "-0.04em",
|
||||
"fontWeight": "700"
|
||||
}
|
||||
],
|
||||
"headline-lg": [
|
||||
"32px",
|
||||
{
|
||||
"lineHeight": "40px",
|
||||
"letterSpacing": "-0.02em",
|
||||
"fontWeight": "700"
|
||||
}
|
||||
],
|
||||
"telemetry-metric-md": [
|
||||
"28px",
|
||||
{
|
||||
"lineHeight": "32px",
|
||||
"letterSpacing": "-0.02em",
|
||||
"fontWeight": "600"
|
||||
}
|
||||
],
|
||||
"headline-md": [
|
||||
"24px",
|
||||
{
|
||||
"lineHeight": "32px",
|
||||
"letterSpacing": "-0.01em",
|
||||
"fontWeight": "600"
|
||||
}
|
||||
],
|
||||
"label-caption": [
|
||||
"11px",
|
||||
{
|
||||
"lineHeight": "14px",
|
||||
"letterSpacing": "0.05em",
|
||||
"fontWeight": "600"
|
||||
}
|
||||
],
|
||||
"headline-sm": [
|
||||
"20px",
|
||||
{
|
||||
"lineHeight": "28px",
|
||||
"fontWeight": "600"
|
||||
}
|
||||
],
|
||||
"body-md": [
|
||||
"14px",
|
||||
{
|
||||
"lineHeight": "20px",
|
||||
"fontWeight": "400"
|
||||
}
|
||||
],
|
||||
"label-data": [
|
||||
"12px",
|
||||
{
|
||||
"lineHeight": "16px",
|
||||
"letterSpacing": "0.08em",
|
||||
"fontWeight": "600"
|
||||
}
|
||||
],
|
||||
"display-hero": [
|
||||
"56px",
|
||||
{
|
||||
"lineHeight": "60px",
|
||||
"letterSpacing": "-0.03em",
|
||||
"fontWeight": "700"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.material-symbols-outlined {
|
||||
font-variation-settings: 'FILL' 0, 'wght' 500, 'GRAD' 0, 'opsz' 24;
|
||||
line-height: 1;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
/* Pulse glow keyframe */
|
||||
@keyframes pulse-red-glow {
|
||||
0%, 100% { box-shadow: 0 0 12px rgba(239, 68, 68, 0.4); }
|
||||
50% { box-shadow: 0 0 24px rgba(239, 68, 68, 0.85); }
|
||||
}
|
||||
.recording-pulse {
|
||||
animation: pulse-red-glow 1.6s infinite ease-in-out;
|
||||
}
|
||||
/* Sub-pixel HUD neon glow */
|
||||
.cyan-glow {
|
||||
text-shadow: 0 0 16px rgba(0, 229, 255, 0.55);
|
||||
}
|
||||
.cyan-border-glow {
|
||||
box-shadow: 0 0 16px rgba(0, 229, 255, 0.25);
|
||||
}
|
||||
/* Touch Action slider styling */
|
||||
.slider-track {
|
||||
touch-action: pan-y;
|
||||
user-select: none;
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
body {
|
||||
min-height: max(884px, 100dvh);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-surface-container-lowest text-on-surface antialiased overflow-x-hidden selection:bg-primary-container selection:text-on-primary-fixed min-h-screen pb-24">
|
||||
<!-- TOP APP BAR (Shared Component Anchor) -->
|
||||
<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 gap-space-xs">
|
||||
<span class="material-symbols-outlined text-primary-container" 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 gap-space-sm">
|
||||
<div class="hidden sm:flex items-center gap-space-xs px-2 py-0.5 rounded bg-surface-container border border-outline-variant">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-primary-container animate-ping"></span>
|
||||
<span class="text-label-data font-label-data text-primary">CAN: OK</span>
|
||||
</div>
|
||||
<button aria-label="Alerts" class="flex items-center justify-center w-10 h-10 rounded text-error-container hover:bg-surface-container active:scale-95 duration-100 ease-out">
|
||||
<span class="material-symbols-outlined text-error" data-icon="warning" style="font-variation-settings: 'FILL' 1;">warning</span>
|
||||
</button>
|
||||
</div>
|
||||
</header>
|
||||
<!-- MAIN HUD CANVASS CONTAINER (Mobile Optimized Cockpit View) -->
|
||||
<main class="w-full max-w-md mx-auto pt-16 px-space-sm flex flex-col gap-space-sm">
|
||||
<!-- TOP SYSTEM CALIBRATION & KALMAN STATUS BAR -->
|
||||
<section class="w-full bg-surface-container-low border border-outline-variant rounded-lg p-2.5 flex items-center justify-between shadow-sm">
|
||||
<div class="flex items-center gap-1.5">
|
||||
<span class="material-symbols-outlined text-primary-container text-[18px]" data-icon="satellite_alt">satellite_alt</span>
|
||||
<span class="text-label-data font-label-data text-on-surface">RTK: 18 SVs</span>
|
||||
<span class="text-label-caption font-label-caption px-1.5 py-0.2 rounded bg-surface-container text-primary border border-outline-variant">20Hz LOCK</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="flex items-center gap-1">
|
||||
<span class="material-symbols-outlined text-on-surface-variant text-[16px]" data-icon="thermostat">thermostat</span>
|
||||
<span class="text-label-data font-label-data text-on-surface">74°F</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-1">
|
||||
<span class="material-symbols-outlined text-primary-container text-[16px]" data-icon="bluetooth">bluetooth</span>
|
||||
<span class="text-label-data font-label-data text-on-surface">CAN-BUS</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-1">
|
||||
<span class="material-symbols-outlined text-primary-fixed text-[16px]" data-icon="battery_full">battery_full</span>
|
||||
<span class="text-label-data font-label-data text-primary-fixed">98%</span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- PROMINENT ACTIVE RECORDING PILL BANNER -->
|
||||
<section class="w-full flex flex-col items-center justify-center py-1">
|
||||
<div class="recording-pulse w-full bg-error-container border border-error/50 rounded-xl px-4 py-2 flex items-center justify-between">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="relative flex h-3 w-3">
|
||||
<span class="animate-ping absolute inline-flex h-full w-full rounded-full bg-error opacity-75"></span>
|
||||
<span class="relative inline-flex rounded-full h-3 w-3 bg-error"></span>
|
||||
</span>
|
||||
<span class="text-label-data font-label-data font-bold text-on-error-container tracking-wider">REC 20Hz</span>
|
||||
<span class="text-label-data font-label-data text-error font-bold ml-1">00:42:15</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-1 bg-surface-container-lowest/80 px-2.5 py-1 rounded border border-outline-variant">
|
||||
<span class="material-symbols-outlined text-primary-container text-[14px]" data-icon="database">database</span>
|
||||
<span class="text-label-caption font-label-caption text-primary">DRIFT V7 • 0 DROPS</span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- PRIMARY SPEED TELEMETRY CLUSTER -->
|
||||
<section class="w-full bg-surface-container-low border border-outline-variant rounded-xl p-4 relative overflow-hidden flex flex-col items-center justify-center">
|
||||
<!-- Background HUD Corner Ticks -->
|
||||
<div class="absolute top-2 left-2 w-3 h-3 border-t-2 border-l-2 border-primary-container/40"></div>
|
||||
<div class="absolute top-2 right-2 w-3 h-3 border-t-2 border-r-2 border-primary-container/40"></div>
|
||||
<div class="absolute bottom-2 left-2 w-3 h-3 border-b-2 border-l-2 border-primary-container/40"></div>
|
||||
<div class="absolute bottom-2 right-2 w-3 h-3 border-b-2 border-r-2 border-primary-container/40"></div>
|
||||
<!-- Live Speed Limit / Target Indicator -->
|
||||
<div class="w-full flex items-center justify-between mb-1">
|
||||
<span class="text-label-data font-label-data text-on-surface-variant flex items-center gap-1">
|
||||
<span class="material-symbols-outlined text-[16px] text-primary-container" data-icon="speed">speed</span>
|
||||
PRIMARY VELOCITY
|
||||
</span>
|
||||
<div class="flex items-center gap-1 bg-surface-container-high px-2 py-0.5 rounded border border-error/50 text-error">
|
||||
<span class="text-label-data font-label-data font-bold">SPEED 74 MPH • LIMIT 55</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Huge Digital Speed Display -->
|
||||
<div class="flex flex-col items-center justify-center my-1">
|
||||
<span class="text-display-hero-mobile font-display-hero-mobile font-extrabold text-primary-container tracking-tighter cyan-glow leading-none text-[84px] md:text-[96px]">74</span>
|
||||
<span class="text-headline-sm font-headline-sm font-bold text-on-surface-variant tracking-widest mt-1">MPH</span>
|
||||
</div>
|
||||
<!-- Dynamic Tachometer / Linear Velocity Bar -->
|
||||
<div class="w-full mt-2 space-y-1">
|
||||
<div class="w-full bg-surface-container-highest h-3 rounded-full overflow-hidden flex p-0.5 border border-outline-variant">
|
||||
<div class="bg-primary-container h-full rounded-l-full" style="width: 55%;"></div>
|
||||
<div class="bg-tertiary-fixed h-full" style="width: 15%;"></div>
|
||||
<div class="bg-error h-full rounded-r-full" style="width: 12%;"></div>
|
||||
<div class="bg-transparent h-full flex-1"></div>
|
||||
</div>
|
||||
<div class="w-full flex justify-between text-label-caption font-label-caption text-on-surface-variant px-1 font-mono">
|
||||
<span>0</span>
|
||||
<span>35</span>
|
||||
<span class="text-primary-container font-bold">55 (LIMIT)</span>
|
||||
<span class="text-error font-bold">74 CRUISE</span>
|
||||
<span>120</span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- DYNAMIC LEAN ANGLE & G-METER CLUSTER (Bento 2-Col Layout) -->
|
||||
<div class="w-full grid grid-cols-2 gap-space-sm">
|
||||
<!-- Dynamic Lean Angle Card -->
|
||||
<section class="bg-surface-container-low border border-outline-variant rounded-xl p-3 flex flex-col justify-between relative overflow-hidden">
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="text-label-data font-label-data text-on-surface-variant flex items-center gap-1">
|
||||
<span class="material-symbols-outlined text-[15px] text-primary-container" data-icon="screen_rotation">screen_rotation</span>
|
||||
LEAN ARC
|
||||
</span>
|
||||
<span class="text-label-caption font-label-caption text-primary bg-surface-container-high px-1.5 py-0.5 rounded">PEAK 44°</span>
|
||||
</div>
|
||||
<!-- Lean Angle Graphic & Indicator -->
|
||||
<div class="my-3 flex flex-col items-center">
|
||||
<!-- Semicircular SVG Arc -->
|
||||
<div class="relative w-28 h-16 flex items-end justify-center">
|
||||
<svg class="w-28 h-16 overflow-visible" viewbox="0 0 100 50">
|
||||
<path d="M 10 50 A 40 40 0 0 1 90 50" fill="none" stroke="#272a30" stroke-linecap="round" stroke-width="8"></path>
|
||||
<!-- Active Bank Arc Left (38 degrees) -->
|
||||
<path d="M 50 10 A 40 40 0 0 0 20 44" fill="none" stroke="#00e5ff" stroke-linecap="round" stroke-width="8"></path>
|
||||
<!-- Center Reference Zero Mark -->
|
||||
<line stroke="#ffffff" stroke-width="2" x1="50" x2="50" y1="6" y2="14"></line>
|
||||
<!-- Needle Pointer Indicator -->
|
||||
<line stroke="#ffb4ab" stroke-linecap="round" stroke-width="3" x1="50" x2="28" y1="50" y2="18"></line>
|
||||
</svg>
|
||||
<div class="absolute bottom-0 text-center">
|
||||
<span class="text-headline-md font-headline-md font-bold text-primary-container cyan-glow leading-none">38°</span>
|
||||
<span class="text-label-caption font-label-caption font-bold text-error block">LEFT</span>
|
||||
</div>
|
||||
</div>
|
||||
<span class="text-label-caption font-label-caption text-on-surface-variant mt-2 font-mono">ROLL: -14.2°/S</span>
|
||||
</div>
|
||||
<!-- G-Guard Lean Interlock Status -->
|
||||
<div class="w-full bg-surface-container-high/90 border border-outline-variant rounded p-1.5 flex items-center gap-1.5">
|
||||
<span class="material-symbols-outlined text-primary text-[14px]" data-icon="volume_off">volume_off</span>
|
||||
<span class="text-[10px] leading-tight font-label-data text-primary font-bold">G-GUARD INTERLOCK ACTIVE (>15°)</span>
|
||||
</div>
|
||||
</section>
|
||||
<!-- Kinematics & 2D G-Force Friction Circle Card -->
|
||||
<section class="bg-surface-container-low border border-outline-variant rounded-xl p-3 flex flex-col justify-between relative overflow-hidden">
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="text-label-data font-label-data text-on-surface-variant flex items-center gap-1">
|
||||
<span class="material-symbols-outlined text-[15px] text-primary-container" data-icon="scatter_plot">scatter_plot</span>
|
||||
G-METER
|
||||
</span>
|
||||
<span class="text-label-caption font-label-caption text-primary-fixed bg-surface-container-high px-1.5 py-0.5 rounded">2D RADAR</span>
|
||||
</div>
|
||||
<!-- 2D Friction Crosshair Target -->
|
||||
<div class="my-2 flex flex-col items-center">
|
||||
<div class="relative w-24 h-24 rounded-full border border-outline-variant bg-surface-container-lowest flex items-center justify-center">
|
||||
<!-- Concentric G Rings (0.5G, 1.0G) -->
|
||||
<div class="w-16 h-16 rounded-full border border-outline-variant/60 flex items-center justify-center">
|
||||
<div class="w-8 h-8 rounded-full border border-outline-variant/30"></div>
|
||||
</div>
|
||||
<!-- Axis lines -->
|
||||
<div class="absolute inset-x-0 h-px bg-outline-variant/50"></div>
|
||||
<div class="absolute inset-y-0 w-px bg-outline-variant/50"></div>
|
||||
<!-- Live Acceleration Vector Dot: 0.85G Lateral Left, +0.22G Accel -->
|
||||
<div class="absolute w-3.5 h-3.5 bg-primary-container rounded-full cyan-border-glow border-2 border-surface-container-lowest -translate-x-6 -translate-y-2 animate-pulse"></div>
|
||||
</div>
|
||||
<div class="mt-2 text-center">
|
||||
<span class="text-headline-sm font-headline-sm font-bold text-on-surface">0.85G</span>
|
||||
<span class="text-[10px] font-label-data text-on-surface-variant block">LAT -0.85 | LONG +0.22</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Metric Footnote -->
|
||||
<div class="w-full bg-surface-container-high rounded p-1.5 text-center border border-outline-variant">
|
||||
<span class="text-label-caption font-label-caption text-primary font-bold">PEAK TRACTION: 91%</span>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
<!-- SECONDARY SENSOR STRIP & ROUTE SECTOR (Grid Tiles) -->
|
||||
<section class="w-full bg-surface-container-low border border-outline-variant rounded-xl p-3 space-y-2">
|
||||
<!-- Sector banner -->
|
||||
<div class="flex items-center justify-between pb-2 border-b border-outline-variant">
|
||||
<div class="flex items-center gap-1.5">
|
||||
<span class="material-symbols-outlined text-primary-container text-[18px]" data-icon="route">route</span>
|
||||
<span class="text-label-data font-label-data font-bold text-on-surface">Turn 11 • Saratoga Sweeper</span>
|
||||
</div>
|
||||
<span class="text-label-caption font-label-caption px-2 py-0.5 rounded bg-surface-container-high text-primary-fixed border border-outline-variant">PACE 3 (BRISK)</span>
|
||||
</div>
|
||||
<!-- 4-Stat Telemetry Matrix -->
|
||||
<div class="grid grid-cols-4 gap-2 pt-1">
|
||||
<!-- Alt -->
|
||||
<div class="flex flex-col">
|
||||
<span class="text-[10px] font-label-data text-on-surface-variant uppercase">ALTITUDE</span>
|
||||
<span class="text-label-data font-label-data font-bold text-on-surface">2,840<span class="text-[9px] font-normal text-on-surface-variant">FT</span></span>
|
||||
<span class="text-[9px] font-label-data text-primary">+180 FPM</span>
|
||||
</div>
|
||||
<!-- Trip -->
|
||||
<div class="flex flex-col">
|
||||
<span class="text-[10px] font-label-data text-on-surface-variant uppercase">TRIP ODO</span>
|
||||
<span class="text-label-data font-label-data font-bold text-on-surface">31.8<span class="text-[9px] font-normal text-on-surface-variant">MI</span></span>
|
||||
<span class="text-[9px] font-label-data text-on-surface-variant">42:15 ELAPSED</span>
|
||||
</div>
|
||||
<!-- Coolant -->
|
||||
<div class="flex flex-col">
|
||||
<span class="text-[10px] font-label-data text-on-surface-variant uppercase">COOLANT</span>
|
||||
<span class="text-label-data font-label-data font-bold text-on-surface">198<span class="text-[9px] font-normal text-on-surface-variant">°F</span></span>
|
||||
<span class="text-[9px] font-label-data text-primary">NORMAL</span>
|
||||
</div>
|
||||
<!-- Oil -->
|
||||
<div class="flex flex-col">
|
||||
<span class="text-[10px] font-label-data text-on-surface-variant uppercase">OIL PRESS</span>
|
||||
<span class="text-label-data font-label-data font-bold text-on-surface">4.2<span class="text-[9px] font-normal text-on-surface-variant">BAR</span></span>
|
||||
<span class="text-[9px] font-label-data text-primary">NOMINAL</span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- SAFETY GLOVE-FRIENDLY CONTROLS AREA -->
|
||||
<section class="w-full space-y-2 mt-1">
|
||||
<!-- Glove Quick Actions (Mark Waypoint & Split Lap) -->
|
||||
<div class="grid grid-cols-3 gap-2">
|
||||
<button class="col-span-2 min-h-[52px] h-[52px] bg-surface-container border-2 border-primary-container rounded-xl px-4 flex items-center justify-center gap-2 cyan-border-glow hover:bg-surface-container-high active:scale-95 duration-100 ease-out transition-all">
|
||||
<span class="material-symbols-outlined text-primary-container text-[24px]" data-icon="add_location_alt" style="font-variation-settings: 'FILL' 1;">add_location_alt</span>
|
||||
<span class="text-label-data font-label-data font-bold text-primary tracking-wide text-sm">MARK HAZARD / POI</span>
|
||||
</button>
|
||||
<button class="col-span-1 min-h-[52px] h-[52px] bg-surface-container border border-outline-variant rounded-xl px-2 flex items-center justify-center gap-1 hover:bg-surface-container-high active:scale-95 duration-100 ease-out transition-all">
|
||||
<span class="material-symbols-outlined text-on-surface text-[20px]" data-icon="flag">flag</span>
|
||||
<span class="text-label-data font-label-data font-semibold text-on-surface text-xs">LAP SPLIT</span>
|
||||
</button>
|
||||
</div>
|
||||
<!-- Slide-to-Stop Ride Control Track (Accidental Touch Protection) -->
|
||||
<div class="relative w-full h-14 bg-surface-container-low border border-error/60 rounded-xl overflow-hidden flex items-center p-1.5 slider-track shadow-inner" id="slideStopContainer">
|
||||
<!-- Background guide text -->
|
||||
<div class="absolute inset-0 flex items-center justify-center pointer-events-none pl-12 pr-4">
|
||||
<span class="text-label-data font-label-data font-bold text-error tracking-wider text-xs animate-pulse">
|
||||
SLIDE TO STOP RECORDING >>>
|
||||
</span>
|
||||
</div>
|
||||
<!-- Draggable glowing handle -->
|
||||
<div class="w-12 h-full bg-error rounded-lg flex items-center justify-center shadow-lg cursor-grab active:cursor-grabbing z-10 transition-transform select-none" id="sliderHandle" style="touch-action: none;">
|
||||
<span class="material-symbols-outlined text-on-error font-bold text-[24px]" data-icon="stop" style="font-variation-settings: 'FILL' 1;">stop</span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
<!-- BOTTOM NAV BAR (Shared Component Anchor) -->
|
||||
<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 Navigation Destination) -->
|
||||
<a aria-current="page" class="flex flex-col items-center justify-center bg-surface-container-high text-primary-container rounded-lg px-2 py-1 min-h-[48px] active:scale-95 duration-100 ease-out" href="#">
|
||||
<span class="material-symbols-outlined text-[24px]" data-icon="speed" style="font-variation-settings: 'FILL' 1;">speed</span>
|
||||
<span class="text-label-caption font-label-caption mt-0.5">Dash</span>
|
||||
</a>
|
||||
<!-- Map -->
|
||||
<a 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] active:scale-95 duration-100 ease-out" href="#">
|
||||
<span class="material-symbols-outlined text-[24px]" data-icon="navigation">navigation</span>
|
||||
<span class="text-label-caption font-label-caption mt-0.5">Map</span>
|
||||
</a>
|
||||
<!-- Activity -->
|
||||
<a 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] active:scale-95 duration-100 ease-out" href="#">
|
||||
<span class="material-symbols-outlined text-[24px]" data-icon="analytics">analytics</span>
|
||||
<span class="text-label-caption font-label-caption mt-0.5">Activity</span>
|
||||
</a>
|
||||
<!-- Garage -->
|
||||
<a 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] active:scale-95 duration-100 ease-out" href="#">
|
||||
<span class="material-symbols-outlined text-[24px]" data-icon="two_wheeler">two_wheeler</span>
|
||||
<span class="text-label-caption font-label-caption mt-0.5">Garage</span>
|
||||
</a>
|
||||
<!-- Settings -->
|
||||
<a 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] active:scale-95 duration-100 ease-out" href="#">
|
||||
<span class="material-symbols-outlined text-[24px]" data-icon="settings">settings</span>
|
||||
<span class="text-label-caption font-label-caption mt-0.5">Settings</span>
|
||||
</a>
|
||||
</nav>
|
||||
<!-- Interactive Slide-to-Stop JavaScript Handle Logic -->
|
||||
<script>
|
||||
(function initSlideToStop() {
|
||||
const handle = document.getElementById('sliderHandle');
|
||||
const track = document.getElementById('slideStopContainer');
|
||||
if (!handle || !track) return;
|
||||
|
||||
let isDragging = false;
|
||||
let startX = 0;
|
||||
let maxSlide = 0;
|
||||
|
||||
const updateMaxSlide = () => {
|
||||
maxSlide = track.clientWidth - handle.clientWidth - 12; // 12px for padding allowance
|
||||
};
|
||||
|
||||
updateMaxSlide();
|
||||
window.addEventListener('resize', updateMaxSlide);
|
||||
|
||||
const onPointerDown = (e) => {
|
||||
isDragging = true;
|
||||
startX = e.clientX || (e.touches && e.touches[0].clientX);
|
||||
handle.style.transition = 'none';
|
||||
};
|
||||
|
||||
const onPointerMove = (e) => {
|
||||
if (!isDragging) return;
|
||||
const currentX = e.clientX || (e.touches && e.touches[0].clientX);
|
||||
const delta = Math.max(0, Math.min(currentX - startX, maxSlide));
|
||||
handle.style.transform = `translateX(${delta}px)`;
|
||||
|
||||
// If completed 92%+ of track
|
||||
if (delta >= maxSlide * 0.92) {
|
||||
isDragging = false;
|
||||
handle.style.transform = `translateX(${maxSlide}px)`;
|
||||
handle.innerHTML = `<span class="material-symbols-outlined text-white text-[24px]" data-icon="check">check</span>`;
|
||||
track.classList.add('bg-error/30');
|
||||
setTimeout(() => {
|
||||
alert("SESSION SAVED TO DRIFT V7 SQLITE DB. RECORDING FINISHED.");
|
||||
handle.style.transform = 'translateX(0px)';
|
||||
handle.innerHTML = `<span class="material-symbols-outlined text-on-error font-bold text-[24px]" data-icon="stop" style="font-variation-settings: 'FILL' 1;">stop</span>`;
|
||||
track.classList.remove('bg-error/30');
|
||||
}, 300);
|
||||
}
|
||||
};
|
||||
|
||||
const onPointerUp = () => {
|
||||
if (!isDragging) return;
|
||||
isDragging = false;
|
||||
handle.style.transition = 'transform 0.25s ease-out';
|
||||
handle.style.transform = 'translateX(0px)';
|
||||
};
|
||||
|
||||
handle.addEventListener('mousedown', onPointerDown);
|
||||
window.addEventListener('mousemove', onPointerMove);
|
||||
window.addEventListener('mouseup', onPointerUp);
|
||||
|
||||
handle.addEventListener('touchstart', onPointerDown, { passive: true });
|
||||
window.addEventListener('touchmove', onPointerMove, { passive: true });
|
||||
window.addEventListener('touchend', onPointerUp);
|
||||
})();
|
||||
</script>
|
||||
</body></html>
|
||||
|
|
@ -0,0 +1,504 @@
|
|||
<!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 HUD - Tactical GPS Map</title>
|
||||
<!-- Material Symbols Outlined -->
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<!-- Google Fonts: Space Grotesk, JetBrains Mono, Inter -->
|
||||
<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&family=JetBrains+Mono:wght@500;600;700&family=Space+Grotesk:wght@600;700&display=swap" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<!-- Tailwind CSS v3 -->
|
||||
<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",
|
||||
"inverse-on-surface": "#2d3036",
|
||||
"on-secondary": "#002a78",
|
||||
"surface": "#101419",
|
||||
"on-surface-variant": "#bac9cc",
|
||||
"surface-container-lowest": "#0b0e13",
|
||||
"secondary": "#b4c5ff",
|
||||
"on-primary-container": "#00626e",
|
||||
"secondary-fixed": "#dbe1ff",
|
||||
"primary-fixed-dim": "#00daf3",
|
||||
"outline": "#849396",
|
||||
"on-tertiary-container": "#6834d1",
|
||||
"on-error": "#690005",
|
||||
"error-container": "#93000a",
|
||||
"surface-container-highest": "#32353b",
|
||||
"on-tertiary-fixed": "#23005c",
|
||||
"surface-container": "#1d2025",
|
||||
"surface-variant": "#32353b",
|
||||
"on-secondary-fixed-variant": "#003ea8",
|
||||
"surface-bright": "#36393f",
|
||||
"on-secondary-fixed": "#00174b",
|
||||
"outline-variant": "#3b494c",
|
||||
"on-secondary-container": "#cdd7ff",
|
||||
"on-tertiary": "#3c0091",
|
||||
"surface-container-low": "#181c21",
|
||||
"on-tertiary-fixed-variant": "#5516be",
|
||||
"surface-container-high": "#272a30",
|
||||
"primary-fixed": "#9cf0ff",
|
||||
"tertiary-container": "#d9c8ff",
|
||||
"on-primary-fixed-variant": "#004f58",
|
||||
"tertiary": "#f2e9ff",
|
||||
"error": "#ffb4ab",
|
||||
"on-primary": "#00363d",
|
||||
"tertiary-fixed": "#e9ddff",
|
||||
"inverse-surface": "#e0e2ea",
|
||||
"inverse-primary": "#006875",
|
||||
"primary": "#c3f5ff",
|
||||
"on-background": "#e0e2ea",
|
||||
"secondary-fixed-dim": "#b4c5ff",
|
||||
"primary-container": "#00e5ff",
|
||||
"background": "#101419",
|
||||
"surface-tint": "#00daf3",
|
||||
"secondary-container": "#0053db",
|
||||
"on-surface": "#e0e2ea",
|
||||
"on-primary-fixed": "#001f24",
|
||||
"surface-dim": "#101419",
|
||||
"tertiary-fixed-dim": "#d0bcff"
|
||||
},
|
||||
"borderRadius": {
|
||||
"DEFAULT": "0.25rem",
|
||||
"lg": "0.5rem",
|
||||
"xl": "0.75rem",
|
||||
"full": "9999px"
|
||||
},
|
||||
"spacing": {
|
||||
"gutter": "1rem",
|
||||
"space-md": "1rem",
|
||||
"space-lg": "1.5rem",
|
||||
"space-xs": "0.25rem",
|
||||
"margin-lg": "2rem",
|
||||
"gutter-lg": "1.5rem",
|
||||
"space-xl": "2rem",
|
||||
"space-sm": "0.5rem",
|
||||
"margin": "1rem"
|
||||
},
|
||||
"fontFamily": {
|
||||
"headline-lg": ["Space Grotesk"],
|
||||
"telemetry-metric-lg": ["JetBrains Mono"],
|
||||
"display-hero": ["Space Grotesk"],
|
||||
"body-md": ["Inter"],
|
||||
"label-caption": ["Inter"],
|
||||
"display-hero-mobile": ["Space Grotesk"],
|
||||
"telemetry-metric-md": ["JetBrains Mono"],
|
||||
"body-lg": ["Inter"],
|
||||
"telemetry-metric-lg-mobile": ["JetBrains Mono"],
|
||||
"label-data": ["JetBrains Mono"],
|
||||
"headline-sm": ["Space Grotesk"],
|
||||
"headline-md": ["Space Grotesk"]
|
||||
},
|
||||
"fontSize": {
|
||||
"headline-lg": ["32px", {"lineHeight": "40px", "letterSpacing": "-0.02em", "fontWeight": "700"}],
|
||||
"telemetry-metric-lg": ["48px", {"lineHeight": "48px", "letterSpacing": "-0.04em", "fontWeight": "700"}],
|
||||
"display-hero": ["56px", {"lineHeight": "60px", "letterSpacing": "-0.03em", "fontWeight": "700"}],
|
||||
"body-md": ["14px", {"lineHeight": "20px", "fontWeight": "400"}],
|
||||
"label-caption": ["11px", {"lineHeight": "14px", "letterSpacing": "0.05em", "fontWeight": "600"}],
|
||||
"display-hero-mobile": ["40px", {"lineHeight": "44px", "letterSpacing": "-0.02em", "fontWeight": "700"}],
|
||||
"telemetry-metric-md": ["28px", {"lineHeight": "32px", "letterSpacing": "-0.02em", "fontWeight": "600"}],
|
||||
"body-lg": ["16px", {"lineHeight": "24px", "fontWeight": "500"}],
|
||||
"telemetry-metric-lg-mobile": ["36px", {"lineHeight": "36px", "letterSpacing": "-0.03em", "fontWeight": "700"}],
|
||||
"label-data": ["12px", {"lineHeight": "16px", "letterSpacing": "0.08em", "fontWeight": "600"}],
|
||||
"headline-sm": ["20px", {"lineHeight": "28px", "fontWeight": "600"}],
|
||||
"headline-md": ["24px", {"lineHeight": "32px", "letterSpacing": "-0.01em", "fontWeight": "600"}]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.material-symbols-outlined {
|
||||
font-family: 'Material Symbols Outlined';
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
font-size: 24px;
|
||||
line-height: 1;
|
||||
letter-spacing: normal;
|
||||
text-transform: none;
|
||||
display: inline-block;
|
||||
white-space: nowrap;
|
||||
word-wrap: normal;
|
||||
direction: ltr;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24;
|
||||
}
|
||||
.material-symbols-outlined[data-weight="fill"] {
|
||||
font-variation-settings: 'FILL' 1, 'wght' 500, 'GRAD' 0, 'opsz' 24;
|
||||
}
|
||||
/* Subtle neon scanline & grid effects for tactical display */
|
||||
.tactical-grid-bg {
|
||||
background-image:
|
||||
radial-gradient(circle at 50% 40%, rgba(0, 229, 255, 0.08) 0%, transparent 60%),
|
||||
linear-gradient(to right, rgba(59, 73, 76, 0.15) 1px, transparent 1px),
|
||||
linear-gradient(to bottom, rgba(59, 73, 76, 0.15) 1px, transparent 1px);
|
||||
background-size: 100% 100%, 36px 36px, 36px 36px;
|
||||
}
|
||||
.neon-cyan-glow {
|
||||
box-shadow: 0 0 16px rgba(0, 229, 255, 0.35);
|
||||
}
|
||||
.neon-pulse-anim {
|
||||
animation: pulseNeon 2.4s cubic-bezier(0.4, 0, 0.6, 1) infinite;
|
||||
}
|
||||
@keyframes pulseNeon {
|
||||
0%, 100% { opacity: 0.9; transform: scale(1); }
|
||||
50% { opacity: 0.4; transform: scale(1.18); }
|
||||
}
|
||||
/* Custom scrollbar for horizontal chips */
|
||||
.no-scrollbar::-webkit-scrollbar { display: none; }
|
||||
.no-scrollbar { -ms-overflow-style: none; scrollbar-width: none; }
|
||||
</style>
|
||||
<style>
|
||||
body {
|
||||
min-height: max(884px, 100dvh);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-surface-container-lowest text-on-surface antialiased overflow-hidden select-none h-screen w-screen flex flex-col justify-between">
|
||||
<!-- ========================================== -->
|
||||
<!-- TOP APP BAR (Shared Component Anchor) -->
|
||||
<!-- ========================================== -->
|
||||
<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" data-icon="sensors">sensors</span>
|
||||
<span class="text-headline-sm font-headline-sm font-bold tracking-wider text-primary-container">MOTORSIGNAL HUD</span>
|
||||
</div>
|
||||
<!-- Mini HUD Telemetry Status Cluster (Glove Safe / Quick Glance) -->
|
||||
<div class="hidden sm:flex items-center space-x-3 text-label-data font-label-data text-on-surface-variant">
|
||||
<div class="flex items-center space-x-1.5 px-2 py-0.5 rounded bg-surface-container border border-outline-variant">
|
||||
<span class="w-2 h-2 rounded-full bg-primary-container animate-ping"></span>
|
||||
<span class="text-primary-container">20Hz GPS LOCK</span>
|
||||
</div>
|
||||
<span class="text-outline">|</span>
|
||||
<span>18 SVs</span>
|
||||
<span class="text-outline">|</span>
|
||||
<span>98% BAT</span>
|
||||
<span class="text-outline">|</span>
|
||||
<span class="text-primary-fixed">MESH CH-04</span>
|
||||
</div>
|
||||
<!-- Trailing Action -->
|
||||
<div class="flex items-center space-x-2">
|
||||
<div class="sm:hidden flex items-center px-2 py-0.5 rounded bg-surface-container text-label-caption font-label-caption text-primary-container border border-outline-variant">
|
||||
20Hz
|
||||
</div>
|
||||
<button class="w-10 h-10 flex items-center justify-center rounded-lg text-primary-container hover:bg-surface-container active:scale-95 duration-100 ease-out">
|
||||
<span class="material-symbols-outlined" data-icon="warning">warning</span>
|
||||
</button>
|
||||
</div>
|
||||
</header>
|
||||
<!-- ======================================================= -->
|
||||
<!-- FULLSCREEN TACTICAL VECTOR MAP CANVAS (Center Playfield)-->
|
||||
<!-- ======================================================= -->
|
||||
<main class="relative w-full h-full flex-1 overflow-hidden pt-14 pb-20 tactical-grid-bg">
|
||||
<!-- Vector Map Simulation SVG Layer -->
|
||||
<div class="absolute inset-0 w-full h-full pointer-events-none">
|
||||
<svg class="w-full h-full" fill="none" viewbox="0 0 400 800" xmlns="http://www.w3.org/2000/svg">
|
||||
<!-- Topographic elevation contour lines -->
|
||||
<path d="M-60 120 C 50 140, 180 80, 260 130 C 340 180, 420 140, 480 180" stroke="#1d2025" stroke-dasharray="4 3" stroke-width="1.5"></path>
|
||||
<path d="M-40 220 C 80 250, 160 190, 290 240 C 370 270, 430 220, 500 260" stroke="#272a30" stroke-width="1.5"></path>
|
||||
<path d="M-50 360 C 70 380, 190 320, 280 390 C 360 440, 420 370, 490 420" stroke="#1d2025" stroke-dasharray="6 4" stroke-width="1.2"></path>
|
||||
<path d="M-30 520 C 90 560, 220 480, 310 570 C 390 620, 440 540, 520 600" stroke="#272a30" stroke-width="1.5"></path>
|
||||
<path d="M-20 680 C 100 700, 210 630, 320 720 C 380 770, 450 690, 510 740" stroke="#1d2025" stroke-width="1.2"></path>
|
||||
<!-- Curvy Ridge Roads: Skyline Blvd CA-35, Highway 9, Highway 84 -->
|
||||
<!-- Secondary twisty feeder: Highway 84 -->
|
||||
<path d="M 380 210 Q 280 260 210 240 T 120 310" fill="none" opacity="0.7" stroke="#3b494c" stroke-linecap="round" stroke-width="3"></path>
|
||||
<text fill="#849396" font-family="JetBrains Mono" font-size="9" letter-spacing="1" x="240" y="275">HWY 84 LA HONDA</text>
|
||||
<!-- Main Route Highlight: Skyline Blvd (CA-35) Neon Cyan Illuminated Vector Track -->
|
||||
<path d="M 120 780 C 130 670, 110 590, 180 500 C 230 430, 260 380, 210 300 C 170 230, 230 160, 240 40" fill="none" filter="drop-shadow(0 0 10px rgba(0, 229, 255, 0.7))" id="skylineTrack" opacity="0.9" stroke="#00e5ff" stroke-linecap="round" stroke-width="5"></path>
|
||||
<path d="M 120 780 C 130 670, 110 590, 180 500 C 230 430, 260 380, 210 300 C 170 230, 230 160, 240 40" fill="none" stroke="#c3f5ff" stroke-linecap="round" stroke-width="1.5"></path>
|
||||
<!-- Highway 9 Junction branch -->
|
||||
<path d="M 180 500 C 230 540, 290 560, 370 600" fill="none" stroke="#0053db" stroke-dasharray="8 4" stroke-width="3.5"></path>
|
||||
<text fill="#b4c5ff" font-family="JetBrains Mono" font-size="9" letter-spacing="1" x="280" y="585">HWY 9 SARATOGA</text>
|
||||
<!-- Apex Markers & Hairpin Apex Indicators -->
|
||||
<circle cx="160" cy="530" fill="#101419" r="5" stroke="#00e5ff" stroke-width="2"></circle>
|
||||
<circle cx="160" cy="530" fill="#00e5ff" r="2"></circle>
|
||||
<text fill="#00daf3" font-family="JetBrains Mono" font-size="8" x="172" y="534">APEX 32°</text>
|
||||
<circle cx="238" cy="355" fill="#101419" r="5" stroke="#ffb4ab" stroke-width="2"></circle>
|
||||
<circle cx="238" cy="355" fill="#ffb4ab" r="2"></circle>
|
||||
<text fill="#ffb4ab" font-family="JetBrains Mono" font-size="8" x="250" y="358">HAIRPIN R18</text>
|
||||
<!-- Waypoint Icon (Alice's Restaurant) -->
|
||||
<g transform="translate(195, 280)">
|
||||
<rect fill="#0b0e13" height="12" rx="2" stroke="#00e5ff" stroke-width="1.5" width="12" x="-6" y="-6"></rect>
|
||||
<circle cx="0" cy="0" fill="#00e5ff" r="2.5"></circle>
|
||||
<text fill="#e0e2ea" font-family="Space Grotesk" font-size="10" font-weight="700" x="12" y="3">Alice's Restaurant</text>
|
||||
<text fill="#00daf3" font-family="JetBrains Mono" font-size="8" x="12" y="14">ELEV 1,240 FT</text>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
<!-- Live Telemetry Layer: Heading Beam & Rider Chevron Position Marker -->
|
||||
<div class="absolute top-[48%] left-[45%] -translate-x-1/2 -translate-y-1/2 pointer-events-none z-10">
|
||||
<!-- Forward Heading Vision Cone Beam -->
|
||||
<div class="absolute -top-24 -left-12 w-32 h-28 bg-gradient-to-t from-primary-container/30 to-transparent clip-path-beam [clip-path:polygon(50%_100%,0%_0%,100%_0%)]"></div>
|
||||
<!-- Pulsing Beacon Halo -->
|
||||
<div class="absolute -inset-4 rounded-full bg-primary-container/20 neon-pulse-anim"></div>
|
||||
<!-- Rider Chevron Shield -->
|
||||
<div class="relative w-12 h-12 rounded-full bg-surface-container-lowest border-2 border-primary-container flex items-center justify-center shadow-lg neon-cyan-glow">
|
||||
<span class="material-symbols-outlined text-primary-container rotate-[335deg] text-2xl" data-icon="navigation" data-weight="fill">navigation</span>
|
||||
</div>
|
||||
<!-- Real-Time Velocity Sub-Unit Badge Attached to Rider -->
|
||||
<div class="absolute -bottom-7 -left-5 px-2 py-0.5 rounded bg-surface-container-lowest/90 border border-primary-container/50 backdrop-blur-md flex items-baseline space-x-1">
|
||||
<span class="text-headline-sm font-telemetry-metric-md text-primary-container font-bold">44</span>
|
||||
<span class="text-label-caption font-label-caption text-primary-fixed">MPH</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Live Road Hazard Ahead Marker Blip (Waze / Mesh Sourced) -->
|
||||
<div class="absolute top-[34%] left-[55%] z-10 flex items-center space-x-2 pointer-events-auto">
|
||||
<div class="relative flex items-center justify-center">
|
||||
<span class="absolute w-8 h-8 rounded-full bg-error-container/60 animate-ping"></span>
|
||||
<div class="w-7 h-7 rounded-full bg-surface-container-lowest border border-error flex items-center justify-center shadow-[0_0_12px_rgba(239,68,68,0.7)]">
|
||||
<span class="material-symbols-outlined text-error text-base" data-icon="warning" data-weight="fill">warning</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-surface-container-lowest/95 border border-error/70 backdrop-blur-md px-2.5 py-1 rounded-lg shadow-xl">
|
||||
<div class="flex items-center space-x-1 text-label-data font-label-data text-error">
|
||||
<span class="font-bold">GRAVEL ON APEX</span>
|
||||
<span>•</span>
|
||||
<span>0.8 MI</span>
|
||||
</div>
|
||||
<div class="text-[10px] text-on-surface-variant font-label-caption">Reported by Mesh Lead (1m ago)</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- ========================================== -->
|
||||
<!-- FLOATING TOP SEARCH CARD -->
|
||||
<!-- ========================================== -->
|
||||
<div class="absolute top-3 left-3 right-3 z-30 flex flex-col space-y-2 pointer-events-auto">
|
||||
<div class="w-full bg-surface-container-lowest/90 backdrop-blur-md border border-outline-variant rounded-xl p-2 shadow-2xl flex items-center justify-between">
|
||||
<div class="flex items-center space-x-2 flex-1 pl-1">
|
||||
<span class="material-symbols-outlined text-primary-container text-xl" data-icon="search">search</span>
|
||||
<input class="bg-transparent border-0 text-on-surface placeholder:text-on-surface-variant/60 text-body-md font-body-md focus:ring-0 w-full p-0 truncate outline-none" placeholder="Search twisty routes, apex passes, waypoints..." type="text" value="Skyline Blvd CA-35"/>
|
||||
</div>
|
||||
<div class="flex items-center space-x-1 pr-1 border-l border-outline-variant/60 pl-2">
|
||||
<button class="w-9 h-9 rounded-lg flex items-center justify-center text-on-surface-variant hover:text-primary-container hover:bg-surface-container active:scale-95 transition-all">
|
||||
<span class="material-symbols-outlined text-xl" data-icon="mic">mic</span>
|
||||
</button>
|
||||
<button class="w-9 h-9 rounded-lg flex items-center justify-center text-on-surface-variant hover:text-primary-container hover:bg-surface-container active:scale-95 transition-all">
|
||||
<span class="material-symbols-outlined text-xl" data-icon="tune">tune</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Quick Destination Twisties Filter Chips -->
|
||||
<div class="flex items-center space-x-2 overflow-x-auto no-scrollbar py-0.5">
|
||||
<button class="flex items-center space-x-1 px-3 py-1.5 rounded-full bg-surface-container-high/90 border border-primary-container/40 text-primary text-label-data font-label-data whitespace-nowrap active:scale-95 transition-all shadow-sm">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-primary-container"></span>
|
||||
<span>Alice's Restaurant</span>
|
||||
</button>
|
||||
<button class="flex items-center space-x-1 px-3 py-1.5 rounded-full bg-surface-container-low/90 border border-outline-variant text-on-surface-variant text-label-data font-label-data whitespace-nowrap active:scale-95 transition-all hover:border-primary-container/50">
|
||||
<span>Skyline Ridge</span>
|
||||
</button>
|
||||
<button class="flex items-center space-x-1 px-3 py-1.5 rounded-full bg-surface-container-low/90 border border-outline-variant text-on-surface-variant text-label-data font-label-data whitespace-nowrap active:scale-95 transition-all hover:border-primary-container/50">
|
||||
<span>Saratoga Gap</span>
|
||||
</button>
|
||||
<button class="flex items-center space-x-1 px-3 py-1.5 rounded-full bg-surface-container-low/90 border border-outline-variant text-on-surface-variant text-label-data font-label-data whitespace-nowrap active:scale-95 transition-all hover:border-primary-container/50">
|
||||
<span>9 Switchbacks</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- ========================================================= -->
|
||||
<!-- FLOATING RIGHT VERTICAL PILL DOCK (Tactical Quick Controls)-->
|
||||
<!-- ========================================================= -->
|
||||
<div class="absolute right-3 top-28 z-30 flex flex-col space-y-3 pointer-events-auto">
|
||||
<div class="flex flex-col rounded-2xl bg-surface-container-lowest/90 backdrop-blur-md border border-outline-variant p-1 shadow-2xl space-y-1">
|
||||
<!-- Compass Orient Toggle (North-Up vs Heading-Up) -->
|
||||
<button class="w-12 h-12 rounded-xl flex flex-col items-center justify-center text-primary-container hover:bg-surface-container active:scale-95 transition-all relative" title="Heading-Up Active">
|
||||
<span class="material-symbols-outlined text-2xl rotate-45 text-primary-container" data-icon="explore">explore</span>
|
||||
<span class="text-[9px] font-label-caption text-primary-fixed tracking-tighter">HDG</span>
|
||||
</button>
|
||||
<div class="h-px w-8 bg-outline-variant/60 self-center"></div>
|
||||
<!-- Re-center Rider Position (Target Reticle) -->
|
||||
<button class="w-12 h-12 rounded-xl flex items-center justify-center bg-primary-container/10 text-primary-container border border-primary-container/40 active:scale-95 transition-all shadow-[0_0_12px_rgba(0,229,255,0.25)]" title="Recenter Position">
|
||||
<span class="material-symbols-outlined text-2xl animate-pulse" data-icon="my_location" data-weight="fill">my_location</span>
|
||||
</button>
|
||||
<div class="h-px w-8 bg-outline-variant/60 self-center"></div>
|
||||
<!-- Map Layers / Tactical Filters -->
|
||||
<button class="w-12 h-12 rounded-xl flex items-center justify-center text-primary-container bg-surface-container hover:bg-surface-container-high active:scale-95 transition-all" title="Map Layers">
|
||||
<span class="material-symbols-outlined text-2xl" data-icon="layers">layers</span>
|
||||
</button>
|
||||
<div class="h-px w-8 bg-outline-variant/60 self-center"></div>
|
||||
<!-- 3D Tilt / Relief Contour Toggle -->
|
||||
<button class="w-12 h-12 rounded-xl flex items-center justify-center text-on-surface-variant hover:text-primary-container hover:bg-surface-container active:scale-95 transition-all" title="3D Topo Relief">
|
||||
<span class="material-symbols-outlined text-2xl" data-icon="3d_rotation">3d_rotation</span>
|
||||
</button>
|
||||
</div>
|
||||
<!-- Quick Session Action Floating Button -->
|
||||
<button class="w-12 h-12 rounded-2xl bg-surface-container-lowest/90 backdrop-blur-md border border-outline-variant flex items-center justify-center text-primary-container hover:border-primary-container active:scale-95 shadow-xl transition-all">
|
||||
<span class="material-symbols-outlined text-2xl" data-icon="add_location_alt">add_location_alt</span>
|
||||
</button>
|
||||
</div>
|
||||
<!-- ======================================================== -->
|
||||
<!-- OPEN BOTTOM SHEET DRAWER (Map Layers & Telemetry Overlays)-->
|
||||
<!-- ======================================================== -->
|
||||
<div class="absolute bottom-0 left-0 right-0 z-40 bg-surface-container-lowest/95 backdrop-blur-xl border-t border-outline-variant rounded-t-2xl shadow-2xl pointer-events-auto transition-transform">
|
||||
<!-- Drawer Pull Handle Pill -->
|
||||
<div class="w-full flex justify-center pt-2.5 pb-1 cursor-grab">
|
||||
<div class="w-12 h-1 rounded-full bg-outline-variant"></div>
|
||||
</div>
|
||||
<div class="px-4 pb-4 pt-1 max-h-[406px] overflow-y-auto no-scrollbar">
|
||||
<!-- Drawer Header Title & Telemetrics -->
|
||||
<div class="flex items-center justify-between pb-3 border-b border-outline-variant/40">
|
||||
<div>
|
||||
<h2 class="text-headline-sm font-headline-sm font-bold text-on-surface flex items-center space-x-2">
|
||||
<span>TACTICAL MAP LAYERS</span>
|
||||
</h2>
|
||||
<div class="text-label-data font-label-data text-primary-container text-[11px] flex items-center space-x-1.5 mt-0.5">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-primary-container"></span>
|
||||
<span>KALMAN V4.8 ACTIVE • 20HZ IMU FUSION</span>
|
||||
</div>
|
||||
</div>
|
||||
<span class="px-2 py-1 rounded bg-surface-container text-label-data font-label-data text-on-surface-variant border border-outline-variant">
|
||||
OFFLINE READY
|
||||
</span>
|
||||
</div>
|
||||
<!-- 3 Selectable Map Styles Preview Thumbnails -->
|
||||
<div class="mt-3">
|
||||
<div class="text-label-caption font-label-caption text-on-surface-variant uppercase tracking-wider mb-2">
|
||||
Base Cartography Vector
|
||||
</div>
|
||||
<div class="grid grid-cols-3 gap-2.5">
|
||||
<!-- 1: Tactical Dark (Selected) -->
|
||||
<div class="relative rounded-xl overflow-hidden border-2 border-primary-container bg-surface-container-low p-2 cursor-pointer shadow-[0_0_14px_rgba(0,229,255,0.25)] flex flex-col justify-between h-20">
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="material-symbols-outlined text-primary-container text-lg" data-icon="dark_mode">dark_mode</span>
|
||||
<span class="w-4 h-4 rounded-full bg-primary-container flex items-center justify-center text-surface-container-lowest">
|
||||
<span class="material-symbols-outlined text-xs" data-icon="check">check</span>
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<div class="text-body-md font-body-md font-bold text-on-surface text-xs">Tactical Dark</div>
|
||||
<div class="text-[10px] text-primary font-label-data">Neon Apexes</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 2: Satellite 4K -->
|
||||
<div class="relative rounded-xl overflow-hidden border border-outline-variant bg-surface-container-low p-2 cursor-pointer hover:border-outline flex flex-col justify-between h-20 opacity-80 hover:opacity-100 transition-all">
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="material-symbols-outlined text-on-surface-variant text-lg" data-icon="satellite_alt">satellite_alt</span>
|
||||
</div>
|
||||
<div>
|
||||
<div class="text-body-md font-body-md font-bold text-on-surface text-xs">Satellite 4K</div>
|
||||
<div class="text-[10px] text-on-surface-variant font-label-data">Ortho Aerial</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 3: 3D Topo Elevation -->
|
||||
<div class="relative rounded-xl overflow-hidden border border-outline-variant bg-surface-container-low p-2 cursor-pointer hover:border-outline flex flex-col justify-between h-20 opacity-80 hover:opacity-100 transition-all">
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="material-symbols-outlined text-on-surface-variant text-lg" data-icon="terrain">terrain</span>
|
||||
</div>
|
||||
<div>
|
||||
<div class="text-body-md font-body-md font-bold text-on-surface text-xs">3D Topo</div>
|
||||
<div class="text-[10px] text-on-surface-variant font-label-data">Relief Contours</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Tactical Overlay Toggles Stack -->
|
||||
<div class="mt-4 space-y-2.5">
|
||||
<div class="text-label-caption font-label-caption text-on-surface-variant uppercase tracking-wider">
|
||||
Live Telemetry & Radar Feeds
|
||||
</div>
|
||||
<!-- Police Traps & Radar Feed Toggle -->
|
||||
<div class="flex items-center justify-between p-2.5 rounded-xl bg-surface-container border border-outline-variant/60">
|
||||
<div class="flex items-center space-x-3">
|
||||
<div class="w-9 h-9 rounded-lg bg-surface-container-high flex items-center justify-center text-primary-container">
|
||||
<span class="material-symbols-outlined text-xl" data-icon="radar">radar</span>
|
||||
</div>
|
||||
<div>
|
||||
<div class="text-body-md font-body-md font-semibold text-on-surface text-sm">Police Traps & Radar Feed</div>
|
||||
<div class="text-label-data font-label-data text-on-surface-variant text-[11px]">3,420 cached radar nodes (Waze mesh)</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Oversized Glove Switch Toggle (Active) -->
|
||||
<label class="relative inline-flex items-center cursor-pointer min-w-[52px]">
|
||||
<input checked="" class="sr-only peer" type="checkbox"/>
|
||||
<div class="w-13 h-7 w-12 bg-surface-container-lowest peer-focus:outline-none rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-primary-container after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-primary-container after:border-primary-container after:border after:rounded-full after:h-6 after:w-5 after:transition-all peer-checked:bg-primary-container/20 border border-outline-variant peer-checked:border-primary-container"></div>
|
||||
</label>
|
||||
</div>
|
||||
<!-- Offline Pack Blips Toggle -->
|
||||
<div class="flex items-center justify-between p-2.5 rounded-xl bg-surface-container border border-outline-variant/60">
|
||||
<div class="flex items-center space-x-3">
|
||||
<div class="w-9 h-9 rounded-lg bg-surface-container-high flex items-center justify-center text-primary-container">
|
||||
<span class="material-symbols-outlined text-xl" data-icon="groups">groups</span>
|
||||
</div>
|
||||
<div>
|
||||
<div class="text-body-md font-body-md font-semibold text-on-surface text-sm">Offline Pack Blips</div>
|
||||
<div class="text-label-data font-label-data text-on-surface-variant text-[11px]">4 squad riders in 5-mile radio range</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Oversized Glove Switch Toggle (Active) -->
|
||||
<label class="relative inline-flex items-center cursor-pointer min-w-[52px]">
|
||||
<input checked="" class="sr-only peer" type="checkbox"/>
|
||||
<div class="w-13 h-7 w-12 bg-surface-container-lowest peer-focus:outline-none rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-primary-container after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-primary-container after:border-primary-container after:border after:rounded-full after:h-6 after:w-5 after:transition-all peer-checked:bg-primary-container/20 border border-outline-variant peer-checked:border-primary-container"></div>
|
||||
</label>
|
||||
</div>
|
||||
<!-- Curvature / Apex Heatmap Toggle -->
|
||||
<div class="flex items-center justify-between p-2.5 rounded-xl bg-surface-container border border-outline-variant/60">
|
||||
<div class="flex items-center space-x-3">
|
||||
<div class="w-9 h-9 rounded-lg bg-surface-container-high flex items-center justify-center text-primary-container">
|
||||
<span class="material-symbols-outlined text-xl" data-icon="timeline">timeline</span>
|
||||
</div>
|
||||
<div>
|
||||
<div class="text-body-md font-body-md font-semibold text-on-surface text-sm">Curvature / Apex Heatmap</div>
|
||||
<div class="text-label-data font-label-data text-on-surface-variant text-[11px]">Color-coded corner severity index</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Oversized Glove Switch Toggle (Active) -->
|
||||
<label class="relative inline-flex items-center cursor-pointer min-w-[52px]">
|
||||
<input checked="" class="sr-only peer" type="checkbox"/>
|
||||
<div class="w-13 h-7 w-12 bg-surface-container-lowest peer-focus:outline-none rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-primary-container after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-primary-container after:border-primary-container after:border after:rounded-full after:h-6 after:w-5 after:transition-all peer-checked:bg-primary-container/20 border border-outline-variant peer-checked:border-primary-container"></div>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
<!-- ================================================= -->
|
||||
<!-- BOTTOM NAVIGATION BAR (Shared Component Anchor) -->
|
||||
<!-- ================================================= -->
|
||||
<!-- Strict semantic map matching: Active destination = "Map" -->
|
||||
<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">
|
||||
<!-- 1: Dash (Inactive) -->
|
||||
<a class="flex flex-col items-center justify-center text-on-surface-variant px-2 py-1 min-h-[48px] hover:bg-surface-container-low hover:text-primary-fixed active:scale-95 duration-100 ease-out flex-1" href="#">
|
||||
<span class="material-symbols-outlined text-2xl" data-icon="speed">speed</span>
|
||||
<span class="text-label-caption font-label-caption mt-0.5">Dash</span>
|
||||
</a>
|
||||
<!-- 2: Map (ACTIVE STATE - Destination locked from JSON logic) -->
|
||||
<a class="flex flex-col items-center justify-center bg-surface-container-high text-primary-container rounded-lg px-2 py-1 min-h-[48px] hover:bg-surface-container-low hover:text-primary-fixed active:scale-95 duration-100 ease-out flex-1" href="#">
|
||||
<span class="material-symbols-outlined text-2xl" data-icon="navigation" data-weight="fill">navigation</span>
|
||||
<span class="text-label-caption font-label-caption mt-0.5 font-bold">Map</span>
|
||||
</a>
|
||||
<!-- 3: Activity (Inactive) -->
|
||||
<a class="flex flex-col items-center justify-center text-on-surface-variant px-2 py-1 min-h-[48px] hover:bg-surface-container-low hover:text-primary-fixed active:scale-95 duration-100 ease-out flex-1" href="#">
|
||||
<span class="material-symbols-outlined text-2xl" data-icon="analytics">analytics</span>
|
||||
<span class="text-label-caption font-label-caption mt-0.5">Activity</span>
|
||||
</a>
|
||||
<!-- 4: Garage (Inactive) -->
|
||||
<a class="flex flex-col items-center justify-center text-on-surface-variant px-2 py-1 min-h-[48px] hover:bg-surface-container-low hover:text-primary-fixed active:scale-95 duration-100 ease-out flex-1" href="#">
|
||||
<span class="material-symbols-outlined text-2xl" data-icon="two_wheeler">two_wheeler</span>
|
||||
<span class="text-label-caption font-label-caption mt-0.5">Garage</span>
|
||||
</a>
|
||||
<!-- 5: Settings (Inactive) -->
|
||||
<a class="flex flex-col items-center justify-center text-on-surface-variant px-2 py-1 min-h-[48px] hover:bg-surface-container-low hover:text-primary-fixed active:scale-95 duration-100 ease-out flex-1" href="#">
|
||||
<span class="material-symbols-outlined text-2xl" data-icon="settings">settings</span>
|
||||
<span class="text-label-caption font-label-caption mt-0.5">Settings</span>
|
||||
</a>
|
||||
</nav>
|
||||
<!-- Lightweight Inline Interaction Helper -->
|
||||
<script>
|
||||
// Ensure active toggle interaction styling is tactile and reactive
|
||||
document.querySelectorAll('input[type="checkbox"]').forEach(toggle => {
|
||||
toggle.addEventListener('change', (e) => {
|
||||
// Haptic feedback simulation trigger point
|
||||
if (window.navigator && window.navigator.vibrate) {
|
||||
window.navigator.vibrate(20);
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body></html>
|
||||
|
|
@ -0,0 +1,572 @@
|
|||
<!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 HUD - Launch Telemetry</title>
|
||||
<!-- Material Symbols Outlined -->
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<!-- Fonts: Space Grotesk, JetBrains Mono, Inter -->
|
||||
<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&family=JetBrains+Mono:ital,wght@0,400;0,500;0,600;0,700;1,600&family=Space+Grotesk:wght@500;600;700&display=swap" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<!-- Tailwind CSS -->
|
||||
<script src="https://cdn.tailwindcss.com?plugins=forms,container-queries"></script>
|
||||
<!-- Theme Configuration verbatim -->
|
||||
<script id="tailwind-config">
|
||||
tailwind.config = {
|
||||
darkMode: "class",
|
||||
theme: {
|
||||
extend: {
|
||||
"colors": {
|
||||
"primary": "#c3f5ff",
|
||||
"on-error": "#690005",
|
||||
"tertiary-fixed-dim": "#d0bcff",
|
||||
"on-secondary-container": "#cdd7ff",
|
||||
"on-primary-fixed": "#001f24",
|
||||
"on-error-container": "#ffdad6",
|
||||
"surface": "#101419",
|
||||
"on-secondary-fixed": "#00174b",
|
||||
"primary-fixed-dim": "#00daf3",
|
||||
"on-tertiary-fixed": "#23005c",
|
||||
"on-surface": "#e0e2ea",
|
||||
"tertiary-fixed": "#e9ddff",
|
||||
"surface-container-highest": "#32353b",
|
||||
"inverse-primary": "#006875",
|
||||
"surface-container": "#1d2025",
|
||||
"on-tertiary": "#3c0091",
|
||||
"secondary-fixed-dim": "#b4c5ff",
|
||||
"on-tertiary-container": "#6834d1",
|
||||
"on-primary": "#00363d",
|
||||
"tertiary-container": "#d9c8ff",
|
||||
"on-background": "#e0e2ea",
|
||||
"surface-container-high": "#272a30",
|
||||
"surface-variant": "#32353b",
|
||||
"secondary-fixed": "#dbe1ff",
|
||||
"secondary": "#b4c5ff",
|
||||
"primary-fixed": "#9cf0ff",
|
||||
"inverse-surface": "#e0e2ea",
|
||||
"outline": "#849396",
|
||||
"on-primary-container": "#00626e",
|
||||
"error-container": "#93000a",
|
||||
"surface-tint": "#00daf3",
|
||||
"background": "#101419",
|
||||
"inverse-on-surface": "#2d3036",
|
||||
"surface-container-low": "#181c21",
|
||||
"on-tertiary-fixed-variant": "#5516be",
|
||||
"on-surface-variant": "#bac9cc",
|
||||
"on-primary-fixed-variant": "#004f58",
|
||||
"surface-dim": "#101419",
|
||||
"primary-container": "#00e5ff",
|
||||
"outline-variant": "#3b494c",
|
||||
"on-secondary-fixed-variant": "#003ea8",
|
||||
"surface-container-lowest": "#0b0e13",
|
||||
"surface-bright": "#36393f",
|
||||
"error": "#ffb4ab",
|
||||
"tertiary": "#f2e9ff",
|
||||
"secondary-container": "#0053db",
|
||||
"on-secondary": "#002a78"
|
||||
},
|
||||
"borderRadius": {
|
||||
"DEFAULT": "0.25rem",
|
||||
"lg": "0.5rem",
|
||||
"xl": "0.75rem",
|
||||
"full": "9999px"
|
||||
},
|
||||
"spacing": {
|
||||
"space-xl": "2rem",
|
||||
"space-lg": "1.5rem",
|
||||
"gutter-lg": "1.5rem",
|
||||
"space-md": "1rem",
|
||||
"margin-lg": "2rem",
|
||||
"margin": "1rem",
|
||||
"space-xs": "0.25rem",
|
||||
"space-sm": "0.5rem",
|
||||
"gutter": "1rem"
|
||||
},
|
||||
"fontFamily": {
|
||||
"display-hero": ["Space Grotesk"],
|
||||
"label-data": ["JetBrains Mono"],
|
||||
"headline-sm": ["Space Grotesk"],
|
||||
"telemetry-metric-lg-mobile": ["JetBrains Mono"],
|
||||
"telemetry-metric-md": ["JetBrains Mono"],
|
||||
"telemetry-metric-lg": ["JetBrains Mono"],
|
||||
"body-md": ["Inter"],
|
||||
"label-caption": ["Inter"],
|
||||
"headline-lg": ["Space Grotesk"],
|
||||
"headline-md": ["Space Grotesk"],
|
||||
"body-lg": ["Inter"],
|
||||
"display-hero-mobile": ["Space Grotesk"]
|
||||
},
|
||||
"fontSize": {
|
||||
"display-hero": ["56px", {"lineHeight": "60px", "letterSpacing": "-0.03em", "fontWeight": "700"}],
|
||||
"label-data": ["12px", {"lineHeight": "16px", "letterSpacing": "0.08em", "fontWeight": "600"}],
|
||||
"headline-sm": ["20px", {"lineHeight": "28px", "fontWeight": "600"}],
|
||||
"telemetry-metric-lg-mobile": ["36px", {"lineHeight": "36px", "letterSpacing": "-0.03em", "fontWeight": "700"}],
|
||||
"telemetry-metric-md": ["28px", {"lineHeight": "32px", "letterSpacing": "-0.02em", "fontWeight": "600"}],
|
||||
"telemetry-metric-lg": ["48px", {"lineHeight": "48px", "letterSpacing": "-0.04em", "fontWeight": "700"}],
|
||||
"body-md": ["14px", {"lineHeight": "20px", "fontWeight": "400"}],
|
||||
"label-caption": ["11px", {"lineHeight": "14px", "letterSpacing": "0.05em", "fontWeight": "600"}],
|
||||
"headline-lg": ["32px", {"lineHeight": "40px", "letterSpacing": "-0.02em", "fontWeight": "700"}],
|
||||
"headline-md": ["24px", {"lineHeight": "32px", "letterSpacing": "-0.01em", "fontWeight": "600"}],
|
||||
"body-lg": ["16px", {"lineHeight": "24px", "fontWeight": "500"}],
|
||||
"display-hero-mobile": ["40px", {"lineHeight": "44px", "letterSpacing": "-0.02em", "fontWeight": "700"}]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.material-symbols-outlined {
|
||||
font-family: 'Material Symbols Outlined';
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
font-size: 20px;
|
||||
line-height: 1;
|
||||
display: inline-block;
|
||||
text-transform: none;
|
||||
letter-spacing: normal;
|
||||
word-wrap: normal;
|
||||
white-space: nowrap;
|
||||
direction: ltr;
|
||||
}
|
||||
/* Hardware tactical styling */
|
||||
body {
|
||||
background-color: #070A0F;
|
||||
color: #e0e2ea;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
user-select: none;
|
||||
touch-action: manipulation;
|
||||
}
|
||||
.neon-cyan-glow {
|
||||
box-shadow: 0 0 16px rgba(0, 229, 255, 0.28);
|
||||
}
|
||||
.neon-gold-glow {
|
||||
box-shadow: 0 0 12px rgba(245, 158, 11, 0.3);
|
||||
}
|
||||
.tactical-border {
|
||||
border: 1px solid #1E293B;
|
||||
}
|
||||
.tactical-grid-bg {
|
||||
background-size: 20px 20px;
|
||||
background-image:
|
||||
linear-gradient(to right, rgba(30, 41, 59, 0.2) 1px, transparent 1px),
|
||||
linear-gradient(to bottom, rgba(30, 41, 59, 0.2) 1px, transparent 1px);
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
body {
|
||||
min-height: max(884px, 100dvh);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="min-h-screen bg-[#070A0F] text-on-surface antialiased flex flex-col justify-between pb-24">
|
||||
<!-- ================= TOP APP BAR (Shared Component JSON Blueprint) ================= -->
|
||||
<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">
|
||||
<button class="w-10 h-10 flex items-center justify-center rounded-lg text-primary-container hover:bg-surface-container active:scale-95 duration-100 ease-out" type="button">
|
||||
<span class="material-symbols-outlined text-primary-container" data-icon="arrow_back">arrow_back</span>
|
||||
</button>
|
||||
<div class="flex items-center space-x-1.5">
|
||||
<span class="text-headline-sm font-headline-sm font-bold tracking-wider text-primary-container">MOTORSIGNAL HUD</span>
|
||||
<span class="inline-flex items-center px-1.5 py-0.5 rounded bg-surface-container-high border border-outline-variant font-label-data text-label-data text-primary-container">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-primary-container animate-pulse mr-1"></span>
|
||||
20Hz GNSS
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center space-x-3 font-label-data text-label-data text-on-surface-variant">
|
||||
<div class="flex items-center space-x-1 text-primary-container">
|
||||
<span class="material-symbols-outlined text-base" data-icon="battery_charging_full" data-weight="fill" style="font-variation-settings: 'FILL' 1;">battery_charging_full</span>
|
||||
<span>98%</span>
|
||||
</div>
|
||||
<span class="text-outline">08:42</span>
|
||||
<button class="w-8 h-8 flex items-center justify-center rounded text-on-surface-variant hover:text-primary-container" type="button">
|
||||
<span class="material-symbols-outlined" data-icon="sensors">sensors</span>
|
||||
</button>
|
||||
</div>
|
||||
</header>
|
||||
<!-- ================= MAIN CONTENT CANVA / COCKPIT TELEMETRY ================= -->
|
||||
<main class="w-full max-w-md mx-auto pt-16 px-3 flex-1 flex flex-col space-y-3">
|
||||
<!-- Run Title & Session Timestamp Header Banner -->
|
||||
<section class="mt-2 bg-[#0D131F] rounded-xl tactical-border p-3.5 relative overflow-hidden">
|
||||
<div class="absolute -right-6 -bottom-6 w-24 h-24 bg-primary-container/5 rounded-full blur-xl pointer-events-none"></div>
|
||||
<div class="flex justify-between items-start">
|
||||
<div>
|
||||
<div class="flex items-center space-x-2">
|
||||
<h1 class="text-headline-sm font-headline-sm font-bold tracking-tight text-white flex items-center gap-1.5">
|
||||
<span>LAUNCH RUN #04 ANALYSIS</span>
|
||||
</h1>
|
||||
</div>
|
||||
<p class="font-label-data text-label-data text-on-surface-variant mt-0.5 flex items-center gap-1">
|
||||
<span class="material-symbols-outlined text-xs text-primary-container" data-icon="schedule">schedule</span>
|
||||
<span>Today 08:42 AM • Weather Sys Sync</span>
|
||||
</p>
|
||||
</div>
|
||||
<span class="px-2 py-1 rounded bg-[#070A0F] tactical-border text-primary font-label-data text-[10px] tracking-wider uppercase font-semibold">
|
||||
SESSION #14
|
||||
</span>
|
||||
</div>
|
||||
<!-- Validation & Trophy Badges Cluster -->
|
||||
<div class="mt-3 flex flex-wrap gap-1.5 items-center">
|
||||
<!-- Gold PR Trophy Badge -->
|
||||
<div class="flex items-center space-x-1.5 px-2.5 py-1 rounded-lg bg-amber-500/15 border border-amber-400 text-amber-300 font-label-data text-label-caption font-bold neon-gold-glow">
|
||||
<span class="text-sm">🏆</span>
|
||||
<span>NEW ALL-TIME PR</span>
|
||||
</div>
|
||||
<!-- SAE Draggy Slope Verified Badge -->
|
||||
<div class="flex items-center space-x-1 px-2.5 py-1 rounded-lg bg-emerald-500/15 border border-emerald-400/80 text-emerald-400 font-label-data text-label-caption font-semibold">
|
||||
<span class="material-symbols-outlined text-xs" data-icon="check_circle">check_circle</span>
|
||||
<span>SAE SLOPE: -0.2% VALID</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Vehicle & Launch Parameters Tag -->
|
||||
<div class="mt-2 pt-2 border-t border-[#1E293B] flex items-center justify-between font-label-data text-[11px] text-on-surface-variant">
|
||||
<span class="text-primary-fixed truncate">2024 Ducati Panigale V4 S • Launch Control Level 2</span>
|
||||
<span class="text-outline shrink-0 ml-1">EBC 1 | DTC 2</span>
|
||||
</div>
|
||||
</section>
|
||||
<!-- ================= TELEMETRY DUAL-AXIS CHART ================= -->
|
||||
<section class="bg-[#0D131F] rounded-xl tactical-border p-3 relative overflow-hidden flex flex-col">
|
||||
<!-- Card Top Bar: Title & Legend -->
|
||||
<div class="flex items-center justify-between pb-2 border-b border-[#1E293B]">
|
||||
<div class="flex items-center space-x-1.5">
|
||||
<span class="material-symbols-outlined text-primary-container text-base" data-icon="show_chart">show_chart</span>
|
||||
<span class="font-label-data text-label-data uppercase tracking-wider text-white">VELOCITY & LONGITUDINAL G-FORCE TRACE</span>
|
||||
</div>
|
||||
<span class="font-label-data text-[10px] text-primary-container bg-primary-container/10 px-1.5 py-0.5 rounded border border-primary-container/30">
|
||||
20Hz DUAL LOG
|
||||
</span>
|
||||
</div>
|
||||
<!-- Legend & Axis Indicator -->
|
||||
<div class="flex justify-between items-center py-1.5 font-label-data text-[11px]">
|
||||
<div class="flex items-center space-x-3">
|
||||
<span class="flex items-center space-x-1 text-primary-container font-semibold">
|
||||
<span class="w-2.5 h-1 bg-primary-container rounded-sm inline-block shadow-[0_0_8px_#00e5ff]"></span>
|
||||
<span>SPEED (MPH)</span>
|
||||
</span>
|
||||
<span class="flex items-center space-x-1 text-amber-400 font-semibold">
|
||||
<span class="w-2.5 h-1 bg-amber-400 rounded-sm inline-block shadow-[0_0_8px_#f59e0b]"></span>
|
||||
<span>ACCEL G-FORCE</span>
|
||||
</span>
|
||||
</div>
|
||||
<span class="text-outline text-[10px]">PEAK: +1.18G</span>
|
||||
</div>
|
||||
<!-- Interactive SVG Chart Canvas Area -->
|
||||
<div class="relative w-full h-52 bg-[#070A0F] tactical-border rounded-lg tactical-grid-bg overflow-hidden my-1">
|
||||
<!-- Y-Axis Labels Left (MPH) -->
|
||||
<div class="absolute left-1.5 top-1 bottom-6 flex flex-col justify-between font-label-data text-[9px] text-primary-container/80 pointer-events-none z-10 font-bold">
|
||||
<span>140</span>
|
||||
<span>100</span>
|
||||
<span>60</span>
|
||||
<span>20</span>
|
||||
<span>0</span>
|
||||
</div>
|
||||
<!-- Y-Axis Labels Right (G-Force) -->
|
||||
<div class="absolute right-1.5 top-1 bottom-6 flex flex-col justify-between font-label-data text-[9px] text-amber-400/90 pointer-events-none z-10 font-bold text-right">
|
||||
<span>+1.4G</span>
|
||||
<span>+1.0G</span>
|
||||
<span>+0.6G</span>
|
||||
<span>+0.2G</span>
|
||||
<span>-0.2G</span>
|
||||
</div>
|
||||
<!-- SVG Trace Graph -->
|
||||
<svg class="w-full h-full" preserveaspectratio="none" viewbox="0 0 380 208">
|
||||
<defs>
|
||||
<!-- Cyan gradient fill under Speed -->
|
||||
<lineargradient id="speedGrad" x1="0%" x2="0%" y1="0%" y2="100%">
|
||||
<stop offset="0%" stop-color="#00e5ff" stop-opacity="0.25"></stop>
|
||||
<stop offset="100%" stop-color="#00e5ff" stop-opacity="0.0"></stop>
|
||||
</lineargradient>
|
||||
<!-- Amber gradient fill under G-force -->
|
||||
<lineargradient id="gGrad" x1="0%" x2="0%" y1="0%" y2="100%">
|
||||
<stop offset="0%" stop-color="#f59e0b" stop-opacity="0.2"></stop>
|
||||
<stop offset="100%" stop-color="#f59e0b" stop-opacity="0.0"></stop>
|
||||
</lineargradient>
|
||||
</defs>
|
||||
<!-- Horizontal Reference Gridlines -->
|
||||
<line stroke="#1E293B" stroke-dasharray="3,3" stroke-width="0.8" x1="28" x2="352" y1="20" y2="20"></line>
|
||||
<line stroke="#1E293B" stroke-dasharray="3,3" stroke-width="0.8" x1="28" x2="352" y1="60" y2="60"></line>
|
||||
<line stroke="#1E293B" stroke-dasharray="3,3" stroke-width="0.8" x1="28" x2="352" y1="100" y2="100"></line>
|
||||
<line stroke="#1E293B" stroke-dasharray="3,3" stroke-width="0.8" x1="28" x2="352" y1="140" y2="140"></line>
|
||||
<line stroke="#1E293B" stroke-width="1" x1="28" x2="352" y1="180" y2="180"></line>
|
||||
<!-- Longitudinal G-Force Area & Curve (Amber) -->
|
||||
<!-- Launch peak spike at +1.18G, settling through shifts -->
|
||||
<path d="M 30,175
|
||||
C 36,45 44,28 52,32
|
||||
C 65,38 78,85 92,90
|
||||
C 100,95 106,120 114,80
|
||||
C 126,86 148,110 170,115
|
||||
C 178,122 184,136 194,104
|
||||
C 210,112 245,130 268,134
|
||||
C 278,140 286,152 296,126
|
||||
C 315,132 342,145 352,148
|
||||
L 352,180 L 30,180 Z" fill="url(#gGrad)"></path>
|
||||
<path d="M 30,175
|
||||
C 36,45 44,28 52,32
|
||||
C 65,38 78,85 92,90
|
||||
C 100,95 106,120 114,80
|
||||
C 126,86 148,110 170,115
|
||||
C 178,122 184,136 194,104
|
||||
C 210,112 245,130 268,134
|
||||
C 278,140 286,152 296,126
|
||||
C 315,132 342,145 352,148" fill="none" stroke="#f59e0b" stroke-linecap="round" stroke-width="2.2"></path>
|
||||
<!-- Speed Velocity Area & Curve (Cyan MPH) -->
|
||||
<!-- Accelerating 0 to 135 MPH over 11.2s -->
|
||||
<path d="M 30,180
|
||||
C 45,168 70,140 102,110
|
||||
C 135,82 175,64 215,48
|
||||
C 260,34 310,22 352,16
|
||||
L 352,180 Z" fill="url(#speedGrad)"></path>
|
||||
<path d="M 30,180
|
||||
C 45,168 70,140 102,110
|
||||
C 135,82 175,64 215,48
|
||||
C 260,34 310,22 352,16" fill="none" stroke="#00e5ff" stroke-linecap="round" stroke-width="2.5"></path>
|
||||
<!-- Interactive Scrubber Cursor Line at T+3.28s (60 MPH transition) -->
|
||||
<line stroke="#00e5ff" stroke-dasharray="2,2" stroke-width="1.5" x1="126" x2="126" y1="10" y2="182"></line>
|
||||
<!-- Scrubber Intersect Dots -->
|
||||
<circle cx="126" cy="95" fill="#00e5ff" r="4.5" stroke="#070A0F" stroke-width="1.5"></circle>
|
||||
<circle cx="126" cy="98" fill="#f59e0b" r="4.5" stroke="#070A0F" stroke-width="1.5"></circle>
|
||||
<!-- Gear Shift Vertical Markers -->
|
||||
<line stroke="#3b494c" stroke-width="1" x1="108" x2="108" y1="168" y2="182"></line>
|
||||
<line stroke="#3b494c" stroke-width="1" x1="188" x2="188" y1="168" y2="182"></line>
|
||||
<line stroke="#3b494c" stroke-width="1" x1="290" x2="290" y1="168" y2="182"></line>
|
||||
</svg>
|
||||
<!-- Floating Scrubber Tooltip Overlay -->
|
||||
<div class="absolute left-20 top-3 bg-[#0D131FE6] backdrop-blur-md px-2.5 py-1.5 rounded-lg border border-primary-container neon-cyan-glow z-20 pointer-events-none">
|
||||
<div class="flex items-center space-x-1.5 font-label-data text-label-data font-bold text-white tracking-tight">
|
||||
<span class="text-primary-container">T+3.28s</span>
|
||||
<span class="text-outline">|</span>
|
||||
<span class="text-primary">60.0 MPH</span>
|
||||
<span class="text-outline">|</span>
|
||||
<span class="text-amber-400">+0.82G</span>
|
||||
<span class="text-outline">|</span>
|
||||
<span class="px-1 bg-surface-container-high rounded text-[10px] text-white">G2</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Gear Shift Indicator Labels along Bottom Track -->
|
||||
<div class="absolute left-7 right-7 bottom-0.5 flex justify-between font-label-data text-[10px] font-bold text-outline">
|
||||
<span class="text-primary-container">1st (Launch)</span>
|
||||
<span class="text-on-surface-variant">2nd Shift</span>
|
||||
<span class="text-on-surface-variant">3rd Shift</span>
|
||||
<span class="text-on-surface-variant">4th Gear</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Scrub Timeline Time Axis labels -->
|
||||
<div class="flex justify-between items-center px-6 pt-1 font-label-data text-[10px] text-outline">
|
||||
<span>0.0s</span>
|
||||
<span>2.5s</span>
|
||||
<span>5.0s</span>
|
||||
<span>7.5s</span>
|
||||
<span>10.0s</span>
|
||||
<span>11.2s</span>
|
||||
</div>
|
||||
</section>
|
||||
<!-- ================= MILESTONE SPLITS TABLE / DATA GRID ================= -->
|
||||
<section class="bg-[#0D131F] rounded-xl tactical-border p-3 flex flex-col space-y-2.5">
|
||||
<div class="flex justify-between items-center border-b border-[#1E293B] pb-2">
|
||||
<div class="flex items-center space-x-1.5">
|
||||
<span class="material-symbols-outlined text-primary-container text-base" data-icon="timer">timer</span>
|
||||
<span class="font-label-data text-label-data uppercase tracking-wider text-white">MILESTONE ACCELERATION SPLITS</span>
|
||||
</div>
|
||||
<div class="flex items-center space-x-1 font-label-data text-[10px] text-emerald-400 bg-emerald-500/10 px-2 py-0.5 rounded border border-emerald-500/30">
|
||||
<span class="material-symbols-outlined text-xs" data-icon="verified">verified</span>
|
||||
<span>100% VALIDATED</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Splits Grid List -->
|
||||
<div class="grid grid-cols-1 gap-1.5">
|
||||
<!-- 0-30 MPH Split -->
|
||||
<div class="flex items-center justify-between p-2.5 rounded-lg bg-[#070A0F] tactical-border">
|
||||
<div class="flex items-center space-x-2.5">
|
||||
<span class="w-1.5 h-6 bg-outline rounded-full"></span>
|
||||
<div>
|
||||
<span class="font-headline-sm text-sm font-bold text-white tracking-wider block">0 - 30 MPH</span>
|
||||
<span class="font-label-data text-[10px] text-outline">60FT: 1.62s • PEAK: +1.18G</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<span class="font-label-data text-telemetry-metric-md text-white font-bold leading-none">1.41<span class="text-xs text-outline font-normal ml-0.5">s</span></span>
|
||||
<span class="block font-label-data text-[10px] text-on-surface-variant">-0.04s vs avg</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 0-60 MPH Split (Highlight / PR) -->
|
||||
<div class="flex items-center justify-between p-2.5 rounded-lg bg-surface-container-high border-2 border-primary-container neon-cyan-glow relative overflow-hidden">
|
||||
<div class="absolute -right-4 -top-4 w-16 h-16 bg-primary-container/10 rounded-full blur-md"></div>
|
||||
<div class="flex items-center space-x-2.5">
|
||||
<span class="w-1.5 h-8 bg-primary-container rounded-full"></span>
|
||||
<div>
|
||||
<div class="flex items-center space-x-1.5">
|
||||
<span class="font-headline-sm text-base font-bold text-white tracking-wider">0 - 60 MPH</span>
|
||||
<span class="px-1.5 py-0.5 rounded bg-amber-400/20 text-amber-300 font-label-data text-[10px] font-bold border border-amber-400/40">
|
||||
★ NEW PR
|
||||
</span>
|
||||
</div>
|
||||
<span class="font-label-data text-[11px] text-primary font-semibold">SAE CORR: 3.25s (-0.14s)</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<span class="font-label-data text-telemetry-metric-lg-mobile text-primary-container font-extrabold leading-none">3.28<span class="text-sm font-normal ml-0.5 text-primary">s</span></span>
|
||||
<span class="block font-label-data text-[10px] text-emerald-400 font-semibold">BEST SECTOR</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 0-100 MPH Split -->
|
||||
<div class="flex items-center justify-between p-2.5 rounded-lg bg-[#070A0F] tactical-border">
|
||||
<div class="flex items-center space-x-2.5">
|
||||
<span class="w-1.5 h-6 bg-outline rounded-full"></span>
|
||||
<div>
|
||||
<span class="font-headline-sm text-sm font-bold text-white tracking-wider block">0 - 100 MPH</span>
|
||||
<span class="font-label-data text-[10px] text-outline">SLOPE: -0.18% • 330FT: 4.88s</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<span class="font-label-data text-telemetry-metric-md text-white font-bold leading-none">7.41<span class="text-xs text-outline font-normal ml-0.5">s</span></span>
|
||||
<span class="block font-label-data text-[10px] text-on-surface-variant">+0.02s vs PR</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 1/8 Mile Split -->
|
||||
<div class="flex items-center justify-between p-2.5 rounded-lg bg-[#070A0F] tactical-border">
|
||||
<div class="flex items-center space-x-2.5">
|
||||
<span class="w-1.5 h-6 bg-outline rounded-full"></span>
|
||||
<div>
|
||||
<span class="font-headline-sm text-sm font-bold text-white tracking-wider block">1/8 MILE (660 FT)</span>
|
||||
<span class="font-label-data text-[10px] text-primary">TRAP VELOCITY: 104.8 MPH</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<span class="font-label-data text-telemetry-metric-md text-white font-bold leading-none">7.12<span class="text-xs text-outline font-normal ml-0.5">s</span></span>
|
||||
<span class="block font-label-data text-[10px] text-on-surface-variant">104.8 MPH</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 1/4 Mile Split -->
|
||||
<div class="flex items-center justify-between p-2.5 rounded-lg bg-[#070A0F] border border-primary-container/40">
|
||||
<div class="flex items-center space-x-2.5">
|
||||
<span class="w-1.5 h-6 bg-amber-400 rounded-full"></span>
|
||||
<div>
|
||||
<div class="flex items-center space-x-1.5">
|
||||
<span class="font-headline-sm text-sm font-bold text-white tracking-wider">1/4 MILE (1320 FT)</span>
|
||||
<span class="px-1.5 py-0.2 rounded bg-primary-container/10 text-primary-container font-label-data text-[9px] border border-primary-container/30">
|
||||
SUB-11S VERIFIED
|
||||
</span>
|
||||
</div>
|
||||
<span class="font-label-data text-[10px] text-amber-300">TRAP VELOCITY: 131.4 MPH</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<span class="font-label-data text-telemetry-metric-md text-primary-container font-bold leading-none">10.92<span class="text-xs text-outline font-normal ml-0.5">s</span></span>
|
||||
<span class="block font-label-data text-[10px] text-amber-400 font-semibold">131.4 MPH</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- NHRA Roll-Out Standard Bar Toggle -->
|
||||
<div class="pt-1 flex items-center justify-between px-1">
|
||||
<div class="flex items-center space-x-2">
|
||||
<div class="w-4 h-4 rounded bg-primary-container/20 border border-primary-container flex items-center justify-center">
|
||||
<span class="material-symbols-outlined text-xs text-primary-container" data-icon="check">check</span>
|
||||
</div>
|
||||
<span class="font-label-data text-[11px] text-on-surface-variant">Rollout 1ft: 0.28s applied (NHRA standard)</span>
|
||||
</div>
|
||||
<span class="font-label-data text-[10px] text-primary-container cursor-pointer hover:underline">Configure</span>
|
||||
</div>
|
||||
</section>
|
||||
<!-- ================= ATMOSPHERIC & ENVIRONMENTAL CARD ================= -->
|
||||
<section class="bg-[#0D131F] rounded-xl tactical-border p-3">
|
||||
<div class="flex items-center justify-between border-b border-[#1E293B] pb-2 mb-2.5">
|
||||
<div class="flex items-center space-x-1.5">
|
||||
<span class="material-symbols-outlined text-primary-container text-base" data-icon="thermostat">thermostat</span>
|
||||
<span class="font-label-data text-label-data uppercase tracking-wider text-white">ENVIRONMENTAL & SURFACE GRIP</span>
|
||||
</div>
|
||||
<span class="font-label-data text-[10px] text-outline">AUTO STATION SYNC</span>
|
||||
</div>
|
||||
<div class="grid grid-cols-2 gap-2 font-label-data">
|
||||
<!-- Weather Telemetry Column -->
|
||||
<div class="p-2 rounded-lg bg-[#070A0F] tactical-border flex flex-col justify-between">
|
||||
<div class="text-[10px] text-outline flex items-center justify-between">
|
||||
<span>DENSITY ALTITUDE</span>
|
||||
<span class="text-primary-container font-bold">+420 FT</span>
|
||||
</div>
|
||||
<div class="my-1.5 flex items-baseline space-x-1">
|
||||
<span class="text-lg font-bold text-white">74°F</span>
|
||||
<span class="text-[10px] text-outline">/ 29.92 inHg</span>
|
||||
</div>
|
||||
<div class="text-[10px] text-on-surface-variant flex justify-between border-t border-[#1E293B] pt-1">
|
||||
<span>HUMIDITY: 42%</span>
|
||||
<span class="text-primary">BARO: 98.8%</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Track Surface Telemetry Column -->
|
||||
<div class="p-2 rounded-lg bg-[#070A0F] tactical-border flex flex-col justify-between">
|
||||
<div class="text-[10px] text-outline flex items-center justify-between">
|
||||
<span>TRACK SURFACE</span>
|
||||
<span class="text-emerald-400 font-bold">OPTIMAL</span>
|
||||
</div>
|
||||
<div class="my-1.5 flex items-baseline space-x-1">
|
||||
<span class="text-lg font-bold text-white">94%</span>
|
||||
<span class="text-[10px] text-emerald-400">Grip Index</span>
|
||||
</div>
|
||||
<div class="text-[10px] text-on-surface-variant flex justify-between border-t border-[#1E293B] pt-1">
|
||||
<span>TEMP: 88°F</span>
|
||||
<span class="text-outline">DRY ASPHALT</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- ================= BOTTOM ACTION BUTTONS (Tactile Cockpit Triggers) ================= -->
|
||||
<div class="pt-1 pb-2 grid grid-cols-2 gap-2.5">
|
||||
<!-- Secondary Cockpit Action: Compare Runs -->
|
||||
<button class="h-12 min-h-[48px] px-3 rounded-xl bg-[#0D131F] tactical-border text-white font-label-data text-label-data font-semibold flex items-center justify-center space-x-2 hover:border-primary-container hover:bg-[#141C2E] active:scale-95 duration-100 ease-out" type="button">
|
||||
<span class="material-symbols-outlined text-primary-container" data-icon="compare_arrows">compare_arrows</span>
|
||||
<span>Compare Runs</span>
|
||||
</button>
|
||||
<!-- Primary Cockpit Action: Export 20Hz CSV -->
|
||||
<button class="h-12 min-h-[48px] px-3 rounded-xl bg-primary-container text-[#070A0F] font-label-data text-label-data font-bold flex items-center justify-center space-x-2 neon-cyan-glow hover:bg-[#00B8CC] active:scale-95 duration-100 ease-out" type="button">
|
||||
<span class="material-symbols-outlined text-[#070A0F] font-bold" data-icon="download">download</span>
|
||||
<span>Export 20Hz CSV</span>
|
||||
</button>
|
||||
</div>
|
||||
</main>
|
||||
<!-- ================= BOTTOM NAVBAR (Shared Component JSON Blueprint) ================= -->
|
||||
<!-- Semantic Mapping Active: Page is "LAUNCH RUN #04 ANALYSIS" -> maps to "Activity" -->
|
||||
<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">
|
||||
<!-- Tab 1: Dash (Inactive) -->
|
||||
<button class="flex flex-col items-center justify-center text-on-surface-variant px-2 py-1 min-h-[48px] hover:bg-surface-container-low hover:text-primary-fixed active:scale-95 duration-100 ease-out" type="button">
|
||||
<span class="material-symbols-outlined" data-icon="speed">speed</span>
|
||||
<span class="font-label-caption text-label-caption mt-0.5">Dash</span>
|
||||
</button>
|
||||
<!-- Tab 2: Map (Inactive) -->
|
||||
<button class="flex flex-col items-center justify-center text-on-surface-variant px-2 py-1 min-h-[48px] hover:bg-surface-container-low hover:text-primary-fixed active:scale-95 duration-100 ease-out" type="button">
|
||||
<span class="material-symbols-outlined" data-icon="navigation">navigation</span>
|
||||
<span class="font-label-caption text-label-caption mt-0.5">Map</span>
|
||||
</button>
|
||||
<!-- Tab 3: Activity (ACTIVE STATE - Telemetry Analysis Screen) -->
|
||||
<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] active:scale-95 duration-100 ease-out" type="button">
|
||||
<span class="material-symbols-outlined" data-icon="analytics" data-weight="fill" style="font-variation-settings: 'FILL' 1;">analytics</span>
|
||||
<span class="font-label-caption text-label-caption mt-0.5 font-bold">Activity</span>
|
||||
</button>
|
||||
<!-- Tab 4: Garage (Inactive) -->
|
||||
<button class="flex flex-col items-center justify-center text-on-surface-variant px-2 py-1 min-h-[48px] hover:bg-surface-container-low hover:text-primary-fixed active:scale-95 duration-100 ease-out" type="button">
|
||||
<span class="material-symbols-outlined" data-icon="two_wheeler">two_wheeler</span>
|
||||
<span class="font-label-caption text-label-caption mt-0.5">Garage</span>
|
||||
</button>
|
||||
<!-- Tab 5: Settings (Inactive) -->
|
||||
<button class="flex flex-col items-center justify-center text-on-surface-variant px-2 py-1 min-h-[48px] hover:bg-surface-container-low hover:text-primary-fixed active:scale-95 duration-100 ease-out" type="button">
|
||||
<span class="material-symbols-outlined" data-icon="settings">settings</span>
|
||||
<span class="font-label-caption text-label-caption mt-0.5">Settings</span>
|
||||
</button>
|
||||
</nav>
|
||||
<!-- Lightweight inline interaction script for scrubber feedback -->
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
// Tactical button feedback sound / haptic simulator
|
||||
const buttons = document.querySelectorAll('button');
|
||||
buttons.forEach(btn => {
|
||||
btn.addEventListener('click', () => {
|
||||
if (navigator.vibrate) {
|
||||
navigator.vibrate(15);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body></html>
|
||||
|
|
@ -0,0 +1,432 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<html class="dark" lang="en"><head>
|
||||
<meta charset="utf-8"/>
|
||||
<meta content="width=device-width, initial-scale=1.0" name="viewport"/>
|
||||
<title>MotorSignal Telemetry Vault // Personal Records</title>
|
||||
<!-- Google Fonts: Space Grotesk, JetBrains Mono, Inter -->
|
||||
<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&family=JetBrains+Mono:wght@400;500;600;700&family=Space+Grotesk:wght@500;600;700&display=swap" rel="stylesheet"/>
|
||||
<!-- Material Symbols Outlined -->
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<!-- Tailwind CSS v3 -->
|
||||
<script src="https://cdn.tailwindcss.com?plugins=forms,container-queries"></script>
|
||||
<script id="tailwind-config">
|
||||
tailwind.config = {
|
||||
darkMode: "class",
|
||||
theme: {
|
||||
extend: {
|
||||
"colors": {
|
||||
"on-primary": "#00363d",
|
||||
"primary-fixed": "#9cf0ff",
|
||||
"surface-variant": "#32353b",
|
||||
"primary-container": "#00e5ff",
|
||||
"outline-variant": "#3b494c",
|
||||
"tertiary-container": "#d9c8ff",
|
||||
"on-error-container": "#ffdad6",
|
||||
"secondary-container": "#0053db",
|
||||
"surface-container": "#1d2025",
|
||||
"on-primary-container": "#00626e",
|
||||
"secondary-fixed": "#dbe1ff",
|
||||
"on-background": "#e0e2ea",
|
||||
"surface-container-high": "#272a30",
|
||||
"error": "#ffb4ab",
|
||||
"tertiary": "#f2e9ff",
|
||||
"surface-container-highest": "#32353b",
|
||||
"primary-fixed-dim": "#00daf3",
|
||||
"surface-tint": "#00daf3",
|
||||
"surface-dim": "#101419",
|
||||
"on-primary-fixed": "#001f24",
|
||||
"error-container": "#93000a",
|
||||
"on-error": "#690005",
|
||||
"on-tertiary-container": "#6834d1",
|
||||
"surface-bright": "#36393f",
|
||||
"on-tertiary-fixed": "#23005c",
|
||||
"inverse-on-surface": "#2d3036",
|
||||
"on-secondary-container": "#cdd7ff",
|
||||
"surface": "#101419",
|
||||
"on-secondary": "#002a78",
|
||||
"inverse-surface": "#e0e2ea",
|
||||
"inverse-primary": "#006875",
|
||||
"tertiary-fixed-dim": "#d0bcff",
|
||||
"secondary-fixed-dim": "#b4c5ff",
|
||||
"secondary": "#b4c5ff",
|
||||
"surface-container-lowest": "#0b0e13",
|
||||
"on-secondary-fixed": "#00174b",
|
||||
"on-primary-fixed-variant": "#004f58",
|
||||
"on-surface": "#e0e2ea",
|
||||
"on-secondary-fixed-variant": "#003ea8",
|
||||
"background": "#101419",
|
||||
"on-surface-variant": "#bac9cc",
|
||||
"surface-container-low": "#181c21",
|
||||
"on-tertiary": "#3c0091",
|
||||
"on-tertiary-fixed-variant": "#5516be",
|
||||
"tertiary-fixed": "#e9ddff",
|
||||
"primary": "#c3f5ff",
|
||||
"outline": "#849396"
|
||||
},
|
||||
"borderRadius": {
|
||||
"DEFAULT": "0.25rem",
|
||||
"lg": "0.5rem",
|
||||
"xl": "0.75rem",
|
||||
"full": "9999px"
|
||||
},
|
||||
"spacing": {
|
||||
"gutter": "1rem",
|
||||
"margin": "1rem",
|
||||
"margin-lg": "2rem",
|
||||
"space-sm": "0.5rem",
|
||||
"space-xs": "0.25rem",
|
||||
"space-xl": "2rem",
|
||||
"space-md": "1rem",
|
||||
"space-lg": "1.5rem",
|
||||
"gutter-lg": "1.5rem"
|
||||
},
|
||||
"fontFamily": {
|
||||
"headline-sm": ["Space Grotesk"],
|
||||
"display-hero": ["Space Grotesk"],
|
||||
"telemetry-metric-md": ["JetBrains Mono"],
|
||||
"telemetry-metric-lg-mobile": ["JetBrains Mono"],
|
||||
"headline-lg": ["Space Grotesk"],
|
||||
"display-hero-mobile": ["Space Grotesk"],
|
||||
"body-md": ["Inter"],
|
||||
"headline-md": ["Space Grotesk"],
|
||||
"label-caption": ["Inter"],
|
||||
"body-lg": ["Inter"],
|
||||
"telemetry-metric-lg": ["JetBrains Mono"],
|
||||
"label-data": ["JetBrains Mono"]
|
||||
},
|
||||
"fontSize": {
|
||||
"headline-sm": ["20px", { "lineHeight": "28px", "fontWeight": "600" }],
|
||||
"display-hero": ["56px", { "lineHeight": "60px", "letterSpacing": "-0.03em", "fontWeight": "700" }],
|
||||
"telemetry-metric-md": ["28px", { "lineHeight": "32px", "letterSpacing": "-0.02em", "fontWeight": "600" }],
|
||||
"telemetry-metric-lg-mobile": ["36px", { "lineHeight": "36px", "letterSpacing": "-0.03em", "fontWeight": "700" }],
|
||||
"headline-lg": ["32px", { "lineHeight": "40px", "letterSpacing": "-0.02em", "fontWeight": "700" }],
|
||||
"display-hero-mobile": ["40px", { "lineHeight": "44px", "letterSpacing": "-0.02em", "fontWeight": "700" }],
|
||||
"body-md": ["14px", { "lineHeight": "20px", "fontWeight": "400" }],
|
||||
"headline-md": ["24px", { "lineHeight": "32px", "letterSpacing": "-0.01em", "fontWeight": "600" }],
|
||||
"label-caption": ["11px", { "lineHeight": "14px", "letterSpacing": "0.05em", "fontWeight": "600" }],
|
||||
"body-lg": ["16px", { "lineHeight": "24px", "fontWeight": "500" }],
|
||||
"telemetry-metric-lg": ["48px", { "lineHeight": "48px", "letterSpacing": "-0.04em", "fontWeight": "700" }],
|
||||
"label-data": ["12px", { "lineHeight": "16px", "letterSpacing": "0.08em", "fontWeight": "600" }]
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
body {
|
||||
min-height: max(884px, 100dvh);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-surface text-on-surface font-body-md antialiased selection:bg-primary-container selection:text-on-primary-container min-h-screen pb-24">
|
||||
<!-- TOP HUD STATUS & BAR -->
|
||||
<header class="fixed top-0 left-0 w-full z-50 flex justify-between items-center px-gutter h-14 bg-surface-container-lowest dark:bg-surface-container-lowest border-b border-outline-variant dark:border-outline-variant">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-primary-container" data-icon="sensors">sensors</span>
|
||||
<span class="text-headline-sm font-headline-sm font-bold tracking-wider text-primary-container dark:text-primary-container">MOTORSIGNAL HUD</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-3">
|
||||
<!-- 20Hz GNSS Lock Chip -->
|
||||
<div class="flex items-center gap-1.5 px-2 py-0.5 rounded-full bg-surface-container-high border border-outline-variant">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-primary-container animate-pulse"></span>
|
||||
<span class="text-label-caption font-label-caption text-primary font-semibold">20Hz GNSS</span>
|
||||
</div>
|
||||
<!-- Battery Status -->
|
||||
<div class="flex items-center gap-1 text-on-surface-variant">
|
||||
<span class="material-symbols-outlined text-sm" data-icon="battery_full">battery_full</span>
|
||||
<span class="text-label-data font-label-data">98%</span>
|
||||
</div>
|
||||
<!-- Warning Trailing Icon -->
|
||||
<button aria-label="Warnings" class="flex items-center justify-center p-1 rounded hover:bg-surface-container text-on-surface-variant hover:text-primary-container transition-colors">
|
||||
<span class="material-symbols-outlined text-base" data-icon="warning">warning</span>
|
||||
</button>
|
||||
</div>
|
||||
</header>
|
||||
<!-- MAIN HUD CANVAS -->
|
||||
<main class="pt-16 px-gutter max-w-md mx-auto space-y-4">
|
||||
<!-- SUB-NAV / CONTEXT TITLE -->
|
||||
<div class="flex items-center justify-between pt-2">
|
||||
<div class="flex items-center gap-2">
|
||||
<button aria-label="Go back" class="w-12 h-12 flex items-center justify-center rounded-lg bg-surface-container-low border border-outline-variant text-on-surface-variant hover:text-primary-container hover:border-primary-container active:scale-95 transition-all">
|
||||
<span class="material-symbols-outlined" data-icon="arrow_back">arrow_back</span>
|
||||
</button>
|
||||
<div>
|
||||
<div class="text-label-caption font-label-caption text-primary-fixed-dim uppercase tracking-wider">SECURE TELEMETRY VAULT</div>
|
||||
<h1 class="text-headline-sm font-headline-sm text-on-surface font-bold tracking-tight">PERSONAL RECORDS</h1>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-10 h-10 rounded-lg bg-surface-container-high border border-outline-variant flex items-center justify-center text-primary-container shadow-[0_0_12px_rgba(0,229,255,0.2)]">
|
||||
<span class="material-symbols-outlined" data-icon="military_tech">military_tech</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- HIGH TACTILE SEGMENTED PILL SWITCHER (Min 48px Height) -->
|
||||
<div class="bg-surface-container-lowest p-1 rounded-xl border border-outline-variant grid grid-cols-2 gap-1 min-h-[52px]">
|
||||
<button class="min-h-[46px] flex items-center justify-center gap-2 rounded-lg text-on-surface-variant font-label-data uppercase hover:bg-surface-container transition-all active:scale-95">
|
||||
<span class="material-symbols-outlined text-base" data-icon="two_wheeler">two_wheeler</span>
|
||||
<span>Rides (48)</span>
|
||||
</button>
|
||||
<button class="min-h-[46px] flex items-center justify-center gap-2 rounded-lg bg-surface-container-high border border-primary-container text-primary-container font-label-data uppercase font-bold shadow-[0_0_14px_rgba(0,229,255,0.25)] transition-all">
|
||||
<span class="material-symbols-outlined text-base" data-icon="emoji_events">emoji_events</span>
|
||||
<span>Records (Trophies)</span>
|
||||
<span class="w-2 h-2 rounded-full bg-primary-container"></span>
|
||||
</button>
|
||||
</div>
|
||||
<!-- RIDER LIFETIME STATS MASTHEAD -->
|
||||
<div class="bg-surface-container-low border border-outline-variant rounded-xl p-4 space-y-3 relative overflow-hidden">
|
||||
<!-- Glow ambient corner accent -->
|
||||
<div class="absolute -top-12 -right-12 w-28 h-28 bg-primary-container/10 rounded-full blur-2xl pointer-events-none"></div>
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="w-12 h-12 rounded-lg bg-surface-container-high border border-outline-variant flex items-center justify-center text-primary-container">
|
||||
<span class="material-symbols-outlined text-2xl" data-icon="two_wheeler">two_wheeler</span>
|
||||
</div>
|
||||
<div>
|
||||
<div class="flex items-center gap-1.5">
|
||||
<span class="text-headline-sm font-headline-sm font-bold text-on-surface">@AlexMercer</span>
|
||||
<span class="px-1.5 py-0.5 rounded bg-surface-container-highest border border-primary-container text-primary-container text-label-caption font-label-caption font-bold">PRO</span>
|
||||
</div>
|
||||
<div class="text-label-caption font-label-caption text-on-surface-variant flex items-center gap-1">
|
||||
<span>Ducati Panigale V4 S</span>
|
||||
<span class="text-primary-fixed-dim">•</span>
|
||||
<span class="text-primary-container">Apex Master</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<span class="material-symbols-outlined text-primary-container" data-icon="verified_user">verified_user</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Lifetime Summary Strip -->
|
||||
<div class="pt-2 border-t border-outline-variant grid grid-cols-3 gap-2 text-center">
|
||||
<div class="p-2 rounded-lg bg-surface-container-lowest border border-outline-variant">
|
||||
<div class="text-label-caption font-label-caption text-on-surface-variant">TOTAL DIST</div>
|
||||
<div class="text-label-data font-label-data font-bold text-on-surface">12,480 MI</div>
|
||||
</div>
|
||||
<div class="p-2 rounded-lg bg-surface-container-lowest border border-outline-variant">
|
||||
<div class="text-label-caption font-label-caption text-on-surface-variant">LOGGED RUNS</div>
|
||||
<div class="text-label-data font-label-data font-bold text-on-surface">48 SESSIONS</div>
|
||||
</div>
|
||||
<div class="p-2 rounded-lg bg-surface-container-lowest border border-outline-variant">
|
||||
<div class="text-label-caption font-label-caption text-on-surface-variant">DRIFT STATE</div>
|
||||
<div class="text-label-data font-label-data font-bold text-primary-container">0.00% SAE</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center justify-between text-label-caption font-label-caption text-on-surface-variant bg-surface-container-lowest px-2.5 py-1.5 rounded-lg border border-outline-variant">
|
||||
<span class="flex items-center gap-1 text-primary">
|
||||
<span class="material-symbols-outlined text-xs" data-icon="verified">verified</span>
|
||||
100% SAE & IMU Drift Verified
|
||||
</span>
|
||||
<span class="font-label-data text-outline">HASH #4F89-A2</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- TROPHY SHOWCASE BENTO GRID -->
|
||||
<div class="space-y-3">
|
||||
<div class="flex items-center justify-between px-1">
|
||||
<span class="text-label-caption font-label-caption text-on-surface-variant uppercase tracking-wider">VERIFIED APEX TELEMETRY TROPHIES</span>
|
||||
<span class="text-label-caption font-label-caption text-primary-container font-mono">6 UNLOCKED</span>
|
||||
</div>
|
||||
<!-- CARD 1: Speed & Acceleration -->
|
||||
<div class="bg-surface-container-low border border-outline-variant hover:border-primary-container transition-colors rounded-xl p-4 space-y-3">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-primary-container" data-icon="timer">timer</span>
|
||||
<span class="text-label-data font-label-data uppercase text-on-surface-variant font-bold">All-Time Best 0-60 MPH</span>
|
||||
</div>
|
||||
<span class="px-2 py-0.5 rounded-full bg-surface-container-high border border-outline text-primary-container text-label-caption font-label-caption font-bold flex items-center gap-1">
|
||||
<span class="material-symbols-outlined text-xs" data-icon="stars">stars</span> GOLD CERTIFIED
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex items-baseline justify-between">
|
||||
<div class="flex items-baseline gap-1">
|
||||
<span class="text-telemetry-metric-lg-mobile font-telemetry-metric-lg-mobile text-primary-container tracking-tight">3.28</span>
|
||||
<span class="text-headline-sm font-headline-sm text-on-surface-variant font-bold">SEC</span>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<div class="text-label-data font-label-data text-on-surface font-semibold">-0.2% Slope</div>
|
||||
<div class="text-label-caption font-label-caption text-outline">SAE J1318 Validated</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center justify-between pt-2 border-t border-outline-variant text-label-caption font-label-caption text-on-surface-variant">
|
||||
<span class="flex items-center gap-1">
|
||||
<span class="material-symbols-outlined text-xs" data-icon="location_on">location_on</span> Saratoga Strip
|
||||
</span>
|
||||
<span class="font-label-data">Session #14 • Panigale V4 S</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- CARD 2 & 3: LEAN ANGLE TWIN BENTO CLUSTER -->
|
||||
<div class="grid grid-cols-2 gap-3">
|
||||
<!-- Card 2: Left Apex -->
|
||||
<div class="bg-surface-container-low border border-outline-variant rounded-xl p-3 space-y-2 flex flex-col justify-between">
|
||||
<div>
|
||||
<div class="flex items-center justify-between mb-1">
|
||||
<span class="text-label-caption font-label-caption text-on-surface-variant uppercase font-bold">Max Lean (L)</span>
|
||||
<span class="material-symbols-outlined text-primary-container text-sm" data-icon="turn_left">turn_left</span>
|
||||
</div>
|
||||
<div class="text-telemetry-metric-md font-telemetry-metric-md text-primary-container font-bold">
|
||||
54.2°
|
||||
</div>
|
||||
<!-- Lean Arc Graphic Visualizer -->
|
||||
<div class="w-full bg-surface-container-lowest h-2 rounded-full overflow-hidden border border-outline-variant my-1.5">
|
||||
<div class="bg-primary-container h-full rounded-full" style="width: 88%;"></div>
|
||||
</div>
|
||||
<span class="inline-block px-1.5 py-0.5 rounded bg-surface-container-high border border-outline text-primary text-[10px] font-bold">
|
||||
APEX SCRAPER
|
||||
</span>
|
||||
</div>
|
||||
<div class="pt-2 border-t border-outline-variant">
|
||||
<div class="text-[10px] font-label-data text-on-surface font-medium">Turn 7 Hairpin</div>
|
||||
<div class="text-[9px] font-label-caption text-outline">20Hz IMU Kalman Fused</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Card 3: Right Apex -->
|
||||
<div class="bg-surface-container-low border border-outline-variant rounded-xl p-3 space-y-2 flex flex-col justify-between">
|
||||
<div>
|
||||
<div class="flex items-center justify-between mb-1">
|
||||
<span class="text-label-caption font-label-caption text-on-surface-variant uppercase font-bold">Max Lean (R)</span>
|
||||
<span class="material-symbols-outlined text-primary-container text-sm" data-icon="turn_right">turn_right</span>
|
||||
</div>
|
||||
<div class="text-telemetry-metric-md font-telemetry-metric-md text-primary-container font-bold">
|
||||
52.8°
|
||||
</div>
|
||||
<!-- Lean Arc Graphic Visualizer -->
|
||||
<div class="w-full bg-surface-container-lowest h-2 rounded-full overflow-hidden border border-outline-variant my-1.5">
|
||||
<div class="bg-primary-container h-full rounded-full" style="width: 84%;"></div>
|
||||
</div>
|
||||
<span class="inline-block px-1.5 py-0.5 rounded bg-surface-container-high border border-outline text-primary text-[10px] font-bold">
|
||||
KNEE DOWN
|
||||
</span>
|
||||
</div>
|
||||
<div class="pt-2 border-t border-outline-variant">
|
||||
<div class="text-[10px] font-label-data text-on-surface font-medium">Pescadero Arc</div>
|
||||
<div class="text-[9px] font-label-caption text-outline">Sector 3 Verified</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- CARD 4: Elevation Altitude -->
|
||||
<div class="bg-surface-container-low border border-outline-variant rounded-xl p-4 space-y-3">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-primary-container" data-icon="landscape">landscape</span>
|
||||
<span class="text-label-data font-label-data uppercase text-on-surface-variant font-bold">Highest Summit</span>
|
||||
</div>
|
||||
<span class="px-2 py-0.5 rounded-full bg-surface-container-high border border-outline text-primary-container text-label-caption font-label-caption font-bold">
|
||||
ALPINE RECON
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex items-baseline justify-between">
|
||||
<div class="flex items-baseline gap-1">
|
||||
<span class="text-telemetry-metric-lg-mobile font-telemetry-metric-lg-mobile text-primary-container">9,624</span>
|
||||
<span class="text-headline-sm font-headline-sm text-on-surface-variant font-bold">FT</span>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<div class="text-label-data font-label-data text-on-surface font-semibold">Tioga Pass Summit</div>
|
||||
<div class="text-label-caption font-label-caption text-outline">Sierra Nevada Range</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center justify-between pt-2 border-t border-outline-variant text-label-caption font-label-caption text-on-surface-variant">
|
||||
<span>Barometric Altimeter Linked</span>
|
||||
<span class="font-label-data text-primary">Baro: 704 hPa</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- CARD 5: Endurance Pack Ride -->
|
||||
<div class="bg-surface-container-low border border-outline-variant rounded-xl p-4 space-y-3">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-primary-container" data-icon="route">route</span>
|
||||
<span class="text-label-data font-label-data uppercase text-on-surface-variant font-bold">Longest Pack Ride</span>
|
||||
</div>
|
||||
<span class="px-2 py-0.5 rounded-full bg-surface-container-high border border-outline text-primary-container text-label-caption font-label-caption font-bold">
|
||||
IRON SADDLE
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex items-baseline justify-between">
|
||||
<div class="flex items-baseline gap-1">
|
||||
<span class="text-telemetry-metric-lg-mobile font-telemetry-metric-lg-mobile text-primary-container">342.8</span>
|
||||
<span class="text-headline-sm font-headline-sm text-on-surface-variant font-bold">MI</span>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<div class="text-label-data font-label-data text-on-surface font-semibold">Pacific Coast Highway (PCH)</div>
|
||||
<div class="text-label-caption font-label-caption text-outline">Duration: 6h 45m</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center justify-between pt-2 border-t border-outline-variant text-label-caption font-label-caption text-on-surface-variant">
|
||||
<span class="flex items-center gap-1">
|
||||
<span class="material-symbols-outlined text-xs" data-icon="groups">groups</span> 14 Bikes in Pack Mesh
|
||||
</span>
|
||||
<span class="font-label-data text-primary-fixed-dim">Zero Pings Dropped</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- CARD 6: Peak Cornering G-Force -->
|
||||
<div class="bg-surface-container-low border border-outline-variant rounded-xl p-4 space-y-3">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-primary-container" data-icon="radar">radar</span>
|
||||
<span class="text-label-data font-label-data uppercase text-on-surface-variant font-bold">Peak Cornering G</span>
|
||||
</div>
|
||||
<span class="px-2 py-0.5 rounded-full bg-surface-container-high border border-outline text-primary-container text-label-caption font-label-caption font-bold">
|
||||
GRAVITY DEFICIT
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex items-baseline justify-between">
|
||||
<div class="flex items-baseline gap-1">
|
||||
<span class="text-telemetry-metric-lg-mobile font-telemetry-metric-lg-mobile text-primary-container">1.24</span>
|
||||
<span class="text-headline-sm font-headline-sm text-on-surface-variant font-bold">G</span>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<div class="text-label-data font-label-data text-on-surface font-semibold">Lateral: +1.18G</div>
|
||||
<div class="text-label-caption font-label-caption text-outline">Latigo Canyon Apex</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center justify-between pt-2 border-t border-outline-variant text-label-caption font-label-caption text-on-surface-variant">
|
||||
<span>Friction Circle Envelope 94%</span>
|
||||
<span class="font-label-data text-primary-container">IMU 6-DOF Fused</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- PRIMARY ACTION BUTTONS (Glove Friendly >48px Target) -->
|
||||
<div class="pt-4 pb-6 space-y-3">
|
||||
<!-- Primary Glove Target Button -->
|
||||
<button class="w-full min-h-[52px] bg-primary-container text-on-primary-container rounded-xl font-label-data font-bold text-body-lg flex items-center justify-center gap-2 shadow-[0_0_16px_rgba(0,229,255,0.4)] active:scale-95 transition-all">
|
||||
<span class="material-symbols-outlined text-xl" data-icon="share">share</span>
|
||||
<span>SHARE TROPHY CABINET</span>
|
||||
</button>
|
||||
<!-- Secondary Certificate Button -->
|
||||
<button class="w-full min-h-[48px] bg-surface-container-low border border-outline-variant hover:border-primary-container text-on-surface rounded-xl font-label-data text-body-md flex items-center justify-center gap-2 hover:bg-surface-container active:scale-95 transition-all">
|
||||
<span class="material-symbols-outlined text-lg text-primary-container" data-icon="file_download">file_download</span>
|
||||
<span>EXPORT 20HZ VERIFIED CERTIFICATE (PDF/PNG)</span>
|
||||
</button>
|
||||
</div>
|
||||
</main>
|
||||
<!-- FIXED BOTTOM DOCK (SHARED COMPONENT BOTTOMNAVBAR) -->
|
||||
<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 dark:bg-surface-container-lowest border-t border-outline-variant dark:border-outline-variant">
|
||||
<!-- Dash Destination (Inactive) -->
|
||||
<a class="flex flex-col items-center justify-center text-on-surface-variant dark:text-on-surface-variant px-2 py-1 min-h-[48px] hover:bg-surface-container-low dark:hover:bg-surface-container-low hover:text-primary-fixed dark:hover:text-primary-fixed active:scale-95 duration-100 ease-out" href="#">
|
||||
<span class="material-symbols-outlined text-2xl" data-icon="speed">speed</span>
|
||||
<span class="text-label-caption font-label-caption mt-0.5">Dash</span>
|
||||
</a>
|
||||
<!-- Map Destination (Inactive) -->
|
||||
<a class="flex flex-col items-center justify-center text-on-surface-variant dark:text-on-surface-variant px-2 py-1 min-h-[48px] hover:bg-surface-container-low dark:hover:bg-surface-container-low hover:text-primary-fixed dark:hover:text-primary-fixed active:scale-95 duration-100 ease-out" href="#">
|
||||
<span class="material-symbols-outlined text-2xl" data-icon="navigation">navigation</span>
|
||||
<span class="text-label-caption font-label-caption mt-0.5">Map</span>
|
||||
</a>
|
||||
<!-- Activity Destination (Active Lock: Telemetry Records Vault) -->
|
||||
<a class="flex flex-col items-center justify-center bg-surface-container-high dark:bg-surface-container-high text-primary-container dark:text-primary-container rounded-lg px-2 py-1 min-h-[48px] active:scale-95 duration-100 ease-out shadow-[0_0_12px_rgba(0,229,255,0.15)]" href="#">
|
||||
<span class="material-symbols-outlined text-2xl font-bold" data-icon="analytics" data-weight="fill" style="font-variation-settings: 'FILL' 1;">analytics</span>
|
||||
<span class="text-label-caption font-label-caption font-bold mt-0.5">Activity</span>
|
||||
</a>
|
||||
<!-- Garage Destination (Inactive) -->
|
||||
<a class="flex flex-col items-center justify-center text-on-surface-variant dark:text-on-surface-variant px-2 py-1 min-h-[48px] hover:bg-surface-container-low dark:hover:bg-surface-container-low hover:text-primary-fixed dark:hover:text-primary-fixed active:scale-95 duration-100 ease-out" href="#">
|
||||
<span class="material-symbols-outlined text-2xl" data-icon="two_wheeler">two_wheeler</span>
|
||||
<span class="text-label-caption font-label-caption mt-0.5">Garage</span>
|
||||
</a>
|
||||
<!-- Settings Destination (Inactive) -->
|
||||
<a class="flex flex-col items-center justify-center text-on-surface-variant dark:text-on-surface-variant px-2 py-1 min-h-[48px] hover:bg-surface-container-low dark:hover:bg-surface-container-low hover:text-primary-fixed dark:hover:text-primary-fixed active:scale-95 duration-100 ease-out" href="#">
|
||||
<span class="material-symbols-outlined text-2xl" data-icon="settings">settings</span>
|
||||
<span class="text-label-caption font-label-caption mt-0.5">Settings</span>
|
||||
</a>
|
||||
</nav>
|
||||
</body></html>
|
||||
|
|
@ -0,0 +1,537 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<html class="dark" lang="en"><head>
|
||||
<meta charset="utf-8"/>
|
||||
<meta content="width=device-width, initial-scale=1.0" name="viewport"/>
|
||||
<title>MotorSignal HUD - Service & Maintenance GAR-03</title>
|
||||
<!-- Material Symbols Outlined -->
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<!-- Fonts: Space Grotesk, JetBrains Mono, Inter -->
|
||||
<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&family=JetBrains+Mono:wght@500;600;700&family=Space+Grotesk:wght@600;700;800&display=swap" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<!-- Tailwind CSS v3 -->
|
||||
<script src="https://cdn.tailwindcss.com?plugins=forms,container-queries"></script>
|
||||
<script id="tailwind-config">
|
||||
tailwind.config = {
|
||||
darkMode: "class",
|
||||
theme: {
|
||||
extend: {
|
||||
"colors": {
|
||||
"on-surface-variant": "#bac9cc",
|
||||
"surface-container-high": "#272a30",
|
||||
"surface-container": "#1d2025",
|
||||
"outline-variant": "#3b494c",
|
||||
"on-surface": "#e0e2ea",
|
||||
"on-background": "#e0e2ea",
|
||||
"on-secondary-fixed": "#00174b",
|
||||
"tertiary-fixed": "#e9ddff",
|
||||
"outline": "#849396",
|
||||
"surface-dim": "#101419",
|
||||
"surface": "#101419",
|
||||
"secondary": "#b4c5ff",
|
||||
"on-secondary": "#002a78",
|
||||
"surface-container-lowest": "#0b0e13",
|
||||
"primary": "#c3f5ff",
|
||||
"surface-bright": "#36393f",
|
||||
"surface-container-highest": "#32353b",
|
||||
"on-primary": "#00363d",
|
||||
"inverse-primary": "#006875",
|
||||
"error-container": "#93000a",
|
||||
"background": "#101419",
|
||||
"secondary-container": "#0053db",
|
||||
"on-secondary-container": "#cdd7ff",
|
||||
"on-tertiary-fixed-variant": "#5516be",
|
||||
"primary-container": "#00e5ff",
|
||||
"tertiary": "#f2e9ff",
|
||||
"surface-container-low": "#181c21",
|
||||
"on-tertiary-container": "#6834d1",
|
||||
"on-primary-fixed": "#001f24",
|
||||
"surface-tint": "#00daf3",
|
||||
"tertiary-container": "#d9c8ff",
|
||||
"tertiary-fixed-dim": "#d0bcff",
|
||||
"inverse-on-surface": "#2d3036",
|
||||
"surface-variant": "#32353b",
|
||||
"on-error-container": "#ffdad6",
|
||||
"on-error": "#690005",
|
||||
"secondary-fixed": "#dbe1ff",
|
||||
"on-tertiary-fixed": "#23005c",
|
||||
"secondary-fixed-dim": "#b4c5ff",
|
||||
"on-tertiary": "#3c0091",
|
||||
"on-primary-container": "#00626e",
|
||||
"inverse-surface": "#e0e2ea",
|
||||
"primary-fixed": "#9cf0ff",
|
||||
"on-primary-fixed-variant": "#004f58",
|
||||
"primary-fixed-dim": "#00daf3",
|
||||
"error": "#ffb4ab",
|
||||
"on-secondary-fixed-variant": "#003ea8"
|
||||
},
|
||||
"borderRadius": {
|
||||
"DEFAULT": "0.25rem",
|
||||
"lg": "0.5rem",
|
||||
"xl": "0.75rem",
|
||||
"full": "9999px"
|
||||
},
|
||||
"spacing": {
|
||||
"space-md": "1rem",
|
||||
"margin": "1rem",
|
||||
"space-xs": "0.25rem",
|
||||
"space-xl": "2rem",
|
||||
"space-lg": "1.5rem",
|
||||
"gutter-lg": "1.5rem",
|
||||
"gutter": "1rem",
|
||||
"space-sm": "0.5rem",
|
||||
"margin-lg": "2rem"
|
||||
},
|
||||
"fontFamily": {
|
||||
"telemetry-metric-lg": ["JetBrains Mono"],
|
||||
"headline-lg": ["Space Grotesk"],
|
||||
"display-hero-mobile": ["Space Grotesk"],
|
||||
"body-lg": ["Inter"],
|
||||
"headline-sm": ["Space Grotesk"],
|
||||
"headline-md": ["Space Grotesk"],
|
||||
"telemetry-metric-md": ["JetBrains Mono"],
|
||||
"telemetry-metric-lg-mobile": ["JetBrains Mono"],
|
||||
"label-caption": ["Inter"],
|
||||
"label-data": ["JetBrains Mono"],
|
||||
"display-hero": ["Space Grotesk"],
|
||||
"body-md": ["Inter"]
|
||||
},
|
||||
"fontSize": {
|
||||
"telemetry-metric-lg": ["48px", { "lineHeight": "48px", "letterSpacing": "-0.04em", "fontWeight": "700" }],
|
||||
"headline-lg": ["32px", { "lineHeight": "40px", "letterSpacing": "-0.02em", "fontWeight": "700" }],
|
||||
"display-hero-mobile": ["40px", { "lineHeight": "44px", "letterSpacing": "-0.02em", "fontWeight": "700" }],
|
||||
"body-lg": ["16px", { "lineHeight": "24px", "fontWeight": "500" }],
|
||||
"headline-sm": ["20px", { "lineHeight": "28px", "fontWeight": "600" }],
|
||||
"headline-md": ["24px", { "lineHeight": "32px", "letterSpacing": "-0.01em", "fontWeight": "600" }],
|
||||
"telemetry-metric-md": ["28px", { "lineHeight": "32px", "letterSpacing": "-0.02em", "fontWeight": "600" }],
|
||||
"telemetry-metric-lg-mobile": ["36px", { "lineHeight": "36px", "letterSpacing": "-0.03em", "fontWeight": "700" }],
|
||||
"label-caption": ["11px", { "lineHeight": "14px", "letterSpacing": "0.05em", "fontWeight": "600" }],
|
||||
"label-data": ["12px", { "lineHeight": "16px", "letterSpacing": "0.08em", "fontWeight": "600" }],
|
||||
"display-hero": ["56px", { "lineHeight": "60px", "letterSpacing": "-0.03em", "fontWeight": "700" }],
|
||||
"body-md": ["14px", { "lineHeight": "20px", "fontWeight": "400" }]
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.material-symbols-outlined {
|
||||
font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
line-height: 1;
|
||||
}
|
||||
/* Subtle neon scanline & grid texture */
|
||||
.telemetry-grid {
|
||||
background-image: linear-gradient(to right, rgba(30, 41, 59, 0.25) 1px, transparent 1px),
|
||||
linear-gradient(to bottom, rgba(30, 41, 59, 0.25) 1px, transparent 1px);
|
||||
background-size: 24px 24px;
|
||||
}
|
||||
.cyan-glow {
|
||||
box-shadow: 0 0 16px rgba(0, 229, 255, 0.25);
|
||||
}
|
||||
.amber-glow {
|
||||
box-shadow: 0 0 16px rgba(245, 158, 11, 0.25);
|
||||
}
|
||||
.cyan-glow-intense {
|
||||
box-shadow: 0 0 20px rgba(0, 229, 255, 0.45);
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
body {
|
||||
min-height: max(884px, 100dvh);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-[#070A0F] text-on-surface antialiased min-h-screen pb-24 font-body-md telemetry-grid selection:bg-primary-container selection:text-surface-container-lowest">
|
||||
<!-- TOP APP BAR / HEADER (Shared Component Anchor) -->
|
||||
<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 gap-space-sm">
|
||||
<button aria-label="Navigate Back" class="w-10 h-10 flex items-center justify-center rounded-lg text-primary-container hover:bg-surface-container active:scale-95 duration-100 ease-out" type="button">
|
||||
<span class="material-symbols-outlined text-[20px]" data-icon="sensors">sensors</span>
|
||||
</button>
|
||||
<span class="text-headline-sm font-headline-sm font-bold tracking-wider text-primary-container">MOTORSIGNAL HUD</span>
|
||||
</div>
|
||||
<!-- Real-time HUD Telemetry Badges -->
|
||||
<div class="flex items-center gap-2">
|
||||
<div class="flex items-center gap-1.5 px-2 py-0.5 rounded bg-surface-container border border-outline-variant">
|
||||
<span class="inline-block w-1.5 h-1.5 rounded-full bg-primary-container animate-pulse"></span>
|
||||
<span class="font-label-data text-label-data text-on-surface-variant">20Hz GNSS</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-1 px-2 py-0.5 rounded bg-surface-container border border-outline-variant">
|
||||
<span class="material-symbols-outlined text-primary-container text-[14px]" data-icon="bolt">bolt</span>
|
||||
<span class="font-label-data text-label-data text-on-surface">98%</span>
|
||||
</div>
|
||||
<button aria-label="Warning status" class="w-10 h-10 flex items-center justify-center text-on-surface-variant hover:text-primary-container active:scale-95 duration-100 ease-out" type="button">
|
||||
<span class="material-symbols-outlined text-[20px]" data-icon="warning">warning</span>
|
||||
</button>
|
||||
</div>
|
||||
</header>
|
||||
<!-- MAIN VIEWPORT CONTAINER (Tactical Mobile Cockpit Layout) -->
|
||||
<main class="pt-16 px-gutter max-w-md mx-auto space-y-space-md">
|
||||
<!-- SUB-NAV / SCREEN BREADCRUMB -->
|
||||
<section class="mt-2 flex items-center justify-between">
|
||||
<div>
|
||||
<div class="flex items-center gap-1.5">
|
||||
<span class="px-1.5 py-0.5 bg-surface-container-high border border-outline-variant text-[10px] font-label-data text-primary-container tracking-widest rounded">GAR-03 • TELEMETRY LOG</span>
|
||||
<span class="flex items-center gap-1 text-label-caption font-label-caption text-on-surface-variant">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-[#10B981]"></span>
|
||||
SYNCED
|
||||
</span>
|
||||
</div>
|
||||
<h1 class="text-headline-md font-headline-md tracking-tight text-on-surface mt-1">SERVICE & MAINTENANCE</h1>
|
||||
</div>
|
||||
<button aria-label="Refresh Data" class="w-12 h-12 flex items-center justify-center rounded-lg bg-surface-container border border-outline-variant text-on-surface-variant hover:border-primary-container hover:text-primary-container active:scale-95 transition-all" type="button">
|
||||
<span class="material-symbols-outlined text-[22px]" data-icon="sync">sync</span>
|
||||
</button>
|
||||
</section>
|
||||
<!-- ACTIVE BIKE HEADER CARD (Level 2 Elevation) -->
|
||||
<section class="bg-[#0D131F] rounded-xl border border-[#1E293B] p-space-md cyan-glow relative overflow-hidden">
|
||||
<!-- Glow Accent Line -->
|
||||
<div class="absolute top-0 left-0 right-0 h-[2px] bg-gradient-to-r from-transparent via-primary-container to-transparent opacity-80"></div>
|
||||
<div class="flex items-start justify-between">
|
||||
<div>
|
||||
<div class="inline-flex items-center gap-1.5 px-2 py-0.5 rounded-full bg-[rgba(0,229,255,0.12)] border border-primary-container text-primary-container font-label-caption text-[10px] tracking-widest uppercase mb-1">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-primary-container"></span>
|
||||
ACTIVE BIKE
|
||||
</div>
|
||||
<h2 class="text-headline-sm font-headline-sm text-on-surface tracking-tight">2024 Ducati Panigale V4 S</h2>
|
||||
<p class="text-label-data font-label-data text-outline text-[11px] tracking-wider mt-0.5">VIN: ZDM14BKW7PB003921</p>
|
||||
</div>
|
||||
<!-- Switch Bike Action -->
|
||||
<button aria-label="Switch Bike" class="min-h-[48px] min-w-[48px] flex items-center justify-center rounded-lg bg-surface-container-high border border-outline-variant text-on-surface hover:text-primary-container hover:border-primary-container active:scale-95 transition-all" type="button">
|
||||
<span class="material-symbols-outlined text-[20px]" data-icon="two_wheeler">two_wheeler</span>
|
||||
</button>
|
||||
</div>
|
||||
<!-- Quick Telemetry Chips (2x2 Tactical Bento) -->
|
||||
<div class="grid grid-cols-2 gap-2 mt-space-md pt-space-sm border-t border-outline-variant">
|
||||
<div class="p-2.5 rounded-lg bg-[#070A0F] border border-outline-variant">
|
||||
<div class="text-label-caption font-label-caption text-outline uppercase tracking-wider">Odometer</div>
|
||||
<div class="flex items-baseline gap-1 mt-0.5">
|
||||
<span class="text-telemetry-metric-md font-telemetry-metric-md text-primary tracking-tight">6,428</span>
|
||||
<span class="text-label-caption font-label-caption text-on-surface-variant font-bold">MI</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="p-2.5 rounded-lg bg-[#070A0F] border border-outline-variant">
|
||||
<div class="text-label-caption font-label-caption text-outline uppercase tracking-wider">Engine Run-Time</div>
|
||||
<div class="flex items-baseline gap-1 mt-0.5">
|
||||
<span class="text-telemetry-metric-md font-telemetry-metric-md text-on-surface tracking-tight">142.4</span>
|
||||
<span class="text-label-caption font-label-caption text-on-surface-variant font-bold">HRS</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="p-2 rounded-lg bg-[#070A0F] border border-outline-variant col-span-2 flex items-center justify-between">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-primary-container text-[18px]" data-icon="cable">cable</span>
|
||||
<span class="text-label-data font-label-data text-[11px] text-on-surface-variant">CAN-Bus Telemetry Stream</span>
|
||||
</div>
|
||||
<span class="inline-flex items-center gap-1 font-label-data text-label-data text-primary-container text-[11px]">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-primary-container animate-ping"></span>
|
||||
CONNECTED (50Hz)
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- MAINTENANCE HEALTH MONITOR (Diagnostic Matrix) -->
|
||||
<section class="space-y-space-sm">
|
||||
<div class="flex items-center justify-between px-1">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-primary-container text-[20px]" data-icon="monitor_heart">monitor_heart</span>
|
||||
<h2 class="text-headline-sm font-headline-sm text-on-surface">DIAGNOSTIC MATRIX</h2>
|
||||
</div>
|
||||
<span class="text-[10px] font-label-data text-outline">UPDATED 10S AGO</span>
|
||||
</div>
|
||||
<!-- Overall Index Score Banner -->
|
||||
<div class="p-3 rounded-lg bg-[rgba(245,158,11,0.1)] border border-[#F59E0B] amber-glow flex items-center justify-between">
|
||||
<div class="flex items-center gap-2.5">
|
||||
<span class="material-symbols-outlined text-[#F59E0B] text-[24px]" data-icon="warning">warning</span>
|
||||
<div>
|
||||
<div class="text-label-data font-label-data text-on-surface font-bold text-[12px] tracking-wide">88% OPERATIONAL</div>
|
||||
<div class="text-label-caption font-label-caption text-[#F59E0B]">1 SERVICE WARNING DETECTED</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<span class="text-telemetry-metric-md font-telemetry-metric-md text-[#F59E0B]">88</span>
|
||||
<span class="text-label-caption font-label-caption text-[#F59E0B]">/100</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Item 1: Engine Oil & Filter (Amber Alert) -->
|
||||
<div class="bg-[#0D131F] rounded-xl border border-outline-variant p-space-md space-y-2.5">
|
||||
<div class="flex items-start justify-between">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-[#F59E0B] text-[22px]" data-icon="oil_barrel">oil_barrel</span>
|
||||
<div>
|
||||
<h3 class="text-body-lg font-body-lg text-on-surface font-semibold">Engine Oil & Filter</h3>
|
||||
<p class="text-label-caption font-label-caption text-outline">Motul 300V Factory Line 15W-50</p>
|
||||
</div>
|
||||
</div>
|
||||
<span class="px-2 py-0.5 rounded bg-[rgba(245,158,11,0.15)] border border-[#F59E0B] text-[#F59E0B] font-label-data text-[11px] tracking-wider font-bold">
|
||||
DUE IN 380 MI
|
||||
</span>
|
||||
</div>
|
||||
<!-- Progress Gauge -->
|
||||
<div class="space-y-1">
|
||||
<div class="w-full h-2.5 bg-[#070A0F] rounded-full overflow-hidden border border-outline-variant">
|
||||
<div class="h-full bg-gradient-to-r from-primary-container to-[#F59E0B] rounded-full" style="width: 88%;"></div>
|
||||
</div>
|
||||
<div class="flex justify-between text-[11px] font-label-data text-outline">
|
||||
<span>Interval: 3,750 mi</span>
|
||||
<span class="text-[#F59E0B]">88% elapsed (3,370 mi logged)</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Item 2: Chain Tension & Lube (OK) -->
|
||||
<div class="bg-[#0D131F] rounded-xl border border-outline-variant p-space-md space-y-2.5">
|
||||
<div class="flex items-start justify-between">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-[#10B981] text-[22px]" data-icon="link">link</span>
|
||||
<div>
|
||||
<h3 class="text-body-lg font-body-lg text-on-surface font-semibold">Chain Tension & Lube</h3>
|
||||
<p class="text-label-caption font-label-caption text-outline">Target Slack: 28-30mm • Motul Chain Paste</p>
|
||||
</div>
|
||||
</div>
|
||||
<span class="px-2 py-0.5 rounded bg-[rgba(16,185,129,0.15)] border border-[#10B981] text-[#10B981] font-label-data text-[11px] tracking-wider font-bold">
|
||||
OK (450 MI REM)
|
||||
</span>
|
||||
</div>
|
||||
<!-- Progress Gauge -->
|
||||
<div class="space-y-1">
|
||||
<div class="w-full h-2.5 bg-[#070A0F] rounded-full overflow-hidden border border-outline-variant">
|
||||
<div class="h-full bg-[#10B981] rounded-full" style="width: 55%;"></div>
|
||||
</div>
|
||||
<div class="flex justify-between text-[11px] font-label-data text-outline">
|
||||
<span>Interval: 1,000 mi</span>
|
||||
<span class="text-on-surface-variant">Slack: 29.2mm (Nominal)</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Item 3: Brake Fluid (Brembo Racing DOT 4) -->
|
||||
<div class="bg-[#0D131F] rounded-xl border border-outline-variant p-space-md">
|
||||
<div class="flex items-start justify-between">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-[#10B981] text-[22px]" data-icon="water_drop">water_drop</span>
|
||||
<div>
|
||||
<h3 class="text-body-lg font-body-lg text-on-surface font-semibold">Brembo Racing DOT 4 Fluid</h3>
|
||||
<p class="text-label-caption font-label-caption text-outline">Dry BP: 310°C • Wet BP: 195°C</p>
|
||||
</div>
|
||||
</div>
|
||||
<span class="px-2 py-0.5 rounded bg-[rgba(16,185,129,0.15)] border border-[#10B981] text-[#10B981] font-label-data text-[11px] tracking-wider font-bold">
|
||||
GOOD (240 DAYS)
|
||||
</span>
|
||||
</div>
|
||||
<div class="grid grid-cols-2 gap-2 mt-3 pt-2 border-t border-outline-variant text-[11px] font-label-data">
|
||||
<div class="flex justify-between p-1.5 rounded bg-[#070A0F]">
|
||||
<span class="text-outline">Moisture Level:</span>
|
||||
<span class="text-[#10B981] font-bold">0.8% (<2.0%)</span>
|
||||
</div>
|
||||
<div class="flex justify-between p-1.5 rounded bg-[#070A0F]">
|
||||
<span class="text-outline">Caliper Temp Max:</span>
|
||||
<span class="text-on-surface font-bold">148°C</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Item 4: Tire Tread Life & Pressures (Dual Axle Telemetry Card) -->
|
||||
<div class="bg-[#0D131F] rounded-xl border border-outline-variant p-space-md space-y-3">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-primary-container text-[22px]" data-icon="tire_repair">tire_repair</span>
|
||||
<h3 class="text-body-lg font-body-lg text-on-surface font-semibold">Tire Telemetry & Compounds</h3>
|
||||
</div>
|
||||
<span class="text-label-caption font-label-caption text-outline">TPMS 20Hz</span>
|
||||
</div>
|
||||
<!-- Front Tire -->
|
||||
<div class="p-2.5 rounded-lg bg-[#070A0F] border border-outline-variant space-y-2">
|
||||
<div class="flex justify-between items-start">
|
||||
<div>
|
||||
<span class="text-label-data font-label-data text-primary-container text-[11px] font-bold">FRONT AXLE</span>
|
||||
<div class="text-[12px] font-body-md text-on-surface">Pirelli Supercorsa SC3 120/70 ZR17</div>
|
||||
</div>
|
||||
<span class="px-1.5 py-0.5 rounded bg-[rgba(16,185,129,0.15)] border border-[#10B981] text-[#10B981] font-label-data text-[10px]">
|
||||
OPTIMAL
|
||||
</span>
|
||||
</div>
|
||||
<div class="grid grid-cols-2 gap-2 text-label-data text-[11px]">
|
||||
<div>
|
||||
<div class="text-outline text-[10px]">COLD PRESSURE</div>
|
||||
<div class="flex items-baseline gap-1">
|
||||
<span class="text-telemetry-metric-md font-telemetry-metric-md text-on-surface text-[18px]">32.0</span>
|
||||
<span class="text-outline text-[10px]">PSI</span>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="text-outline text-[10px]">TREAD REMAINING</div>
|
||||
<div class="flex items-baseline gap-1">
|
||||
<span class="text-telemetry-metric-md font-telemetry-metric-md text-[#10B981] text-[18px]">68%</span>
|
||||
<span class="text-outline text-[10px]">(3.4mm)</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Rear Tire -->
|
||||
<div class="p-2.5 rounded-lg bg-[#070A0F] border border-outline-variant space-y-2">
|
||||
<div class="flex justify-between items-start">
|
||||
<div>
|
||||
<span class="text-label-data font-label-data text-[#F59E0B] text-[11px] font-bold">REAR AXLE</span>
|
||||
<div class="text-[12px] font-body-md text-on-surface">Pirelli Supercorsa SC3 200/60 ZR17</div>
|
||||
</div>
|
||||
<span class="px-1.5 py-0.5 rounded bg-[rgba(245,158,11,0.2)] border border-[#F59E0B] text-[#F59E0B] font-label-data text-[10px]">
|
||||
MODERATE WEAR
|
||||
</span>
|
||||
</div>
|
||||
<div class="grid grid-cols-2 gap-2 text-label-data text-[11px]">
|
||||
<div>
|
||||
<div class="text-outline text-[10px]">COLD PRESSURE</div>
|
||||
<div class="flex items-baseline gap-1">
|
||||
<span class="text-telemetry-metric-md font-telemetry-metric-md text-on-surface text-[18px]">26.5</span>
|
||||
<span class="text-outline text-[10px]">PSI</span>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="text-outline text-[10px]">TREAD (APEX MONITORED)</div>
|
||||
<div class="flex items-baseline gap-1">
|
||||
<span class="text-telemetry-metric-md font-telemetry-metric-md text-[#F59E0B] text-[18px]">42%</span>
|
||||
<span class="text-outline text-[10px]">(2.1mm)</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- PROMINENT ACTION BUTTONS (Glove-Friendly Min 48px/52px Touch Zone) -->
|
||||
<section class="space-y-2 pt-2">
|
||||
<!-- Primary: Log Service Record -->
|
||||
<button class="w-full min-h-[52px] px-space-md rounded-xl bg-primary-container text-surface-container-lowest font-telemetry-metric-md font-bold tracking-wider flex items-center justify-center gap-2 cyan-glow-intense hover:bg-surface-tint active:scale-[0.98] transition-all" type="button">
|
||||
<span class="material-symbols-outlined text-[24px]" data-icon="add_circle">add_circle</span>
|
||||
<span>+ LOG SERVICE RECORD</span>
|
||||
</button>
|
||||
<!-- Secondary: Export PDF -->
|
||||
<button class="w-full min-h-[48px] px-space-md rounded-xl bg-[#0D131F] border border-outline-variant text-on-surface font-body-lg font-semibold flex items-center justify-center gap-2 hover:border-primary-container hover:text-primary-container active:scale-[0.98] transition-all" type="button">
|
||||
<span class="material-symbols-outlined text-[20px]" data-icon="description">description</span>
|
||||
<span>EXPORT MAINTENANCE PDF</span>
|
||||
</button>
|
||||
</section>
|
||||
<!-- SERVICE & MAINTENANCE HISTORY LOG -->
|
||||
<section class="space-y-space-sm pt-2">
|
||||
<div class="flex items-center justify-between px-1">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-primary-container text-[20px]" data-icon="history">history</span>
|
||||
<h2 class="text-headline-sm font-headline-sm text-on-surface">TELEMETRY LOGS</h2>
|
||||
</div>
|
||||
<span class="text-label-caption font-label-caption text-primary-container font-semibold">VIEW ALL (14)</span>
|
||||
</div>
|
||||
<!-- History Entries Stack -->
|
||||
<div class="space-y-2.5">
|
||||
<!-- Entry 1: Desmo Service -->
|
||||
<article class="p-space-md rounded-xl bg-[#0D131F] border border-outline-variant space-y-2 hover:border-primary-container transition-colors">
|
||||
<div class="flex justify-between items-start">
|
||||
<span class="font-body-lg font-body-lg text-on-surface font-semibold text-[15px]">5,000 MI Scheduled Desmo Inspection</span>
|
||||
<span class="font-telemetry-metric-md text-primary font-bold text-[14px]">$420.00</span>
|
||||
</div>
|
||||
<div class="flex flex-wrap items-center gap-x-3 gap-y-1 text-label-data text-[11px] text-outline">
|
||||
<span class="flex items-center gap-1">
|
||||
<span class="material-symbols-outlined text-[14px]" data-icon="calendar_today">calendar_today</span>
|
||||
Aug 18, 2024
|
||||
</span>
|
||||
<span class="flex items-center gap-1">
|
||||
<span class="material-symbols-outlined text-[14px]" data-icon="speed">speed</span>
|
||||
5,020 MI
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between pt-2 border-t border-outline-variant text-[11px] font-label-caption">
|
||||
<span class="text-on-surface-variant flex items-center gap-1">
|
||||
<span class="material-symbols-outlined text-[14px] text-primary-container" data-icon="storefront">storefront</span>
|
||||
Peninsula Moto Works
|
||||
</span>
|
||||
<span class="px-1.5 py-0.5 rounded bg-[rgba(0,229,255,0.1)] text-primary-container border border-primary-container font-label-data flex items-center gap-1 text-[10px]">
|
||||
<span class="material-symbols-outlined text-[12px]" data-icon="verified">verified</span>
|
||||
CAN-BUS VERIFIED
|
||||
</span>
|
||||
</div>
|
||||
</article>
|
||||
<!-- Entry 2: Oil & Filter -->
|
||||
<article class="p-space-md rounded-xl bg-[#0D131F] border border-outline-variant space-y-2 hover:border-primary-container transition-colors">
|
||||
<div class="flex justify-between items-start">
|
||||
<span class="font-body-lg font-body-lg text-on-surface font-semibold text-[15px]">Oil & Filter Replacement (Motul 300V)</span>
|
||||
<span class="font-telemetry-metric-md text-on-surface font-bold text-[14px]">$84.50</span>
|
||||
</div>
|
||||
<div class="flex flex-wrap items-center gap-x-3 gap-y-1 text-label-data text-[11px] text-outline">
|
||||
<span class="flex items-center gap-1">
|
||||
<span class="material-symbols-outlined text-[14px]" data-icon="calendar_today">calendar_today</span>
|
||||
Jun 02, 2024
|
||||
</span>
|
||||
<span class="flex items-center gap-1">
|
||||
<span class="material-symbols-outlined text-[14px]" data-icon="speed">speed</span>
|
||||
3,058 MI
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between pt-2 border-t border-outline-variant text-[11px] font-label-caption">
|
||||
<span class="text-on-surface-variant flex items-center gap-1">
|
||||
<span class="material-symbols-outlined text-[14px] text-outline" data-icon="person">person</span>
|
||||
Owner (@AlexMercer)
|
||||
</span>
|
||||
<span class="px-1.5 py-0.5 rounded bg-surface-container border border-outline text-outline font-label-data text-[10px]">
|
||||
SELF-CERTIFIED
|
||||
</span>
|
||||
</div>
|
||||
</article>
|
||||
<!-- Entry 3: Trackside Tires -->
|
||||
<article class="p-space-md rounded-xl bg-[#0D131F] border border-outline-variant space-y-2 hover:border-primary-container transition-colors">
|
||||
<div class="flex justify-between items-start">
|
||||
<span class="font-body-lg font-body-lg text-on-surface font-semibold text-[15px]">New Tires: Pirelli Diablo Supercorsa SC3</span>
|
||||
<span class="font-telemetry-metric-md text-on-surface font-bold text-[14px]">$560.00</span>
|
||||
</div>
|
||||
<div class="flex flex-wrap items-center gap-x-3 gap-y-1 text-label-data text-[11px] text-outline">
|
||||
<span class="flex items-center gap-1">
|
||||
<span class="material-symbols-outlined text-[14px]" data-icon="calendar_today">calendar_today</span>
|
||||
Apr 14, 2024
|
||||
</span>
|
||||
<span class="flex items-center gap-1">
|
||||
<span class="material-symbols-outlined text-[14px]" data-icon="speed">speed</span>
|
||||
1,840 MI
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between pt-2 border-t border-outline-variant text-[11px] font-label-caption">
|
||||
<span class="text-on-surface-variant flex items-center gap-1">
|
||||
<span class="material-symbols-outlined text-[14px] text-primary-container" data-icon="sports_motorsports">sports_motorsports</span>
|
||||
Trackside Service (Laguna Seca)
|
||||
</span>
|
||||
<span class="px-1.5 py-0.5 rounded bg-[rgba(0,229,255,0.1)] text-primary-container border border-primary-container font-label-data flex items-center gap-1 text-[10px]">
|
||||
<span class="material-symbols-outlined text-[12px]" data-icon="verified">verified</span>
|
||||
PRO VERIFIED
|
||||
</span>
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
<!-- BOTTOM NAVIGATION BAR (Shared Component Anchor) -->
|
||||
<!-- Contextual State: 'Garage' is 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">
|
||||
<!-- Item 1: Dash -->
|
||||
<a class="flex flex-col items-center justify-center text-on-surface-variant px-2 py-1 min-h-[48px] hover:bg-surface-container-low hover:text-primary-fixed active:scale-95 duration-100 ease-out" href="#">
|
||||
<span class="material-symbols-outlined text-[24px]" data-icon="speed">speed</span>
|
||||
<span class="text-label-caption font-label-caption mt-0.5">Dash</span>
|
||||
</a>
|
||||
<!-- Item 2: Map -->
|
||||
<a class="flex flex-col items-center justify-center text-on-surface-variant px-2 py-1 min-h-[48px] hover:bg-surface-container-low hover:text-primary-fixed active:scale-95 duration-100 ease-out" href="#">
|
||||
<span class="material-symbols-outlined text-[24px]" data-icon="navigation">navigation</span>
|
||||
<span class="text-label-caption font-label-caption mt-0.5">Map</span>
|
||||
</a>
|
||||
<!-- Item 3: Activity -->
|
||||
<a class="flex flex-col items-center justify-center text-on-surface-variant px-2 py-1 min-h-[48px] hover:bg-surface-container-low hover:text-primary-fixed active:scale-95 duration-100 ease-out" href="#">
|
||||
<span class="material-symbols-outlined text-[24px]" data-icon="analytics">analytics</span>
|
||||
<span class="text-label-caption font-label-caption mt-0.5">Activity</span>
|
||||
</a>
|
||||
<!-- Item 4: Garage (MANDATORY ACTIVE STATE MATCH) -->
|
||||
<a class="flex flex-col items-center justify-center bg-surface-container-high text-primary-container rounded-lg px-2 py-1 min-h-[48px] active:scale-95 duration-100 ease-out" href="#">
|
||||
<span class="material-symbols-outlined text-[24px]" data-icon="two_wheeler" data-weight="fill" style="font-variation-settings: 'FILL' 1;">two_wheeler</span>
|
||||
<span class="text-label-caption font-label-caption font-bold mt-0.5">Garage</span>
|
||||
</a>
|
||||
<!-- Item 5: Settings -->
|
||||
<a class="flex flex-col items-center justify-center text-on-surface-variant px-2 py-1 min-h-[48px] hover:bg-surface-container-low hover:text-primary-fixed active:scale-95 duration-100 ease-out" href="#">
|
||||
<span class="material-symbols-outlined text-[24px]" data-icon="settings">settings</span>
|
||||
<span class="text-label-caption font-label-caption mt-0.5">Settings</span>
|
||||
</a>
|
||||
</nav>
|
||||
</body></html>
|
||||
|
|
@ -0,0 +1,558 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<html class="dark" lang="en"><head>
|
||||
<meta charset="utf-8"/>
|
||||
<meta content="width=device-width, initial-scale=1.0" name="viewport"/>
|
||||
<title>MotorSignal HUD - ROUT-02 Cue Sheet</title>
|
||||
<!-- Material Symbols Outlined -->
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<!-- Google Fonts: Space Grotesk, JetBrains Mono, Inter -->
|
||||
<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&family=JetBrains+Mono:wght@400;500;600;700&family=Space+Grotesk:wght@500;600;700&display=swap" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<!-- Tailwind CSS with Forms & Container Queries -->
|
||||
<script src="https://cdn.tailwindcss.com?plugins=forms,container-queries"></script>
|
||||
<script id="tailwind-config">
|
||||
tailwind.config = {
|
||||
darkMode: "class",
|
||||
theme: {
|
||||
extend: {
|
||||
"colors": {
|
||||
"error-container": "#93000a",
|
||||
"on-tertiary-fixed": "#23005c",
|
||||
"inverse-on-surface": "#2d3036",
|
||||
"surface-container-lowest": "#0b0e13",
|
||||
"on-secondary-container": "#cdd7ff",
|
||||
"on-primary-fixed-variant": "#004f58",
|
||||
"on-tertiary-fixed-variant": "#5516be",
|
||||
"primary-fixed-dim": "#00daf3",
|
||||
"on-tertiary-container": "#6834d1",
|
||||
"on-error-container": "#ffdad6",
|
||||
"background": "#101419",
|
||||
"primary-fixed": "#9cf0ff",
|
||||
"surface-bright": "#36393f",
|
||||
"tertiary-container": "#d9c8ff",
|
||||
"surface": "#101419",
|
||||
"surface-container-highest": "#32353b",
|
||||
"on-secondary-fixed": "#00174b",
|
||||
"surface-variant": "#32353b",
|
||||
"on-primary": "#00363d",
|
||||
"error": "#ffb4ab",
|
||||
"surface-dim": "#101419",
|
||||
"inverse-surface": "#e0e2ea",
|
||||
"surface-container": "#1d2025",
|
||||
"primary-container": "#00e5ff",
|
||||
"secondary-container": "#0053db",
|
||||
"secondary-fixed": "#dbe1ff",
|
||||
"on-surface-variant": "#bac9cc",
|
||||
"on-secondary-fixed-variant": "#003ea8",
|
||||
"primary": "#c3f5ff",
|
||||
"outline-variant": "#3b494c",
|
||||
"on-tertiary": "#3c0091",
|
||||
"secondary-fixed-dim": "#b4c5ff",
|
||||
"outline": "#849396",
|
||||
"inverse-primary": "#006875",
|
||||
"surface-container-high": "#272a30",
|
||||
"on-primary-fixed": "#001f24",
|
||||
"on-surface": "#e0e2ea",
|
||||
"tertiary-fixed-dim": "#d0bcff",
|
||||
"tertiary-fixed": "#e9ddff",
|
||||
"tertiary": "#f2e9ff",
|
||||
"surface-container-low": "#181c21",
|
||||
"on-secondary": "#002a78",
|
||||
"on-background": "#e0e2ea",
|
||||
"on-error": "#690005",
|
||||
"secondary": "#b4c5ff",
|
||||
"surface-tint": "#00daf3",
|
||||
"on-primary-container": "#00626e"
|
||||
},
|
||||
"borderRadius": {
|
||||
"DEFAULT": "0.25rem",
|
||||
"lg": "0.5rem",
|
||||
"xl": "0.75rem",
|
||||
"full": "9999px"
|
||||
},
|
||||
"spacing": {
|
||||
"space-md": "1rem",
|
||||
"space-lg": "1.5rem",
|
||||
"space-sm": "0.5rem",
|
||||
"gutter-lg": "1.5rem",
|
||||
"space-xl": "2rem",
|
||||
"gutter": "1rem",
|
||||
"space-xs": "0.25rem",
|
||||
"margin": "1rem",
|
||||
"margin-lg": "2rem"
|
||||
},
|
||||
"fontFamily": {
|
||||
"body-md": ["Inter"],
|
||||
"display-hero": ["Space Grotesk"],
|
||||
"telemetry-metric-lg": ["JetBrains Mono"],
|
||||
"headline-md": ["Space Grotesk"],
|
||||
"headline-lg": ["Space Grotesk"],
|
||||
"telemetry-metric-md": ["JetBrains Mono"],
|
||||
"display-hero-mobile": ["Space Grotesk"],
|
||||
"telemetry-metric-lg-mobile": ["JetBrains Mono"],
|
||||
"headline-sm": ["Space Grotesk"],
|
||||
"body-lg": ["Inter"],
|
||||
"label-data": ["JetBrains Mono"],
|
||||
"label-caption": ["Inter"]
|
||||
},
|
||||
"fontSize": {
|
||||
"body-md": ["14px", { "lineHeight": "20px", "fontWeight": "400" }],
|
||||
"display-hero": ["56px", { "lineHeight": "60px", "letterSpacing": "-0.03em", "fontWeight": "700" }],
|
||||
"telemetry-metric-lg": ["48px", { "lineHeight": "48px", "letterSpacing": "-0.04em", "fontWeight": "700" }],
|
||||
"headline-md": ["24px", { "lineHeight": "32px", "letterSpacing": "-0.01em", "fontWeight": "600" }],
|
||||
"headline-lg": ["32px", { "lineHeight": "40px", "letterSpacing": "-0.02em", "fontWeight": "700" }],
|
||||
"telemetry-metric-md": ["28px", { "lineHeight": "32px", "letterSpacing": "-0.02em", "fontWeight": "600" }],
|
||||
"display-hero-mobile": ["40px", { "lineHeight": "44px", "letterSpacing": "-0.02em", "fontWeight": "700" }],
|
||||
"telemetry-metric-lg-mobile": ["36px", { "lineHeight": "36px", "letterSpacing": "-0.03em", "fontWeight": "700" }],
|
||||
"headline-sm": ["20px", { "lineHeight": "28px", "fontWeight": "600" }],
|
||||
"body-lg": ["16px", { "lineHeight": "24px", "fontWeight": "500" }],
|
||||
"label-data": ["12px", { "lineHeight": "16px", "letterSpacing": "0.08em", "fontWeight": "600" }],
|
||||
"label-caption": ["11px", { "lineHeight": "14px", "letterSpacing": "0.05em", "fontWeight": "600" }]
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.material-symbols-outlined {
|
||||
font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
line-height: 1;
|
||||
}
|
||||
/* Subtle neon scanline & grid glow backdrop */
|
||||
.hud-grid-pattern {
|
||||
background-size: 32px 32px;
|
||||
background-image:
|
||||
linear-gradient(to right, rgba(59, 73, 76, 0.15) 1px, transparent 1px),
|
||||
linear-gradient(to bottom, rgba(59, 73, 76, 0.15) 1px, transparent 1px);
|
||||
}
|
||||
.neon-cyan-glow {
|
||||
box-shadow: 0 0 16px rgba(0, 229, 255, 0.35);
|
||||
}
|
||||
.neon-cyan-glow-subtle {
|
||||
box-shadow: 0 0 12px rgba(0, 229, 255, 0.15);
|
||||
}
|
||||
.no-scrollbar::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
.no-scrollbar {
|
||||
-ms-overflow-style: none;
|
||||
scrollbar-width: none;
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
body {
|
||||
min-height: max(884px, 100dvh);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-surface text-on-surface antialiased selection:bg-primary-container selection:text-surface-container-lowest min-h-screen pb-36">
|
||||
<!-- TOP APP BAR (from Shared Components JSON: TopAppBar) -->
|
||||
<header class="fixed top-0 left-0 w-full z-50 flex justify-between items-center px-gutter h-14 bg-surface-container-lowest dark:bg-surface-container-lowest border-b border-outline-variant dark:border-outline-variant">
|
||||
<div class="flex items-center gap-space-sm">
|
||||
<button aria-label="Back" class="w-12 h-12 flex items-center justify-center rounded-lg text-on-surface-variant hover:text-primary-container hover:bg-surface-container active:scale-95 duration-100 ease-out" type="button">
|
||||
<span class="material-symbols-outlined" data-icon="arrow_back">arrow_back</span>
|
||||
</button>
|
||||
<div class="flex items-center gap-1.5">
|
||||
<span class="material-symbols-outlined text-primary-container text-headline-sm" data-icon="sensors">sensors</span>
|
||||
<span class="text-headline-sm font-headline-sm font-bold tracking-wider text-primary-container dark:text-primary-container">MOTORSIGNAL HUD</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- System Telemetry Status (GPS 20Hz / Battery / Warning) -->
|
||||
<div class="flex items-center gap-space-sm">
|
||||
<div class="hidden sm:flex items-center gap-1 bg-surface-container-low px-2 py-1 rounded border border-outline-variant">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-primary-container animate-ping"></span>
|
||||
<span class="font-label-data text-label-data text-primary-container">20Hz KALMAN</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-1 text-on-surface-variant px-1">
|
||||
<span class="material-symbols-outlined text-sm text-primary-container" data-icon="battery_charging_full">battery_charging_full</span>
|
||||
<span class="font-label-data text-label-data text-on-surface-variant">98%</span>
|
||||
</div>
|
||||
<button aria-label="Route Advisory Warning" class="w-10 h-10 flex items-center justify-center rounded text-primary-container hover:bg-surface-container active:scale-95 duration-100 ease-out" type="button">
|
||||
<span class="material-symbols-outlined" data-icon="warning">warning</span>
|
||||
</button>
|
||||
</div>
|
||||
</header>
|
||||
<!-- MAIN VIEWPORT CONTAINER -->
|
||||
<main class="pt-16 px-gutter max-w-3xl mx-auto space-y-space-md">
|
||||
<!-- SUB-HEADER / BREADCRUMB & VERIFICATION BADGE -->
|
||||
<div class="flex items-center justify-between pt-2">
|
||||
<div class="flex items-center gap-1.5 text-outline">
|
||||
<span class="material-symbols-outlined text-sm text-primary-container" data-icon="alt_route">alt_route</span>
|
||||
<span class="font-label-data text-label-data tracking-wider text-primary-container">ROUT-02 // CUE SHEET & APEX NAV</span>
|
||||
</div>
|
||||
<span class="inline-flex items-center gap-1 px-2.5 py-1 rounded-full bg-surface-container-high border border-primary-container/40 text-primary-container font-label-data text-label-caption tracking-wider uppercase">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-primary-container"></span>
|
||||
VERIFIED ROUTE
|
||||
</span>
|
||||
</div>
|
||||
<!-- ROUTE TITLE & DESCRIPTION BANNER -->
|
||||
<div class="bg-surface-container-low border border-outline-variant rounded-xl p-space-md hud-grid-pattern relative overflow-hidden">
|
||||
<div class="absolute -right-12 -top-12 w-36 h-36 bg-primary-container/5 rounded-full blur-2xl pointer-events-none"></div>
|
||||
<div class="flex flex-col gap-1">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="font-label-data text-label-caption text-outline uppercase tracking-widest">Waypoint Sector: NorCal Ridge</span>
|
||||
<span class="text-outline">•</span>
|
||||
<span class="font-label-data text-label-caption text-primary-container font-semibold">CADENCE PACED</span>
|
||||
</div>
|
||||
<h1 class="font-headline-lg-mobile sm:font-headline-lg text-headline-lg-mobile sm:text-headline-lg text-on-surface tracking-tight">
|
||||
Skyline to Santa Cruz Coastal Arc
|
||||
</h1>
|
||||
<p class="font-body-md text-body-md text-on-surface-variant mt-1">
|
||||
High-cadence mountain crest transit descending from dense redwoods into open Pacific coastal sweepers. Highly technical camber transitions through CA-9.
|
||||
</p>
|
||||
</div>
|
||||
<!-- KEY ROUTE STATS STRIP (5-COL / BENTO) -->
|
||||
<div class="grid grid-cols-2 sm:grid-cols-5 gap-space-xs mt-space-md pt-space-md border-t border-outline-variant">
|
||||
<!-- Metric 1: Distance -->
|
||||
<div class="bg-surface-container-lowest/80 border border-outline-variant p-2.5 rounded-lg flex flex-col justify-between">
|
||||
<span class="font-label-data text-label-caption text-outline uppercase">DISTANCE</span>
|
||||
<div class="flex items-baseline gap-1 mt-1">
|
||||
<span class="font-telemetry-metric-md text-telemetry-metric-md text-primary-container">64.2</span>
|
||||
<span class="font-label-data text-label-caption text-outline">MI</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Metric 2: Est. Duration -->
|
||||
<div class="bg-surface-container-lowest/80 border border-outline-variant p-2.5 rounded-lg flex flex-col justify-between">
|
||||
<span class="font-label-data text-label-caption text-outline uppercase">EST TIME</span>
|
||||
<div class="flex items-baseline gap-1 mt-1">
|
||||
<span class="font-telemetry-metric-md text-telemetry-metric-md text-on-surface">1h 24m</span>
|
||||
<span class="font-label-data text-label-caption text-outline">@P3</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Metric 3: Curve Count -->
|
||||
<div class="bg-surface-container-lowest/80 border border-outline-variant p-2.5 rounded-lg flex flex-col justify-between">
|
||||
<span class="font-label-data text-label-caption text-outline uppercase">APEX COUNT</span>
|
||||
<div class="flex items-baseline gap-1 mt-1">
|
||||
<span class="font-telemetry-metric-md text-telemetry-metric-md text-on-surface">142</span>
|
||||
<span class="font-label-data text-label-caption text-primary-container font-bold">CURVES</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Metric 4: Elevation Gain -->
|
||||
<div class="bg-surface-container-lowest/80 border border-outline-variant p-2.5 rounded-lg flex flex-col justify-between">
|
||||
<span class="font-label-data text-label-caption text-outline uppercase">ASCENT</span>
|
||||
<div class="flex items-baseline gap-1 mt-1">
|
||||
<span class="font-telemetry-metric-md text-telemetry-metric-md text-on-surface">+3,480</span>
|
||||
<span class="font-label-data text-label-caption text-outline">FT</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Metric 5: Curviness Gauge -->
|
||||
<div class="col-span-2 sm:col-span-1 bg-surface-container-lowest/80 border border-outline-variant p-2.5 rounded-lg flex flex-col justify-between">
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="font-label-data text-label-caption text-outline uppercase">CURVINESS</span>
|
||||
<span class="font-label-data text-label-caption text-primary-container">HIGH</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-2 mt-1">
|
||||
<span class="font-telemetry-metric-md text-telemetry-metric-md text-primary-container">94%</span>
|
||||
<div class="flex-1 bg-surface-container-high h-2 rounded-full overflow-hidden border border-outline-variant">
|
||||
<div class="bg-primary-container h-full rounded-full w-[94%] shadow-[0_0_8px_#00e5ff]"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- ELEVATION PROFILE & GRADIENT CARD -->
|
||||
<div class="bg-surface-container-low border border-outline-variant rounded-xl p-space-md space-y-space-sm relative">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-primary-container" data-icon="show_chart">show_chart</span>
|
||||
<h2 class="font-headline-sm text-headline-sm text-on-surface tracking-tight">Elevation & Thermal Gradient</h2>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="inline-flex items-center gap-1 px-2 py-0.5 rounded bg-error-container/30 border border-error/40 text-error font-label-data text-label-caption">
|
||||
<span class="material-symbols-outlined text-xs" data-icon="warning">warning</span>
|
||||
-8.4% MAX GRADE
|
||||
</span>
|
||||
<span class="inline-flex items-center gap-1 px-2 py-0.5 rounded bg-surface-container-high border border-outline-variant text-on-surface font-label-data text-label-caption">
|
||||
96% ASPHALT
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Vector Elevation Visualizer (Synthetic SVG Chart) -->
|
||||
<div class="w-full bg-surface-container-lowest rounded-lg p-3 border border-outline-variant overflow-hidden">
|
||||
<div class="flex justify-between items-center text-outline font-label-data text-label-caption mb-1">
|
||||
<span>PEAK: 3,214 FT (CA-35 CREST)</span>
|
||||
<span>SEA LEVEL: 20 FT (PACIFIC SHORE)</span>
|
||||
</div>
|
||||
<div class="relative w-full h-32">
|
||||
<svg class="w-full h-full overflow-visible" preserveaspectratio="none" viewbox="0 0 500 120">
|
||||
<defs>
|
||||
<lineargradient id="elevationGrad" x1="0" x2="0" y1="0" y2="1">
|
||||
<stop offset="0%" stop-color="#00e5ff" stop-opacity="0.45"></stop>
|
||||
<stop offset="70%" stop-color="#00e5ff" stop-opacity="0.05"></stop>
|
||||
<stop offset="100%" stop-color="#00e5ff" stop-opacity="0"></stop>
|
||||
</lineargradient>
|
||||
</defs>
|
||||
<!-- Elevation line area fill -->
|
||||
<path d="M 0,42 Q 60,38 120,12 T 240,65 T 360,95 L 500,116 L 500,120 L 0,120 Z" fill="url(#elevationGrad)"></path>
|
||||
<!-- Elevation line stroke -->
|
||||
<path d="M 0,42 Q 60,38 120,12 T 240,65 T 360,95 L 500,116" fill="none" stroke="#00e5ff" stroke-linecap="round" stroke-width="2.5"></path>
|
||||
<!-- Key Waypoint Markers -->
|
||||
<!-- Alice's -->
|
||||
<circle cx="10" cy="42" fill="#00e5ff" r="3.5" stroke="#070A0F" stroke-width="1.5"></circle>
|
||||
<!-- Peak Crest -->
|
||||
<circle cx="120" cy="12" fill="#00e5ff" r="4.5" stroke="#ffffff" stroke-width="1.5"></circle>
|
||||
<!-- Saratoga Gap Hairpins -->
|
||||
<circle cx="180" cy="40" fill="#f59e0b" r="3.5" stroke="#070A0F" stroke-width="1.5"></circle>
|
||||
<!-- Boulder Creek Depot -->
|
||||
<circle cx="280" cy="78" fill="#00e5ff" r="3.5" stroke="#070A0F" stroke-width="1.5"></circle>
|
||||
<!-- Coastal Finish -->
|
||||
<circle cx="490" cy="115" fill="#10b981" r="4" stroke="#ffffff" stroke-width="1.5"></circle>
|
||||
</svg>
|
||||
</div>
|
||||
<!-- Waypoint Labels Strip under chart -->
|
||||
<div class="grid grid-cols-4 gap-1 pt-2 border-t border-outline-variant font-label-data text-[10px] sm:text-label-caption text-outline">
|
||||
<div>
|
||||
<span class="text-primary-container block font-semibold truncate">0.0 MI</span>
|
||||
<span class="truncate block">Alice's (2,420')</span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="text-primary-container block font-semibold truncate">14.8 MI</span>
|
||||
<span class="truncate block">Saratoga Gap</span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="text-primary-container block font-semibold truncate">28.5 MI</span>
|
||||
<span class="truncate block">Boulder Creek</span>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<span class="text-primary-container block font-semibold truncate">64.2 MI</span>
|
||||
<span class="truncate block">Santa Cruz (20')</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- TURN-BY-TURN CUE SHEET CONTROLS & FILTER -->
|
||||
<div class="space-y-space-sm">
|
||||
<div class="flex flex-col sm:flex-row items-stretch sm:items-center justify-between gap-space-sm">
|
||||
<div>
|
||||
<h2 class="font-headline-sm text-headline-sm text-on-surface">Tactical Cue Sheet</h2>
|
||||
<p class="font-label-data text-label-caption text-outline">7 PRECISION TRANSITIONS // MESH RECON</p>
|
||||
</div>
|
||||
<!-- Filter Pills (Glove-Friendly Min 48px hit area) -->
|
||||
<div class="flex items-center gap-1 bg-surface-container-lowest p-1 rounded-lg border border-outline-variant overflow-x-auto no-scrollbar">
|
||||
<button class="min-h-[44px] px-3 py-1.5 rounded bg-primary-container text-surface-container-lowest font-label-data text-label-caption font-bold tracking-wider active:scale-95 duration-100 ease-out whitespace-nowrap" type="button">
|
||||
ALL (7)
|
||||
</button>
|
||||
<button class="min-h-[44px] px-3 py-1.5 rounded text-on-surface-variant hover:text-primary-container font-label-data text-label-caption font-medium tracking-wider active:scale-95 duration-100 ease-out whitespace-nowrap" type="button">
|
||||
HAIRPINS (2)
|
||||
</button>
|
||||
<button class="min-h-[44px] px-3 py-1.5 rounded text-on-surface-variant hover:text-primary-container font-label-data text-label-caption font-medium tracking-wider active:scale-95 duration-100 ease-out whitespace-nowrap" type="button">
|
||||
FUEL / POI (1)
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- CUE SHEET MANEUVER CARDS STACK -->
|
||||
<div class="space-y-space-xs">
|
||||
<!-- CUE ITEM 1: START -->
|
||||
<div class="bg-surface-container-low border border-outline-variant rounded-xl p-space-md hover:border-primary-container/50 transition-colors">
|
||||
<div class="flex items-start gap-space-md">
|
||||
<!-- Large Glove-Friendly Turn Direction Icon Container -->
|
||||
<div class="w-12 h-12 rounded-lg bg-surface-container-high border border-outline-variant flex items-center justify-center text-primary-container shrink-0">
|
||||
<span class="material-symbols-outlined text-2xl" data-icon="flag">flag</span>
|
||||
</div>
|
||||
<!-- Maneuver Body -->
|
||||
<div class="flex-1 space-y-1">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="font-telemetry-metric-md text-telemetry-metric-md text-primary-container">0.0</span>
|
||||
<span class="font-label-data text-label-data text-outline">MI</span>
|
||||
<span class="px-1.5 py-0.5 rounded bg-surface-container-highest font-label-data text-[11px] text-on-surface font-bold border border-outline-variant">CA-84</span>
|
||||
</div>
|
||||
<span class="font-label-data text-label-caption text-primary-container font-semibold">STAGE A</span>
|
||||
</div>
|
||||
<p class="font-headline-sm text-base text-on-surface">Start at Alice's Restaurant (Skyline Blvd & CA-84)</p>
|
||||
<p class="font-body-md text-body-md text-on-surface-variant">Staging Area Grid A. Calibrate inertial lean IMU and verify pack intercom frequency.</p>
|
||||
<div class="flex flex-wrap items-center gap-1.5 pt-1">
|
||||
<span class="px-2 py-0.5 rounded-full bg-surface-container-high text-outline font-label-data text-label-caption">GPS SYNC 20Hz</span>
|
||||
<span class="px-2 py-0.5 rounded-full bg-surface-container-high text-outline font-label-data text-label-caption">COLD TYRE ADVISORY</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- CUE ITEM 2: RIGHT FORK (CA-35) -->
|
||||
<div class="bg-surface-container-low border border-outline-variant rounded-xl p-space-md hover:border-primary-container/50 transition-colors">
|
||||
<div class="flex items-start gap-space-md">
|
||||
<div class="w-12 h-12 rounded-lg bg-surface-container-high border border-outline-variant flex items-center justify-center text-primary-container shrink-0">
|
||||
<span class="material-symbols-outlined text-3xl" data-icon="fork_right">fork_right</span>
|
||||
</div>
|
||||
<div class="flex-1 space-y-1">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="font-telemetry-metric-md text-telemetry-metric-md text-primary-container">4.2</span>
|
||||
<span class="font-label-data text-label-data text-outline">MI</span>
|
||||
<span class="px-1.5 py-0.5 rounded bg-surface-container-highest font-label-data text-[11px] text-on-surface font-bold border border-outline-variant">CA-35 S</span>
|
||||
</div>
|
||||
<span class="font-label-data text-label-caption text-outline">ADV: 45 MPH</span>
|
||||
</div>
|
||||
<p class="font-headline-sm text-base text-on-surface">Right fork onto CA-35 South (Skyline Blvd)</p>
|
||||
<p class="font-body-md text-body-md text-on-surface-variant">Fast sweeping technical S-curves through ridge tree tunnels.</p>
|
||||
<!-- Apex Warning Tag -->
|
||||
<div class="flex items-center gap-2 p-2 rounded bg-surface-container-lowest border border-outline-variant text-primary-fixed mt-1">
|
||||
<span class="material-symbols-outlined text-sm text-primary-container" data-icon="water_drop">water_drop</span>
|
||||
<span class="font-label-data text-label-caption">HAZARD NOTE: Damp redwood morning shade on apex entry.</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- CUE ITEM 3: SHARP LEFT HAIRPIN (CA-9) -->
|
||||
<div class="bg-surface-container-low border-2 border-primary-container/60 rounded-xl p-space-md neon-cyan-glow-subtle">
|
||||
<div class="flex items-start gap-space-md">
|
||||
<div class="w-12 h-12 rounded-lg bg-surface-container-highest border border-primary-container flex items-center justify-center text-primary-container shrink-0">
|
||||
<span class="material-symbols-outlined text-3xl" data-icon="u_turn_left">u_turn_left</span>
|
||||
</div>
|
||||
<div class="flex-1 space-y-1">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="font-telemetry-metric-md text-telemetry-metric-md text-primary-container">14.8</span>
|
||||
<span class="font-label-data text-label-data text-outline">MI</span>
|
||||
<span class="px-1.5 py-0.5 rounded bg-surface-container-highest font-label-data text-[11px] text-primary-container font-bold border border-primary-container/50">CA-9 S</span>
|
||||
</div>
|
||||
<span class="px-2 py-0.5 rounded bg-error-container text-on-error-container font-label-data text-label-caption font-bold animate-pulse">
|
||||
CRITICAL
|
||||
</span>
|
||||
</div>
|
||||
<p class="font-headline-sm text-base text-on-surface">Left hairpin turn onto CA-9 South toward Boulder Creek</p>
|
||||
<p class="font-body-md text-body-md text-on-surface-variant">Saratoga Gap descent. Rapid downhill elevation loss into tight radius chicanes.</p>
|
||||
<div class="p-2 rounded bg-error-container/20 border border-error/50 text-error flex items-center gap-2 mt-1">
|
||||
<span class="material-symbols-outlined text-sm" data-icon="warning">warning</span>
|
||||
<span class="font-label-data text-label-caption">Sharp 49° Apex Warning // Decreasing Radius // 25 MPH Target</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- CUE ITEM 4: RE-GROUP & FUEL STOP -->
|
||||
<div class="bg-surface-container-low border border-outline-variant rounded-xl p-space-md hover:border-primary-container/50 transition-colors">
|
||||
<div class="flex items-start gap-space-md">
|
||||
<div class="w-12 h-12 rounded-lg bg-surface-container-high border border-outline-variant flex items-center justify-center text-primary-container shrink-0">
|
||||
<span class="material-symbols-outlined text-2xl" data-icon="local_gas_station">local_gas_station</span>
|
||||
</div>
|
||||
<div class="flex-1 space-y-1">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="font-telemetry-metric-md text-telemetry-metric-md text-primary-container">28.5</span>
|
||||
<span class="font-label-data text-label-data text-outline">MI</span>
|
||||
<span class="px-1.5 py-0.5 rounded bg-surface-container-highest font-label-data text-[11px] text-on-surface font-bold border border-outline-variant">POI // FUEL</span>
|
||||
</div>
|
||||
<span class="font-label-data text-label-caption text-primary-container font-semibold">10 MIN PAUSE</span>
|
||||
</div>
|
||||
<p class="font-headline-sm text-base text-on-surface">Fuel Stop & Staging Rest Marker — 76 Station</p>
|
||||
<p class="font-body-md text-body-md text-on-surface-variant">Boulder Creek Depot. 91+ Octane, tyre pressure check station, pack re-sync.</p>
|
||||
<div class="flex items-center gap-2 pt-1 font-label-data text-label-caption text-primary-fixed">
|
||||
<span class="material-symbols-outlined text-xs" data-icon="group">group</span>
|
||||
<span>Recommended Pack Re-group (Mesh Ping Check: 100% Ok)</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- CUE ITEM 5: RIGHT FORK FELTON EMPIRE -->
|
||||
<div class="bg-surface-container-low border border-outline-variant rounded-xl p-space-md hover:border-primary-container/50 transition-colors">
|
||||
<div class="flex items-start gap-space-md">
|
||||
<div class="w-12 h-12 rounded-lg bg-surface-container-high border border-outline-variant flex items-center justify-center text-primary-container shrink-0">
|
||||
<span class="material-symbols-outlined text-3xl" data-icon="turn_right">turn_right</span>
|
||||
</div>
|
||||
<div class="flex-1 space-y-1">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="font-telemetry-metric-md text-telemetry-metric-md text-primary-container">42.1</span>
|
||||
<span class="font-label-data text-label-data text-outline">MI</span>
|
||||
<span class="px-1.5 py-0.5 rounded bg-surface-container-highest font-label-data text-[11px] text-on-surface font-bold border border-outline-variant">FELTON EMPIRE</span>
|
||||
</div>
|
||||
<span class="font-label-data text-label-caption text-outline">ADV: 35 MPH</span>
|
||||
</div>
|
||||
<p class="font-headline-sm text-base text-on-surface">Keep right onto Felton Empire Rd / Graham Hill Rd</p>
|
||||
<p class="font-body-md text-body-md text-on-surface-variant">Technical switchbacks with sharp gradient changes before valley opening.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- CUE ITEM 6: MERGE PACIFIC HWY 1 -->
|
||||
<div class="bg-surface-container-low border border-outline-variant rounded-xl p-space-md hover:border-primary-container/50 transition-colors">
|
||||
<div class="flex items-start gap-space-md">
|
||||
<div class="w-12 h-12 rounded-lg bg-surface-container-high border border-outline-variant flex items-center justify-center text-primary-container shrink-0">
|
||||
<span class="material-symbols-outlined text-3xl" data-icon="merge">merge</span>
|
||||
</div>
|
||||
<div class="flex-1 space-y-1">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="font-telemetry-metric-md text-telemetry-metric-md text-primary-container">53.4</span>
|
||||
<span class="font-label-data text-label-data text-outline">MI</span>
|
||||
<span class="px-1.5 py-0.5 rounded bg-surface-container-highest font-label-data text-[11px] text-on-surface font-bold border border-outline-variant">CA-1 S</span>
|
||||
</div>
|
||||
<span class="font-label-data text-label-caption text-primary-container">SWEEPER</span>
|
||||
</div>
|
||||
<p class="font-headline-sm text-base text-on-surface">Merge onto CA-1 South (Cabrillo Hwy / Hwy 1)</p>
|
||||
<p class="font-body-md text-body-md text-on-surface-variant">Scenic wide-lane coastal sweeper with crosswind exposure. Open throttle zone.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- CUE ITEM 7: DESTINATION OVERLOOK -->
|
||||
<div class="bg-surface-container-low border border-outline-variant rounded-xl p-space-md hover:border-primary-container/50 transition-colors">
|
||||
<div class="flex items-start gap-space-md">
|
||||
<div class="w-12 h-12 rounded-lg bg-surface-container-high border border-outline-variant flex items-center justify-center text-primary-container shrink-0">
|
||||
<span class="material-symbols-outlined text-2xl" data-icon="sports_score">sports_score</span>
|
||||
</div>
|
||||
<div class="flex-1 space-y-1">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="font-telemetry-metric-md text-telemetry-metric-md text-primary-container">64.2</span>
|
||||
<span class="font-label-data text-label-data text-outline">MI</span>
|
||||
<span class="px-1.5 py-0.5 rounded bg-surface-container-highest font-label-data text-[11px] text-on-surface font-bold border border-outline-variant">FINISH</span>
|
||||
</div>
|
||||
<span class="font-label-data text-label-caption text-primary-container font-semibold">COASTLINE</span>
|
||||
</div>
|
||||
<p class="font-headline-sm text-base text-on-surface">Destination: Santa Cruz Wharf / Beach Overlook</p>
|
||||
<p class="font-body-md text-body-md text-on-surface-variant">Route conclusion. Terminal telemetry sync and pack session debrief spot.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
<!-- BOTTOM FLOATING ACTION BAR (Tactical Large Actions) -->
|
||||
<aside aria-label="Route Action Bar" class="fixed bottom-14 left-0 w-full z-40 px-gutter py-space-xs bg-surface-container-lowest/90 backdrop-blur-md border-t border-outline-variant">
|
||||
<div class="max-w-3xl mx-auto flex items-center gap-space-sm">
|
||||
<!-- Secondary Action: Export GPX / 20Hz Cue Sheet -->
|
||||
<button class="h-[52px] px-4 rounded-lg bg-surface-container-high border border-outline-variant text-on-surface font-label-data text-label-caption font-semibold flex items-center justify-center gap-1.5 hover:border-primary-container active:scale-95 duration-100 ease-out whitespace-nowrap" type="button">
|
||||
<span class="material-symbols-outlined text-lg" data-icon="download">download</span>
|
||||
<span class="hidden sm:inline">EXPORT</span> GPX
|
||||
</button>
|
||||
<!-- Primary Telemetry Trigger (52px+ min height for gloved fingers, Neon Cyan Fill) -->
|
||||
<button class="flex-1 h-[52px] rounded-lg bg-primary-container text-surface-container-lowest font-headline-sm text-sm sm:text-base font-bold tracking-wider flex items-center justify-center gap-2 neon-cyan-glow hover:bg-primary-fixed active:scale-95 duration-100 ease-out" type="button">
|
||||
<span class="material-symbols-outlined text-2xl font-bold" data-icon="navigation" style="font-variation-settings: 'FILL' 1;">navigation</span>
|
||||
<span>START TURN-BY-TURN NAVIGATION</span>
|
||||
</button>
|
||||
</div>
|
||||
</aside>
|
||||
<!-- BOTTOM NAVIGATION BAR (from Shared Components JSON: BottomNavBar) -->
|
||||
<!-- "Map" is active navigation tab corresponding to the route/navigation task -->
|
||||
<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 dark:bg-surface-container-lowest border-t border-outline-variant dark:border-outline-variant">
|
||||
<!-- 1. Dash (Inactive) -->
|
||||
<a class="flex flex-col items-center justify-center text-on-surface-variant dark:text-on-surface-variant px-2 py-1 min-h-[48px] hover:bg-surface-container-low hover:text-primary-fixed active:scale-95 duration-100 ease-out" href="#">
|
||||
<span class="material-symbols-outlined text-xl" data-icon="speed">speed</span>
|
||||
<span class="font-label-caption text-label-caption">Dash</span>
|
||||
</a>
|
||||
<!-- 2. Map (Active State based on JSON style_active_navigation) -->
|
||||
<a class="flex flex-col items-center justify-center bg-surface-container-high dark:bg-surface-container-high text-primary-container dark:text-primary-container rounded-lg px-2 py-1 min-h-[48px] active:scale-95 duration-100 ease-out shadow-sm" href="#">
|
||||
<span class="material-symbols-outlined text-xl" data-icon="navigation" style="font-variation-settings: 'FILL' 1;">navigation</span>
|
||||
<span class="font-label-caption text-label-caption font-semibold">Map</span>
|
||||
</a>
|
||||
<!-- 3. Activity (Inactive) -->
|
||||
<a class="flex flex-col items-center justify-center text-on-surface-variant dark:text-on-surface-variant px-2 py-1 min-h-[48px] hover:bg-surface-container-low hover:text-primary-fixed active:scale-95 duration-100 ease-out" href="#">
|
||||
<span class="material-symbols-outlined text-xl" data-icon="analytics">analytics</span>
|
||||
<span class="font-label-caption text-label-caption">Activity</span>
|
||||
</a>
|
||||
<!-- 4. Garage (Inactive) -->
|
||||
<a class="flex flex-col items-center justify-center text-on-surface-variant dark:text-on-surface-variant px-2 py-1 min-h-[48px] hover:bg-surface-container-low hover:text-primary-fixed active:scale-95 duration-100 ease-out" href="#">
|
||||
<span class="material-symbols-outlined text-xl" data-icon="two_wheeler">two_wheeler</span>
|
||||
<span class="font-label-caption text-label-caption">Garage</span>
|
||||
</a>
|
||||
<!-- 5. Settings (Inactive) -->
|
||||
<a class="flex flex-col items-center justify-center text-on-surface-variant dark:text-on-surface-variant px-2 py-1 min-h-[48px] hover:bg-surface-container-low hover:text-primary-fixed active:scale-95 duration-100 ease-out" href="#">
|
||||
<span class="material-symbols-outlined text-xl" data-icon="settings">settings</span>
|
||||
<span class="font-label-caption text-label-caption">Settings</span>
|
||||
</a>
|
||||
</nav>
|
||||
</body></html>
|
||||
|
|
@ -0,0 +1,548 @@
|
|||
<!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 HUD - Rider Profile @ApexMarcus</title>
|
||||
<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&family=JetBrains+Mono:wght@500;600;700&family=Space+Grotesk:wght@600;700&display=swap" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<script src="https://cdn.tailwindcss.com?plugins=forms,container-queries"></script>
|
||||
<script id="tailwind-config">
|
||||
tailwind.config = {
|
||||
darkMode: "class",
|
||||
theme: {
|
||||
extend: {
|
||||
"colors": {
|
||||
"tertiary-fixed": "#e9ddff",
|
||||
"surface-container-low": "#181c21",
|
||||
"on-primary-container": "#00626e",
|
||||
"on-secondary-fixed": "#00174b",
|
||||
"surface-container": "#1d2025",
|
||||
"secondary-container": "#0053db",
|
||||
"tertiary-fixed-dim": "#d0bcff",
|
||||
"on-secondary-container": "#cdd7ff",
|
||||
"inverse-on-surface": "#2d3036",
|
||||
"on-secondary-fixed-variant": "#003ea8",
|
||||
"on-secondary": "#002a78",
|
||||
"secondary-fixed-dim": "#b4c5ff",
|
||||
"on-primary-fixed": "#001f24",
|
||||
"primary-container": "#00e5ff",
|
||||
"error": "#ffb4ab",
|
||||
"outline-variant": "#3b494c",
|
||||
"surface": "#101419",
|
||||
"primary-fixed": "#9cf0ff",
|
||||
"surface-variant": "#32353b",
|
||||
"surface-bright": "#36393f",
|
||||
"on-tertiary-container": "#6834d1",
|
||||
"on-error-container": "#ffdad6",
|
||||
"secondary": "#b4c5ff",
|
||||
"on-tertiary-fixed": "#23005c",
|
||||
"tertiary-container": "#d9c8ff",
|
||||
"outline": "#849396",
|
||||
"on-error": "#690005",
|
||||
"tertiary": "#f2e9ff",
|
||||
"primary": "#c3f5ff",
|
||||
"on-tertiary": "#3c0091",
|
||||
"inverse-surface": "#e0e2ea",
|
||||
"surface-tint": "#00daf3",
|
||||
"on-surface-variant": "#bac9cc",
|
||||
"surface-container-high": "#272a30",
|
||||
"on-surface": "#e0e2ea",
|
||||
"on-primary": "#00363d",
|
||||
"background": "#101419",
|
||||
"secondary-fixed": "#dbe1ff",
|
||||
"primary-fixed-dim": "#00daf3",
|
||||
"on-primary-fixed-variant": "#004f58",
|
||||
"surface-container-lowest": "#0b0e13",
|
||||
"surface-container-highest": "#32353b",
|
||||
"on-tertiary-fixed-variant": "#5516be",
|
||||
"inverse-primary": "#006875",
|
||||
"surface-dim": "#101419",
|
||||
"on-background": "#e0e2ea",
|
||||
"error-container": "#93000a"
|
||||
},
|
||||
"borderRadius": {
|
||||
"DEFAULT": "0.25rem",
|
||||
"lg": "0.5rem",
|
||||
"xl": "0.75rem",
|
||||
"full": "9999px"
|
||||
},
|
||||
"spacing": {
|
||||
"margin": "1rem",
|
||||
"space-xl": "2rem",
|
||||
"space-lg": "1.5rem",
|
||||
"margin-lg": "2rem",
|
||||
"space-sm": "0.5rem",
|
||||
"space-md": "1rem",
|
||||
"space-xs": "0.25rem",
|
||||
"gutter": "1rem",
|
||||
"gutter-lg": "1.5rem"
|
||||
},
|
||||
"fontFamily": {
|
||||
"telemetry-metric-md": ["JetBrains Mono"],
|
||||
"label-caption": ["Inter"],
|
||||
"headline-md": ["Space Grotesk"],
|
||||
"body-lg": ["Inter"],
|
||||
"label-data": ["JetBrains Mono"],
|
||||
"headline-sm": ["Space Grotesk"],
|
||||
"headline-lg": ["Space Grotesk"],
|
||||
"body-md": ["Inter"],
|
||||
"display-hero-mobile": ["Space Grotesk"],
|
||||
"telemetry-metric-lg": ["JetBrains Mono"],
|
||||
"telemetry-metric-lg-mobile": ["JetBrains Mono"],
|
||||
"display-hero": ["Space Grotesk"]
|
||||
},
|
||||
"fontSize": {
|
||||
"telemetry-metric-md": ["28px", { "lineHeight": "32px", "letterSpacing": "-0.02em", "fontWeight": "600" }],
|
||||
"label-caption": ["11px", { "lineHeight": "14px", "letterSpacing": "0.05em", "fontWeight": "600" }],
|
||||
"headline-md": ["24px", { "lineHeight": "32px", "letterSpacing": "-0.01em", "fontWeight": "600" }],
|
||||
"body-lg": ["16px", { "lineHeight": "24px", "fontWeight": "500" }],
|
||||
"label-data": ["12px", { "lineHeight": "16px", "letterSpacing": "0.08em", "fontWeight": "600" }],
|
||||
"headline-sm": ["20px", { "lineHeight": "28px", "fontWeight": "600" }],
|
||||
"headline-lg": ["32px", { "lineHeight": "40px", "letterSpacing": "-0.02em", "fontWeight": "700" }],
|
||||
"body-md": ["14px", { "lineHeight": "20px", "fontWeight": "400" }],
|
||||
"display-hero-mobile": ["40px", { "lineHeight": "44px", "letterSpacing": "-0.02em", "fontWeight": "700" }],
|
||||
"telemetry-metric-lg": ["48px", { "lineHeight": "48px", "letterSpacing": "-0.04em", "fontWeight": "700" }],
|
||||
"telemetry-metric-lg-mobile": ["36px", { "lineHeight": "36px", "letterSpacing": "-0.03em", "fontWeight": "700" }],
|
||||
"display-hero": ["56px", { "lineHeight": "60px", "letterSpacing": "-0.03em", "fontWeight": "700" }]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.material-symbols-outlined {
|
||||
font-variation-settings: 'FILL' 0, 'wght' 500, 'GRAD' 0, 'opsz' 24;
|
||||
}
|
||||
.cyan-glow {
|
||||
box-shadow: 0 0 16px rgba(0, 229, 255, 0.35);
|
||||
}
|
||||
.cyan-border-glow {
|
||||
box-shadow: inset 0 0 10px rgba(0, 229, 255, 0.2), 0 0 12px rgba(0, 229, 255, 0.25);
|
||||
}
|
||||
.hud-clip-tactical {
|
||||
clip-path: polygon(0 0, calc(100% - 10px) 0, 100% 10px, 100% 100%, 0 100%);
|
||||
}
|
||||
/* Hide scrollbar for tactical horizontal swipe */
|
||||
.no-scrollbar::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
.no-scrollbar {
|
||||
-ms-overflow-style: none;
|
||||
scrollbar-width: none;
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
body {
|
||||
min-height: max(884px, 100dvh);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-surface-container-lowest text-on-surface antialiased min-h-screen pb-24 selection:bg-primary-container selection:text-on-primary-fixed">
|
||||
<!-- TOP APP BAR (Shared Component Anchor) -->
|
||||
<header class="fixed top-0 left-0 w-full z-50 flex justify-between items-center px-gutter h-14 bg-surface-container-lowest dark:bg-surface-container-lowest border-b border-outline-variant dark:border-outline-variant">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-primary-container animate-pulse text-[20px]" data-icon="sensors">sensors</span>
|
||||
<span class="text-headline-sm font-headline-sm font-bold tracking-wider text-primary-container dark:text-primary-container uppercase">MOTORSIGNAL HUD</span>
|
||||
</div>
|
||||
<!-- Top Telemetry Status Stream -->
|
||||
<div class="flex items-center space-x-3 text-label-caption font-label-caption text-on-surface-variant">
|
||||
<span class="flex items-center gap-1 font-label-data text-primary-fixed">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-primary-container inline-block"></span>
|
||||
20Hz GNSS
|
||||
</span>
|
||||
<span class="hidden sm:inline-flex items-center gap-1">
|
||||
<span class="material-symbols-outlined text-[16px]" data-icon="battery_charging_full">battery_charging_full</span>
|
||||
98%
|
||||
</span>
|
||||
<button aria-label="Alerts" class="flex items-center justify-center w-8 h-8 rounded text-on-surface-variant hover:text-primary-container active:scale-95 transition-transform">
|
||||
<span class="material-symbols-outlined text-[20px]" data-icon="warning">warning</span>
|
||||
</button>
|
||||
</div>
|
||||
</header>
|
||||
<!-- MAIN VIEWPORT -->
|
||||
<main class="w-full max-w-md mx-auto pt-14 px-0">
|
||||
<!-- CANYON PASS BANNER & TACTICAL PROFILE HEADER -->
|
||||
<section class="relative w-full">
|
||||
<!-- High-altitude scenic pass header image -->
|
||||
<div class="relative w-full h-44 bg-surface-container-low overflow-hidden">
|
||||
<img alt="Canyon Pass Route" class="w-full h-full object-cover filter brightness-[0.65] contrast-[1.25]" data-alt="Cinematic high-angle view of a twisting mountain canyon motorcycle pass at blue dusk with neon light trails. The dark asphalt weaves aggressively through rugged cliffs under deep carbon-blue skies with dramatic electric cyan atmospheric road signs and subtle fog textures. A mood of high-velocity precision motorsport and tactical isolation." src="https://lh3.googleusercontent.com/aida-public/AB6AXuDg6uqYe1INH3jVlK3NO9UOVUtIJwc88799nDRWkLCT7tO4-hHAm1TwT-F9sbHEbo0csUpOha_ccrf7y-JTHVY9McIdFDRnXVZqQBZZ5_LQjEztyElPepN3QsK7K1WOBTKwtuIxmRvEqNfRaUvz8jYENkfgJUMN4phKiwaVgd8yXwcCprBXPWDHNITmlz0m9_UvfM-ImgLcOGesAarWLFf-0azWgELYeDvI2o5NRy3p_6-GswX0MRZeDAlmvUDkAUZn0qc92FlVacU"/>
|
||||
<div class="absolute inset-0 bg-gradient-to-b from-surface-container-lowest/20 via-surface-container-lowest/60 to-surface-container-lowest"></div>
|
||||
<div class="absolute top-3 right-3 flex items-center gap-1.5 px-2.5 py-1 bg-surface-container-lowest/80 backdrop-blur-md rounded border border-outline-variant">
|
||||
<span class="material-symbols-outlined text-[14px] text-primary-container" data-icon="route">route</span>
|
||||
<span class="text-label-caption font-label-caption text-on-surface tracking-wider">CA-35 NORTH PASS</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- AVATAR & IDENTITY CLUSTER -->
|
||||
<div class="px-gutter -mt-16 relative z-10 flex flex-col items-start">
|
||||
<div class="flex items-end justify-between w-full">
|
||||
<!-- Cyber HUD Avatar with Telemetry Ring -->
|
||||
<div class="relative group">
|
||||
<div class="w-24 h-24 rounded-full p-[3px] bg-gradient-to-tr from-primary-container via-outline-variant to-primary-container/20 cyan-glow">
|
||||
<div class="w-full h-full rounded-full overflow-hidden bg-surface-container-low border border-outline-variant relative">
|
||||
<img alt="@ApexMarcus Helmet Avatar" class="w-full h-full object-cover" data-alt="High-performance carbon-fiber motorcycle helmet with active holographic heads-up display illuminated on the tinted visor. Sharp studio lighting reveals deep woven carbon texture, sleek aerodynamic spoilers, and vivid glowing electric cyan telemetry gauges and rev curves projected directly onto the visor glass against a void-black background." src="https://lh3.googleusercontent.com/aida-public/AB6AXuBZU8IAWnMbn4ILpg5r9RfA2Oh6_jTOhB4ZptitIIJDgIqeYl7CGKxJTU-umTRA3UegfMrrWakhn7q7Q5qZMIpIYGp5_YIzh6FPB0h_p8EJXPtlfo9Tw_YNXSmow5U2ocs93JhBWNDkeRF5XbUjIHExLn3h7FHUwLtInRBm5v_ih0HF6XCJJKOkbwMMVR0uurXJPlQjPD_oEQaWc4UkVWRiCLmj1XqdOFbISPZgDnn73vIJtaQSIKwGBngCdOCuzOq84U8eKByZN8M"/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Live Status Beacon -->
|
||||
<div class="absolute bottom-1 right-1 w-5 h-5 rounded-full bg-surface-container-lowest flex items-center justify-center p-0.5">
|
||||
<span class="w-3.5 h-3.5 rounded-full bg-primary-container animate-pulse flex items-center justify-center">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-surface-container-lowest"></span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Quick Action Buttons Row (Glove Friendly, 48px+ Touch Bounds) -->
|
||||
<div class="flex items-center gap-2 mb-1">
|
||||
<button class="h-12 px-5 bg-primary-container text-on-primary-fixed font-telemetry-metric-md text-body-md rounded font-bold tracking-wide flex items-center justify-center gap-1.5 cyan-glow active:scale-95 duration-100 ease-out transition-all">
|
||||
<span class="material-symbols-outlined text-[20px]" data-icon="person_add">person_add</span>
|
||||
<span>FOLLOW</span>
|
||||
</button>
|
||||
<button class="h-12 w-12 bg-surface-container border border-outline-variant text-on-surface hover:text-primary-container hover:border-primary-container flex items-center justify-center rounded active:scale-95 duration-100 ease-out">
|
||||
<span class="material-symbols-outlined text-[20px]" data-icon="chat_bubble">chat_bubble</span>
|
||||
</button>
|
||||
<button class="h-12 w-12 bg-surface-container border border-outline-variant text-on-surface hover:text-primary-container hover:border-primary-container flex items-center justify-center rounded active:scale-95 duration-100 ease-out">
|
||||
<span class="material-symbols-outlined text-[20px]" data-icon="share">share</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Rider Names & Badges -->
|
||||
<div class="mt-3 w-full">
|
||||
<div class="flex items-center gap-2 flex-wrap">
|
||||
<h1 class="text-headline-md font-headline-md font-bold text-on-surface flex items-center gap-1.5">
|
||||
@ApexMarcus
|
||||
<span class="material-symbols-outlined text-primary-container text-[20px]" data-icon="verified" data-weight="fill">verified</span>
|
||||
</h1>
|
||||
<span class="px-2 py-0.5 text-label-caption font-label-data bg-primary-container/15 text-primary-container border border-primary-container/40 rounded-full font-bold uppercase tracking-wider">
|
||||
PRO RIDER
|
||||
</span>
|
||||
</div>
|
||||
<!-- Club & Rank Tag -->
|
||||
<div class="flex items-center gap-1.5 mt-1.5 text-on-surface-variant font-body-md text-body-md">
|
||||
<span class="material-symbols-outlined text-secondary text-[18px]" data-icon="shield">shield</span>
|
||||
<span class="font-medium text-on-surface">Pacific Coast Riders MC</span>
|
||||
<span class="text-outline-variant">•</span>
|
||||
<span class="text-secondary font-label-data text-label-data">ROAD CAPTAIN</span>
|
||||
</div>
|
||||
<!-- Bio -->
|
||||
<p class="mt-2.5 text-body-md font-body-md text-on-surface-variant leading-relaxed">
|
||||
Track coach & canyon carver. 🏁 Panigale V4 S & MT-09 SP. Dedicated to clean apexes, zero-drift telemetry, and group pack synchronization.
|
||||
</p>
|
||||
<!-- Social Metrics Strip -->
|
||||
<div class="grid grid-cols-3 gap-2 mt-4 pt-3 border-t border-outline-variant/60">
|
||||
<div class="bg-surface-container-low p-2.5 rounded border border-outline-variant">
|
||||
<p class="font-telemetry-metric-md text-headline-sm text-on-surface font-bold">1,420</p>
|
||||
<p class="text-label-caption font-label-caption text-on-surface-variant uppercase tracking-wider">Followers</p>
|
||||
</div>
|
||||
<div class="bg-surface-container-low p-2.5 rounded border border-outline-variant">
|
||||
<p class="font-telemetry-metric-md text-headline-sm text-on-surface font-bold">312</p>
|
||||
<p class="text-label-caption font-label-caption text-on-surface-variant uppercase tracking-wider">Following</p>
|
||||
</div>
|
||||
<div class="bg-surface-container-low p-2.5 rounded border border-outline-variant">
|
||||
<p class="font-telemetry-metric-md text-headline-sm text-on-surface font-bold">48</p>
|
||||
<p class="text-label-caption font-label-caption text-on-surface-variant uppercase tracking-wider">Shared Rides</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Highlighted Telemetry Benchmark Banner -->
|
||||
<div class="mt-3 p-3 bg-surface-container border border-primary-container/30 rounded-lg flex items-center justify-between cyan-border-glow">
|
||||
<div class="flex items-center gap-2.5">
|
||||
<div class="w-8 h-8 rounded bg-primary-container/10 border border-primary-container/30 flex items-center justify-center text-primary-container">
|
||||
<span class="material-symbols-outlined text-[18px]" data-icon="screen_rotation_alt">screen_rotation_alt</span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="text-label-caption font-label-caption text-on-surface-variant uppercase tracking-wider block">Verified Max Lean</span>
|
||||
<span class="font-telemetry-metric-md text-headline-sm text-primary-container font-bold">54.2°</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="h-8 w-px bg-outline-variant"></div>
|
||||
<div class="flex items-center gap-2.5">
|
||||
<div class="w-8 h-8 rounded bg-surface-container-high border border-outline-variant flex items-center justify-center text-secondary">
|
||||
<span class="material-symbols-outlined text-[18px]" data-icon="hub">hub</span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="text-label-caption font-label-caption text-on-surface-variant uppercase tracking-wider block">Cohesion Score</span>
|
||||
<span class="font-telemetry-metric-md text-headline-sm text-secondary font-bold">99.4%</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- CONTENT SECTIONS -->
|
||||
<div class="px-gutter space-y-6 mt-6">
|
||||
<!-- SECTION 1: MOTORCYCLE STABLE -->
|
||||
<section>
|
||||
<div class="flex items-center justify-between mb-3">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-primary-container text-[20px]" data-icon="two_wheeler">two_wheeler</span>
|
||||
<h2 class="text-headline-sm font-headline-sm font-bold uppercase tracking-wider text-on-surface">Motorcycle Stable</h2>
|
||||
</div>
|
||||
<span class="text-label-caption font-label-data px-2 py-0.5 rounded bg-surface-container-high border border-outline-variant text-primary-fixed">2 Units Active</span>
|
||||
</div>
|
||||
<div class="space-y-3">
|
||||
<!-- Bike Card 1 (Panigale) -->
|
||||
<div class="bg-surface-container-low border border-outline-variant rounded-xl p-3.5 relative overflow-hidden transition-all hover:border-primary-container/50">
|
||||
<div class="flex justify-between items-start">
|
||||
<div>
|
||||
<div class="flex items-center gap-2">
|
||||
<h3 class="font-headline-sm text-body-lg font-bold text-on-surface">2024 Ducati Panigale V4 S</h3>
|
||||
<span class="w-2 h-2 rounded-full bg-primary-container"></span>
|
||||
</div>
|
||||
<p class="text-label-data font-label-data text-on-surface-variant text-[11px] mt-0.5">Desmosedici Stradale SP2 • 1,103 cc</p>
|
||||
</div>
|
||||
<span class="px-2 py-1 rounded text-label-caption font-label-caption bg-surface-container-highest text-primary-container font-semibold uppercase">Primary Track</span>
|
||||
</div>
|
||||
<!-- Specs Grid -->
|
||||
<div class="grid grid-cols-3 gap-2 mt-3.5 pt-3 border-t border-outline-variant/60 font-label-data">
|
||||
<div>
|
||||
<span class="text-label-caption text-on-surface-variant block uppercase">Odometer</span>
|
||||
<span class="text-body-md font-bold text-on-surface">6,420 MI</span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="text-label-caption text-on-surface-variant block uppercase">Telemetry</span>
|
||||
<span class="text-body-md font-bold text-primary-container">CAN 50Hz</span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="text-label-caption text-on-surface-variant block uppercase">Fitted Tires</span>
|
||||
<span class="text-body-md font-bold text-on-surface">SC3 Slick</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Bike Card 2 (Yamaha MT-09) -->
|
||||
<div class="bg-surface-container-low border border-outline-variant rounded-xl p-3.5 relative overflow-hidden transition-all hover:border-outline">
|
||||
<div class="flex justify-between items-start">
|
||||
<div>
|
||||
<div class="flex items-center gap-2">
|
||||
<h3 class="font-headline-sm text-body-lg font-bold text-on-surface">2023 Yamaha MT-09 SP</h3>
|
||||
<span class="w-2 h-2 rounded-full bg-outline"></span>
|
||||
</div>
|
||||
<p class="text-label-data font-label-data text-on-surface-variant text-[11px] mt-0.5">CP3 Crossplane inline-triple • 890 cc</p>
|
||||
</div>
|
||||
<span class="px-2 py-1 rounded text-label-caption font-label-caption bg-surface-container-highest text-on-surface-variant uppercase font-semibold">Wet & Scrambler</span>
|
||||
</div>
|
||||
<div class="grid grid-cols-3 gap-2 mt-3.5 pt-3 border-t border-outline-variant/60 font-label-data">
|
||||
<div>
|
||||
<span class="text-label-caption text-on-surface-variant block uppercase">Odometer</span>
|
||||
<span class="text-body-md font-bold text-on-surface">8,110 MI</span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="text-label-caption text-on-surface-variant block uppercase">Telemetry</span>
|
||||
<span class="text-body-md font-bold text-on-surface">OBD-II OK</span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="text-label-caption text-on-surface-variant block uppercase">Fitted Tires</span>
|
||||
<span class="text-body-md font-bold text-on-surface">Road 6 GT</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- SECTION 2: TROPHY SHOWCASE (Telemetry Badges) -->
|
||||
<section>
|
||||
<div class="flex items-center justify-between mb-3">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-primary-container text-[20px]" data-icon="military_tech">military_tech</span>
|
||||
<h2 class="text-headline-sm font-headline-sm font-bold uppercase tracking-wider text-on-surface">Trophy Showcase</h2>
|
||||
</div>
|
||||
<span class="text-label-caption font-label-data text-on-surface-variant">IMU Verified</span>
|
||||
</div>
|
||||
<!-- Horizontal scrollable tactile badges -->
|
||||
<div class="flex space-x-3 overflow-x-auto no-scrollbar py-1">
|
||||
<!-- Badge 1: Apex King -->
|
||||
<div class="min-w-[170px] bg-surface-container p-3 rounded-xl border border-primary-container/40 flex-shrink-0 relative overflow-hidden">
|
||||
<div class="absolute -right-2 -bottom-2 opacity-10 text-primary-container">
|
||||
<span class="material-symbols-outlined text-[64px]" data-icon="speed">speed</span>
|
||||
</div>
|
||||
<div class="w-8 h-8 rounded bg-primary-container/20 border border-primary-container/50 flex items-center justify-center text-primary-container mb-2">
|
||||
<span class="material-symbols-outlined text-[18px]" data-icon="bolt">bolt</span>
|
||||
</div>
|
||||
<p class="font-headline-sm text-body-md font-bold text-primary-container">Apex King</p>
|
||||
<p class="font-telemetry-metric-md text-headline-sm text-on-surface font-bold">54.2° Lean</p>
|
||||
<p class="text-label-caption font-label-caption text-on-surface-variant mt-1">Turn 7 • Kalman Filtered</p>
|
||||
</div>
|
||||
<!-- Badge 2: Sub-3.5s -->
|
||||
<div class="min-w-[170px] bg-surface-container p-3 rounded-xl border border-outline-variant flex-shrink-0 relative overflow-hidden">
|
||||
<div class="w-8 h-8 rounded bg-surface-container-high border border-outline-variant flex items-center justify-center text-secondary mb-2">
|
||||
<span class="material-symbols-outlined text-[18px]" data-icon="timer">timer</span>
|
||||
</div>
|
||||
<p class="font-headline-sm text-body-md font-bold text-on-surface">Sub-3.5s</p>
|
||||
<p class="font-telemetry-metric-md text-headline-sm text-on-surface font-bold">3.28s 0-60</p>
|
||||
<p class="text-label-caption font-label-caption text-on-surface-variant mt-1">SAE J1318 Validated</p>
|
||||
</div>
|
||||
<!-- Badge 3: Iron Saddle -->
|
||||
<div class="min-w-[170px] bg-surface-container p-3 rounded-xl border border-outline-variant flex-shrink-0 relative overflow-hidden">
|
||||
<div class="w-8 h-8 rounded bg-surface-container-high border border-outline-variant flex items-center justify-center text-on-surface-variant mb-2">
|
||||
<span class="material-symbols-outlined text-[18px]" data-icon="distance">distance</span>
|
||||
</div>
|
||||
<p class="font-headline-sm text-body-md font-bold text-on-surface">Iron Saddle</p>
|
||||
<p class="font-telemetry-metric-md text-headline-sm text-on-surface font-bold">12,480 MI</p>
|
||||
<p class="text-label-caption font-label-caption text-on-surface-variant mt-1">High Mileage Certified</p>
|
||||
</div>
|
||||
<!-- Badge 4: Pack Lead -->
|
||||
<div class="min-w-[170px] bg-surface-container p-3 rounded-xl border border-outline-variant flex-shrink-0 relative overflow-hidden">
|
||||
<div class="w-8 h-8 rounded bg-surface-container-high border border-outline-variant flex items-center justify-center text-primary-fixed mb-2">
|
||||
<span class="material-symbols-outlined text-[18px]" data-icon="groups">groups</span>
|
||||
</div>
|
||||
<p class="font-headline-sm text-body-md font-bold text-on-surface">Pack Lead</p>
|
||||
<p class="font-telemetry-metric-md text-headline-sm text-on-surface font-bold">24 Rides</p>
|
||||
<p class="text-label-caption font-label-caption text-on-surface-variant mt-1">Sanctioned Group Escort</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- SECTION 3: RECENT ACTIVITY FEED -->
|
||||
<section class="space-y-3">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-primary-container text-[20px]" data-icon="analytics">analytics</span>
|
||||
<h2 class="text-headline-sm font-headline-sm font-bold uppercase tracking-wider text-on-surface">Recorded Missions</h2>
|
||||
</div>
|
||||
<button class="text-label-caption font-label-data text-primary-container hover:underline">ALL LOGS</button>
|
||||
</div>
|
||||
<!-- Activity Card 1: Skyline to Santa Cruz -->
|
||||
<article class="bg-surface-container-low border border-outline-variant rounded-xl p-4 space-y-3">
|
||||
<div class="flex items-start justify-between">
|
||||
<div>
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="px-2 py-0.5 rounded text-[10px] font-label-data bg-primary-container/20 text-primary-container font-semibold">YESTERDAY</span>
|
||||
<span class="text-label-caption font-label-caption text-on-surface-variant">14:15 PST</span>
|
||||
</div>
|
||||
<h3 class="font-headline-sm text-body-lg font-bold text-on-surface mt-1">Skyline to Santa Cruz Coastal Arc</h3>
|
||||
<p class="text-label-caption font-label-caption text-on-surface-variant">Panigale V4 S • Dry Track conditions</p>
|
||||
</div>
|
||||
<button class="w-10 h-10 rounded bg-surface-container flex items-center justify-center border border-outline-variant text-on-surface hover:text-primary-container active:scale-95">
|
||||
<span class="material-symbols-outlined text-[18px]" data-icon="file_download">file_download</span>
|
||||
</button>
|
||||
</div>
|
||||
<!-- Micro Sparkline / Telemetry Arc Preview -->
|
||||
<div class="w-full bg-surface-container-lowest p-2.5 rounded-lg border border-outline-variant">
|
||||
<div class="flex justify-between items-center text-label-caption font-label-data text-on-surface-variant mb-1">
|
||||
<span>ELEVATION & LEAN TRACE</span>
|
||||
<span class="text-primary-container">MAX 51.4°</span>
|
||||
</div>
|
||||
<!-- Tactical SVG Sparkline -->
|
||||
<svg class="w-full h-10 stroke-primary-container fill-none" viewbox="0 0 300 40">
|
||||
<path d="M0,35 Q30,20 60,30 T120,10 T180,28 T240,5 T300,22" stroke-linecap="round" stroke-width="2.5"></path>
|
||||
<path d="M0,35 Q30,20 60,30 T120,10 T180,28 T240,5 T300,22 L300,40 L0,40 Z" fill="rgba(0, 229, 255, 0.08)"></path>
|
||||
</svg>
|
||||
</div>
|
||||
<!-- Quick Metrics Bar -->
|
||||
<div class="grid grid-cols-4 gap-2 text-center py-1 bg-surface-container rounded font-label-data">
|
||||
<div>
|
||||
<span class="text-[10px] text-on-surface-variant uppercase block">Dist</span>
|
||||
<span class="text-body-md font-bold text-on-surface">64.2 MI</span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="text-[10px] text-on-surface-variant uppercase block">Duration</span>
|
||||
<span class="text-body-md font-bold text-on-surface">1h 24m</span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="text-[10px] text-on-surface-variant uppercase block">Max Lean</span>
|
||||
<span class="text-body-md font-bold text-primary-container">51.4°</span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="text-[10px] text-on-surface-variant uppercase block">Pace</span>
|
||||
<span class="text-body-md font-bold text-secondary">Pace 3</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Social Reactions & GPX Export -->
|
||||
<div class="flex items-center justify-between pt-2 border-t border-outline-variant/60 text-label-caption font-label-data text-on-surface-variant">
|
||||
<div class="flex items-center gap-3">
|
||||
<button class="flex items-center gap-1 hover:text-on-surface">
|
||||
<span>👊</span>
|
||||
<span class="font-bold text-on-surface">42 Bumps</span>
|
||||
</button>
|
||||
<button class="flex items-center gap-1 hover:text-on-surface">
|
||||
<span class="material-symbols-outlined text-[14px]" data-icon="forum">forum</span>
|
||||
<span>12 Comments</span>
|
||||
</button>
|
||||
</div>
|
||||
<span class="text-label-caption px-2 py-0.5 bg-surface-container rounded border border-outline-variant text-primary-fixed uppercase tracking-wider">GPX READY</span>
|
||||
</div>
|
||||
</article>
|
||||
<!-- Activity Card 2: Saratoga Gap Sprint -->
|
||||
<article class="bg-surface-container-low border border-outline-variant rounded-xl p-4 space-y-3">
|
||||
<div class="flex items-start justify-between">
|
||||
<div>
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="px-2 py-0.5 rounded text-[10px] font-label-data bg-surface-container-highest text-on-surface font-semibold">3 DAYS AGO</span>
|
||||
<span class="px-2 py-0.5 rounded text-[10px] font-label-data bg-error-container/40 text-error font-semibold">NEW RECORD</span>
|
||||
</div>
|
||||
<h3 class="font-headline-sm text-body-lg font-bold text-on-surface mt-1">Saratoga Gap Apex Sprint</h3>
|
||||
<p class="text-label-caption font-label-caption text-on-surface-variant">Panigale V4 S • Solo Telemetry Mode</p>
|
||||
</div>
|
||||
<button class="w-10 h-10 rounded bg-surface-container flex items-center justify-center border border-outline-variant text-on-surface hover:text-primary-container active:scale-95">
|
||||
<span class="material-symbols-outlined text-[18px]" data-icon="file_download">file_download</span>
|
||||
</button>
|
||||
</div>
|
||||
<!-- Quick Metrics Bar -->
|
||||
<div class="grid grid-cols-4 gap-2 text-center py-1 bg-surface-container rounded font-label-data">
|
||||
<div>
|
||||
<span class="text-[10px] text-on-surface-variant uppercase block">Dist</span>
|
||||
<span class="text-body-md font-bold text-on-surface">28.5 MI</span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="text-[10px] text-on-surface-variant uppercase block">Duration</span>
|
||||
<span class="text-body-md font-bold text-on-surface">42m</span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="text-[10px] text-on-surface-variant uppercase block">Max Lean</span>
|
||||
<span class="text-body-md font-bold text-primary-container">54.2°</span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="text-[10px] text-on-surface-variant uppercase block">Avg Speed</span>
|
||||
<span class="text-body-md font-bold text-on-surface">48 MPH</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center justify-between pt-2 border-t border-outline-variant/60 text-label-caption font-label-data text-on-surface-variant">
|
||||
<div class="flex items-center gap-3">
|
||||
<button class="flex items-center gap-1 hover:text-on-surface">
|
||||
<span>👊</span>
|
||||
<span class="font-bold text-on-surface">89 Bumps</span>
|
||||
</button>
|
||||
<button class="flex items-center gap-1 hover:text-on-surface">
|
||||
<span class="material-symbols-outlined text-[14px]" data-icon="forum">forum</span>
|
||||
<span>27 Comments</span>
|
||||
</button>
|
||||
</div>
|
||||
<span class="text-label-caption px-2 py-0.5 bg-surface-container rounded border border-outline-variant text-primary-fixed uppercase tracking-wider">GPX READY</span>
|
||||
</div>
|
||||
</article>
|
||||
</section>
|
||||
</div>
|
||||
</main>
|
||||
<!-- FIXED BOTTOM NAVIGATION BAR (Shared Component Anchor) -->
|
||||
<!-- Contextual Active: Rider Profile / Social ecosystem selected -->
|
||||
<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 dark:bg-surface-container-lowest border-t border-outline-variant dark:border-outline-variant">
|
||||
<!-- Dash -->
|
||||
<a class="flex flex-col items-center justify-center text-on-surface-variant dark:text-on-surface-variant px-2 py-1 min-h-[48px] hover:bg-surface-container-low dark:hover:bg-surface-container-low hover:text-primary-fixed dark:hover:text-primary-fixed active:scale-95 duration-100 ease-out" href="#">
|
||||
<span class="material-symbols-outlined text-[24px]" data-icon="speed">speed</span>
|
||||
<span class="text-label-caption font-label-caption mt-0.5">Dash</span>
|
||||
</a>
|
||||
<!-- Map -->
|
||||
<a class="flex flex-col items-center justify-center text-on-surface-variant dark:text-on-surface-variant px-2 py-1 min-h-[48px] hover:bg-surface-container-low dark:hover:bg-surface-container-low hover:text-primary-fixed dark:hover:text-primary-fixed active:scale-95 duration-100 ease-out" href="#">
|
||||
<span class="material-symbols-outlined text-[24px]" data-icon="navigation">navigation</span>
|
||||
<span class="text-label-caption font-label-caption mt-0.5">Map</span>
|
||||
</a>
|
||||
<!-- Activity -->
|
||||
<a class="flex flex-col items-center justify-center text-on-surface-variant dark:text-on-surface-variant px-2 py-1 min-h-[48px] hover:bg-surface-container-low dark:hover:bg-surface-container-low hover:text-primary-fixed dark:hover:text-primary-fixed active:scale-95 duration-100 ease-out" href="#">
|
||||
<span class="material-symbols-outlined text-[24px]" data-icon="analytics">analytics</span>
|
||||
<span class="text-label-caption font-label-caption mt-0.5">Activity</span>
|
||||
</a>
|
||||
<!-- Garage -->
|
||||
<a class="flex flex-col items-center justify-center text-on-surface-variant dark:text-on-surface-variant px-2 py-1 min-h-[48px] hover:bg-surface-container-low dark:hover:bg-surface-container-low hover:text-primary-fixed dark:hover:text-primary-fixed active:scale-95 duration-100 ease-out" href="#">
|
||||
<span class="material-symbols-outlined text-[24px]" data-icon="two_wheeler">two_wheeler</span>
|
||||
<span class="text-label-caption font-label-caption mt-0.5">Garage</span>
|
||||
</a>
|
||||
<!-- Social (ACTIVE STATE ON PROFILE) -->
|
||||
<a class="flex flex-col items-center justify-center bg-surface-container-high dark:bg-surface-container-high text-primary-container dark:text-primary-container rounded-lg px-2 py-1 min-h-[48px] active:scale-95 duration-100 ease-out cyan-border-glow" href="#">
|
||||
<span class="material-symbols-outlined text-[24px]" data-icon="group" data-weight="fill">group</span>
|
||||
<span class="text-label-caption font-label-caption font-bold mt-0.5">Social</span>
|
||||
</a>
|
||||
<!-- Settings -->
|
||||
<a class="flex flex-col items-center justify-center text-on-surface-variant dark:text-on-surface-variant px-2 py-1 min-h-[48px] hover:bg-surface-container-low dark:hover:bg-surface-container-low hover:text-primary-fixed dark:hover:text-primary-fixed active:scale-95 duration-100 ease-out" href="#">
|
||||
<span class="material-symbols-outlined text-[24px]" data-icon="settings">settings</span>
|
||||
<span class="text-label-caption font-label-caption mt-0.5">Settings</span>
|
||||
</a>
|
||||
</nav>
|
||||
</body></html>
|
||||
|
|
@ -0,0 +1,490 @@
|
|||
<!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 - Pack Network // SOC-03</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&family=JetBrains+Mono:wght@500;600;700&family=Space+Grotesk:wght@500;600;700&display=swap" rel="stylesheet"/>
|
||||
<!-- Material Symbols Outlined -->
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<!-- Tailwind CSS v3 -->
|
||||
<script src="https://cdn.tailwindcss.com?plugins=forms,container-queries"></script>
|
||||
<script id="tailwind-config">
|
||||
tailwind.config = {
|
||||
darkMode: "class",
|
||||
theme: {
|
||||
extend: {
|
||||
"colors": {
|
||||
"surface-container": "#1d2025",
|
||||
"surface-dim": "#101419",
|
||||
"on-primary-fixed-variant": "#004f58",
|
||||
"inverse-surface": "#e0e2ea",
|
||||
"on-tertiary-container": "#6834d1",
|
||||
"secondary-fixed-dim": "#b4c5ff",
|
||||
"error": "#ffb4ab",
|
||||
"surface-bright": "#36393f",
|
||||
"surface": "#101419",
|
||||
"on-primary-fixed": "#001f24",
|
||||
"on-secondary": "#002a78",
|
||||
"error-container": "#93000a",
|
||||
"surface-variant": "#32353b",
|
||||
"on-surface-variant": "#bac9cc",
|
||||
"on-surface": "#e0e2ea",
|
||||
"surface-container-highest": "#32353b",
|
||||
"secondary-container": "#0053db",
|
||||
"on-tertiary-fixed-variant": "#5516be",
|
||||
"on-error": "#690005",
|
||||
"outline": "#849396",
|
||||
"inverse-on-surface": "#2d3036",
|
||||
"on-secondary-fixed": "#00174b",
|
||||
"inverse-primary": "#006875",
|
||||
"surface-tint": "#00daf3",
|
||||
"surface-container-high": "#272a30",
|
||||
"on-primary-container": "#00626e",
|
||||
"on-secondary-fixed-variant": "#003ea8",
|
||||
"on-background": "#e0e2ea",
|
||||
"tertiary": "#f2e9ff",
|
||||
"primary": "#c3f5ff",
|
||||
"on-error-container": "#ffdad6",
|
||||
"tertiary-fixed-dim": "#d0bcff",
|
||||
"primary-fixed": "#9cf0ff",
|
||||
"primary-container": "#00e5ff",
|
||||
"on-tertiary-fixed": "#23005c",
|
||||
"tertiary-container": "#d9c8ff",
|
||||
"tertiary-fixed": "#e9ddff",
|
||||
"outline-variant": "#3b494c",
|
||||
"on-primary": "#00363d",
|
||||
"surface-container-low": "#181c21",
|
||||
"secondary": "#b4c5ff",
|
||||
"primary-fixed-dim": "#00daf3",
|
||||
"on-tertiary": "#3c0091",
|
||||
"surface-container-lowest": "#0b0e13",
|
||||
"secondary-fixed": "#dbe1ff",
|
||||
"on-secondary-container": "#cdd7ff",
|
||||
"background": "#101419"
|
||||
},
|
||||
"borderRadius": {
|
||||
"DEFAULT": "0.25rem",
|
||||
"lg": "0.5rem",
|
||||
"xl": "0.75rem",
|
||||
"full": "9999px"
|
||||
},
|
||||
"spacing": {
|
||||
"space-md": "1rem",
|
||||
"margin-lg": "2rem",
|
||||
"space-xl": "2rem",
|
||||
"margin": "1rem",
|
||||
"space-sm": "0.5rem",
|
||||
"space-lg": "1.5rem",
|
||||
"space-xs": "0.25rem",
|
||||
"gutter": "1rem",
|
||||
"gutter-lg": "1.5rem"
|
||||
},
|
||||
"fontFamily": {
|
||||
"headline-lg": ["Space Grotesk"],
|
||||
"label-caption": ["Inter"],
|
||||
"headline-sm": ["Space Grotesk"],
|
||||
"body-lg": ["Inter"],
|
||||
"telemetry-metric-md": ["JetBrains Mono"],
|
||||
"telemetry-metric-lg-mobile": ["JetBrains Mono"],
|
||||
"body-md": ["Inter"],
|
||||
"display-hero": ["Space Grotesk"],
|
||||
"display-hero-mobile": ["Space Grotesk"],
|
||||
"headline-md": ["Space Grotesk"],
|
||||
"telemetry-metric-lg": ["JetBrains Mono"],
|
||||
"label-data": ["JetBrains Mono"]
|
||||
},
|
||||
"fontSize": {
|
||||
"headline-lg": ["32px", { "lineHeight": "40px", "letterSpacing": "-0.02em", "fontWeight": "700" }],
|
||||
"label-caption": ["11px", { "lineHeight": "14px", "letterSpacing": "0.05em", "fontWeight": "600" }],
|
||||
"headline-sm": ["20px", { "lineHeight": "28px", "fontWeight": "600" }],
|
||||
"body-lg": ["16px", { "lineHeight": "24px", "fontWeight": "500" }],
|
||||
"telemetry-metric-md": ["28px", { "lineHeight": "32px", "letterSpacing": "-0.02em", "fontWeight": "600" }],
|
||||
"telemetry-metric-lg-mobile": ["36px", { "lineHeight": "36px", "letterSpacing": "-0.03em", "fontWeight": "700" }],
|
||||
"body-md": ["14px", { "lineHeight": "20px", "fontWeight": "400" }],
|
||||
"display-hero": ["56px", { "lineHeight": "60px", "letterSpacing": "-0.03em", "fontWeight": "700" }],
|
||||
"display-hero-mobile": ["40px", { "lineHeight": "44px", "letterSpacing": "-0.02em", "fontWeight": "700" }],
|
||||
"headline-md": ["24px", { "lineHeight": "32px", "letterSpacing": "-0.01em", "fontWeight": "600" }],
|
||||
"telemetry-metric-lg": ["48px", { "lineHeight": "48px", "letterSpacing": "-0.04em", "fontWeight": "700" }],
|
||||
"label-data": ["12px", { "lineHeight": "16px", "letterSpacing": "0.08em", "fontWeight": "600" }]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.material-symbols-outlined {
|
||||
font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24;
|
||||
}
|
||||
.hud-cyan-glow {
|
||||
box-shadow: 0 0 16px rgba(0, 229, 255, 0.25);
|
||||
}
|
||||
.hud-amber-glow {
|
||||
box-shadow: 0 0 16px rgba(245, 158, 11, 0.25);
|
||||
}
|
||||
/* Touch Target enforce */
|
||||
.touch-target-48 {
|
||||
min-height: 48px;
|
||||
min-width: 48px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-surface-container-lowest text-on-surface antialiased selection:bg-primary-container selection:text-surface-container-lowest font-body-md overflow-x-hidden pb-24">
|
||||
<!-- TOP APP BAR -->
|
||||
<header class="fixed top-0 left-0 w-full z-50 flex justify-between items-center px-gutter h-16 bg-surface-container-lowest/95 backdrop-blur-md border-b border-outline-variant">
|
||||
<div class="flex items-center gap-space-sm">
|
||||
<button aria-label="Mesh Network Status" class="touch-target-48 flex items-center justify-center text-primary-container active:scale-95 duration-100 ease-out">
|
||||
<span class="material-symbols-outlined text-primary-container" data-icon="sensors">sensors</span>
|
||||
</button>
|
||||
<div>
|
||||
<div class="flex items-center gap-1.5">
|
||||
<span class="w-2 h-2 rounded-full bg-primary-container animate-pulse"></span>
|
||||
<h1 class="text-headline-sm font-headline-sm font-bold tracking-wider text-primary-container">
|
||||
PACK NETWORK <span class="text-on-surface-variant font-label-data text-label-data font-normal">// SOC-03</span>
|
||||
</h1>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="text-label-data font-label-data text-primary-fixed text-[10px] tracking-widest uppercase">20Hz GNSS SYNCED</span>
|
||||
<span class="text-outline-variant text-[10px]">|</span>
|
||||
<span class="text-label-data font-label-data text-on-surface-variant text-[10px] flex items-center gap-0.5">
|
||||
<span class="material-symbols-outlined text-[13px] text-primary" data-icon="battery_full">battery_full</span> 98%
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Right HUD Badges & User Avatar -->
|
||||
<div class="flex items-center gap-space-sm">
|
||||
<button aria-label="System Alerts" class="touch-target-48 relative flex items-center justify-center text-on-surface-variant hover:text-primary-container active:scale-95 duration-100 ease-out">
|
||||
<span class="material-symbols-outlined text-on-surface-variant" data-icon="warning">warning</span>
|
||||
<span class="absolute top-2.5 right-2.5 w-2 h-2 rounded-full bg-primary-container hud-cyan-glow"></span>
|
||||
</button>
|
||||
<!-- Rider Profile Avatar Badge -->
|
||||
<div class="relative w-10 h-10 rounded-lg overflow-hidden border border-primary-container/60 shadow-sm hud-cyan-glow">
|
||||
<img alt="User Profile" class="w-full h-full object-cover" src="https://lh3.googleusercontent.com/aida/AEtjO1WVxZBfZMbTdHeRSt73fWRy6gjWk3_qTm8SSSfoWQnQsHYP2ngztRX-GwRDxracXqrxt42j0x_3rYX-Deu1wGtF7R_qj3ZMExn0d6mErdfGFPGmEtddnnmd0i_Ez6Mv8kj3AYzks1N9Gq4hr9VObylWxDqngSG4Yi5vS-Sj7j3tfyZc_6dknnGpnnb5vC4PQmhuUp58_MzZvopIwkRWq0S27smUu_5zRLguTCXTKrFUEw9TiLBSRA4aXu4"/>
|
||||
<div class="absolute bottom-0 right-0 w-2.5 h-2.5 bg-primary-container border-2 border-surface-container-lowest rounded-full"></div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<!-- MAIN SCROLLABLE CONTENT -->
|
||||
<main class="mt-16 px-gutter pt-4 space-y-5 max-w-lg mx-auto">
|
||||
<!-- SEARCH & COCKPIT INPUT BAR -->
|
||||
<div class="space-y-3">
|
||||
<div class="relative flex items-center">
|
||||
<span class="absolute left-3.5 text-outline material-symbols-outlined pointer-events-none text-[20px]" data-icon="search">search</span>
|
||||
<input class="w-full h-12 pl-11 pr-4 bg-surface-container-low border border-outline-variant rounded-xl text-body-md font-body-md text-on-surface placeholder:text-outline focus:outline-none focus:border-primary-container focus:ring-1 focus:ring-primary-container duration-150 transition-all font-label-caption" placeholder="Search riders by callsign, handle, or club..." type="text"/>
|
||||
<button aria-label="Filter voice tags" class="absolute right-2 px-2 py-1 text-label-data font-label-data text-outline hover:text-primary-container touch-target-48 flex items-center justify-center">
|
||||
<span class="material-symbols-outlined text-[18px]" data-icon="mic">mic</span>
|
||||
</button>
|
||||
</div>
|
||||
<!-- Quick Filter Pills -->
|
||||
<div class="flex items-center gap-2 overflow-x-auto pb-1 no-scrollbar">
|
||||
<button class="px-3.5 py-1.5 rounded-full bg-surface-container-high border border-primary-container text-primary-container font-label-caption text-label-caption whitespace-nowrap active:scale-95 duration-100 ease-out shadow-[0_0_10px_rgba(0,229,255,0.2)]">
|
||||
All (28)
|
||||
</button>
|
||||
<button class="px-3.5 py-1.5 rounded-full bg-surface-container-low border border-outline-variant text-on-surface-variant hover:border-primary-container hover:text-primary-container font-label-caption text-label-caption whitespace-nowrap active:scale-95 duration-100 ease-out">
|
||||
<span class="inline-block w-1.5 h-1.5 rounded-full bg-primary-container mr-1.5 animate-pulse"></span>Online Now (9)
|
||||
</button>
|
||||
<button class="px-3.5 py-1.5 rounded-full bg-surface-container-low border border-outline-variant text-on-surface-variant hover:border-primary-container hover:text-primary-container font-label-caption text-label-caption whitespace-nowrap active:scale-95 duration-100 ease-out">
|
||||
In-Flight (4)
|
||||
</button>
|
||||
<button class="px-3.5 py-1.5 rounded-full bg-surface-container-low border border-outline-variant text-on-surface-variant hover:border-primary-container hover:text-primary-container font-label-caption text-label-caption whitespace-nowrap active:scale-95 duration-100 ease-out">
|
||||
Club Comms
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- ALERT / NOTIFICATION BANNER: PENDING PACK INVITES -->
|
||||
<section class="bg-surface-container-low border border-outline-variant rounded-xl p-3.5 relative overflow-hidden backdrop-blur-md">
|
||||
<div class="absolute -right-10 -bottom-10 w-24 h-24 bg-primary-container/10 rounded-full blur-2xl pointer-events-none"></div>
|
||||
<div class="flex items-center justify-between mb-2.5">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-primary-container text-[20px]" data-icon="group_add">group_add</span>
|
||||
<span class="font-headline-sm text-headline-sm text-sm font-bold tracking-wide uppercase text-on-surface">2 Pending Pack Invites</span>
|
||||
</div>
|
||||
<span class="px-2 py-0.5 rounded bg-surface-container-highest border border-outline-variant text-primary-container font-label-data text-[10px] tracking-wider font-bold">
|
||||
URGENT MESH
|
||||
</span>
|
||||
</div>
|
||||
<!-- Invite Item 1 -->
|
||||
<div class="bg-surface-container-lowest/80 border border-outline-variant/70 rounded-lg p-2.5 mb-2 flex items-center justify-between">
|
||||
<div class="flex items-center gap-2.5">
|
||||
<div class="w-8 h-8 rounded-lg bg-surface-container-high border border-primary-container/40 flex items-center justify-center font-label-data text-primary-container font-bold text-xs">
|
||||
AM
|
||||
</div>
|
||||
<div>
|
||||
<div class="text-body-md font-body-md font-bold text-on-surface text-xs">@ApexMarcus</div>
|
||||
<div class="text-label-caption font-label-caption text-on-surface-variant text-[10px]">wants to link 20Hz Mesh</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-1.5">
|
||||
<button class="min-h-[40px] px-3 rounded-lg bg-primary-container text-surface-container-lowest font-label-data text-label-data font-bold active:scale-95 duration-100 ease-out hud-cyan-glow">
|
||||
Accept
|
||||
</button>
|
||||
<button class="min-h-[40px] px-2.5 rounded-lg border border-outline-variant text-on-surface-variant font-label-data text-label-data hover:text-on-surface active:scale-95 duration-100 ease-out">
|
||||
Review
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Invite Item 2 -->
|
||||
<div class="bg-surface-container-lowest/80 border border-outline-variant/70 rounded-lg p-2.5 flex items-center justify-between">
|
||||
<div class="flex items-center gap-2.5">
|
||||
<div class="w-8 h-8 rounded-lg bg-surface-container-high border border-outline-variant flex items-center justify-center font-label-data text-secondary font-bold text-xs">
|
||||
NT
|
||||
</div>
|
||||
<div>
|
||||
<div class="text-body-md font-body-md font-bold text-on-surface text-xs">@NorCal_Torque</div>
|
||||
<div class="text-label-caption font-label-caption text-on-surface-variant text-[10px]">P2P Comms link request</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-1.5">
|
||||
<button class="min-h-[40px] px-3 rounded-lg bg-primary-container text-surface-container-lowest font-label-data text-label-data font-bold active:scale-95 duration-100 ease-out hud-cyan-glow">
|
||||
Accept
|
||||
</button>
|
||||
<button class="min-h-[40px] px-2.5 rounded-lg border border-outline-variant text-on-surface-variant font-label-data text-label-data hover:text-on-surface active:scale-95 duration-100 ease-out">
|
||||
Review
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- SECTION TITLE -->
|
||||
<div class="flex items-center justify-between pt-1">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="w-1.5 h-3.5 bg-primary-container rounded-sm"></span>
|
||||
<h2 class="text-headline-sm font-headline-sm font-bold text-on-surface tracking-tight">
|
||||
Pack Network & Riding Buddies <span class="text-on-surface-variant font-label-data text-sm font-normal">(28)</span>
|
||||
</h2>
|
||||
</div>
|
||||
<button class="text-label-data font-label-data text-primary-container hover:underline text-xs flex items-center gap-0.5">
|
||||
<span class="material-symbols-outlined text-[16px]" data-icon="tune">tune</span> SORT
|
||||
</button>
|
||||
</div>
|
||||
<!-- RIDER CARD 1: @SarahSweep -->
|
||||
<article class="bg-surface-container-low border border-outline-variant rounded-xl p-4 transition-all duration-150 hover:border-primary-container/80 space-y-3 relative overflow-hidden">
|
||||
<!-- Top meta info -->
|
||||
<div class="flex items-start justify-between">
|
||||
<div class="flex gap-3">
|
||||
<div class="relative w-12 h-12 rounded-xl bg-surface-container-high border border-outline-variant flex items-center justify-center text-primary-container font-headline-sm font-bold text-base">
|
||||
SS
|
||||
<span class="absolute -bottom-1 -right-1 w-3 h-3 rounded-full bg-primary-container border-2 border-surface-container-low"></span>
|
||||
</div>
|
||||
<div>
|
||||
<div class="flex items-center gap-1.5">
|
||||
<h3 class="text-headline-sm font-headline-sm text-base font-bold text-on-surface tracking-tight">@SarahSweep</h3>
|
||||
<span class="material-symbols-outlined text-primary-container text-[16px]" data-icon="verified">verified</span>
|
||||
</div>
|
||||
<p class="text-label-caption font-label-caption text-on-surface-variant text-[11px]">
|
||||
Road Captain • Pacific Coast Riders MC
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<span class="px-2 py-0.5 rounded bg-surface-container-highest text-primary-container font-label-data text-[10px] uppercase font-bold border border-primary-container/30">
|
||||
CH-01
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Live telemetry status banner -->
|
||||
<div class="bg-surface-container-lowest/90 border border-outline-variant/60 rounded-lg px-2.5 py-1.5 flex items-center gap-2">
|
||||
<span class="w-2 h-2 rounded-full bg-primary-container animate-ping"></span>
|
||||
<span class="text-label-data font-label-data text-primary-container text-[11px] font-semibold">
|
||||
Online • Riding Skyline Blvd (44 MPH)
|
||||
</span>
|
||||
</div>
|
||||
<!-- Telemetry chips -->
|
||||
<div class="flex flex-wrap gap-1.5 pt-0.5">
|
||||
<span class="px-2.5 py-1 rounded bg-surface-container-high border border-outline-variant text-on-surface-variant font-label-data text-[11px]">
|
||||
18 Mutual Rides
|
||||
</span>
|
||||
<span class="px-2.5 py-1 rounded bg-surface-container-high border border-primary-container/40 text-primary-container font-label-data text-[11px] font-bold">
|
||||
Max Lean: 48° R
|
||||
</span>
|
||||
<span class="px-2.5 py-1 rounded bg-surface-container-high border border-outline-variant text-on-surface font-label-data text-[11px]">
|
||||
KTM 890 Duke R
|
||||
</span>
|
||||
</div>
|
||||
<!-- 48px+ Glove-friendly primary CTA -->
|
||||
<button class="w-full min-h-[50px] rounded-lg bg-primary-container text-surface-container-lowest font-headline-sm font-bold text-sm tracking-wider uppercase flex items-center justify-center gap-2 hover:bg-primary-fixed-dim active:scale-95 duration-100 ease-out hud-cyan-glow">
|
||||
<span class="material-symbols-outlined text-[20px]" data-icon="cell_tower">cell_tower</span>
|
||||
Invite to Mesh
|
||||
</button>
|
||||
</article>
|
||||
<!-- RIDER CARD 2: @KevBL -->
|
||||
<article class="bg-surface-container-low border border-outline-variant rounded-xl p-4 transition-all duration-150 hover:border-primary-container/80 space-y-3 relative overflow-hidden">
|
||||
<div class="flex items-start justify-between">
|
||||
<div class="flex gap-3">
|
||||
<div class="relative w-12 h-12 rounded-xl bg-surface-container-high border border-outline-variant flex items-center justify-center text-secondary font-headline-sm font-bold text-base">
|
||||
KB
|
||||
<span class="absolute -bottom-1 -right-1 w-3 h-3 rounded-full bg-primary-container border-2 border-surface-container-low"></span>
|
||||
</div>
|
||||
<div>
|
||||
<div class="flex items-center gap-1.5">
|
||||
<h3 class="text-headline-sm font-headline-sm text-base font-bold text-on-surface tracking-tight">@KevBL</h3>
|
||||
<span class="material-symbols-outlined text-secondary text-[16px]" data-icon="shield">shield</span>
|
||||
</div>
|
||||
<p class="text-label-caption font-label-caption text-on-surface-variant text-[11px]">
|
||||
President • Pacific Coast Riders MC
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<span class="px-2 py-0.5 rounded bg-surface-container-highest text-secondary font-label-data text-[10px] uppercase font-bold border border-outline-variant">
|
||||
CH-01
|
||||
</span>
|
||||
</div>
|
||||
<!-- Live telemetry status banner -->
|
||||
<div class="bg-surface-container-lowest/90 border border-outline-variant/60 rounded-lg px-2.5 py-1.5 flex items-center gap-2">
|
||||
<span class="w-2 h-2 rounded-full bg-secondary-container animate-pulse"></span>
|
||||
<span class="text-label-data font-label-data text-secondary text-[11px] font-semibold">
|
||||
Online • Staged at Alice's Restaurant (KSU 22m)
|
||||
</span>
|
||||
</div>
|
||||
<!-- Telemetry chips -->
|
||||
<div class="flex flex-wrap gap-1.5 pt-0.5">
|
||||
<span class="px-2.5 py-1 rounded bg-surface-container-high border border-outline-variant text-on-surface-variant font-label-data text-[11px]">
|
||||
46 Mutual Rides
|
||||
</span>
|
||||
<span class="px-2.5 py-1 rounded bg-surface-container-high border border-outline-variant text-on-surface font-label-data text-[11px]">
|
||||
BMW S1000RR M-Pack
|
||||
</span>
|
||||
<span class="px-2.5 py-1 rounded bg-surface-container-high border border-outline-variant text-on-surface-variant font-label-data text-[11px]">
|
||||
Radar: 1.2mi
|
||||
</span>
|
||||
</div>
|
||||
<!-- CTA -->
|
||||
<button class="w-full min-h-[50px] rounded-lg border-2 border-primary-container text-primary-container bg-surface-container-low hover:bg-primary-container hover:text-surface-container-lowest font-headline-sm font-bold text-sm tracking-wider uppercase flex items-center justify-center gap-2 active:scale-95 duration-100 ease-out">
|
||||
<span class="material-symbols-outlined text-[20px]" data-icon="hub">hub</span>
|
||||
Join Pack
|
||||
</button>
|
||||
</article>
|
||||
<!-- RIDER CARD 3: @Dave_Lead -->
|
||||
<article class="bg-surface-container-low border border-outline-variant/70 rounded-xl p-4 space-y-3 relative overflow-hidden opacity-90">
|
||||
<div class="flex items-start justify-between">
|
||||
<div class="flex gap-3">
|
||||
<div class="relative w-12 h-12 rounded-xl bg-surface-container border border-outline-variant flex items-center justify-center text-outline font-headline-sm font-bold text-base">
|
||||
DL
|
||||
<span class="absolute -bottom-1 -right-1 w-3 h-3 rounded-full bg-outline-variant border-2 border-surface-container-low"></span>
|
||||
</div>
|
||||
<div>
|
||||
<div class="flex items-center gap-1.5">
|
||||
<h3 class="text-headline-sm font-headline-sm text-base font-bold text-on-surface tracking-tight">@Dave_Lead</h3>
|
||||
</div>
|
||||
<p class="text-label-caption font-label-caption text-on-surface-variant text-[11px]">
|
||||
Lead Captain • Pacific Coast Riders MC
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<span class="px-2 py-0.5 rounded bg-surface-container text-outline font-label-data text-[10px] uppercase font-bold border border-outline-variant">
|
||||
STANDBY
|
||||
</span>
|
||||
</div>
|
||||
<!-- Telemetry status -->
|
||||
<div class="bg-surface-container-lowest/70 border border-outline-variant/40 rounded-lg px-2.5 py-1.5 flex items-center gap-2">
|
||||
<span class="w-2 h-2 rounded-full bg-outline"></span>
|
||||
<span class="text-label-data font-label-data text-outline text-[11px]">
|
||||
Offline • Last active 2h ago
|
||||
</span>
|
||||
</div>
|
||||
<!-- Chips -->
|
||||
<div class="flex flex-wrap gap-1.5 pt-0.5">
|
||||
<span class="px-2.5 py-1 rounded bg-surface-container-high border border-outline-variant text-on-surface-variant font-label-data text-[11px]">
|
||||
32 Mutual Rides
|
||||
</span>
|
||||
<span class="px-2.5 py-1 rounded bg-surface-container-high border border-outline-variant text-on-surface font-label-data text-[11px]">
|
||||
Ducati Panigale V4
|
||||
</span>
|
||||
<span class="px-2.5 py-1 rounded bg-surface-container-high border border-outline-variant text-on-surface-variant font-label-data text-[11px]">
|
||||
Pace 3 Brisk
|
||||
</span>
|
||||
</div>
|
||||
<!-- CTA -->
|
||||
<button class="w-full min-h-[48px] rounded-lg border border-outline-variant text-on-surface-variant hover:text-primary-container hover:border-primary-container bg-surface-container font-headline-sm font-semibold text-xs tracking-wider uppercase flex items-center justify-center gap-2 active:scale-95 duration-100 ease-out">
|
||||
<span class="material-symbols-outlined text-[18px]" data-icon="podcasts">podcasts</span>
|
||||
Ping Callsign
|
||||
</button>
|
||||
</article>
|
||||
<!-- RIDER CARD 4: @ElenaADV -->
|
||||
<article class="bg-surface-container-low border border-outline-variant rounded-xl p-4 transition-all duration-150 hover:border-primary-container/80 space-y-3 relative overflow-hidden">
|
||||
<div class="flex items-start justify-between">
|
||||
<div class="flex gap-3">
|
||||
<div class="relative w-12 h-12 rounded-xl bg-surface-container-high border border-outline-variant flex items-center justify-center text-primary-fixed-dim font-headline-sm font-bold text-base">
|
||||
EA
|
||||
<span class="absolute -bottom-1 -right-1 w-3 h-3 rounded-full bg-primary-container border-2 border-surface-container-low"></span>
|
||||
</div>
|
||||
<div>
|
||||
<div class="flex items-center gap-1.5">
|
||||
<h3 class="text-headline-sm font-headline-sm text-base font-bold text-on-surface tracking-tight">@ElenaADV</h3>
|
||||
</div>
|
||||
<p class="text-label-caption font-label-caption text-on-surface-variant text-[11px]">
|
||||
Mid-Marshal • Sierra ADV Collective
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<span class="px-2 py-0.5 rounded bg-surface-container-highest text-primary-container font-label-data text-[10px] uppercase font-bold border border-primary-container/30">
|
||||
MESH CH-02
|
||||
</span>
|
||||
</div>
|
||||
<!-- Telemetry status -->
|
||||
<div class="bg-surface-container-lowest/90 border border-outline-variant/60 rounded-lg px-2.5 py-1.5 flex items-center gap-2">
|
||||
<span class="w-2 h-2 rounded-full bg-primary-container"></span>
|
||||
<span class="text-label-data font-label-data text-primary-container text-[11px] font-semibold">
|
||||
Online • Standby in Garage
|
||||
</span>
|
||||
</div>
|
||||
<!-- Chips -->
|
||||
<div class="flex flex-wrap gap-1.5 pt-0.5">
|
||||
<span class="px-2.5 py-1 rounded bg-surface-container-high border border-outline-variant text-on-surface-variant font-label-data text-[11px]">
|
||||
12 Mutual Rides
|
||||
</span>
|
||||
<span class="px-2.5 py-1 rounded bg-surface-container-high border border-outline-variant text-on-surface font-label-data text-[11px]">
|
||||
BMW R1250GS
|
||||
</span>
|
||||
<span class="px-2.5 py-1 rounded bg-surface-container-high border border-outline-variant text-on-surface-variant font-label-data text-[11px]">
|
||||
Mesh CH-02
|
||||
</span>
|
||||
</div>
|
||||
<!-- CTA -->
|
||||
<button class="w-full min-h-[48px] rounded-lg border border-primary-container/60 text-primary-container bg-surface-container-high hover:bg-primary-container hover:text-surface-container-lowest font-headline-sm font-semibold text-xs tracking-wider uppercase flex items-center justify-center gap-2 active:scale-95 duration-100 ease-out">
|
||||
<span class="material-symbols-outlined text-[18px]" data-icon="link">link</span>
|
||||
Connect
|
||||
</button>
|
||||
</article>
|
||||
<!-- ACTION SECTION: INVITATION PROMINENT GLOVE-FRIENDLY BUTTON -->
|
||||
<div class="pt-2 pb-6">
|
||||
<button class="w-full min-h-[54px] rounded-xl bg-gradient-to-r from-surface-container-high via-surface-container-highest to-surface-container-high border-2 border-primary-container text-primary-container font-headline-sm font-bold text-sm tracking-widest uppercase flex items-center justify-center gap-3 active:scale-95 duration-100 ease-out hud-cyan-glow">
|
||||
<span class="material-symbols-outlined text-[24px]" data-icon="qr_code_scanner">qr_code_scanner</span>
|
||||
Invite Rider via QR / Link
|
||||
<span class="material-symbols-outlined text-[20px]" data-icon="share">share</span>
|
||||
</button>
|
||||
</div>
|
||||
</main>
|
||||
<!-- BOTTOM NAVIGATION BAR (Shared Component Anchor) -->
|
||||
<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 dark:bg-surface-container-lowest border-t border-outline-variant dark:border-outline-variant">
|
||||
<!-- Dash Destination -->
|
||||
<button aria-label="Dash" class="flex flex-col items-center justify-center text-on-surface-variant dark:text-on-surface-variant px-2 py-1 min-h-[48px] hover:bg-surface-container-low dark:hover:bg-surface-container-low hover:text-primary-fixed dark:hover:text-primary-fixed active:scale-95 duration-100 ease-out">
|
||||
<span class="material-symbols-outlined text-[22px]" data-icon="speed">speed</span>
|
||||
<span class="text-label-caption font-label-caption mt-0.5">Dash</span>
|
||||
</button>
|
||||
<!-- Map Destination -->
|
||||
<button aria-label="Map" class="flex flex-col items-center justify-center text-on-surface-variant dark:text-on-surface-variant px-2 py-1 min-h-[48px] hover:bg-surface-container-low dark:hover:bg-surface-container-low hover:text-primary-fixed dark:hover:text-primary-fixed active:scale-95 duration-100 ease-out">
|
||||
<span class="material-symbols-outlined text-[22px]" data-icon="navigation">navigation</span>
|
||||
<span class="text-label-caption font-label-caption mt-0.5">Map</span>
|
||||
</button>
|
||||
<!-- Activity Destination -->
|
||||
<button aria-label="Activity" class="flex flex-col items-center justify-center text-on-surface-variant dark:text-on-surface-variant px-2 py-1 min-h-[48px] hover:bg-surface-container-low dark:hover:bg-surface-container-low hover:text-primary-fixed dark:hover:text-primary-fixed active:scale-95 duration-100 ease-out">
|
||||
<span class="material-symbols-outlined text-[22px]" data-icon="analytics">analytics</span>
|
||||
<span class="text-label-caption font-label-caption mt-0.5">Activity</span>
|
||||
</button>
|
||||
<!-- Garage Destination -->
|
||||
<button aria-label="Garage" class="flex flex-col items-center justify-center text-on-surface-variant dark:text-on-surface-variant px-2 py-1 min-h-[48px] hover:bg-surface-container-low dark:hover:bg-surface-container-low hover:text-primary-fixed dark:hover:text-primary-fixed active:scale-95 duration-100 ease-out">
|
||||
<span class="material-symbols-outlined text-[22px]" data-icon="two_wheeler">two_wheeler</span>
|
||||
<span class="text-label-caption font-label-caption mt-0.5">Garage</span>
|
||||
</button>
|
||||
<!-- Settings / Active Contextual Destination (Active item configured per rules) -->
|
||||
<button aria-label="Settings" class="flex flex-col items-center justify-center bg-surface-container-high dark:bg-surface-container-high text-primary-container dark:text-primary-container rounded-lg px-2 py-1 min-h-[48px] active:scale-95 duration-100 ease-out border border-primary-container/40 hud-cyan-glow">
|
||||
<span class="material-symbols-outlined text-[22px]" data-icon="settings">settings</span>
|
||||
<span class="text-label-caption font-label-caption mt-0.5 font-bold">Settings</span>
|
||||
</button>
|
||||
</nav>
|
||||
</body></html>
|
||||
|
|
@ -0,0 +1,467 @@
|
|||
<!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 HUD // Clubs Discovery</title>
|
||||
<!-- Fonts & Material Symbols -->
|
||||
<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&family=JetBrains+Mono:wght@500;600;700&family=Space+Grotesk:wght@600;700&family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@100..900&family=JetBrains+Mono:wght@100..900&family=Space+Grotesk:wght@100..900&display=swap" rel="stylesheet"/>
|
||||
<!-- Tailwind CSS with CDN -->
|
||||
<script src="https://cdn.tailwindcss.com?plugins=forms,container-queries"></script>
|
||||
<script id="tailwind-config">
|
||||
tailwind.config = {
|
||||
darkMode: "class",
|
||||
theme: {
|
||||
extend: {
|
||||
"colors": {
|
||||
"secondary": "#b4c5ff",
|
||||
"surface-container": "#1d2025",
|
||||
"surface-tint": "#00daf3",
|
||||
"surface-container-low": "#181c21",
|
||||
"on-error-container": "#ffdad6",
|
||||
"inverse-surface": "#e0e2ea",
|
||||
"surface-container-high": "#272a30",
|
||||
"tertiary-fixed-dim": "#d0bcff",
|
||||
"primary-fixed-dim": "#00daf3",
|
||||
"surface-container-highest": "#32353b",
|
||||
"on-primary-container": "#00626e",
|
||||
"on-primary-fixed": "#001f24",
|
||||
"surface-container-lowest": "#0b0e13",
|
||||
"secondary-fixed": "#dbe1ff",
|
||||
"primary-container": "#00e5ff",
|
||||
"surface": "#101419",
|
||||
"background": "#101419",
|
||||
"outline": "#849396",
|
||||
"on-error": "#690005",
|
||||
"primary-fixed": "#9cf0ff",
|
||||
"on-tertiary-container": "#6834d1",
|
||||
"primary": "#c3f5ff",
|
||||
"secondary-container": "#0053db",
|
||||
"surface-variant": "#32353b",
|
||||
"tertiary": "#f2e9ff",
|
||||
"on-secondary-fixed-variant": "#003ea8",
|
||||
"on-primary-fixed-variant": "#004f58",
|
||||
"on-secondary": "#002a78",
|
||||
"on-background": "#e0e2ea",
|
||||
"tertiary-container": "#d9c8ff",
|
||||
"on-surface-variant": "#bac9cc",
|
||||
"on-tertiary-fixed": "#23005c",
|
||||
"surface-bright": "#36393f",
|
||||
"error": "#ffb4ab",
|
||||
"on-tertiary-fixed-variant": "#5516be",
|
||||
"on-surface": "#e0e2ea",
|
||||
"on-secondary-fixed": "#00174b",
|
||||
"inverse-on-surface": "#2d3036",
|
||||
"secondary-fixed-dim": "#b4c5ff",
|
||||
"surface-dim": "#101419",
|
||||
"outline-variant": "#3b494c",
|
||||
"error-container": "#93000a",
|
||||
"on-tertiary": "#3c0091",
|
||||
"on-primary": "#00363d",
|
||||
"tertiary-fixed": "#e9ddff",
|
||||
"on-secondary-container": "#cdd7ff",
|
||||
"inverse-primary": "#006875"
|
||||
},
|
||||
"borderRadius": {
|
||||
"DEFAULT": "0.25rem",
|
||||
"lg": "0.5rem",
|
||||
"xl": "0.75rem",
|
||||
"full": "9999px"
|
||||
},
|
||||
"spacing": {
|
||||
"space-sm": "0.5rem",
|
||||
"gutter-lg": "1.5rem",
|
||||
"space-md": "1rem",
|
||||
"margin": "1rem",
|
||||
"space-xl": "2rem",
|
||||
"gutter": "1rem",
|
||||
"space-xs": "0.25rem",
|
||||
"space-lg": "1.5rem",
|
||||
"margin-lg": "2rem"
|
||||
},
|
||||
"fontFamily": {
|
||||
"telemetry-metric-lg-mobile": ["JetBrains Mono"],
|
||||
"body-md": ["Inter"],
|
||||
"label-caption": ["Inter"],
|
||||
"display-hero": ["Space Grotesk"],
|
||||
"body-lg": ["Inter"],
|
||||
"label-data": ["JetBrains Mono"],
|
||||
"headline-md": ["Space Grotesk"],
|
||||
"telemetry-metric-lg": ["JetBrains Mono"],
|
||||
"telemetry-metric-md": ["JetBrains Mono"],
|
||||
"headline-lg": ["Space Grotesk"],
|
||||
"display-hero-mobile": ["Space Grotesk"],
|
||||
"headline-sm": ["Space Grotesk"]
|
||||
},
|
||||
"fontSize": {
|
||||
"telemetry-metric-lg-mobile": ["36px", { "lineHeight": "36px", "letterSpacing": "-0.03em", "fontWeight": "700" }],
|
||||
"body-md": ["14px", { "lineHeight": "20px", "fontWeight": "400" }],
|
||||
"label-caption": ["11px", { "lineHeight": "14px", "letterSpacing": "0.05em", "fontWeight": "600" }],
|
||||
"display-hero": ["56px", { "lineHeight": "60px", "letterSpacing": "-0.03em", "fontWeight": "700" }],
|
||||
"body-lg": ["16px", { "lineHeight": "24px", "fontWeight": "500" }],
|
||||
"label-data": ["12px", { "lineHeight": "16px", "letterSpacing": "0.08em", "fontWeight": "600" }],
|
||||
"headline-md": ["24px", { "lineHeight": "32px", "letterSpacing": "-0.01em", "fontWeight": "600" }],
|
||||
"telemetry-metric-lg": ["48px", { "lineHeight": "48px", "letterSpacing": "-0.04em", "fontWeight": "700" }],
|
||||
"telemetry-metric-md": ["28px", { "lineHeight": "32px", "letterSpacing": "-0.02em", "fontWeight": "600" }],
|
||||
"headline-lg": ["32px", { "lineHeight": "40px", "letterSpacing": "-0.02em", "fontWeight": "700" }],
|
||||
"display-hero-mobile": ["40px", { "lineHeight": "44px", "letterSpacing": "-0.02em", "fontWeight": "700" }],
|
||||
"headline-sm": ["20px", { "lineHeight": "28px", "fontWeight": "600" }]
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
/* Glow utilities for tactical cockpit telemetry aesthetic */
|
||||
.glow-cyan-sm {
|
||||
box-shadow: 0 0 10px rgba(0, 229, 255, 0.25);
|
||||
}
|
||||
.glow-cyan-btn {
|
||||
box-shadow: 0 0 14px rgba(0, 229, 255, 0.4);
|
||||
}
|
||||
.scrollbar-none::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
.scrollbar-none {
|
||||
-ms-overflow-style: none;
|
||||
scrollbar-width: none;
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
body {
|
||||
min-height: max(884px, 100dvh);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-surface-container-lowest text-on-surface min-h-screen antialiased selection:bg-primary-container selection:text-surface-container-lowest pb-28">
|
||||
<!-- Mobile Viewport Container 375px centered for prototype viewing -->
|
||||
<div class="max-w-[420px] mx-auto min-h-screen relative flex flex-col bg-surface-container-lowest border-x border-outline-variant/40">
|
||||
<!-- TOP APP BAR (Shared Components JSON execution) -->
|
||||
<header class="fixed top-0 left-0 w-full max-w-[420px] left-1/2 -translate-x-1/2 z-50 flex justify-between items-center px-4 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-xl" data-icon="sensors">sensors</span>
|
||||
<span class="font-headline-sm text-headline-sm font-bold tracking-wider text-primary-container">MOTORSIGNAL HUD</span>
|
||||
</div>
|
||||
<div class="flex items-center space-x-3">
|
||||
<div class="flex items-center space-x-1 px-2 py-0.5 rounded bg-surface-container border border-outline-variant">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-primary-container animate-pulse"></span>
|
||||
<span class="font-label-data text-[10px] text-primary">GNSS 20Hz</span>
|
||||
</div>
|
||||
<button aria-label="Alerts" class="flex items-center justify-center w-8 h-8 rounded-lg text-primary-container hover:bg-surface-container active:scale-95 duration-100 ease-out">
|
||||
<span class="material-symbols-outlined text-xl" data-icon="warning">warning</span>
|
||||
</button>
|
||||
</div>
|
||||
</header>
|
||||
<!-- SUB-HUD TELEMETRY DIAGNOSTIC BAR -->
|
||||
<div class="mt-14 px-4 py-2 bg-surface-container-low border-b border-outline-variant/60 flex items-center justify-between font-label-data text-label-data text-on-surface-variant">
|
||||
<div class="flex items-center space-x-2">
|
||||
<span class="text-primary-container">●</span>
|
||||
<span>MESH RF: <strong class="text-on-surface font-semibold">ONLINE (CH-04)</strong></span>
|
||||
</div>
|
||||
<div class="flex items-center space-x-3">
|
||||
<span>LAT: <strong class="text-primary font-semibold">12ms</strong></span>
|
||||
<span>BAT: <strong class="text-on-surface font-semibold">98%</strong></span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- MAIN RECON CONTENT AREA -->
|
||||
<main class="flex-1 px-4 pt-4 space-y-4">
|
||||
<!-- SECTION TITLE & ACTION -->
|
||||
<div class="flex items-end justify-between border-b border-outline-variant/30 pb-2">
|
||||
<div>
|
||||
<div class="font-label-data text-label-data text-primary-container uppercase tracking-widest">Tactical Recon // Hub</div>
|
||||
<h1 class="font-headline-md text-headline-md font-bold text-on-surface uppercase tracking-tight">Clubs Directory</h1>
|
||||
</div>
|
||||
<!-- HEADER CREATE CTA -->
|
||||
<button class="h-10 px-3 flex items-center space-x-1.5 rounded-lg bg-surface-container-high border border-primary-container text-primary-container font-label-data text-label-data font-semibold hover:bg-surface-container active:scale-95 duration-100 glow-cyan-sm">
|
||||
<span class="material-symbols-outlined text-base" data-icon="add">add</span>
|
||||
<span>NEW SQUAD</span>
|
||||
</button>
|
||||
</div>
|
||||
<!-- SEARCH INPUT -->
|
||||
<div class="relative">
|
||||
<div class="absolute inset-y-0 left-0 pl-3.5 flex items-center pointer-events-none text-on-surface-variant">
|
||||
<span class="material-symbols-outlined text-lg" data-icon="search">search</span>
|
||||
</div>
|
||||
<input class="w-full h-12 pl-10 pr-10 bg-surface-container-lowest border border-outline-variant rounded-lg font-body-md text-body-md text-on-surface placeholder:text-on-surface-variant focus:border-primary-container focus:ring-1 focus:ring-primary-container focus:outline-none transition-all" placeholder="Search clubs, callsigns, territories..." type="text"/>
|
||||
<div class="absolute inset-y-0 right-0 pr-3 flex items-center">
|
||||
<span class="px-1.5 py-0.5 rounded bg-surface-container font-label-data text-[10px] text-outline border border-outline-variant">⌘K</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- HORIZONTAL FILTER CHIPS -->
|
||||
<div class="flex items-center space-x-2 overflow-x-auto scrollbar-none py-1 -mx-4 px-4">
|
||||
<!-- Active Chip -->
|
||||
<button class="flex-shrink-0 h-9 px-3.5 rounded-lg bg-surface-container-high border border-primary-container text-primary-container font-label-data text-label-data font-bold flex items-center space-x-1.5 glow-cyan-sm active:scale-95 duration-100">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-primary-container"></span>
|
||||
<span>All Sectors</span>
|
||||
</button>
|
||||
<!-- Inactive Chips -->
|
||||
<button class="flex-shrink-0 h-9 px-3.5 rounded-lg bg-surface-container-low border border-outline-variant text-on-surface-variant hover:text-on-surface hover:border-outline font-label-data text-label-data flex items-center space-x-1 active:scale-95 duration-100">
|
||||
<span>Sportbike</span>
|
||||
</button>
|
||||
<button class="flex-shrink-0 h-9 px-3.5 rounded-lg bg-surface-container-low border border-outline-variant text-on-surface-variant hover:text-on-surface hover:border-outline font-label-data text-label-data flex items-center space-x-1 active:scale-95 duration-100">
|
||||
<span>ADV / Dual Sport</span>
|
||||
</button>
|
||||
<button class="flex-shrink-0 h-9 px-3.5 rounded-lg bg-surface-container-low border border-outline-variant text-on-surface-variant hover:text-on-surface hover:border-outline font-label-data text-label-data flex items-center space-x-1 active:scale-95 duration-100">
|
||||
<span>Canyon Carvers</span>
|
||||
</button>
|
||||
<button class="flex-shrink-0 h-9 px-3.5 rounded-lg bg-surface-container-low border border-outline-variant text-on-surface-variant hover:text-on-surface hover:border-outline font-label-data text-label-data flex items-center space-x-1 active:scale-95 duration-100">
|
||||
<span>Track Day</span>
|
||||
</button>
|
||||
</div>
|
||||
<!-- SUB-FILTER / SORT STATUS ROW -->
|
||||
<div class="flex items-center justify-between py-1 text-label-caption font-label-caption text-on-surface-variant">
|
||||
<div class="flex items-center space-x-1.5">
|
||||
<span class="font-label-data text-primary-fixed-dim">34</span>
|
||||
<span>VERIFIED SQUADRONS DETECTED</span>
|
||||
</div>
|
||||
<button class="flex items-center space-x-1 font-label-data text-primary hover:text-primary-container transition-colors">
|
||||
<span>SORT: COHESION SCORE</span>
|
||||
<span class="material-symbols-outlined text-xs" data-icon="expand_more">expand_more</span>
|
||||
</button>
|
||||
</div>
|
||||
<!-- CLUB CARDS LIST -->
|
||||
<div class="space-y-4">
|
||||
<!-- CLUB 1: NorCal Apex Hunters -->
|
||||
<article class="bg-surface-container-low border border-outline-variant hover:border-primary-container/80 transition-all rounded-xl p-3.5 space-y-3 relative overflow-hidden">
|
||||
<!-- Subtle Top Indicator Accent -->
|
||||
<div class="absolute top-0 left-0 right-0 h-[2px] bg-gradient-to-r from-primary-container via-secondary-container to-transparent"></div>
|
||||
<!-- Header info -->
|
||||
<div class="flex items-start justify-between">
|
||||
<div class="flex items-center space-x-3">
|
||||
<div class="w-12 h-12 rounded-lg bg-surface-container-highest border border-primary-container/60 flex items-center justify-center text-primary-container shadow-inner">
|
||||
<span class="material-symbols-outlined text-2xl" data-icon="explore">explore</span>
|
||||
</div>
|
||||
<div>
|
||||
<div class="flex items-center space-x-1.5">
|
||||
<h2 class="font-headline-sm text-base font-bold text-on-surface">NorCal Apex Hunters</h2>
|
||||
<span class="material-symbols-outlined text-primary-container text-sm" data-icon="verified" style="font-variation-settings: 'FILL' 1;">verified</span>
|
||||
</div>
|
||||
<p class="font-label-data text-label-data text-on-surface-variant">48 Pilots • Skyline Chapter • NorCal Sector</p>
|
||||
</div>
|
||||
</div>
|
||||
<span class="px-2 py-0.5 rounded bg-primary-container/15 border border-primary-container/60 font-label-data text-[10px] text-primary-container font-bold">PRO ROSTER</span>
|
||||
</div>
|
||||
<!-- Badges Cluster -->
|
||||
<div class="flex flex-wrap gap-1.5 font-label-caption text-[10px]">
|
||||
<span class="px-2 py-0.5 rounded bg-surface-container border border-outline-variant text-on-surface flex items-center space-x-1">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-primary-container"></span>
|
||||
<span>SANCTIONED MESH (CH-02)</span>
|
||||
</span>
|
||||
<span class="px-2 py-0.5 rounded bg-surface-container border border-outline-variant text-on-surface">
|
||||
PACE 4 TECHNICAL
|
||||
</span>
|
||||
</div>
|
||||
<!-- Telemetry Stats Bento Block -->
|
||||
<div class="grid grid-cols-3 gap-2 bg-surface-container-lowest/80 p-2.5 rounded-lg border border-outline-variant/50">
|
||||
<div>
|
||||
<div class="font-label-data text-[10px] text-on-surface-variant uppercase">Avg Lean Arc</div>
|
||||
<div class="font-telemetry-metric-md text-xl font-bold text-primary-container">52.4<span class="text-xs font-normal text-on-surface-variant">°</span></div>
|
||||
</div>
|
||||
<div class="border-x border-outline-variant/40 px-2">
|
||||
<div class="font-label-data text-[10px] text-on-surface-variant uppercase">Mesh Cohesion</div>
|
||||
<div class="font-telemetry-metric-md text-xl font-bold text-primary">99.2<span class="text-xs font-normal text-on-surface-variant">%</span></div>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<div class="font-label-data text-[10px] text-on-surface-variant uppercase">Squad Runs</div>
|
||||
<div class="font-telemetry-metric-md text-xl font-bold text-on-surface">18<span class="text-xs font-normal text-on-surface-variant">/mo</span></div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Pinned Route -->
|
||||
<div class="flex items-center justify-between text-body-md text-xs bg-surface-container px-2.5 py-1.5 rounded border border-outline-variant/40">
|
||||
<div class="flex items-center space-x-1.5 truncate text-on-surface-variant">
|
||||
<span class="material-symbols-outlined text-sm text-primary-container" data-icon="route">route</span>
|
||||
<span class="truncate font-body-md">Primary Patrol: <strong>Skyline Blvd & CA-9 Arc</strong></span>
|
||||
</div>
|
||||
<span class="font-label-data text-[10px] text-primary-fixed-dim whitespace-nowrap">42.8 KM</span>
|
||||
</div>
|
||||
<!-- Action Buttons -->
|
||||
<div class="grid grid-cols-2 gap-2 pt-1">
|
||||
<button class="h-11 rounded-lg bg-surface-container border border-outline-variant hover:border-primary-container text-on-surface font-label-data text-label-data font-semibold flex items-center justify-center active:scale-95 duration-100">
|
||||
VIEW CHAPTER
|
||||
</button>
|
||||
<button class="h-11 rounded-lg bg-primary-container hover:bg-surface-tint text-surface-container-lowest font-label-data text-label-data font-bold flex items-center justify-center space-x-1 glow-cyan-btn active:scale-95 duration-100">
|
||||
<span class="material-symbols-outlined text-base" data-icon="podcasts">podcasts</span>
|
||||
<span>JOIN MESH</span>
|
||||
</button>
|
||||
</div>
|
||||
</article>
|
||||
<!-- CLUB 2: Bay Area Adventure Riders -->
|
||||
<article class="bg-surface-container-low border border-outline-variant hover:border-primary-container/80 transition-all rounded-xl p-3.5 space-y-3 relative overflow-hidden">
|
||||
<!-- Header info -->
|
||||
<div class="flex items-start justify-between">
|
||||
<div class="flex items-center space-x-3">
|
||||
<div class="w-12 h-12 rounded-lg bg-surface-container-highest border border-outline-variant flex items-center justify-center text-primary-fixed shadow-inner">
|
||||
<span class="material-symbols-outlined text-2xl" data-icon="landscape">landscape</span>
|
||||
</div>
|
||||
<div>
|
||||
<div class="flex items-center space-x-1.5">
|
||||
<h2 class="font-headline-sm text-base font-bold text-on-surface">Bay Area Adventure</h2>
|
||||
<span class="material-symbols-outlined text-primary-container text-sm" data-icon="verified" style="font-variation-settings: 'FILL' 1;">verified</span>
|
||||
</div>
|
||||
<p class="font-label-data text-label-data text-on-surface-variant">120 Pilots • NorCal & Sierra Foothills</p>
|
||||
</div>
|
||||
</div>
|
||||
<span class="px-2 py-0.5 rounded bg-surface-container-high border border-outline-variant font-label-data text-[10px] text-secondary font-bold">RECRUITING</span>
|
||||
</div>
|
||||
<!-- Badges Cluster -->
|
||||
<div class="flex flex-wrap gap-1.5 font-label-caption text-[10px]">
|
||||
<span class="px-2 py-0.5 rounded bg-surface-container border border-outline-variant text-on-surface">
|
||||
ADV / DUAL SPORT
|
||||
</span>
|
||||
<span class="px-2 py-0.5 rounded bg-surface-container border border-outline-variant text-on-surface">
|
||||
MIXED (60% DIRT / 40% TARMAC)
|
||||
</span>
|
||||
</div>
|
||||
<!-- Telemetry Stats Bento Block -->
|
||||
<div class="grid grid-cols-3 gap-2 bg-surface-container-lowest/80 p-2.5 rounded-lg border border-outline-variant/50">
|
||||
<div>
|
||||
<div class="font-label-data text-[10px] text-on-surface-variant uppercase">Avg Stage</div>
|
||||
<div class="font-telemetry-metric-md text-xl font-bold text-on-surface">240<span class="text-xs font-normal text-on-surface-variant">mi</span></div>
|
||||
</div>
|
||||
<div class="border-x border-outline-variant/40 px-2">
|
||||
<div class="font-label-data text-[10px] text-on-surface-variant uppercase">Elev Gain</div>
|
||||
<div class="font-telemetry-metric-md text-xl font-bold text-primary-container">+6.4k<span class="text-xs font-normal text-on-surface-variant">ft</span></div>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<div class="font-label-data text-[10px] text-on-surface-variant uppercase">Sync Quality</div>
|
||||
<div class="font-telemetry-metric-md text-xl font-bold text-primary">98.4<span class="text-xs font-normal text-on-surface-variant">%</span></div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Pinned Route -->
|
||||
<div class="flex items-center justify-between text-body-md text-xs bg-surface-container px-2.5 py-1.5 rounded border border-outline-variant/40">
|
||||
<div class="flex items-center space-x-1.5 truncate text-on-surface-variant">
|
||||
<span class="material-symbols-outlined text-sm text-primary-container" data-icon="terrain">terrain</span>
|
||||
<span class="truncate font-body-md">Primary Patrol: <strong>Sonora Pass & Fire Roads</strong></span>
|
||||
</div>
|
||||
<span class="font-label-data text-[10px] text-on-surface-variant whitespace-nowrap">Grade 3 Offroad</span>
|
||||
</div>
|
||||
<!-- Action Button -->
|
||||
<button class="w-full h-11 rounded-lg bg-surface-container-high border border-outline hover:border-primary-container text-on-surface font-label-data text-label-data font-semibold flex items-center justify-center space-x-2 active:scale-95 duration-100">
|
||||
<span class="material-symbols-outlined text-base text-primary-container" data-icon="group_add">group_add</span>
|
||||
<span>REQUEST TO JOIN SQUAD</span>
|
||||
</button>
|
||||
</article>
|
||||
<!-- CLUB 3: Coastline Cruisers -->
|
||||
<article class="bg-surface-container-low border border-outline-variant hover:border-primary-container/80 transition-all rounded-xl p-3.5 space-y-3 relative overflow-hidden">
|
||||
<!-- Header info -->
|
||||
<div class="flex items-start justify-between">
|
||||
<div class="flex items-center space-x-3">
|
||||
<div class="w-12 h-12 rounded-lg bg-surface-container-highest border border-outline-variant flex items-center justify-center text-primary-container shadow-inner">
|
||||
<span class="material-symbols-outlined text-2xl" data-icon="waves">waves</span>
|
||||
</div>
|
||||
<div>
|
||||
<div class="flex items-center space-x-1.5">
|
||||
<h2 class="font-headline-sm text-base font-bold text-on-surface">Coastline Cruisers</h2>
|
||||
</div>
|
||||
<p class="font-label-data text-label-data text-on-surface-variant">86 Pilots • Highway 1 Corridor • Pacific Chapter</p>
|
||||
</div>
|
||||
</div>
|
||||
<span class="px-2 py-0.5 rounded bg-surface-container border border-outline-variant font-label-data text-[10px] text-on-surface font-bold">PACE 2</span>
|
||||
</div>
|
||||
<!-- Badges Cluster -->
|
||||
<div class="flex flex-wrap gap-1.5 font-label-caption text-[10px]">
|
||||
<span class="px-2 py-0.5 rounded bg-surface-container border border-outline-variant text-on-surface">
|
||||
SCENIC CRUISE
|
||||
</span>
|
||||
<span class="px-2 py-0.5 rounded bg-surface-container border border-outline-variant text-on-surface">
|
||||
ALL BIKES WELCOME
|
||||
</span>
|
||||
<span class="px-2 py-0.5 rounded bg-surface-container border border-outline-variant text-on-surface">
|
||||
WEEKEND ROLLOUT
|
||||
</span>
|
||||
</div>
|
||||
<!-- Telemetry Stats Bento Block -->
|
||||
<div class="grid grid-cols-3 gap-2 bg-surface-container-lowest/80 p-2.5 rounded-lg border border-outline-variant/50">
|
||||
<div>
|
||||
<div class="font-label-data text-[10px] text-on-surface-variant uppercase">Logged</div>
|
||||
<div class="font-telemetry-metric-md text-xl font-bold text-on-surface">3.4k<span class="text-xs font-normal text-on-surface-variant">mi</span></div>
|
||||
</div>
|
||||
<div class="border-x border-outline-variant/40 px-2">
|
||||
<div class="font-label-data text-[10px] text-on-surface-variant uppercase">Safety Rating</div>
|
||||
<div class="font-telemetry-metric-md text-xl font-bold text-primary-container">100<span class="text-xs font-normal text-on-surface-variant">%</span></div>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<div class="font-label-data text-[10px] text-on-surface-variant uppercase">Rhythm</div>
|
||||
<div class="font-telemetry-metric-md text-xl font-bold text-on-surface">Sun<span class="text-xs font-normal text-on-surface-variant">days</span></div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Pinned Route -->
|
||||
<div class="flex items-center justify-between text-body-md text-xs bg-surface-container px-2.5 py-1.5 rounded border border-outline-variant/40">
|
||||
<div class="flex items-center space-x-1.5 truncate text-on-surface-variant">
|
||||
<span class="material-symbols-outlined text-sm text-primary-container" data-icon="navigation">navigation</span>
|
||||
<span class="truncate font-body-md">Primary Patrol: <strong>Half Moon Bay to Monterey Run</strong></span>
|
||||
</div>
|
||||
<span class="font-label-data text-[10px] text-on-surface-variant whitespace-nowrap">92 MI</span>
|
||||
</div>
|
||||
<!-- Action Button -->
|
||||
<button class="w-full h-11 rounded-lg bg-surface-container-high border border-outline hover:border-primary-container text-on-surface font-label-data text-label-data font-semibold flex items-center justify-center space-x-2 active:scale-95 duration-100">
|
||||
<span class="material-symbols-outlined text-base text-primary-container" data-icon="login">login</span>
|
||||
<span>REQUEST TO JOIN</span>
|
||||
</button>
|
||||
</article>
|
||||
<!-- CLUB 4: Desmo Syndicate Teaser / Invite -->
|
||||
<article class="bg-surface-container border border-outline-variant/80 rounded-xl p-3.5 space-y-2 border-dashed">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center space-x-2.5">
|
||||
<div class="w-9 h-9 rounded-lg bg-error-container/40 border border-error/50 flex items-center justify-center text-error">
|
||||
<span class="material-symbols-outlined text-lg" data-icon="lock">lock</span>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="font-headline-sm text-sm font-bold text-on-surface">Sierra Ridge Trackday Syndicate</h3>
|
||||
<p class="font-label-data text-[11px] text-on-surface-variant">Private Invitational Mesh • Laguna Seca Track Pack</p>
|
||||
</div>
|
||||
</div>
|
||||
<span class="px-2 py-0.5 rounded bg-error-container/20 border border-error/40 font-label-data text-[10px] text-error">INVITE ONLY</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between pt-1">
|
||||
<span class="font-label-data text-[11px] text-on-surface-variant">Requires Level 4 Telemetry Clearance</span>
|
||||
<button class="h-8 px-3 rounded bg-surface-container-high text-on-surface hover:text-primary-container font-label-data text-[11px] font-semibold border border-outline-variant">
|
||||
ENTER PIN
|
||||
</button>
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
</main>
|
||||
<!-- FLOATING ACTION BUTTON (Create Club Quick Access) -->
|
||||
<div class="fixed bottom-20 right-4 z-40">
|
||||
<button class="h-12 px-4 rounded-full bg-primary-container text-surface-container-lowest font-headline-sm text-sm font-bold flex items-center space-x-2 glow-cyan-btn active:scale-95 duration-100 hover:bg-surface-tint shadow-2xl">
|
||||
<span class="material-symbols-outlined text-xl" data-icon="add">add</span>
|
||||
<span>CREATE SQUAD</span>
|
||||
</button>
|
||||
</div>
|
||||
<!-- BOTTOM NAVIGATION BAR (Shared Components JSON execution) -->
|
||||
<!-- Destination count: 5 from JSON ("Dash", "Map", "Activity", "Garage", "Settings") -->
|
||||
<!-- Active mapping: Activity / Telemetry / HUD context with high tactile 48px hit areas -->
|
||||
<nav class="fixed bottom-0 left-0 w-full max-w-[420px] left-1/2 -translate-x-1/2 z-50 flex justify-around items-center px-space-xs py-space-xs bg-surface-container-lowest border-t border-outline-variant">
|
||||
<!-- Dash -->
|
||||
<a class="flex flex-col items-center justify-center text-on-surface-variant px-2 py-1 min-h-[48px] hover:bg-surface-container-low hover:text-primary-fixed active:scale-95 duration-100 ease-out" href="#dash">
|
||||
<span class="material-symbols-outlined text-xl" data-icon="speed">speed</span>
|
||||
<span class="font-label-caption text-label-caption mt-0.5">Dash</span>
|
||||
</a>
|
||||
<!-- Map -->
|
||||
<a class="flex flex-col items-center justify-center text-on-surface-variant px-2 py-1 min-h-[48px] hover:bg-surface-container-low hover:text-primary-fixed active:scale-95 duration-100 ease-out" href="#map">
|
||||
<span class="material-symbols-outlined text-xl" data-icon="navigation">navigation</span>
|
||||
<span class="font-label-caption text-label-caption mt-0.5">Map</span>
|
||||
</a>
|
||||
<!-- Activity (Active destination for Discovery & Recon Hub) -->
|
||||
<a class="flex flex-col items-center justify-center bg-surface-container-high text-primary-container rounded-lg px-2 py-1 min-h-[48px] active:scale-95 duration-100 ease-out" href="#activity">
|
||||
<span class="material-symbols-outlined text-xl" data-icon="analytics" style="font-variation-settings: 'FILL' 1;">analytics</span>
|
||||
<span class="font-label-caption text-label-caption mt-0.5 font-bold">Activity</span>
|
||||
</a>
|
||||
<!-- Garage -->
|
||||
<a class="flex flex-col items-center justify-center text-on-surface-variant px-2 py-1 min-h-[48px] hover:bg-surface-container-low hover:text-primary-fixed active:scale-95 duration-100 ease-out" href="#garage">
|
||||
<span class="material-symbols-outlined text-xl" data-icon="two_wheeler">two_wheeler</span>
|
||||
<span class="font-label-caption text-label-caption mt-0.5">Garage</span>
|
||||
</a>
|
||||
<!-- Settings -->
|
||||
<a class="flex flex-col items-center justify-center text-on-surface-variant px-2 py-1 min-h-[48px] hover:bg-surface-container-low hover:text-primary-fixed active:scale-95 duration-100 ease-out" href="#settings">
|
||||
<span class="material-symbols-outlined text-xl" data-icon="settings">settings</span>
|
||||
<span class="font-label-caption text-label-caption mt-0.5">Settings</span>
|
||||
</a>
|
||||
</nav>
|
||||
</div>
|
||||
</body></html>
|
||||
|
|
@ -0,0 +1,519 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en" class="dark">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Create Motorcycle Club — Wizard</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=Space+Grotesk:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />
|
||||
<!-- Bootstrap 5.3 CSS -->
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<script>
|
||||
tailwind.config = {
|
||||
darkMode: 'class',
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
telemetry: {
|
||||
bg: '#070A0F',
|
||||
card: '#0D1117',
|
||||
surface: '#121720',
|
||||
border: '#1C2331',
|
||||
cyan: '#00e5ff',
|
||||
cyanDim: 'rgba(0, 229, 255, 0.15)',
|
||||
cyanGlow: 'rgba(0, 229, 255, 0.35)',
|
||||
gold: '#ffd166',
|
||||
danger: '#ff4d6d'
|
||||
}
|
||||
},
|
||||
fontFamily: {
|
||||
sans: ['"Space Grotesk"', 'sans-serif'],
|
||||
mono: ['"JetBrains Mono"', 'monospace']
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
body {
|
||||
background-color: #070A0F;
|
||||
color: #E2E8F0;
|
||||
font-family: 'Space Grotesk', sans-serif;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
background-image:
|
||||
radial-gradient(circle at 50% 0%, rgba(0, 229, 255, 0.08) 0%, transparent 60%),
|
||||
linear-gradient(to bottom, #070A0F 0%, #05080C 100%);
|
||||
}
|
||||
|
||||
/* Mobile Container Frame: 375px nominal */
|
||||
.mobile-frame {
|
||||
width: 100%;
|
||||
max-width: 390px;
|
||||
min-height: 100vh;
|
||||
background-color: #070A0F;
|
||||
position: relative;
|
||||
border-left: 1px solid #141b27;
|
||||
border-right: 1px solid #141b27;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding-bottom: 30px;
|
||||
}
|
||||
|
||||
/* Tactical Custom Inputs */
|
||||
.telemetry-input {
|
||||
background-color: #0D131C !important;
|
||||
border: 1px solid #1C2738 !important;
|
||||
color: #F1F5F9 !important;
|
||||
border-radius: 8px !important;
|
||||
padding: 12px 14px !important;
|
||||
font-size: 0.925rem !important;
|
||||
font-family: 'Space Grotesk', sans-serif !important;
|
||||
transition: all 0.2s ease-in-out !important;
|
||||
}
|
||||
.telemetry-input:focus {
|
||||
background-color: #0F1722 !important;
|
||||
border-color: #00e5ff !important;
|
||||
box-shadow: 0 0 0 3px rgba(0, 229, 255, 0.22), 0 0 16px rgba(0, 229, 255, 0.2) !important;
|
||||
outline: none !important;
|
||||
}
|
||||
.telemetry-input::placeholder {
|
||||
color: #475569 !important;
|
||||
font-size: 0.85rem !important;
|
||||
}
|
||||
|
||||
/* Step Indicators */
|
||||
.step-pill {
|
||||
position: relative;
|
||||
transition: all 0.25s ease;
|
||||
}
|
||||
.step-pill.active {
|
||||
border-color: #00e5ff;
|
||||
background: linear-gradient(180deg, rgba(0, 229, 255, 0.15) 0%, rgba(0, 229, 255, 0.03) 100%);
|
||||
box-shadow: 0 0 12px rgba(0, 229, 255, 0.25);
|
||||
}
|
||||
.step-pill.active .step-num {
|
||||
background-color: #00e5ff;
|
||||
color: #070A0F;
|
||||
font-weight: 700;
|
||||
}
|
||||
.step-pill.active .step-label {
|
||||
color: #00e5ff;
|
||||
font-weight: 600;
|
||||
}
|
||||
.step-pill.done {
|
||||
border-color: #10b981;
|
||||
background: rgba(16, 185, 129, 0.05);
|
||||
}
|
||||
.step-pill.done .step-num {
|
||||
background-color: #10b981;
|
||||
color: #070A0F;
|
||||
}
|
||||
|
||||
/* Custom Radio Pill Selection */
|
||||
.privacy-card {
|
||||
border: 1px solid #1C2738;
|
||||
background-color: #0D131C;
|
||||
border-radius: 10px;
|
||||
padding: 12px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
min-height: 48px;
|
||||
}
|
||||
.privacy-card.selected {
|
||||
border-color: #00e5ff;
|
||||
background: rgba(0, 229, 255, 0.07);
|
||||
box-shadow: 0 0 12px rgba(0, 229, 255, 0.15);
|
||||
}
|
||||
.privacy-card:active {
|
||||
transform: scale(0.99);
|
||||
}
|
||||
|
||||
/* Pace Selector Button Grids */
|
||||
.pace-btn {
|
||||
border: 1px solid #1C2738;
|
||||
background-color: #0D131C;
|
||||
border-radius: 8px;
|
||||
padding: 10px 8px;
|
||||
min-height: 52px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
.pace-btn.selected {
|
||||
border-color: #00e5ff;
|
||||
background: linear-gradient(180deg, rgba(0, 229, 255, 0.18) 0%, rgba(0, 229, 255, 0.05) 100%);
|
||||
box-shadow: 0 0 10px rgba(0, 229, 255, 0.25);
|
||||
}
|
||||
|
||||
/* Tactical HUD Glitch & Accent Lines */
|
||||
.corner-bracket {
|
||||
position: relative;
|
||||
}
|
||||
.corner-bracket::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: -1px;
|
||||
left: -1px;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-top: 2px solid #00e5ff;
|
||||
border-left: 2px solid #00e5ff;
|
||||
pointer-events: none;
|
||||
}
|
||||
.corner-bracket::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: -1px;
|
||||
right: -1px;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-bottom: 2px solid #00e5ff;
|
||||
border-right: 2px solid #00e5ff;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* Glow Button */
|
||||
.btn-deploy-tactical {
|
||||
background: #00e5ff;
|
||||
color: #070A0F;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.04em;
|
||||
border: none;
|
||||
box-shadow: 0 0 20px rgba(0, 229, 255, 0.45);
|
||||
transition: all 0.18s ease-in-out;
|
||||
}
|
||||
.btn-deploy-tactical:hover, .btn-deploy-tactical:focus {
|
||||
background: #26ecff;
|
||||
box-shadow: 0 0 28px rgba(0, 229, 255, 0.65);
|
||||
color: #05080C;
|
||||
}
|
||||
.btn-deploy-tactical:active {
|
||||
transform: scale(0.98);
|
||||
box-shadow: 0 0 12px rgba(0, 229, 255, 0.3);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-[#070A0F] text-slate-100 antialiased selection:bg-cyan-500 selection:text-black">
|
||||
|
||||
<div class="mobile-frame mx-auto flex flex-col justify-between">
|
||||
|
||||
<!-- TOP TELEMETRY STATUS BAR -->
|
||||
<header class="border-b border-slate-800/80 bg-[#070A0F]/95 backdrop-blur sticky top-0 z-40 px-3 py-2.5">
|
||||
<div class="flex items-center justify-between font-mono text-[10px] tracking-wider text-slate-400 mb-1.5">
|
||||
<div class="flex items-center space-x-1.5">
|
||||
<span class="inline-block w-1.5 h-1.5 rounded-full bg-cyan-400 animate-pulse"></span>
|
||||
<span class="text-cyan-400 font-semibold">MOTOR<span class="text-white">SIGNAL</span></span>
|
||||
<span class="text-slate-600">//</span>
|
||||
<span class="text-slate-400">CH-04 MESH</span>
|
||||
</div>
|
||||
<div class="flex items-center space-x-2">
|
||||
<span class="bg-cyan-950/60 text-cyan-300 border border-cyan-500/30 px-1.5 py-0.5 rounded text-[9px] font-bold">20Hz GNSS</span>
|
||||
<span class="text-slate-300 flex items-center gap-0.5">
|
||||
<span class="material-symbols-outlined text-[13px] text-cyan-400">battery_charging_90</span> 98%
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- NAVIGATION ROW -->
|
||||
<div class="flex items-center justify-between pt-1">
|
||||
<button type="button" class="w-9 h-9 rounded-lg bg-slate-900 border border-slate-800 flex items-center justify-center text-slate-300 hover:text-white active:scale-95 transition-transform" aria-label="Go Back">
|
||||
<span class="material-symbols-outlined text-[19px]">arrow_back</span>
|
||||
</button>
|
||||
<div class="text-center">
|
||||
<span class="text-[10px] font-mono tracking-widest text-cyan-400 uppercase font-semibold block leading-none">COMMISSION PROTOCOL</span>
|
||||
<h1 class="text-sm font-bold tracking-tight text-white m-0 uppercase font-sans mt-0.5">Create Motorcycle Club</h1>
|
||||
</div>
|
||||
<button type="button" class="w-9 h-9 rounded-lg bg-slate-900 border border-slate-800 flex items-center justify-center text-slate-400 hover:text-slate-200" title="Squad Protocol Info">
|
||||
<span class="material-symbols-outlined text-[18px]">help_outline</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- 3-STEP WIZARD PROGRESS BAR -->
|
||||
<div class="grid grid-cols-3 gap-1.5 mt-3 pt-1">
|
||||
<!-- Step 1: Active -->
|
||||
<div class="step-pill active border rounded-md p-1.5 flex flex-col items-center justify-center text-center">
|
||||
<div class="flex items-center gap-1">
|
||||
<span class="step-num w-3.5 h-3.5 rounded-full text-[9px] flex items-center justify-center font-mono">1</span>
|
||||
<span class="step-label text-[10px] tracking-tight">Identity</span>
|
||||
</div>
|
||||
<span class="w-full h-0.5 bg-cyan-400 rounded-full mt-1 shadow-[0_0_6px_#00e5ff]"></span>
|
||||
</div>
|
||||
|
||||
<!-- Step 2: Next -->
|
||||
<div class="step-pill border border-slate-800/80 rounded-md p-1.5 flex flex-col items-center justify-center text-center bg-slate-900/40">
|
||||
<div class="flex items-center gap-1">
|
||||
<span class="step-num w-3.5 h-3.5 rounded-full bg-slate-800 text-slate-400 text-[9px] flex items-center justify-center font-mono">2</span>
|
||||
<span class="step-label text-[10px] text-slate-400">Rules & Privacy</span>
|
||||
</div>
|
||||
<span class="w-full h-0.5 bg-slate-800 rounded-full mt-1"></span>
|
||||
</div>
|
||||
|
||||
<!-- Step 3: Pending -->
|
||||
<div class="step-pill border border-slate-800/80 rounded-md p-1.5 flex flex-col items-center justify-center text-center bg-slate-900/40">
|
||||
<div class="flex items-center gap-1">
|
||||
<span class="step-num w-3.5 h-3.5 rounded-full bg-slate-800 text-slate-400 text-[9px] flex items-center justify-center font-mono">3</span>
|
||||
<span class="step-label text-[10px] text-slate-400">Officer Ranks</span>
|
||||
</div>
|
||||
<span class="w-full h-0.5 bg-slate-800 rounded-full mt-1"></span>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- MAIN FORM BODY -->
|
||||
<main class="px-3.5 py-3 flex-1 flex flex-col space-y-4">
|
||||
|
||||
<!-- SECTION 1: IDENTITY DETAILS -->
|
||||
<section class="space-y-3">
|
||||
<div class="flex items-center justify-between border-b border-slate-800/70 pb-1.5">
|
||||
<div class="flex items-center space-x-1.5">
|
||||
<span class="material-symbols-outlined text-cyan-400 text-[18px]">badge</span>
|
||||
<span class="font-mono text-xs font-bold text-white tracking-wider uppercase">1. Chapter Identity</span>
|
||||
</div>
|
||||
<span class="font-mono text-[9px] text-cyan-400/80 bg-cyan-950/40 px-1.5 py-0.5 rounded border border-cyan-800/40">STEP 1 OF 3</span>
|
||||
</div>
|
||||
|
||||
<!-- Club Name Input -->
|
||||
<div>
|
||||
<label class="block font-mono text-[11px] text-slate-300 font-medium mb-1.5 flex justify-between items-center">
|
||||
<span>CLUB NAME <span class="text-cyan-400">*</span></span>
|
||||
<span class="text-slate-500 text-[9px] font-normal">MAX 32 CHARS</span>
|
||||
</label>
|
||||
<div class="relative">
|
||||
<input type="text"
|
||||
class="form-control telemetry-input w-full pr-10 text-white placeholder-slate-500 font-sans"
|
||||
value="Skyline Apex Hunters"
|
||||
placeholder="e.g. Skyline Apex Hunters">
|
||||
<span class="material-symbols-outlined absolute right-3 top-1/2 -translate-y-1/2 text-cyan-400 text-[18px] pointer-events-none">verified</span>
|
||||
</div>
|
||||
<p class="font-mono text-[9px] text-slate-500 mt-1 flex items-center gap-1">
|
||||
<span class="inline-block w-1 h-1 rounded-full bg-cyan-400"></span>
|
||||
Appears on 20Hz Pack Radar and Leaderboards
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Chapter Territory Input -->
|
||||
<div>
|
||||
<label class="block font-mono text-[11px] text-slate-300 font-medium mb-1.5 flex justify-between items-center">
|
||||
<span>CHAPTER TERRITORY / SECTOR <span class="text-cyan-400">*</span></span>
|
||||
<span class="text-cyan-400 text-[9px]">CA-SECTOR 04</span>
|
||||
</label>
|
||||
<div class="relative">
|
||||
<input type="text"
|
||||
class="form-control telemetry-input w-full pr-10 text-white placeholder-slate-500 font-sans"
|
||||
value="Bay Area / NorCal"
|
||||
placeholder="e.g. Bay Area / NorCal">
|
||||
<span class="material-symbols-outlined absolute right-3 top-1/2 -translate-y-1/2 text-slate-400 text-[18px] pointer-events-none">location_on</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Club Patch Crest Upload Box -->
|
||||
<div>
|
||||
<label class="block font-mono text-[11px] text-slate-300 font-medium mb-1.5 flex justify-between items-center">
|
||||
<span>CLUB PATCH CREST / LOGO</span>
|
||||
<span class="text-slate-500 text-[9px]">PNG / SVG / JPG (1:1)</span>
|
||||
</label>
|
||||
|
||||
<div class="corner-bracket border border-dashed border-cyan-500/40 bg-slate-900/60 rounded-xl p-3 text-center relative overflow-hidden">
|
||||
<div class="flex items-center space-x-3.5">
|
||||
<!-- Crest Preview Placeholder -->
|
||||
<div class="w-16 h-16 rounded-lg bg-gradient-to-br from-cyan-950/70 to-slate-900 border border-cyan-400/50 flex flex-col items-center justify-center shrink-0 shadow-[0_0_12px_rgba(0,229,255,0.15)] relative">
|
||||
<span class="material-symbols-outlined text-cyan-400 text-[28px]">sports_motorsports</span>
|
||||
<span class="font-mono text-[8px] text-cyan-300 font-bold tracking-tighter uppercase mt-0.5">MC CREST</span>
|
||||
<div class="absolute -top-1 -right-1 w-4 h-4 rounded-full bg-cyan-400 text-black flex items-center justify-center text-[9px] font-bold">✓</div>
|
||||
</div>
|
||||
|
||||
<!-- Action Buttons -->
|
||||
<div class="flex-1 text-left">
|
||||
<div class="font-mono text-xs font-semibold text-slate-200">Patch Emblem Preview</div>
|
||||
<div class="text-[10px] text-slate-400 mb-2 leading-tight">Will be rendered on member HUDs & pack jerseys</div>
|
||||
|
||||
<div class="flex gap-2">
|
||||
<button type="button" class="btn btn-sm bg-slate-800 hover:bg-slate-700 text-cyan-300 border border-cyan-500/30 text-[11px] font-mono py-1.5 px-2.5 rounded-lg flex items-center gap-1 active:scale-95 transition-all min-h-[38px]">
|
||||
<span class="material-symbols-outlined text-[15px]">photo_camera</span>
|
||||
<span>Camera</span>
|
||||
</button>
|
||||
<button type="button" class="btn btn-sm bg-slate-800 hover:bg-slate-700 text-slate-200 border border-slate-700 text-[11px] font-mono py-1.5 px-2.5 rounded-lg flex items-center gap-1 active:scale-95 transition-all min-h-[38px]">
|
||||
<span class="material-symbols-outlined text-[15px]">add_photo_alternate</span>
|
||||
<span>Gallery</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- SECTION 2: RULES, PRIVACY & PACE -->
|
||||
<section class="space-y-3 pt-1">
|
||||
<div class="flex items-center justify-between border-b border-slate-800/70 pb-1.5">
|
||||
<div class="flex items-center space-x-1.5">
|
||||
<span class="material-symbols-outlined text-cyan-400 text-[18px]">lock_clock</span>
|
||||
<span class="font-mono text-xs font-bold text-white tracking-wider uppercase">2. Rules & Governance</span>
|
||||
</div>
|
||||
<span class="font-mono text-[9px] text-slate-400">TELEMETRY ACCESS</span>
|
||||
</div>
|
||||
|
||||
<!-- Privacy Radio Pills -->
|
||||
<div>
|
||||
<label class="block font-mono text-[11px] text-slate-300 font-medium mb-1.5">
|
||||
PRIVACY & INDUCTION PROTOCOL <span class="text-cyan-400">*</span>
|
||||
</label>
|
||||
<div class="space-y-2">
|
||||
|
||||
<!-- Option 1: Open Membership -->
|
||||
<label class="privacy-card flex items-start space-x-2.5 block m-0">
|
||||
<input type="radio" name="privacy_tier" class="form-check-input mt-1 accent-cyan-400 shrink-0" style="accent-color: #00e5ff;">
|
||||
<div class="flex-1">
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="font-mono text-xs font-bold text-white">Open Membership</span>
|
||||
<span class="font-mono text-[9px] text-slate-400 bg-slate-800/80 px-1.5 py-0.5 rounded">INSTANT MESH</span>
|
||||
</div>
|
||||
<div class="text-[10px] text-slate-400 mt-0.5">Any verified rider in sector can auto-pair telemetry and view rides.</div>
|
||||
</div>
|
||||
</label>
|
||||
|
||||
<!-- Option 2: Application Required (Selected) -->
|
||||
<label class="privacy-card selected flex items-start space-x-2.5 block m-0">
|
||||
<input type="radio" name="privacy_tier" checked class="form-check-input mt-1 accent-cyan-400 shrink-0" style="accent-color: #00e5ff;">
|
||||
<div class="flex-1">
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="font-mono text-xs font-bold text-cyan-300 flex items-center gap-1">
|
||||
Application & Screening Required
|
||||
<span class="material-symbols-outlined text-cyan-400 text-[14px]">shield</span>
|
||||
</span>
|
||||
<span class="font-mono text-[9px] text-cyan-300 bg-cyan-950 px-1.5 py-0.5 rounded border border-cyan-500/40">RECOMMENDED</span>
|
||||
</div>
|
||||
<div class="text-[10px] text-slate-300 mt-0.5">Officers review rider lean logs, safety index, and bike specs before induction.</div>
|
||||
</div>
|
||||
</label>
|
||||
|
||||
<!-- Option 3: Secret / Invite Only -->
|
||||
<label class="privacy-card flex items-start space-x-2.5 block m-0">
|
||||
<input type="radio" name="privacy_tier" class="form-check-input mt-1 accent-cyan-400 shrink-0" style="accent-color: #00e5ff;">
|
||||
<div class="flex-1">
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="font-mono text-xs font-bold text-white">Secret / Invitation Only</span>
|
||||
<span class="font-mono text-[9px] text-rose-400 bg-rose-950/60 px-1.5 py-0.5 rounded border border-rose-900/40">HIDDEN MESH</span>
|
||||
</div>
|
||||
<div class="text-[10px] text-slate-400 mt-0.5">Hidden from public directory. Requires 6-digit cryptographic PIN or QR pass.</div>
|
||||
</div>
|
||||
</label>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Minimum Pace Classification Selector -->
|
||||
<div>
|
||||
<div class="flex items-center justify-between mb-1.5">
|
||||
<label class="font-mono text-[11px] text-slate-300 font-medium m-0">
|
||||
MINIMUM PACE CLASSIFICATION <span class="text-cyan-400">*</span>
|
||||
</label>
|
||||
<span class="font-mono text-[9px] text-amber-300">PACE 3 ACTIVE</span>
|
||||
</div>
|
||||
|
||||
<!-- Pace 1 to 4 Grid -->
|
||||
<div class="grid grid-cols-4 gap-1.5">
|
||||
<!-- Pace 1 -->
|
||||
<div class="pace-btn flex flex-col items-center justify-center text-center">
|
||||
<span class="font-mono text-[10px] text-slate-400 font-bold">PACE 1</span>
|
||||
<span class="text-[9px] text-slate-400 leading-tight">Cruiser</span>
|
||||
<span class="font-mono text-[8px] text-slate-500"><35° Lean</span>
|
||||
</div>
|
||||
|
||||
<!-- Pace 2 -->
|
||||
<div class="pace-btn flex flex-col items-center justify-center text-center">
|
||||
<span class="font-mono text-[10px] text-slate-300 font-bold">PACE 2</span>
|
||||
<span class="text-[9px] text-slate-300 leading-tight">Touring</span>
|
||||
<span class="font-mono text-[8px] text-slate-500">35°–42°</span>
|
||||
</div>
|
||||
|
||||
<!-- Pace 3 (Selected) -->
|
||||
<div class="pace-btn selected flex flex-col items-center justify-center text-center">
|
||||
<span class="font-mono text-[10px] text-cyan-300 font-bold">PACE 3</span>
|
||||
<span class="text-[9px] text-white font-semibold leading-tight">Brisk</span>
|
||||
<span class="font-mono text-[8px] text-cyan-400 font-bold">42°–49°</span>
|
||||
</div>
|
||||
|
||||
<!-- Pace 4 -->
|
||||
<div class="pace-btn flex flex-col items-center justify-center text-center">
|
||||
<span class="font-mono text-[10px] text-slate-400 font-bold">PACE 4</span>
|
||||
<span class="text-[9px] text-rose-300 leading-tight">Track Exp.</span>
|
||||
<span class="font-mono text-[8px] text-rose-400 font-bold">>50° Apex</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-[9px] font-mono text-slate-400 mt-1 flex items-center justify-between">
|
||||
<span>Riders below Pace 3 receive automated corner advisory alerts</span>
|
||||
<span class="text-cyan-400 font-semibold">20Hz Verified</span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- SECTION 3: STEP 3 PREVIEW (OFFICER RANKS SUMMARY) -->
|
||||
<section class="border border-slate-800 bg-slate-900/40 rounded-xl p-2.5">
|
||||
<div class="flex items-center justify-between text-xs font-mono">
|
||||
<div class="flex items-center space-x-1.5 text-slate-300">
|
||||
<span class="material-symbols-outlined text-[16px] text-cyan-400">group_work</span>
|
||||
<span>NEXT: 3. OFFICER RANKS LADDER</span>
|
||||
</div>
|
||||
<span class="text-[10px] text-slate-500 font-sans">President • VP • Tail Gunner</span>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- GLOVE-FRIENDLY SUBMIT / DEPLOY ACTION -->
|
||||
<div class="pt-2">
|
||||
<button type="button"
|
||||
class="btn btn-deploy-tactical w-full h-[52px] rounded-xl flex items-center justify-center space-x-2 text-sm uppercase cursor-pointer"
|
||||
style="min-height: 48px;">
|
||||
<span class="material-symbols-outlined text-[20px]">rocket_launch</span>
|
||||
<span class="font-mono font-bold tracking-wider">DEPLOY CLUB CHAPTER</span>
|
||||
<span class="material-symbols-outlined text-[18px]">arrow_forward</span>
|
||||
</button>
|
||||
|
||||
<div class="flex items-center justify-between text-[9px] font-mono text-slate-500 mt-2 px-1">
|
||||
<span class="flex items-center gap-1">
|
||||
<span class="material-symbols-outlined text-[12px] text-cyan-400">security</span>
|
||||
Auto-binds Founder Call-sign @ApexMarcus
|
||||
</span>
|
||||
<span class="text-slate-400">Glove Target: 52px</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</main>
|
||||
|
||||
<!-- FIXED MOBILE TACTICAL BOTTOM NAVIGATION -->
|
||||
<nav class="border-t border-slate-800/90 bg-[#070A0F]/95 backdrop-blur px-2 py-1.5 grid grid-cols-5 text-center mt-auto">
|
||||
<a href="#" class="flex flex-col items-center justify-center py-1 text-slate-400 hover:text-cyan-400 active:scale-95 transition-all text-decoration-none min-h-[48px]">
|
||||
<span class="material-symbols-outlined text-[20px]">speed</span>
|
||||
<span class="text-[9px] font-mono mt-0.5">Dash</span>
|
||||
</a>
|
||||
<a href="#" class="flex flex-col items-center justify-center py-1 text-slate-400 hover:text-cyan-400 active:scale-95 transition-all text-decoration-none min-h-[48px]">
|
||||
<span class="material-symbols-outlined text-[20px]">navigation</span>
|
||||
<span class="text-[9px] font-mono mt-0.5">Map</span>
|
||||
</a>
|
||||
<a href="#" class="flex flex-col items-center justify-center py-1 text-cyan-400 active:scale-95 transition-all text-decoration-none min-h-[48px] relative">
|
||||
<div class="absolute -top-1 w-6 h-0.5 bg-cyan-400 shadow-[0_0_8px_#00e5ff]"></div>
|
||||
<span class="material-symbols-outlined text-[20px]">groups</span>
|
||||
<span class="text-[9px] font-mono font-bold mt-0.5">Clubs</span>
|
||||
</a>
|
||||
<a href="#" class="flex flex-col items-center justify-center py-1 text-slate-400 hover:text-cyan-400 active:scale-95 transition-all text-decoration-none min-h-[48px]">
|
||||
<span class="material-symbols-outlined text-[20px]">two_wheeler</span>
|
||||
<span class="text-[9px] font-mono mt-0.5">Garage</span>
|
||||
</a>
|
||||
<a href="#" class="flex flex-col items-center justify-center py-1 text-slate-400 hover:text-cyan-400 active:scale-95 transition-all text-decoration-none min-h-[48px]">
|
||||
<span class="material-symbols-outlined text-[20px]">settings</span>
|
||||
<span class="text-[9px] font-mono mt-0.5">Settings</span>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Bootstrap JS Bundle -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,451 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<html class="dark" lang="en"><head>
|
||||
<meta charset="utf-8"/>
|
||||
<meta content="width=device-width, initial-scale=1.0" name="viewport"/>
|
||||
<title>MOTORSIGNAL HUD // Group Rides Hub</title>
|
||||
<!-- Material Symbols Outlined -->
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<!-- 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&family=JetBrains+Mono:wght@500;600;700;800&family=Space+Grotesk:wght@500;600;700;800&display=swap" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&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-tertiary-fixed-variant": "#5516be",
|
||||
"surface-variant": "#32353b",
|
||||
"outline": "#849396",
|
||||
"tertiary": "#f2e9ff",
|
||||
"on-secondary-fixed": "#00174b",
|
||||
"error-container": "#93000a",
|
||||
"surface-dim": "#101419",
|
||||
"primary-fixed-dim": "#00daf3",
|
||||
"surface-bright": "#36393f",
|
||||
"on-primary-container": "#00626e",
|
||||
"primary-fixed": "#9cf0ff",
|
||||
"on-primary-fixed": "#001f24",
|
||||
"on-surface-variant": "#bac9cc",
|
||||
"tertiary-container": "#d9c8ff",
|
||||
"outline-variant": "#3b494c",
|
||||
"on-background": "#e0e2ea",
|
||||
"surface-tint": "#00daf3",
|
||||
"surface-container-highest": "#32353b",
|
||||
"background": "#101419",
|
||||
"inverse-surface": "#e0e2ea",
|
||||
"primary-container": "#00e5ff",
|
||||
"on-tertiary-fixed": "#23005c",
|
||||
"on-surface": "#e0e2ea",
|
||||
"on-tertiary": "#3c0091",
|
||||
"on-secondary-fixed-variant": "#003ea8",
|
||||
"tertiary-fixed-dim": "#d0bcff",
|
||||
"surface-container": "#1d2025",
|
||||
"on-secondary-container": "#cdd7ff",
|
||||
"inverse-primary": "#006875",
|
||||
"surface": "#101419",
|
||||
"secondary-fixed": "#dbe1ff",
|
||||
"on-error-container": "#ffdad6",
|
||||
"inverse-on-surface": "#2d3036",
|
||||
"on-secondary": "#002a78",
|
||||
"surface-container-lowest": "#0b0e13",
|
||||
"on-primary-fixed-variant": "#004f58",
|
||||
"surface-container-low": "#181c21",
|
||||
"surface-container-high": "#272a30",
|
||||
"on-primary": "#00363d",
|
||||
"error": "#ffb4ab",
|
||||
"secondary-fixed-dim": "#b4c5ff",
|
||||
"secondary-container": "#0053db",
|
||||
"primary": "#c3f5ff",
|
||||
"on-error": "#690005",
|
||||
"tertiary-fixed": "#e9ddff",
|
||||
"secondary": "#b4c5ff",
|
||||
"on-tertiary-container": "#6834d1"
|
||||
},
|
||||
"borderRadius": {
|
||||
"DEFAULT": "0.25rem",
|
||||
"lg": "0.5rem",
|
||||
"xl": "0.75rem",
|
||||
"full": "9999px"
|
||||
},
|
||||
"spacing": {
|
||||
"space-md": "1rem",
|
||||
"gutter": "1rem",
|
||||
"space-xs": "0.25rem",
|
||||
"space-lg": "1.5rem",
|
||||
"gutter-lg": "1.5rem",
|
||||
"margin": "1rem",
|
||||
"space-sm": "0.5rem",
|
||||
"margin-lg": "2rem",
|
||||
"space-xl": "2rem"
|
||||
},
|
||||
"fontFamily": {
|
||||
"telemetry-metric-md": ["JetBrains Mono"],
|
||||
"headline-md": ["Space Grotesk"],
|
||||
"body-lg": ["Inter"],
|
||||
"label-caption": ["Inter"],
|
||||
"label-data": ["JetBrains Mono"],
|
||||
"display-hero-mobile": ["Space Grotesk"],
|
||||
"headline-lg": ["Space Grotesk"],
|
||||
"telemetry-metric-lg": ["JetBrains Mono"],
|
||||
"headline-sm": ["Space Grotesk"],
|
||||
"body-md": ["Inter"],
|
||||
"telemetry-metric-lg-mobile": ["JetBrains Mono"],
|
||||
"display-hero": ["Space Grotesk"]
|
||||
},
|
||||
"fontSize": {
|
||||
"telemetry-metric-md": ["28px", { "lineHeight": "32px", "letterSpacing": "-0.02em", "fontWeight": "600" }],
|
||||
"headline-md": ["24px", { "lineHeight": "32px", "letterSpacing": "-0.01em", "fontWeight": "600" }],
|
||||
"body-lg": ["16px", { "lineHeight": "24px", "fontWeight": "500" }],
|
||||
"label-caption": ["11px", { "lineHeight": "14px", "letterSpacing": "0.05em", "fontWeight": "600" }],
|
||||
"label-data": ["12px", { "lineHeight": "16px", "letterSpacing": "0.08em", "fontWeight": "600" }],
|
||||
"display-hero-mobile": ["40px", { "lineHeight": "44px", "letterSpacing": "-0.02em", "fontWeight": "700" }],
|
||||
"headline-lg": ["32px", { "lineHeight": "40px", "letterSpacing": "-0.02em", "fontWeight": "700" }],
|
||||
"telemetry-metric-lg": ["48px", { "lineHeight": "48px", "letterSpacing": "-0.04em", "fontWeight": "700" }],
|
||||
"headline-sm": ["20px", { "lineHeight": "28px", "fontWeight": "600" }],
|
||||
"body-md": ["14px", { "lineHeight": "20px", "fontWeight": "400" }],
|
||||
"telemetry-metric-lg-mobile": ["36px", { "lineHeight": "36px", "letterSpacing": "-0.03em", "fontWeight": "700" }],
|
||||
"display-hero": ["56px", { "lineHeight": "60px", "letterSpacing": "-0.03em", "fontWeight": "700" }]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.material-symbols-outlined {
|
||||
font-variation-settings: 'FILL' 0, 'wght' 500, 'GRAD' 0, 'opsz' 24;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
line-height: 1;
|
||||
}
|
||||
/* Glow utilities mapped to design system */
|
||||
.glow-cyan-sm {
|
||||
box-shadow: 0 0 12px rgba(0, 229, 255, 0.35);
|
||||
}
|
||||
.glow-cyan-md {
|
||||
box-shadow: 0 0 20px rgba(0, 229, 255, 0.45);
|
||||
}
|
||||
.glow-blue-card {
|
||||
box-shadow: 0 0 16px rgba(37, 99, 235, 0.15);
|
||||
}
|
||||
.radar-pulse {
|
||||
animation: pulseRadar 2s infinite ease-out;
|
||||
}
|
||||
@keyframes pulseRadar {
|
||||
0% { transform: scale(0.95); opacity: 0.9; }
|
||||
50% { transform: scale(1.3); opacity: 0.3; }
|
||||
100% { transform: scale(0.95); opacity: 0.9; }
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
body {
|
||||
min-height: max(884px, 100dvh);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-background text-on-surface antialiased selection:bg-primary-container selection:text-on-primary min-h-screen pb-28">
|
||||
<!-- TOP APP BAR (Shared Components JSON Anchor) -->
|
||||
<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 gap-2">
|
||||
<span class="material-symbols-outlined text-primary-container" 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 gap-3">
|
||||
<!-- Cockpit mini diagnostics -->
|
||||
<div class="hidden sm:flex items-center gap-2 font-label-data text-label-data text-outline">
|
||||
<span class="text-primary-container">MESH: CH-04</span>
|
||||
<span class="text-outline-variant">•</span>
|
||||
<span>GNSS: 20Hz</span>
|
||||
</div>
|
||||
<button aria-label="System Alerts" class="flex items-center justify-center p-2 rounded-lg text-primary-container hover:bg-surface-container active:scale-95 duration-100 ease-out">
|
||||
<span class="material-symbols-outlined" data-icon="warning">warning</span>
|
||||
</button>
|
||||
</div>
|
||||
</header>
|
||||
<!-- MAIN HUD CONTENT CANVAS -->
|
||||
<main class="pt-16 px-gutter max-w-xl mx-auto space-y-space-md">
|
||||
<!-- SUB-HUD REALTIME STATUS BAR -->
|
||||
<section class="bg-surface-container-lowest border border-outline-variant rounded-xl p-space-sm flex items-center justify-between text-label-data font-label-data">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="relative flex h-2.5 w-2.5">
|
||||
<span class="radar-pulse 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="text-primary tracking-wider font-semibold">MESH ONLINE [CH-04]</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-3 text-outline">
|
||||
<div class="flex items-center gap-1">
|
||||
<span class="material-symbols-outlined text-[16px] text-primary" data-icon="gps_fixed">gps_fixed</span>
|
||||
<span>20Hz LOCK</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-1">
|
||||
<span class="material-symbols-outlined text-[16px] text-primary-container" data-icon="battery_charging_full">battery_charging_full</span>
|
||||
<span class="text-on-surface">98%</span>
|
||||
</div>
|
||||
<div class="w-6 h-6 rounded-full border border-outline-variant bg-surface-container-high flex items-center justify-center overflow-hidden">
|
||||
<span class="material-symbols-outlined text-[16px] text-primary" data-icon="sports_motorsports">sports_motorsports</span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- SECTION TITLE: RECON & TELEMETRY CLUSTER -->
|
||||
<section class="space-y-1">
|
||||
<div class="flex items-center justify-between">
|
||||
<h1 class="text-headline-md font-headline-md tracking-tight text-on-surface">GROUP RIDES // RECON</h1>
|
||||
<span class="px-2 py-0.5 rounded border border-outline-variant bg-surface-container-low font-label-data text-label-data text-primary-container">915MHz P2P</span>
|
||||
</div>
|
||||
<p class="font-body-md text-body-md text-on-surface-variant">Live telemetry radar, tactical formation locks, and decentralized mesh packs.</p>
|
||||
</section>
|
||||
<!-- QUICK JOIN PACK CARD (Top Priority Module) -->
|
||||
<section class="bg-surface-container-low border border-outline-variant rounded-xl p-space-md space-y-space-sm relative overflow-hidden">
|
||||
<!-- Background subtle grid accent -->
|
||||
<div class="absolute -right-10 -bottom-10 opacity-5 pointer-events-none select-none text-primary-container font-headline-lg">
|
||||
<span class="material-symbols-outlined text-[140px]" data-icon="cell_tower">cell_tower</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between border-b border-outline-variant pb-2">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-primary-container" data-icon="radio">radio</span>
|
||||
<span class="font-label-data text-label-data uppercase tracking-wider text-on-surface font-semibold">Enter Pack Join Code</span>
|
||||
</div>
|
||||
<span class="flex items-center gap-1 text-label-caption font-label-caption px-2 py-0.5 rounded bg-surface-container border border-outline-variant text-outline">
|
||||
<span class="material-symbols-outlined text-[14px] text-primary" data-icon="lock">lock</span>
|
||||
<span>AES-256</span>
|
||||
</span>
|
||||
</div>
|
||||
<!-- Character PIN layout -->
|
||||
<div class="grid grid-cols-6 gap-2 pt-1">
|
||||
<div class="h-12 bg-surface-container-lowest border border-outline-variant rounded-lg flex items-center justify-center font-telemetry-metric-md text-telemetry-metric-md text-primary-container font-bold">8</div>
|
||||
<div class="h-12 bg-surface-container-lowest border border-outline-variant rounded-lg flex items-center justify-center font-telemetry-metric-md text-telemetry-metric-md text-primary-container font-bold">4</div>
|
||||
<div class="h-12 bg-surface-container-lowest border border-outline-variant rounded-lg flex items-center justify-center font-telemetry-metric-md text-telemetry-metric-md text-primary-container font-bold">9</div>
|
||||
<div class="h-12 bg-surface-container-lowest border border-outline-variant rounded-lg flex items-center justify-center font-telemetry-metric-md text-telemetry-metric-md text-outline">2</div>
|
||||
<div class="h-12 bg-surface-container-lowest border border-outline-variant rounded-lg flex items-center justify-center font-telemetry-metric-md text-telemetry-metric-md text-outline">0</div>
|
||||
<div class="h-12 bg-surface-container-lowest border border-outline-variant rounded-lg flex items-center justify-center font-telemetry-metric-md text-telemetry-metric-md text-outline">1</div>
|
||||
</div>
|
||||
<!-- Join Mesh CTA -->
|
||||
<div class="pt-1">
|
||||
<button class="w-full min-h-[48px] bg-primary-container text-on-primary-fixed font-headline-sm text-headline-sm font-bold tracking-wider rounded-lg flex items-center justify-center gap-2 glow-cyan-sm hover:brightness-110 active:scale-95 duration-100 ease-out">
|
||||
<span class="material-symbols-outlined" data-icon="bolt">bolt</span>
|
||||
<span>JOIN MESH</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="flex items-center justify-between text-label-caption font-label-caption text-on-surface-variant pt-0.5">
|
||||
<span class="flex items-center gap-1">
|
||||
<span class="material-symbols-outlined text-[14px] text-primary" data-icon="wifi_tethering">wifi_tethering</span>
|
||||
<span>Direct P2P 915MHz RF sync or encrypted cloud relay</span>
|
||||
</span>
|
||||
<button class="text-primary hover:underline">Scan QR</button>
|
||||
</div>
|
||||
</section>
|
||||
<!-- GLOVE-FRIENDLY SEGMENTED FILTER TABS -->
|
||||
<nav aria-label="Ride Filters" class="flex items-center gap-2 p-1 bg-surface-container-lowest border border-outline-variant rounded-xl">
|
||||
<!-- Active Pill -->
|
||||
<button class="flex-1 min-h-[48px] px-3 py-2 rounded-lg bg-surface-container-high border border-primary-container text-primary-container font-headline-sm text-headline-sm flex items-center justify-center gap-2 glow-cyan-sm">
|
||||
<span class="relative flex h-2 w-2">
|
||||
<span class="radar-pulse absolute inline-flex h-full w-full rounded-full bg-primary-container opacity-75"></span>
|
||||
<span class="relative inline-flex rounded-full h-2 w-2 bg-primary-container"></span>
|
||||
</span>
|
||||
<span class="text-label-caption font-label-caption font-bold tracking-wider uppercase">Happening Now</span>
|
||||
</button>
|
||||
<!-- Inactive Tabs -->
|
||||
<button class="flex-1 min-h-[48px] px-3 py-2 rounded-lg text-on-surface-variant hover:bg-surface-container active:scale-95 duration-100 flex items-center justify-center gap-1.5">
|
||||
<span class="text-label-caption font-label-caption font-semibold tracking-wider uppercase">Upcoming</span>
|
||||
<span class="px-1.5 py-0.2 rounded bg-surface-container-high text-outline font-label-data text-[10px]">12</span>
|
||||
</button>
|
||||
<button class="flex-1 min-h-[48px] px-3 py-2 rounded-lg text-on-surface-variant hover:bg-surface-container active:scale-95 duration-100 flex items-center justify-center gap-1.5">
|
||||
<span class="text-label-caption font-label-caption font-semibold tracking-wider uppercase">My Pack</span>
|
||||
<span class="px-1.5 py-0.2 rounded bg-surface-container-high text-outline font-label-data text-[10px]">3</span>
|
||||
</button>
|
||||
</nav>
|
||||
<!-- ACTIVE RIDE CARD ('HAPPENING NOW' SPOTLIGHT) -->
|
||||
<article class="bg-surface-container-low border border-primary-container rounded-xl p-space-md space-y-space-md glow-blue-card relative">
|
||||
<!-- Top Meta line -->
|
||||
<div class="flex items-start justify-between gap-2">
|
||||
<div class="space-y-1">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="inline-flex items-center gap-1.5 px-2.5 py-0.5 rounded-full bg-surface-container-high border border-primary text-primary font-label-data text-label-data font-semibold">
|
||||
<span class="h-1.5 w-1.5 rounded-full bg-primary animate-ping"></span>
|
||||
<span>LIVE MESH • 6 RIDERS LIVE</span>
|
||||
</span>
|
||||
</div>
|
||||
<h2 class="text-headline-sm font-headline-sm text-on-surface font-bold">Skyline Ridge Dawn Patrol</h2>
|
||||
</div>
|
||||
<!-- Cohesion Metric Circular Tile -->
|
||||
<div class="text-right p-2 rounded-lg bg-surface-container-lowest border border-outline-variant">
|
||||
<div class="text-[10px] font-label-data text-outline">COHESION</div>
|
||||
<div class="text-headline-sm font-telemetry-metric-md text-primary-container font-bold">98%</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Telemetry Grid Badges -->
|
||||
<div class="grid grid-cols-2 gap-2 text-label-data font-label-data">
|
||||
<div class="bg-surface-container-lowest p-2 rounded-lg border border-outline-variant flex items-center justify-between">
|
||||
<span class="text-outline">PACE</span>
|
||||
<span class="px-1.5 py-0.5 rounded bg-surface-container text-primary-container font-semibold border border-outline-variant">Pace 4 Tech</span>
|
||||
</div>
|
||||
<div class="bg-surface-container-lowest p-2 rounded-lg border border-outline-variant flex items-center justify-between">
|
||||
<span class="text-outline">LEAD</span>
|
||||
<span class="text-primary font-semibold">@Dave_Lead</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Location & Route details -->
|
||||
<div class="space-y-2 bg-surface-container-lowest p-3 rounded-lg border border-outline-variant text-label-data font-label-data">
|
||||
<div class="flex items-start gap-2">
|
||||
<span class="material-symbols-outlined text-primary text-[18px] mt-0.5" data-icon="location_on">location_on</span>
|
||||
<div class="flex-1">
|
||||
<div class="text-outline text-[11px]">STAGING POINT</div>
|
||||
<div class="text-on-surface font-medium">Alice's Restaurant (Skyline Blvd & CA-84)</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-start gap-2 pt-1 border-t border-outline-variant">
|
||||
<span class="material-symbols-outlined text-primary text-[18px] mt-0.5" data-icon="alt_route">alt_route</span>
|
||||
<div class="flex-1 flex justify-between items-center">
|
||||
<div>
|
||||
<div class="text-outline text-[11px]">ROUTE SEGMENT</div>
|
||||
<div class="text-on-surface font-medium">CA-35 Crest & Saratoga Descent</div>
|
||||
</div>
|
||||
<span class="text-primary-container font-bold text-body-lg">64.2 mi</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center justify-between pt-1 border-t border-outline-variant text-[11px] text-outline">
|
||||
<span>CHANNEL: RF CH-04</span>
|
||||
<span>REFRESH: 20Hz REALTIME</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Action Buttons Cluster (Glove-sized min-h 48px) -->
|
||||
<div class="grid grid-cols-2 gap-2 pt-1">
|
||||
<button class="min-h-[48px] px-3 py-2 rounded-lg bg-surface-container-high border border-primary text-primary font-headline-sm text-headline-sm font-semibold flex items-center justify-center gap-1.5 hover:bg-surface-container hover:text-primary-fixed active:scale-95 duration-100 ease-out">
|
||||
<span class="material-symbols-outlined text-[20px]" data-icon="visibility">visibility</span>
|
||||
<span>INSPECT PACK</span>
|
||||
</button>
|
||||
<button class="min-h-[48px] px-3 py-2 rounded-lg bg-primary-container text-on-primary-fixed font-headline-sm text-headline-sm font-bold flex items-center justify-center gap-1.5 glow-cyan-sm hover:brightness-110 active:scale-95 duration-100 ease-out">
|
||||
<span class="material-symbols-outlined text-[20px]" data-icon="sync">sync</span>
|
||||
<span>SYNC COCKPIT</span>
|
||||
</button>
|
||||
</div>
|
||||
</article>
|
||||
<!-- SECTION: UPCOMING RECON RAIDS -->
|
||||
<section class="space-y-space-sm pt-2">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-primary-container" data-icon="calendar_month">calendar_month</span>
|
||||
<h2 class="text-headline-sm font-headline-sm text-on-surface uppercase tracking-wide">Upcoming Packs</h2>
|
||||
</div>
|
||||
<span class="font-label-data text-label-data text-outline">SORT: KSU TIME</span>
|
||||
</div>
|
||||
<!-- UPCOMING CARD 1 -->
|
||||
<article class="bg-surface-container-lowest border border-outline-variant rounded-xl p-space-md space-y-3 hover:border-outline duration-150">
|
||||
<div class="flex items-start justify-between">
|
||||
<div>
|
||||
<div class="flex items-center gap-2 text-label-data font-label-data">
|
||||
<span class="text-primary-container font-semibold">Saturday 07:30 PST</span>
|
||||
<span class="text-outline-variant">•</span>
|
||||
<span class="px-1.5 py-0.5 rounded bg-surface-container-high text-primary font-label-caption text-[11px] font-bold">KSU in 2h 15m</span>
|
||||
</div>
|
||||
<h3 class="text-headline-sm font-headline-sm text-on-surface font-semibold pt-1">Mulholland Snake & Rock Store Pace Lap</h3>
|
||||
</div>
|
||||
<span class="material-symbols-outlined text-outline" data-icon="two_wheeler">two_wheeler</span>
|
||||
</div>
|
||||
<div class="grid grid-cols-3 gap-2 text-label-caption font-label-caption">
|
||||
<div class="p-2 rounded bg-surface-container-low border border-outline-variant">
|
||||
<span class="text-outline block">PACE</span>
|
||||
<span class="text-on-surface font-label-data font-bold">Brisk (Pace 3)</span>
|
||||
</div>
|
||||
<div class="p-2 rounded bg-surface-container-low border border-outline-variant">
|
||||
<span class="text-outline block">CONFIRMED</span>
|
||||
<span class="text-primary-container font-label-data font-bold">14 Riders</span>
|
||||
</div>
|
||||
<div class="p-2 rounded bg-surface-container-low border border-outline-variant">
|
||||
<span class="text-outline block">DISTANCE</span>
|
||||
<span class="text-on-surface font-label-data font-bold">44.2 mi</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center justify-between pt-2 border-t border-outline-variant">
|
||||
<div class="flex items-center gap-1.5 font-label-data text-label-data text-outline">
|
||||
<span class="material-symbols-outlined text-[16px] text-primary" data-icon="shield_person">shield_person</span>
|
||||
<span>Sweep: <span class="text-on-surface font-semibold">@Sarah_Sweep</span></span>
|
||||
</div>
|
||||
<button class="min-h-[48px] px-4 py-2 rounded-lg bg-surface-container-high border border-outline-variant text-on-surface font-headline-sm text-headline-sm font-semibold flex items-center gap-1.5 hover:border-primary-container hover:text-primary-container active:scale-95 duration-100 ease-out">
|
||||
<span class="material-symbols-outlined text-[18px]" data-icon="download">download</span>
|
||||
<span>SYNC GPX</span>
|
||||
</button>
|
||||
</div>
|
||||
</article>
|
||||
<!-- UPCOMING CARD 2 -->
|
||||
<article class="bg-surface-container-lowest border border-outline-variant rounded-xl p-space-md space-y-3 hover:border-outline duration-150">
|
||||
<div class="flex items-start justify-between">
|
||||
<div>
|
||||
<div class="flex items-center gap-2 text-label-data font-label-data">
|
||||
<span class="text-primary-container font-semibold">Sunday 06:00 PST</span>
|
||||
<span class="text-outline-variant">•</span>
|
||||
<span class="px-1.5 py-0.5 rounded bg-surface-container-high text-on-surface-variant font-label-caption text-[11px] font-bold">ADV MIXED</span>
|
||||
</div>
|
||||
<h3 class="text-headline-sm font-headline-sm text-on-surface font-semibold pt-1">Sierra Foothills ADV Trans-Sierra</h3>
|
||||
</div>
|
||||
<span class="material-symbols-outlined text-outline" data-icon="terrain">terrain</span>
|
||||
</div>
|
||||
<div class="grid grid-cols-3 gap-2 text-label-caption font-label-caption">
|
||||
<div class="p-2 rounded bg-surface-container-low border border-outline-variant">
|
||||
<span class="text-outline block">TERRAIN</span>
|
||||
<span class="text-primary font-label-data font-bold">60% Dirt / 40% Tarmac</span>
|
||||
</div>
|
||||
<div class="p-2 rounded bg-surface-container-low border border-outline-variant">
|
||||
<span class="text-outline block">CONFIRMED</span>
|
||||
<span class="text-primary-container font-label-data font-bold">8 Riders</span>
|
||||
</div>
|
||||
<div class="p-2 rounded bg-surface-container-low border border-outline-variant">
|
||||
<span class="text-outline block">ELEVATION</span>
|
||||
<span class="text-on-surface font-label-data font-bold">+6,400 ft</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center justify-between pt-2 border-t border-outline-variant">
|
||||
<div class="flex items-center gap-1.5 font-label-data text-label-data text-outline">
|
||||
<span class="material-symbols-outlined text-[16px] text-primary" data-icon="person">person</span>
|
||||
<span>Lead: <span class="text-on-surface font-semibold">@ElenaADV</span></span>
|
||||
</div>
|
||||
<button class="min-h-[48px] px-4 py-2 rounded-lg bg-surface-container-high border border-outline-variant text-on-surface font-headline-sm text-headline-sm font-semibold flex items-center gap-1.5 hover:border-primary-container hover:text-primary-container active:scale-95 duration-100 ease-out">
|
||||
<span class="material-symbols-outlined text-[18px]" data-icon="check_circle">check_circle</span>
|
||||
<span>RSVP MESH</span>
|
||||
</button>
|
||||
</div>
|
||||
</article>
|
||||
</section>
|
||||
</main>
|
||||
<!-- FIXED FLOATING PRIMARY CTA: HOST PACK RIDE -->
|
||||
<div class="fixed bottom-20 right-4 left-4 z-40 max-w-xl mx-auto pointer-events-none flex justify-end">
|
||||
<button class="pointer-events-auto min-h-[52px] px-6 py-3 rounded-xl bg-primary-container text-on-primary-fixed font-headline-sm text-headline-sm font-bold tracking-wider flex items-center gap-2 glow-cyan-md hover:brightness-110 active:scale-95 duration-100 ease-out border border-primary">
|
||||
<span class="material-symbols-outlined text-[24px]" data-icon="add_circle">add_circle</span>
|
||||
<span>HOST PACK RIDE</span>
|
||||
</button>
|
||||
</div>
|
||||
<!-- BOTTOM NAVIGATION BAR (Shared Components JSON Anchor) -->
|
||||
<nav aria-label="Global Cockpit Navigation" 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">
|
||||
<!-- Tab 1: Dash -->
|
||||
<a class="flex flex-col items-center justify-center text-on-surface-variant px-2 py-1 min-h-[48px] hover:bg-surface-container-low hover:text-primary-fixed active:scale-95 duration-100 ease-out" href="#">
|
||||
<span class="material-symbols-outlined" data-icon="speed">speed</span>
|
||||
<span class="text-label-caption font-label-caption">Dash</span>
|
||||
</a>
|
||||
<!-- Tab 2: Map -->
|
||||
<a class="flex flex-col items-center justify-center text-on-surface-variant px-2 py-1 min-h-[48px] hover:bg-surface-container-low hover:text-primary-fixed active:scale-95 duration-100 ease-out" href="#">
|
||||
<span class="material-symbols-outlined" data-icon="navigation">navigation</span>
|
||||
<span class="text-label-caption font-label-caption">Map</span>
|
||||
</a>
|
||||
<!-- Tab 3: Activity (Group/Recon Pack Hub - Active) -->
|
||||
<a class="flex flex-col items-center justify-center bg-surface-container-high text-primary-container rounded-lg px-2 py-1 min-h-[48px] active:scale-95 duration-100 ease-out" href="#">
|
||||
<span class="material-symbols-outlined" data-icon="analytics" style="font-variation-settings: 'FILL' 1;">analytics</span>
|
||||
<span class="text-label-caption font-label-caption font-bold">Activity</span>
|
||||
</a>
|
||||
<!-- Tab 4: Garage -->
|
||||
<a class="flex flex-col items-center justify-center text-on-surface-variant px-2 py-1 min-h-[48px] hover:bg-surface-container-low hover:text-primary-fixed active:scale-95 duration-100 ease-out" href="#">
|
||||
<span class="material-symbols-outlined" data-icon="two_wheeler">two_wheeler</span>
|
||||
<span class="text-label-caption font-label-caption">Garage</span>
|
||||
</a>
|
||||
<!-- Tab 5: Settings -->
|
||||
<a class="flex flex-col items-center justify-center text-on-surface-variant px-2 py-1 min-h-[48px] hover:bg-surface-container-low hover:text-primary-fixed active:scale-95 duration-100 ease-out" href="#">
|
||||
<span class="material-symbols-outlined" data-icon="settings">settings</span>
|
||||
<span class="text-label-caption font-label-caption">Settings</span>
|
||||
</a>
|
||||
</nav>
|
||||
</body></html>
|
||||
|
|
@ -0,0 +1,499 @@
|
|||
<!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 HUD - Create Group Ride</title>
|
||||
<!-- Material Symbols & Fonts -->
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<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&family=JetBrains+Mono:wght@500;600;700&family=Space+Grotesk:wght@500;600;700&display=swap" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<!-- Tailwind CSS with custom styling hooks -->
|
||||
<script src="https://cdn.tailwindcss.com?plugins=forms,container-queries"></script>
|
||||
<script id="tailwind-config">
|
||||
tailwind.config = {
|
||||
darkMode: "class",
|
||||
theme: {
|
||||
extend: {
|
||||
"colors": {
|
||||
"surface-container": "#1d2025",
|
||||
"on-primary-container": "#00626e",
|
||||
"tertiary": "#f2e9ff",
|
||||
"secondary-container": "#0053db",
|
||||
"on-tertiary-fixed": "#23005c",
|
||||
"on-error": "#690005",
|
||||
"secondary": "#b4c5ff",
|
||||
"surface-variant": "#32353b",
|
||||
"surface-container-high": "#272a30",
|
||||
"outline": "#849396",
|
||||
"on-secondary-container": "#cdd7ff",
|
||||
"error": "#ffb4ab",
|
||||
"secondary-fixed-dim": "#b4c5ff",
|
||||
"primary-container": "#00e5ff",
|
||||
"surface-container-highest": "#32353b",
|
||||
"secondary-fixed": "#dbe1ff",
|
||||
"inverse-primary": "#006875",
|
||||
"inverse-surface": "#e0e2ea",
|
||||
"tertiary-fixed": "#e9ddff",
|
||||
"primary-fixed-dim": "#00daf3",
|
||||
"on-secondary-fixed": "#00174b",
|
||||
"tertiary-container": "#d9c8ff",
|
||||
"on-tertiary-container": "#6834d1",
|
||||
"inverse-on-surface": "#2d3036",
|
||||
"surface-dim": "#101419",
|
||||
"primary": "#c3f5ff",
|
||||
"on-background": "#e0e2ea",
|
||||
"on-secondary-fixed-variant": "#003ea8",
|
||||
"tertiary-fixed-dim": "#d0bcff",
|
||||
"on-tertiary-fixed-variant": "#5516be",
|
||||
"on-secondary": "#002a78",
|
||||
"on-error-container": "#ffdad6",
|
||||
"surface-container-lowest": "#0b0e13",
|
||||
"surface-bright": "#36393f",
|
||||
"error-container": "#93000a",
|
||||
"on-primary": "#00363d",
|
||||
"outline-variant": "#3b494c",
|
||||
"on-primary-fixed": "#001f24",
|
||||
"surface-container-low": "#181c21",
|
||||
"surface": "#101419",
|
||||
"on-primary-fixed-variant": "#004f58",
|
||||
"on-surface": "#e0e2ea",
|
||||
"on-surface-variant": "#bac9cc",
|
||||
"background": "#101419",
|
||||
"surface-tint": "#00daf3",
|
||||
"primary-fixed": "#9cf0ff",
|
||||
"on-tertiary": "#3c0091"
|
||||
},
|
||||
"borderRadius": {
|
||||
"DEFAULT": "0.25rem",
|
||||
"lg": "0.5rem",
|
||||
"xl": "0.75rem",
|
||||
"full": "9999px"
|
||||
},
|
||||
"spacing": {
|
||||
"space-sm": "0.5rem",
|
||||
"gutter-lg": "1.5rem",
|
||||
"space-xs": "0.25rem",
|
||||
"margin": "1rem",
|
||||
"margin-lg": "2rem",
|
||||
"space-xl": "2rem",
|
||||
"space-md": "1rem",
|
||||
"space-lg": "1.5rem",
|
||||
"gutter": "1rem"
|
||||
},
|
||||
"fontFamily": {
|
||||
"headline-md": ["Space Grotesk"],
|
||||
"body-lg": ["Inter"],
|
||||
"display-hero-mobile": ["Space Grotesk"],
|
||||
"telemetry-metric-lg": ["JetBrains Mono"],
|
||||
"display-hero": ["Space Grotesk"],
|
||||
"headline-sm": ["Space Grotesk"],
|
||||
"telemetry-metric-md": ["JetBrains Mono"],
|
||||
"body-md": ["Inter"],
|
||||
"telemetry-metric-lg-mobile": ["JetBrains Mono"],
|
||||
"label-data": ["JetBrains Mono"],
|
||||
"label-caption": ["Inter"],
|
||||
"headline-lg": ["Space Grotesk"]
|
||||
},
|
||||
"fontSize": {
|
||||
"headline-md": ["24px", { "lineHeight": "32px", "letterSpacing": "-0.01em", "fontWeight": "600" }],
|
||||
"body-lg": ["16px", { "lineHeight": "24px", "fontWeight": "500" }],
|
||||
"display-hero-mobile": ["40px", { "lineHeight": "44px", "letterSpacing": "-0.02em", "fontWeight": "700" }],
|
||||
"telemetry-metric-lg": ["48px", { "lineHeight": "48px", "letterSpacing": "-0.04em", "fontWeight": "700" }],
|
||||
"display-hero": ["56px", { "lineHeight": "60px", "letterSpacing": "-0.03em", "fontWeight": "700" }],
|
||||
"headline-sm": ["20px", { "lineHeight": "28px", "fontWeight": "600" }],
|
||||
"telemetry-metric-md": ["28px", { "lineHeight": "32px", "letterSpacing": "-0.02em", "fontWeight": "600" }],
|
||||
"body-md": ["14px", { "lineHeight": "20px", "fontWeight": "400" }],
|
||||
"telemetry-metric-lg-mobile": ["36px", { "lineHeight": "36px", "letterSpacing": "-0.03em", "fontWeight": "700" }],
|
||||
"label-data": ["12px", { "lineHeight": "16px", "letterSpacing": "0.08em", "fontWeight": "600" }],
|
||||
"label-caption": ["11px", { "lineHeight": "14px", "letterSpacing": "0.05em", "fontWeight": "600" }],
|
||||
"headline-lg": ["32px", { "lineHeight": "40px", "letterSpacing": "-0.02em", "fontWeight": "700" }]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
/* Neon photon & high-contrast glow overrides */
|
||||
.glow-cyan {
|
||||
box-shadow: 0 0 16px rgba(0, 229, 255, 0.25);
|
||||
}
|
||||
.glow-cyan-btn {
|
||||
box-shadow: 0 0 18px rgba(0, 229, 255, 0.4);
|
||||
}
|
||||
.glow-cyan-border {
|
||||
border-color: #00e5ff;
|
||||
box-shadow: inset 0 0 12px rgba(0, 229, 255, 0.15), 0 0 12px rgba(0, 229, 255, 0.2);
|
||||
}
|
||||
.tactical-grid {
|
||||
background-size: 24px 24px;
|
||||
background-image:
|
||||
linear-gradient(to right, rgba(30, 41, 59, 0.3) 1px, transparent 1px),
|
||||
linear-gradient(to bottom, rgba(30, 41, 59, 0.3) 1px, transparent 1px);
|
||||
}
|
||||
/* Material Icon sizing helper */
|
||||
.material-symbols-outlined {
|
||||
font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
line-height: 1;
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
body {
|
||||
min-height: max(884px, 100dvh);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-surface-container-lowest text-on-surface antialiased min-h-screen pb-36 select-none font-body-md tactical-grid">
|
||||
<!-- Top Tactical Status Bar & Shell Navigation -->
|
||||
<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 gap-space-sm">
|
||||
<button aria-label="Back to Group Rides" class="w-10 h-10 flex items-center justify-center rounded-lg bg-surface-container-low border border-outline-variant text-on-surface hover:text-primary-container active:scale-95 transition-all" type="button">
|
||||
<span class="material-symbols-outlined" data-icon="arrow_back">arrow_back</span>
|
||||
</button>
|
||||
<div class="flex flex-col">
|
||||
<span class="font-label-data text-label-data text-outline leading-tight tracking-wider">COMMISSION PROTOCOL // GRP-04</span>
|
||||
<h1 class="font-headline-sm text-headline-sm font-bold tracking-tight text-primary-container leading-none">CREATE GROUP RIDE</h1>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Live Telemetry Status Locks -->
|
||||
<div class="flex items-center gap-space-sm">
|
||||
<div class="flex items-center gap-1 px-2 py-1 rounded bg-surface-container border border-outline-variant">
|
||||
<span class="w-2 h-2 rounded-full bg-primary-container animate-pulse"></span>
|
||||
<span class="font-label-data text-label-data text-primary-container">20Hz GNSS</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-1 px-2 py-1 rounded bg-surface-container border border-outline-variant">
|
||||
<span class="material-symbols-outlined text-[16px] text-on-surface" data-icon="battery_charging_full">battery_charging_full</span>
|
||||
<span class="font-label-data text-label-data text-on-surface">98%</span>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<!-- Main Multi-Step Wizard Content Area -->
|
||||
<main class="w-full max-w-xl mx-auto pt-16 px-gutter">
|
||||
<!-- Step Progress Breadcrumb -->
|
||||
<section class="mt-4 mb-6">
|
||||
<div class="bg-surface-container-low border border-outline-variant rounded-xl p-3">
|
||||
<div class="grid grid-cols-3 gap-2 relative">
|
||||
<!-- Step 1 (Active) -->
|
||||
<div class="flex flex-col items-center gap-1.5 z-10">
|
||||
<div class="w-7 h-7 rounded-full bg-primary-container text-on-primary flex items-center justify-center font-label-data text-label-data font-bold glow-cyan">
|
||||
01
|
||||
</div>
|
||||
<span class="font-label-data text-label-data text-primary-container font-semibold tracking-wider text-center">1. DETAILS</span>
|
||||
</div>
|
||||
<!-- Step 2 (Pending) -->
|
||||
<div class="flex flex-col items-center gap-1.5 z-10">
|
||||
<div class="w-7 h-7 rounded-full bg-surface-container-high border border-outline-variant text-on-surface-variant flex items-center justify-center font-label-data text-label-data">
|
||||
02
|
||||
</div>
|
||||
<span class="font-label-data text-label-data text-on-surface-variant tracking-wider text-center">2. ROUTE & PACE</span>
|
||||
</div>
|
||||
<!-- Step 3 (Pending) -->
|
||||
<div class="flex flex-col items-center gap-1.5 z-10">
|
||||
<div class="w-7 h-7 rounded-full bg-surface-container-high border border-outline-variant text-on-surface-variant flex items-center justify-center font-label-data text-label-data">
|
||||
03
|
||||
</div>
|
||||
<span class="font-label-data text-label-data text-on-surface-variant tracking-wider text-center">3. STAGING</span>
|
||||
</div>
|
||||
<!-- Progress Connector Track -->
|
||||
<div class="absolute top-3.5 left-8 right-8 h-[2px] bg-surface-variant -z-0">
|
||||
<div class="h-full bg-primary-container w-1/3"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- SECTION 1: Mission Identity & Logistics -->
|
||||
<section class="mb-6">
|
||||
<div class="flex items-center justify-between mb-2">
|
||||
<h2 class="font-label-data text-label-data text-primary-container font-bold tracking-widest uppercase">
|
||||
1. RIDE DETAILS & SCHEDULE
|
||||
</h2>
|
||||
<span class="font-label-caption text-label-caption text-outline">PRIMARY IDENTIFIER</span>
|
||||
</div>
|
||||
<div class="bg-surface-container-low border border-outline-variant rounded-xl p-4 flex flex-col gap-4">
|
||||
<!-- Title Input -->
|
||||
<div class="flex flex-col gap-1.5">
|
||||
<label class="font-label-data text-label-data text-on-surface-variant flex items-center justify-between">
|
||||
<span>RIDE CALLSIGN / TITLE</span>
|
||||
<span class="text-primary-container font-semibold">REQUIRED</span>
|
||||
</label>
|
||||
<div class="relative">
|
||||
<input class="w-full h-12 bg-surface-container-lowest border border-outline-variant rounded-lg px-4 text-on-surface font-body-md focus:outline-none focus:border-primary-container focus:ring-1 focus:ring-primary-container transition-all" placeholder="e.g. Skyline Ridge Dawn Patrol" type="text" value="Skyline Ridge Dawn Patrol"/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Staging Point Input -->
|
||||
<div class="flex flex-col gap-1.5">
|
||||
<label class="font-label-data text-label-data text-on-surface-variant flex items-center justify-between">
|
||||
<span>STAGING / DEPARTURE POINT</span>
|
||||
<span class="text-outline">GPS SYNCHRONIZED</span>
|
||||
</label>
|
||||
<div class="relative flex items-center">
|
||||
<span class="material-symbols-outlined absolute left-3.5 text-primary-container pointer-events-none" data-icon="location_on">location_on</span>
|
||||
<input class="w-full h-12 bg-surface-container-lowest border border-outline-variant rounded-lg pl-11 pr-4 text-on-surface font-body-md focus:outline-none focus:border-primary-container focus:ring-1 focus:ring-primary-container transition-all" placeholder="Staging location or coordinates" type="text" value="Alice's Restaurant (Skyline Blvd & CA-84)"/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Date & KSU Picker Matrix -->
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 gap-3">
|
||||
<!-- Departure Date -->
|
||||
<div class="flex flex-col gap-1.5">
|
||||
<label class="font-label-data text-label-data text-on-surface-variant">DATE</label>
|
||||
<div class="relative flex items-center">
|
||||
<span class="material-symbols-outlined absolute left-3 text-outline pointer-events-none" data-icon="calendar_month">calendar_month</span>
|
||||
<input class="w-full h-12 bg-surface-container-lowest border border-outline-variant rounded-lg pl-10 pr-3 text-on-surface font-body-md focus:outline-none focus:border-primary-container transition-all" type="text" value="Saturday, Oct 21"/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- KSU Departure Time -->
|
||||
<div class="flex flex-col gap-1.5">
|
||||
<div class="flex items-center justify-between">
|
||||
<label class="font-label-data text-label-data text-on-surface-variant">KICKSTANDS UP (KSU)</label>
|
||||
<span class="px-1.5 py-0.5 rounded bg-surface-container-high border border-outline-variant text-primary-container font-label-caption text-label-caption">T-14h 22m</span>
|
||||
</div>
|
||||
<div class="relative flex items-center">
|
||||
<span class="material-symbols-outlined absolute left-3 text-primary-container pointer-events-none" data-icon="schedule">schedule</span>
|
||||
<input class="w-full h-12 bg-surface-container-lowest border border-outline-variant rounded-lg pl-10 pr-3 text-on-surface font-body-md focus:outline-none focus:border-primary-container transition-all" type="text" value="07:30 AM PST (KSU)"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- SECTION 2: Route Attachment & Telemetry Vector -->
|
||||
<section class="mb-6">
|
||||
<div class="flex items-center justify-between mb-2">
|
||||
<h2 class="font-label-data text-label-data text-primary-container font-bold tracking-widest uppercase">
|
||||
2. ROUTE & ELEVATION TRACE
|
||||
</h2>
|
||||
<span class="font-label-caption text-label-caption text-outline">TELEMETRY ATTACHED</span>
|
||||
</div>
|
||||
<div class="bg-surface-container-low border border-outline-variant rounded-xl overflow-hidden p-4">
|
||||
<!-- Route Visual Header & Map Thumbnail -->
|
||||
<div class="relative w-full h-36 rounded-lg overflow-hidden border border-outline-variant mb-4 bg-surface-container-lowest">
|
||||
<img class="w-full h-full object-cover opacity-60" data-alt="A dark tactical satellite HUD map displaying a winding mountain pass route highlighted with a glowing electric cyan vector line. Digital contour lines, elevation gradients, and motorcycle telemetry markers indicate corner radii across a deep charcoal terrain." src="https://lh3.googleusercontent.com/aida-public/AB6AXuC8H-zkdNszlGEhytHWfiJLLOnLh5EVRd81HnCdsLhoIACS6k4fiVwMAA7WMUUpr-b_HoiY-2e6jiqjR0u7n494u47Ksrf_PNJmnHOYPbLEtRggxhhBcT_5zVpTQk66Zqqm6YbfiOcmSgLtVasOOFJicx2Dci42-yAoPNQmmoeiRDiA-ouLJrp6gLGXaX6oIH8UJnB4N_6wycYW-bQjSen9psx6wARG_6s54G4GcBF0wE6vkoQhLqR4p3PsNQwsjyQXQxXfUPjVY8o"/>
|
||||
<div class="absolute inset-0 bg-gradient-to-t from-surface-container-lowest via-transparent to-transparent"></div>
|
||||
<!-- Route Name Banner Overlay -->
|
||||
<div class="absolute bottom-2.5 left-3 right-3 flex items-center justify-between">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-primary-container" data-icon="route">route</span>
|
||||
<span class="font-headline-sm text-headline-sm text-on-surface font-bold tracking-wide">CA-35 to CA-9 Loop</span>
|
||||
</div>
|
||||
<span class="px-2 py-0.5 rounded bg-primary-container text-on-primary font-label-data text-label-data font-bold">VERIFIED</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Telemetry Stats Bento Strip -->
|
||||
<div class="grid grid-cols-3 gap-2 mb-4">
|
||||
<div class="bg-surface-container-lowest border border-outline-variant p-2.5 rounded-lg text-center">
|
||||
<span class="font-label-caption text-label-caption text-outline block">TOTAL DISTANCE</span>
|
||||
<span class="font-telemetry-metric-md text-telemetry-metric-md text-primary-container font-bold leading-none mt-1 block">64.2</span>
|
||||
<span class="font-label-data text-label-data text-on-surface-variant">MILES</span>
|
||||
</div>
|
||||
<div class="bg-surface-container-lowest border border-outline-variant p-2.5 rounded-lg text-center">
|
||||
<span class="font-label-caption text-label-caption text-outline block">CORNER DENSITY</span>
|
||||
<span class="font-telemetry-metric-md text-telemetry-metric-md text-on-surface font-bold leading-none mt-1 block">142</span>
|
||||
<span class="font-label-data text-label-data text-on-surface-variant">CURVES</span>
|
||||
</div>
|
||||
<div class="bg-surface-container-lowest border border-outline-variant p-2.5 rounded-lg text-center">
|
||||
<span class="font-label-caption text-label-caption text-outline block">VERTICAL CLIMB</span>
|
||||
<span class="font-telemetry-metric-md text-telemetry-metric-md text-on-surface font-bold leading-none mt-1 block">+3,480</span>
|
||||
<span class="font-label-data text-label-data text-on-surface-variant">FEET GAIN</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Route Management Actions (48px Touch Zones) -->
|
||||
<div class="grid grid-cols-2 gap-3">
|
||||
<button class="h-12 flex items-center justify-center gap-2 rounded-lg bg-surface-container border border-outline-variant text-on-surface font-label-data text-label-data font-semibold hover:border-primary-container hover:text-primary-container active:scale-95 transition-all" type="button">
|
||||
<span class="material-symbols-outlined text-[18px]" data-icon="swap_horiz">swap_horiz</span>
|
||||
SWAP ROUTE
|
||||
</button>
|
||||
<button class="h-12 flex items-center justify-center gap-2 rounded-lg bg-surface-container border border-outline-variant text-on-surface font-label-data text-label-data font-semibold hover:border-primary-container hover:text-primary-container active:scale-95 transition-all" type="button">
|
||||
<span class="material-symbols-outlined text-[18px]" data-icon="file_upload">file_upload</span>
|
||||
IMPORT GPX
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- SECTION 3: Pace Classification Rules -->
|
||||
<section class="mb-6">
|
||||
<div class="flex items-center justify-between mb-2">
|
||||
<h2 class="font-label-data text-label-data text-primary-container font-bold tracking-widest uppercase">
|
||||
3. PACE DISCIPLINE & RULES
|
||||
</h2>
|
||||
<span class="font-label-caption text-label-caption text-outline">TELEMETRY LEAN LIMITS</span>
|
||||
</div>
|
||||
<div aria-label="Ride Pace Category" class="grid grid-cols-1 sm:grid-cols-2 gap-2.5" role="radiogroup">
|
||||
<!-- Pace 1 Card -->
|
||||
<div class="p-3.5 rounded-xl bg-surface-container-low border border-outline-variant flex flex-col justify-between cursor-pointer hover:border-outline active:scale-98 transition-all">
|
||||
<div class="flex items-center justify-between mb-1.5">
|
||||
<span class="font-headline-sm text-headline-sm font-bold text-on-surface">Pace 1 Mellow</span>
|
||||
<div class="w-4 h-4 rounded-full border border-outline-variant flex items-center justify-center"></div>
|
||||
</div>
|
||||
<p class="font-body-md text-body-md text-on-surface-variant mb-2">Scenic touring rhythm suitable for all motorcycle platforms.</p>
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="px-2 py-0.5 rounded bg-surface-container border border-outline-variant font-label-data text-label-data text-outline">< 35° LEAN</span>
|
||||
<span class="font-label-caption text-label-caption text-outline">CASUAL</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Pace 2 Card -->
|
||||
<div class="p-3.5 rounded-xl bg-surface-container-low border border-outline-variant flex flex-col justify-between cursor-pointer hover:border-outline active:scale-98 transition-all">
|
||||
<div class="flex items-center justify-between mb-1.5">
|
||||
<span class="font-headline-sm text-headline-sm font-bold text-on-surface">Pace 2 Moderate</span>
|
||||
<div class="w-4 h-4 rounded-full border border-outline-variant flex items-center justify-center"></div>
|
||||
</div>
|
||||
<p class="font-body-md text-body-md text-on-surface-variant mb-2">Fluid progressive flow through sweeping turns without abrupt braking.</p>
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="px-2 py-0.5 rounded bg-surface-container border border-outline-variant font-label-data text-label-data text-outline">35°-42° LEAN</span>
|
||||
<span class="font-label-caption text-label-caption text-outline">CRUISING</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Pace 3 Card (ACTIVE / SELECTED) -->
|
||||
<div class="p-3.5 rounded-xl bg-surface-container border-2 border-primary-container glow-cyan-border flex flex-col justify-between cursor-pointer active:scale-98 transition-all relative">
|
||||
<div class="flex items-center justify-between mb-1.5">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="font-headline-sm text-headline-sm font-bold text-primary-container">Pace 3 Brisk</span>
|
||||
<span class="px-1.5 py-0.2 rounded bg-primary-container text-on-primary font-label-caption text-label-caption font-bold">SELECTED</span>
|
||||
</div>
|
||||
<div class="w-4 h-4 rounded-full border-2 border-primary-container flex items-center justify-center">
|
||||
<div class="w-2 h-2 rounded-full bg-primary-container"></div>
|
||||
</div>
|
||||
</div>
|
||||
<p class="font-body-md text-body-md text-on-surface mb-2">Experienced canyon cadence with continuous apex awareness and tight line precision.</p>
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="px-2 py-0.5 rounded bg-surface-container-high border border-primary-container font-label-data text-label-data text-primary-container">42°-49° LEAN</span>
|
||||
<span class="font-label-caption text-label-caption text-primary-fixed-dim">TECHNICAL CORNERING</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Pace 4 Card -->
|
||||
<div class="p-3.5 rounded-xl bg-surface-container-low border border-outline-variant flex flex-col justify-between cursor-pointer hover:border-outline active:scale-98 transition-all">
|
||||
<div class="flex items-center justify-between mb-1.5">
|
||||
<span class="font-headline-sm text-headline-sm font-bold text-on-surface">Pace 4 Technical</span>
|
||||
<div class="w-4 h-4 rounded-full border border-outline-variant flex items-center justify-center"></div>
|
||||
</div>
|
||||
<p class="font-body-md text-body-md text-on-surface-variant mb-2">Full commitment canyon pacing. Track experience or knee-slider verification recommended.</p>
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="px-2 py-0.5 rounded bg-surface-container border border-outline-variant font-label-data text-label-data text-error">> 50° LEAN</span>
|
||||
<span class="font-label-caption text-label-caption text-outline">AGGRESSIVE</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- SECTION 4: Pack Capacity & Comms Configuration -->
|
||||
<section class="mb-6">
|
||||
<div class="flex items-center justify-between mb-2">
|
||||
<h2 class="font-label-data text-label-data text-primary-container font-bold tracking-widest uppercase">
|
||||
4. SQUAD FORMATION LIMITS
|
||||
</h2>
|
||||
<span class="font-label-caption text-label-caption text-outline">DYNAMIC MESH ALLOCATION</span>
|
||||
</div>
|
||||
<div class="bg-surface-container-low border border-outline-variant rounded-xl p-4 flex flex-col gap-4">
|
||||
<!-- Stepper Component (Pack Limit) -->
|
||||
<div class="flex flex-col gap-2">
|
||||
<div class="flex items-center justify-between">
|
||||
<label class="font-label-data text-label-data text-on-surface-variant">MAXIMUM PACK CAPACITY</label>
|
||||
<span class="font-label-caption text-label-caption text-outline">STAGGER OPTIMIZED</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between bg-surface-container-lowest border border-outline-variant rounded-lg p-2">
|
||||
<!-- Decrement 48px Touch Zone -->
|
||||
<button aria-label="Decrease pack size" class="w-12 h-12 rounded-lg bg-surface-container border border-outline-variant text-on-surface flex items-center justify-center hover:text-primary-container active:scale-95 transition-all" type="button">
|
||||
<span class="material-symbols-outlined text-[24px]" data-icon="remove">remove</span>
|
||||
</button>
|
||||
<div class="flex flex-col items-center">
|
||||
<div class="flex items-baseline gap-1">
|
||||
<span class="font-telemetry-metric-lg text-telemetry-metric-lg text-primary-container font-bold">8</span>
|
||||
<span class="font-label-data text-label-data text-on-surface-variant uppercase">Riders Max</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Increment 48px Touch Zone -->
|
||||
<button aria-label="Increase pack size" class="w-12 h-12 rounded-lg bg-surface-container border border-outline-variant text-on-surface flex items-center justify-center hover:text-primary-container active:scale-95 transition-all" type="button">
|
||||
<span class="material-symbols-outlined text-[24px]" data-icon="add">add</span>
|
||||
</button>
|
||||
</div>
|
||||
<!-- Stagger Formation Helper Box -->
|
||||
<div class="flex items-center gap-2 p-2.5 rounded-lg bg-surface-container border border-outline-variant">
|
||||
<span class="material-symbols-outlined text-primary-container text-[18px]" data-icon="hub">hub</span>
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant">Recommended 2x2 Staggered Diamond for 8 units (2.0s buffer).</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="h-[1px] bg-outline-variant w-full"></div>
|
||||
<!-- Mesh Comms Channel Switch -->
|
||||
<div class="flex items-center justify-between pt-1">
|
||||
<div class="flex flex-col">
|
||||
<div class="flex items-center gap-1.5">
|
||||
<span class="material-symbols-outlined text-primary-container text-[18px]" data-icon="cell_tower">cell_tower</span>
|
||||
<span class="font-headline-sm text-headline-sm text-on-surface font-semibold text-[16px]">Direct 915MHz P2P Comms Interlock</span>
|
||||
</div>
|
||||
<span class="font-label-caption text-label-caption text-outline">AUTO-ENCRYPTED MOTORNET PROTOCOL (CH-04)</span>
|
||||
</div>
|
||||
<!-- Tactical Oversized Switch -->
|
||||
<label class="relative inline-flex items-center cursor-pointer">
|
||||
<input checked="" class="sr-only peer" type="checkbox"/>
|
||||
<div class="w-14 h-8 bg-surface-container-high peer-focus:outline-none rounded-full peer peer-checked:after:translate-x-6 peer-checked:after:border-surface-container-lowest after:content-[''] after:absolute after:top-[4px] after:left-[4px] after:bg-primary-container after:border-gray-300 after:border after:rounded-full after:h-6 after:w-6 after:transition-all peer-checked:bg-secondary-container"></div>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- SECTION 5: Primary Action Footer (52px Glove Touch Hitbox) -->
|
||||
<div class="mt-4 mb-8">
|
||||
<button class="w-full h-[52px] bg-primary-container text-surface-container-lowest font-headline-sm text-headline-sm font-bold rounded-lg flex items-center justify-center gap-3 tracking-wide glow-cyan-btn hover:bg-primary-fixed-dim active:scale-95 transition-all" type="button">
|
||||
<span>PUBLISH & STAGE PACK RIDE</span>
|
||||
<span class="material-symbols-outlined font-bold" data-icon="bolt">bolt</span>
|
||||
</button>
|
||||
<div class="flex items-center justify-center gap-1 mt-2 text-center">
|
||||
<span class="material-symbols-outlined text-[14px] text-outline" data-icon="touch_app">touch_app</span>
|
||||
<span class="font-label-caption text-label-caption text-outline tracking-wider uppercase">Target: 52px Minimum Glove Hitbox</span>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
<!-- Persistent Bottom Navigation Bar (BottomNavBar Anchor) -->
|
||||
<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">
|
||||
<!-- Tab 1: Dash -->
|
||||
<button class="flex flex-col items-center justify-center text-on-surface-variant px-2 py-1 min-h-[48px] hover:bg-surface-container-low hover:text-primary-fixed active:scale-95 duration-100 ease-out" type="button">
|
||||
<span class="material-symbols-outlined" data-icon="speed">speed</span>
|
||||
<span class="font-label-caption text-label-caption mt-0.5">Dash</span>
|
||||
</button>
|
||||
<!-- Tab 2: Map -->
|
||||
<button class="flex flex-col items-center justify-center text-on-surface-variant px-2 py-1 min-h-[48px] hover:bg-surface-container-low hover:text-primary-fixed active:scale-95 duration-100 ease-out" type="button">
|
||||
<span class="material-symbols-outlined" data-icon="navigation">navigation</span>
|
||||
<span class="font-label-caption text-label-caption mt-0.5">Map</span>
|
||||
</button>
|
||||
<!-- Tab 3: Activity (Active context for Group Rides staging & execution) -->
|
||||
<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] active:scale-95 duration-100 ease-out" type="button">
|
||||
<span class="material-symbols-outlined" data-icon="analytics" style="font-variation-settings: 'FILL' 1;">analytics</span>
|
||||
<span class="font-label-caption text-label-caption font-semibold mt-0.5">Activity</span>
|
||||
</button>
|
||||
<!-- Tab 4: Garage -->
|
||||
<button class="flex flex-col items-center justify-center text-on-surface-variant px-2 py-1 min-h-[48px] hover:bg-surface-container-low hover:text-primary-fixed active:scale-95 duration-100 ease-out" type="button">
|
||||
<span class="material-symbols-outlined" data-icon="two_wheeler">two_wheeler</span>
|
||||
<span class="font-label-caption text-label-caption mt-0.5">Garage</span>
|
||||
</button>
|
||||
<!-- Tab 5: Settings -->
|
||||
<button class="flex flex-col items-center justify-center text-on-surface-variant px-2 py-1 min-h-[48px] hover:bg-surface-container-low hover:text-primary-fixed active:scale-95 duration-100 ease-out" type="button">
|
||||
<span class="material-symbols-outlined" data-icon="settings">settings</span>
|
||||
<span class="font-label-caption text-label-caption mt-0.5">Settings</span>
|
||||
</button>
|
||||
</nav>
|
||||
<!-- Lightweight Inline State Handling for Interactive Demo -->
|
||||
<script>
|
||||
// Rider stepper demo logic
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const stepperMinus = document.querySelector('button[aria-label="Decrease pack size"]');
|
||||
const stepperPlus = document.querySelector('button[aria-label="Increase pack size"]');
|
||||
const riderCountDisplay = document.querySelector('.text-telemetry-metric-lg');
|
||||
|
||||
if (stepperMinus && stepperPlus && riderCountDisplay) {
|
||||
let count = 8;
|
||||
stepperMinus.addEventListener('click', () => {
|
||||
if (count > 2) {
|
||||
count--;
|
||||
riderCountDisplay.textContent = count;
|
||||
}
|
||||
});
|
||||
stepperPlus.addEventListener('click', () => {
|
||||
if (count < 24) {
|
||||
count++;
|
||||
riderCountDisplay.textContent = count;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body></html>
|
||||
|
|
@ -0,0 +1,547 @@
|
|||
<!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>Account & Security Settings - MotorSignal HUD</title>
|
||||
<!-- Material Symbols Outlined -->
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<!-- 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&family=JetBrains+Mono:wght@500;600;700&family=Space+Grotesk:wght@600;700;800&display=swap" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<!-- Tailwind CSS -->
|
||||
<script src="https://cdn.tailwindcss.com?plugins=forms,container-queries"></script>
|
||||
<script id="tailwind-config">
|
||||
tailwind.config = {
|
||||
darkMode: "class",
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
"secondary-fixed": "#dbe1ff",
|
||||
"on-secondary-container": "#cdd7ff",
|
||||
"surface-container-lowest": "#0b0e13",
|
||||
"on-tertiary-fixed-variant": "#5516be",
|
||||
"on-error": "#690005",
|
||||
"tertiary-fixed": "#e9ddff",
|
||||
"secondary-fixed-dim": "#b4c5ff",
|
||||
"inverse-on-surface": "#2d3036",
|
||||
"surface-bright": "#36393f",
|
||||
"tertiary-container": "#d9c8ff",
|
||||
"on-secondary-fixed-variant": "#003ea8",
|
||||
"on-surface-variant": "#bac9cc",
|
||||
"on-tertiary-container": "#6834d1",
|
||||
"background": "#101419",
|
||||
"on-primary": "#00363d",
|
||||
"tertiary-fixed-dim": "#d0bcff",
|
||||
"on-secondary": "#002a78",
|
||||
"tertiary": "#f2e9ff",
|
||||
"inverse-primary": "#006875",
|
||||
"secondary-container": "#0053db",
|
||||
"on-primary-container": "#00626e",
|
||||
"secondary": "#b4c5ff",
|
||||
"on-tertiary": "#3c0091",
|
||||
"inverse-surface": "#e0e2ea",
|
||||
"on-tertiary-fixed": "#23005c",
|
||||
"surface-variant": "#32353b",
|
||||
"outline-variant": "#3b494c",
|
||||
"error-container": "#93000a",
|
||||
"primary-container": "#00e5ff",
|
||||
"surface": "#101419",
|
||||
"error": "#ffb4ab",
|
||||
"on-surface": "#e0e2ea",
|
||||
"surface-tint": "#00daf3",
|
||||
"surface-container": "#1d2025",
|
||||
"on-error-container": "#ffdad6",
|
||||
"primary-fixed": "#9cf0ff",
|
||||
"primary": "#c3f5ff",
|
||||
"outline": "#849396",
|
||||
"surface-dim": "#101419",
|
||||
"surface-container-low": "#181c21",
|
||||
"on-background": "#e0e2ea",
|
||||
"surface-container-highest": "#32353b",
|
||||
"primary-fixed-dim": "#00daf3",
|
||||
"surface-container-high": "#272a30",
|
||||
"on-secondary-fixed": "#00174b",
|
||||
"on-primary-fixed": "#001f24",
|
||||
"on-primary-fixed-variant": "#004f58"
|
||||
},
|
||||
borderRadius: {
|
||||
"DEFAULT": "0.25rem",
|
||||
"lg": "0.5rem",
|
||||
"xl": "0.75rem",
|
||||
"full": "9999px"
|
||||
},
|
||||
spacing: {
|
||||
"margin-lg": "2rem",
|
||||
"gutter": "1rem",
|
||||
"space-xs": "0.25rem",
|
||||
"space-xl": "2rem",
|
||||
"margin": "1rem",
|
||||
"gutter-lg": "1.5rem",
|
||||
"space-sm": "0.5rem",
|
||||
"space-md": "1rem",
|
||||
"space-lg": "1.5rem"
|
||||
},
|
||||
fontFamily: {
|
||||
"telemetry-metric-lg-mobile": ["JetBrains Mono"],
|
||||
"display-hero": ["Space Grotesk"],
|
||||
"body-lg": ["Inter"],
|
||||
"headline-lg": ["Space Grotesk"],
|
||||
"telemetry-metric-md": ["JetBrains Mono"],
|
||||
"telemetry-metric-lg": ["JetBrains Mono"],
|
||||
"headline-md": ["Space Grotesk"],
|
||||
"body-md": ["Inter"],
|
||||
"label-data": ["JetBrains Mono"],
|
||||
"label-caption": ["Inter"],
|
||||
"headline-sm": ["Space Grotesk"],
|
||||
"display-hero-mobile": ["Space Grotesk"]
|
||||
},
|
||||
fontSize: {
|
||||
"telemetry-metric-lg-mobile": ["36px", { lineHeight: "36px", letterSpacing: "-0.03em", fontWeight: "700" }],
|
||||
"display-hero": ["56px", { lineHeight: "60px", letterSpacing: "-0.03em", fontWeight: "700" }],
|
||||
"body-lg": ["16px", { lineHeight: "24px", fontWeight: "500" }],
|
||||
"headline-lg": ["32px", { lineHeight: "40px", letterSpacing: "-0.02em", fontWeight: "700" }],
|
||||
"telemetry-metric-md": ["28px", { lineHeight: "32px", letterSpacing: "-0.02em", fontWeight: "600" }],
|
||||
"telemetry-metric-lg": ["48px", { lineHeight: "48px", letterSpacing: "-0.04em", fontWeight: "700" }],
|
||||
"headline-md": ["24px", { lineHeight: "32px", letterSpacing: "-0.01em", fontWeight: "600" }],
|
||||
"body-md": ["14px", { lineHeight: "20px", fontWeight: "400" }],
|
||||
"label-data": ["12px", { lineHeight: "16px", letterSpacing: "0.08em", fontWeight: "600" }],
|
||||
"label-caption": ["11px", { lineHeight: "14px", letterSpacing: "0.05em", fontWeight: "600" }],
|
||||
"headline-sm": ["20px", { lineHeight: "28px", fontWeight: "600" }],
|
||||
"display-hero-mobile": ["40px", { lineHeight: "44px", letterSpacing: "-0.02em", fontWeight: "700" }]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
/* Physical tactical touches & glove focus ring */
|
||||
.tactical-border {
|
||||
border: 1px solid #1E293B;
|
||||
}
|
||||
.tactical-cyan-border {
|
||||
border: 1px solid rgba(0, 229, 255, 0.4);
|
||||
box-shadow: 0 0 16px rgba(0, 229, 255, 0.08);
|
||||
}
|
||||
.tactical-danger-border {
|
||||
border: 1px solid rgba(239, 68, 68, 0.35);
|
||||
box-shadow: 0 0 18px rgba(239, 68, 68, 0.12);
|
||||
}
|
||||
.glow-cyan {
|
||||
box-shadow: 0 0 14px rgba(0, 229, 255, 0.35);
|
||||
}
|
||||
/* Oversized custom toggle */
|
||||
.glove-toggle {
|
||||
width: 58px;
|
||||
height: 32px;
|
||||
appearance: none;
|
||||
background-color: #181c21;
|
||||
border: 1px solid #3b494c;
|
||||
border-radius: 9999px;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
outline: none;
|
||||
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
.glove-toggle::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 3px;
|
||||
left: 3px;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
background-color: #bac9cc;
|
||||
border-radius: 9999px;
|
||||
transition: transform 0.2s cubic-bezier(0.4, 0, 0.2, 1), background-color 0.2s;
|
||||
}
|
||||
.glove-toggle:checked {
|
||||
background-color: rgba(0, 229, 255, 0.18);
|
||||
border-color: #00e5ff;
|
||||
box-shadow: 0 0 12px rgba(0, 229, 255, 0.35);
|
||||
}
|
||||
.glove-toggle:checked::after {
|
||||
transform: translateX(26px);
|
||||
background-color: #00e5ff;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-[#070A0F] text-on-surface antialiased min-h-screen pb-24 selection:bg-primary-container selection:text-surface-container-lowest">
|
||||
<!-- TOP APP BAR & HARDWARE STATUS HUD -->
|
||||
<header class="fixed top-0 left-0 w-full z-50 bg-surface-container-lowest/95 backdrop-blur-md border-b border-outline-variant">
|
||||
<!-- Live Telemetry Status Strip -->
|
||||
<div class="flex items-center justify-between px-gutter py-1 bg-[#05070a] border-b border-surface-variant/40">
|
||||
<div class="flex items-center space-x-2">
|
||||
<span class="inline-block w-1.5 h-1.5 rounded-full bg-primary-container animate-pulse"></span>
|
||||
<span class="font-label-data text-label-data text-primary-container tracking-wider">20Hz KALMAN LOCK</span>
|
||||
</div>
|
||||
<div class="flex items-center space-x-3 text-on-surface-variant">
|
||||
<div class="flex items-center space-x-1">
|
||||
<span class="material-symbols-outlined text-[13px] text-primary" data-icon="lock" style="font-variation-settings: 'FILL' 1;">lock</span>
|
||||
<span class="font-label-data text-label-data text-on-surface">AES-GCM-256</span>
|
||||
</div>
|
||||
<div class="flex items-center space-x-1">
|
||||
<span class="material-symbols-outlined text-[14px] text-primary-container" data-icon="battery_full">battery_full</span>
|
||||
<span class="font-label-data text-label-data text-on-surface">98%</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Main Navigation Header -->
|
||||
<div class="flex items-center justify-between px-gutter h-14">
|
||||
<div class="flex items-center space-x-2.5">
|
||||
<button aria-label="Navigate Back" class="w-12 h-12 flex items-center justify-center rounded-lg bg-surface-container-low text-on-surface hover:text-primary-container hover:bg-surface-container active:scale-95 transition-all" type="button">
|
||||
<span class="material-symbols-outlined text-2xl" data-icon="arrow_back">arrow_back</span>
|
||||
</button>
|
||||
<div>
|
||||
<h1 class="font-headline-sm text-headline-sm font-bold tracking-tight text-on-surface leading-tight">ACCOUNT & SECURITY</h1>
|
||||
<p class="font-label-data text-label-data text-primary-container flex items-center space-x-1">
|
||||
<span>SEC-09 // AUTH & VAULT</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center space-x-1">
|
||||
<span class="w-2.5 h-2.5 rounded-full bg-primary-container/20 border border-primary-container flex items-center justify-center">
|
||||
<span class="w-1 h-1 rounded-full bg-primary-container"></span>
|
||||
</span>
|
||||
<span class="font-label-data text-label-data text-on-surface-variant">ARMED</span>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<!-- MAIN SCROLLABLE CONTENT CANVAS -->
|
||||
<main class="max-w-md mx-auto pt-24 px-gutter space-y-5">
|
||||
<!-- RIDER QUICK IDENTIFIER HERO TILE -->
|
||||
<div class="tactical-border rounded-xl bg-[#0D131F] p-space-md relative overflow-hidden">
|
||||
<!-- Glow ambient background light -->
|
||||
<div class="absolute -top-10 -right-10 w-32 h-32 bg-primary-container/10 rounded-full blur-2xl pointer-events-none"></div>
|
||||
<div class="flex items-center space-x-4">
|
||||
<!-- Helmet Profile Avatar -->
|
||||
<div class="relative shrink-0">
|
||||
<img alt="Rider Marcus Helmet Telemetry HUD profile avatar" class="w-16 h-16 rounded-xl object-cover border border-primary-container/50 shadow-md" src="https://lh3.googleusercontent.com/aida/AEtjO1WVxZBfZMbTdHeRSt73fWRy6gjWk3_qTm8SSSfoWQnQsHYP2ngztRX-GwRDxracXqrxt42j0x_3rYX-Deu1wGtF7R_qj3ZMExn0d6mErdfGFPGmEtddnnmd0i_Ez6Mv8kj3AYzks1N9Gq4hr9VObylWxDqngSG4Yi5vS-Sj7j3tfyZc_6dknnGpnnb5vC4PQmhuUp58_MzZvopIwkRWq0S27smUu_5zRLguTCXTKrFUEw9TiLBSRA4aXu4"/>
|
||||
<span class="absolute -bottom-1 -right-1 bg-surface-container-lowest border border-primary-container rounded-full p-0.5">
|
||||
<span class="material-symbols-outlined text-[14px] text-primary-container block" data-icon="verified" style="font-variation-settings: 'FILL' 1;">verified</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="min-w-0 flex-1">
|
||||
<div class="flex items-center space-x-2">
|
||||
<span class="font-headline-sm text-headline-sm font-bold text-on-surface truncate">@ApexMarcus</span>
|
||||
<span class="bg-primary-container/15 border border-primary-container text-primary-container font-label-data text-label-data px-1.5 py-0.5 rounded tracking-wider font-bold">PRO</span>
|
||||
</div>
|
||||
<p class="font-label-data text-label-data text-on-surface-variant mt-0.5 truncate">CRYPTO-SIGN // 0x9AF8..C104</p>
|
||||
<div class="flex items-center gap-2 mt-1.5">
|
||||
<span class="inline-flex items-center text-label-caption font-label-caption text-primary-fixed bg-surface-container-high px-2 py-0.5 rounded">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-primary-container mr-1.5"></span>
|
||||
IMU Linked
|
||||
</span>
|
||||
<span class="text-label-caption font-label-caption text-on-surface-variant">KTM 890 R</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- SECTION 1: IDENTITY & AUTHENTICATION -->
|
||||
<section class="space-y-3">
|
||||
<div class="flex items-center justify-between px-1">
|
||||
<div class="flex items-center space-x-2">
|
||||
<span class="material-symbols-outlined text-primary-container text-lg" data-icon="fingerprint">fingerprint</span>
|
||||
<h2 class="font-headline-sm text-headline-sm font-bold text-on-surface text-base tracking-wide">Identity & Authentication</h2>
|
||||
</div>
|
||||
<span class="font-label-data text-label-data text-on-surface-variant">SEC-LEVEL 4</span>
|
||||
</div>
|
||||
<div class="tactical-border rounded-xl bg-[#0D131F] p-4 space-y-4">
|
||||
<!-- Callsign Handle (Immutable) -->
|
||||
<div>
|
||||
<label class="block font-label-data text-label-data text-on-surface-variant uppercase mb-1.5">Rider Callsign (Telemetry Signature)</label>
|
||||
<div class="flex items-center justify-between h-12 px-3 rounded-lg bg-surface-container-lowest border border-surface-variant/60 text-on-surface">
|
||||
<span class="font-label-data text-label-data text-on-surface font-bold tracking-wider">@ApexMarcus</span>
|
||||
<div class="flex items-center space-x-1 text-on-surface-variant">
|
||||
<span class="material-symbols-outlined text-base" data-icon="lock" style="font-variation-settings: 'FILL' 1;">lock</span>
|
||||
<span class="font-label-caption text-label-caption">LOCKED</span>
|
||||
</div>
|
||||
</div>
|
||||
<p class="font-label-caption text-label-caption text-on-surface-variant mt-1">Cryptographically tied to your hardware telemetry blackbox.</p>
|
||||
</div>
|
||||
<!-- Email Field -->
|
||||
<div>
|
||||
<div class="flex justify-between items-center mb-1.5">
|
||||
<label class="font-label-data text-label-data text-on-surface-variant uppercase">Cockpit Dispatch Email</label>
|
||||
<span class="inline-flex items-center text-primary-container font-label-data text-label-data text-[10px] bg-primary-container/10 border border-primary-container/40 px-1.5 py-0.2 rounded font-bold">
|
||||
<span class="material-symbols-outlined text-[12px] mr-1" data-icon="check_circle" style="font-variation-settings: 'FILL' 1;">check_circle</span>
|
||||
VERIFIED
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex flex-col sm:flex-row gap-2">
|
||||
<div class="flex-1 flex items-center h-12 px-3 rounded-lg bg-surface-container-lowest border border-outline-variant text-on-surface">
|
||||
<span class="material-symbols-outlined text-on-surface-variant text-lg mr-2" data-icon="alternate_email">alternate_email</span>
|
||||
<input aria-label="Dispatch Email Address" class="bg-transparent border-0 p-0 text-sm font-body-md text-on-surface focus:ring-0 w-full" readonly="" type="text" value="marcus.apex@motorsignal.io"/>
|
||||
</div>
|
||||
<button class="h-12 px-4 rounded-lg bg-surface-container text-primary-fixed border border-outline-variant hover:border-primary-container active:scale-95 transition-all font-label-data text-label-data flex items-center justify-center shrink-0" type="button">
|
||||
CHANGE EMAIL
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Tactical Separator -->
|
||||
<div class="border-t border-surface-variant/50 pt-2"></div>
|
||||
<!-- Change Password Module -->
|
||||
<div class="space-y-3">
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="font-headline-sm text-sm font-bold text-on-surface uppercase tracking-wider">Change Password</span>
|
||||
<span class="font-label-data text-label-data text-primary-container">HASH: ARGON2ID</span>
|
||||
</div>
|
||||
<!-- Current Password -->
|
||||
<div>
|
||||
<label class="block font-label-data text-label-data text-on-surface-variant uppercase mb-1">Current Password</label>
|
||||
<div class="relative flex items-center">
|
||||
<input aria-label="Current Password" class="w-full h-12 pl-3 pr-12 rounded-lg bg-surface-container-lowest border border-outline-variant text-on-surface text-sm font-label-data focus:border-primary-container focus:ring-1 focus:ring-primary-container tracking-widest" type="password" value="SuperSecretPassword123"/>
|
||||
<button aria-label="Toggle Password Visibility" class="absolute right-0 top-0 h-12 w-12 flex items-center justify-center text-on-surface-variant hover:text-primary-container" type="button">
|
||||
<span class="material-symbols-outlined text-xl" data-icon="visibility">visibility</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- New Password & Strength Meter -->
|
||||
<div>
|
||||
<label class="block font-label-data text-label-data text-on-surface-variant uppercase mb-1">New Password</label>
|
||||
<div class="relative flex items-center">
|
||||
<input aria-label="New Password" class="w-full h-12 pl-3 pr-12 rounded-lg bg-surface-container-lowest border border-primary-container/60 text-on-surface text-sm font-label-data focus:border-primary-container focus:ring-1 focus:ring-primary-container tracking-widest" type="password" value="Nurburgring#2024$TelemetryApex!"/>
|
||||
<button aria-label="Toggle New Password Visibility" class="absolute right-0 top-0 h-12 w-12 flex items-center justify-center text-primary-container" type="button">
|
||||
<span class="material-symbols-outlined text-xl" data-icon="visibility_off">visibility_off</span>
|
||||
</button>
|
||||
</div>
|
||||
<!-- 4-Segment Tactical Strength Meter -->
|
||||
<div class="mt-2.5 space-y-1.5">
|
||||
<div class="flex justify-between items-center text-label-data font-label-data">
|
||||
<span class="text-on-surface-variant">ENTROPY RATING:</span>
|
||||
<span class="text-primary-container font-bold flex items-center">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-primary-container mr-1.5 shadow-[0_0_8px_#00e5ff]"></span>
|
||||
TELEMETRY-GRADE (128-BIT)
|
||||
</span>
|
||||
</div>
|
||||
<div class="grid grid-cols-4 gap-1.5 h-2">
|
||||
<!-- Bar 1: Weak -->
|
||||
<div class="h-full rounded-sm bg-primary-container shadow-[0_0_6px_#00e5ff]"></div>
|
||||
<!-- Bar 2: Moderate -->
|
||||
<div class="h-full rounded-sm bg-primary-container shadow-[0_0_6px_#00e5ff]"></div>
|
||||
<!-- Bar 3: Strong -->
|
||||
<div class="h-full rounded-sm bg-primary-container shadow-[0_0_6px_#00e5ff]"></div>
|
||||
<!-- Bar 4: Telemetry-Grade Active -->
|
||||
<div class="h-full rounded-sm bg-primary-container shadow-[0_0_10px_#00e5ff]"></div>
|
||||
</div>
|
||||
<p class="font-label-caption text-label-caption text-on-surface-variant">Entropy verified against NIST SP 800-63B standards.</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Re-enter Password -->
|
||||
<div>
|
||||
<label class="block font-label-data text-label-data text-on-surface-variant uppercase mb-1">Confirm New Password</label>
|
||||
<input aria-label="Confirm New Password" class="w-full h-12 px-3 rounded-lg bg-surface-container-lowest border border-outline-variant text-on-surface text-sm font-label-data focus:border-primary-container focus:ring-1 focus:ring-primary-container tracking-widest" type="password" value="Nurburgring#2024$TelemetryApex!"/>
|
||||
</div>
|
||||
<!-- Update Credentials Button (Glove friendly 48px+) -->
|
||||
<button class="w-full h-[52px] rounded-lg bg-primary-container text-surface-container-lowest font-label-data text-label-data font-bold tracking-wider hover:bg-primary-fixed-dim glow-cyan active:scale-[0.98] transition-all flex items-center justify-center space-x-2" type="button">
|
||||
<span class="material-symbols-outlined text-lg font-bold" data-icon="key">key</span>
|
||||
<span>UPDATE CREDENTIALS</span>
|
||||
</button>
|
||||
</div>
|
||||
<!-- Tactical Separator -->
|
||||
<div class="border-t border-surface-variant/50 pt-2"></div>
|
||||
<!-- 2FA / MFA Section -->
|
||||
<div class="space-y-3">
|
||||
<div class="flex items-start justify-between">
|
||||
<div class="pr-2">
|
||||
<div class="flex items-center space-x-2">
|
||||
<span class="font-headline-sm text-sm font-bold text-on-surface uppercase">Two-Factor Authentication</span>
|
||||
<span class="w-2 h-2 rounded-full bg-primary-container animate-pulse"></span>
|
||||
</div>
|
||||
<p class="font-body-md text-xs text-on-surface-variant mt-0.5">TOTP Active (YubiKey 5 NFC / Google Authenticator)</p>
|
||||
</div>
|
||||
<!-- Glove-sized physical toggle -->
|
||||
<label class="relative inline-flex items-center cursor-pointer shrink-0">
|
||||
<input aria-label="Two Factor Authentication Active" checked="" class="glove-toggle" type="checkbox"/>
|
||||
</label>
|
||||
</div>
|
||||
<div class="flex items-center justify-between p-3 rounded-lg bg-surface-container-lowest border border-outline-variant/80">
|
||||
<div class="flex items-center space-x-2.5">
|
||||
<span class="material-symbols-outlined text-primary-container text-xl" data-icon="vpn_key" style="font-variation-settings: 'FILL' 1;">vpn_key</span>
|
||||
<div>
|
||||
<p class="font-label-data text-label-data text-on-surface">HARDWARE KEY SYNC</p>
|
||||
<p class="font-label-caption text-label-caption text-on-surface-variant">Slot 1: YubiKey 5C NFC Primary</p>
|
||||
</div>
|
||||
</div>
|
||||
<span class="font-label-data text-label-data text-primary-fixed bg-surface-container-high px-2 py-1 rounded">PAIR 2ND</span>
|
||||
</div>
|
||||
<button class="w-full h-12 rounded-lg bg-surface-container-low border border-outline-variant text-on-surface hover:text-primary-container hover:border-primary-container font-label-data text-label-data tracking-wider transition-all flex items-center justify-center space-x-2 active:scale-98" type="button">
|
||||
<span class="material-symbols-outlined text-lg" data-icon="history_edu">history_edu</span>
|
||||
<span>CONFIGURE BACKUP CODES</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- SECTION 2: CLOUD TELEMETRY & SYNC -->
|
||||
<section class="space-y-3">
|
||||
<div class="flex items-center justify-between px-1">
|
||||
<div class="flex items-center space-x-2">
|
||||
<span class="material-symbols-outlined text-primary-container text-lg" data-icon="cloud_sync">cloud_sync</span>
|
||||
<h2 class="font-headline-sm text-headline-sm font-bold text-on-surface text-base tracking-wide">Cloud Telemetry & Sync</h2>
|
||||
</div>
|
||||
<span class="font-label-data text-label-data text-primary-fixed">R2 MESH // SYNCED</span>
|
||||
</div>
|
||||
<div class="tactical-border rounded-xl bg-[#0D131F] p-4 space-y-4">
|
||||
<!-- Cloudflare R2 Master Toggle -->
|
||||
<div class="flex items-center justify-between pb-3 border-b border-surface-variant/40">
|
||||
<div class="pr-2">
|
||||
<div class="flex items-center space-x-2">
|
||||
<span class="font-headline-sm text-sm font-bold text-on-surface">Cloudflare R2 Telemetry Bucket</span>
|
||||
<span class="bg-primary-container/20 text-primary-container text-[10px] font-label-data px-1.5 py-0.5 rounded font-bold">R2 HIGH-SPEED</span>
|
||||
</div>
|
||||
<p class="font-body-md text-xs text-on-surface-variant mt-0.5">Encrypted object storage for SQLite Drift Schema 7</p>
|
||||
</div>
|
||||
<input aria-label="Enable Cloudflare R2 Bucket Sync" checked="" class="glove-toggle shrink-0" type="checkbox"/>
|
||||
</div>
|
||||
<!-- Automatic Ride Upload -->
|
||||
<div class="flex items-center justify-between pb-3 border-b border-surface-variant/40">
|
||||
<div class="pr-2">
|
||||
<span class="font-headline-sm text-sm font-bold text-on-surface">Automatic Ride Upload</span>
|
||||
<p class="font-body-md text-xs text-on-surface-variant mt-0.5">Auto-stream 20Hz IMU vectors & apex coordinates upon KSU completion</p>
|
||||
</div>
|
||||
<input aria-label="Automatic Ride Upload" checked="" class="glove-toggle shrink-0" type="checkbox"/>
|
||||
</div>
|
||||
<!-- Cellular Data Sync Cap -->
|
||||
<div class="flex items-center justify-between pb-2">
|
||||
<div class="pr-2">
|
||||
<span class="font-headline-sm text-sm font-bold text-on-surface">Wi-Fi Only for 20Hz Raw Logs</span>
|
||||
<p class="font-body-md text-xs text-on-surface-variant mt-0.5">Prevents high roaming usage on mountain passes and remote canyon routes</p>
|
||||
</div>
|
||||
<input aria-label="Wi-Fi Only for Raw Logs" checked="" class="glove-toggle shrink-0" type="checkbox"/>
|
||||
</div>
|
||||
<!-- Cloud Storage Usage Bar -->
|
||||
<div class="bg-surface-container-lowest p-3.5 rounded-lg border border-outline-variant space-y-3">
|
||||
<div class="flex justify-between items-baseline">
|
||||
<div>
|
||||
<span class="font-label-data text-label-data text-on-surface uppercase">R2 VAULT ALLOCATION</span>
|
||||
<p class="font-telemetry-metric-md text-lg text-on-surface font-bold">1.4 GB <span class="text-xs text-on-surface-variant font-normal">/ 10.0 GB</span></p>
|
||||
</div>
|
||||
<span class="font-label-data text-label-data text-primary-container font-bold px-2 py-0.5 bg-primary-container/10 border border-primary-container/30 rounded">14% USED</span>
|
||||
</div>
|
||||
<!-- Multi-tier progress meter bar -->
|
||||
<div class="w-full h-3 rounded-full bg-surface-container-high overflow-hidden flex">
|
||||
<!-- 1.1 GB Raw IMU (78% of used space) -->
|
||||
<div class="bg-primary-container h-full" style="width: 11%;"></div>
|
||||
<!-- 240 MB GPS & Map (17% of used space) -->
|
||||
<div class="bg-secondary-container h-full" style="width: 2.4%;"></div>
|
||||
<!-- 60 MB Replays (4% of used space) -->
|
||||
<div class="bg-tertiary-fixed-dim h-full" style="width: 0.6%;"></div>
|
||||
</div>
|
||||
<!-- Breakdown Legend -->
|
||||
<div class="grid grid-cols-1 sm:grid-cols-3 gap-2 pt-1 text-xs">
|
||||
<div class="flex items-center space-x-1.5">
|
||||
<span class="w-2.5 h-2.5 rounded-sm bg-primary-container shrink-0"></span>
|
||||
<span class="font-label-caption text-on-surface-variant truncate">1.1 GB Raw 20Hz IMU</span>
|
||||
</div>
|
||||
<div class="flex items-center space-x-1.5">
|
||||
<span class="w-2.5 h-2.5 rounded-sm bg-secondary-container shrink-0"></span>
|
||||
<span class="font-label-caption text-on-surface-variant truncate">240 MB GPS & Traces</span>
|
||||
</div>
|
||||
<div class="flex items-center space-x-1.5">
|
||||
<span class="w-2.5 h-2.5 rounded-sm bg-tertiary-fixed-dim shrink-0"></span>
|
||||
<span class="font-label-caption text-on-surface-variant truncate">60 MB Replays</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Glove-friendly Cache Purge Button (48px) -->
|
||||
<button class="w-full h-12 mt-2 rounded-lg bg-surface-container hover:bg-surface-container-high text-primary-container border border-outline-variant hover:border-primary-container font-label-data text-label-data font-bold tracking-wider transition-all flex items-center justify-center space-x-2 active:scale-95" type="button">
|
||||
<span class="material-symbols-outlined text-lg" data-icon="cleaning_services">cleaning_services</span>
|
||||
<span>OPTIMIZE & PURGE LOCAL CACHE</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- SECTION 3: DANGER ZONE & DATA SOVEREIGNTY -->
|
||||
<section class="space-y-3">
|
||||
<div class="flex items-center justify-between px-1">
|
||||
<div class="flex items-center space-x-2">
|
||||
<span class="material-symbols-outlined text-error text-lg" data-icon="warning" style="font-variation-settings: 'FILL' 1;">warning</span>
|
||||
<h2 class="font-headline-sm text-headline-sm font-bold text-error text-base tracking-wide">Danger Zone & Sovereignty</h2>
|
||||
</div>
|
||||
<span class="font-label-data text-label-data text-error font-bold tracking-wider">RESTRICTED</span>
|
||||
</div>
|
||||
<div class="tactical-danger-border rounded-xl bg-[#0D131F] p-4 space-y-4">
|
||||
<!-- Export Telemetry Action -->
|
||||
<div class="space-y-2">
|
||||
<div class="flex items-start justify-between">
|
||||
<div>
|
||||
<p class="font-headline-sm text-sm font-bold text-on-surface">Export All Telemetry Data</p>
|
||||
<p class="font-body-md text-xs text-on-surface-variant mt-0.5">Download entire multi-year riding vault (JSON, GPX, CSV). Compliant with GDPR Art. 20 & CCPA.</p>
|
||||
</div>
|
||||
</div>
|
||||
<button class="w-full h-12 rounded-lg bg-surface-container-lowest border border-outline text-on-surface hover:text-primary-container hover:border-primary-container font-label-data text-label-data font-bold tracking-wider flex items-center justify-center space-x-2 active:scale-95 transition-all" type="button">
|
||||
<span class="material-symbols-outlined text-lg text-primary-container" data-icon="download">download</span>
|
||||
<span>EXPORT ARCHIVE (.TAR.GZ)</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="border-t border-surface-variant/40 pt-2"></div>
|
||||
<!-- Sign Out Button -->
|
||||
<div>
|
||||
<button class="w-full h-12 rounded-lg bg-surface-container-low border border-outline-variant text-on-surface hover:text-error hover:border-error font-label-data text-label-data font-bold tracking-wider flex items-center justify-center space-x-2 active:scale-95 transition-all" type="button">
|
||||
<span class="material-symbols-outlined text-lg text-on-surface-variant" data-icon="logout">logout</span>
|
||||
<span>SIGN OUT OF THIS COCKPIT UNIT</span>
|
||||
</button>
|
||||
</div>
|
||||
<!-- Delete Account & Purge Vault Button -->
|
||||
<div class="pt-1">
|
||||
<button class="w-full h-[52px] rounded-lg bg-error-container/20 border border-error/60 text-error hover:bg-error-container/40 font-label-data text-label-data font-bold tracking-wider flex items-center justify-center space-x-2 active:scale-95 transition-all shadow-[0_0_12px_rgba(239,68,68,0.2)]" type="button">
|
||||
<span class="material-symbols-outlined text-xl" data-icon="delete_forever" style="font-variation-settings: 'FILL' 1;">delete_forever</span>
|
||||
<span>DELETE ACCOUNT & PURGE VAULT</span>
|
||||
</button>
|
||||
<div class="flex items-center justify-center space-x-1.5 mt-2">
|
||||
<span class="material-symbols-outlined text-[13px] text-error" data-icon="info">info</span>
|
||||
<span class="font-label-caption text-label-caption text-error">Irreversible. Erases cryptographic signature and leaderboards.</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- Telemetry System Diagnostics Footer -->
|
||||
<div class="text-center pt-2 pb-6 space-y-1">
|
||||
<p class="font-label-data text-label-data text-on-surface-variant text-[11px]">MOTORSIGNAL CORE OS v4.18.9-PRO // BUILD 8831</p>
|
||||
<p class="font-label-caption text-label-caption text-outline">HARDWARE ID: BCM-2837-AF9 // KERNEL 6.1-RT-TELEMETRY</p>
|
||||
</div>
|
||||
</main>
|
||||
<!-- SHARED BOTTOM NAVIGATION BAR -->
|
||||
<!-- Mapped from Shared Components JSON: BottomNavBar with Settings active -->
|
||||
<nav aria-label="Cockpit Navigation" 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 dark:bg-surface-container-lowest border-t border-outline-variant dark:border-outline-variant">
|
||||
<!-- Item 1: Dash (Inactive) -->
|
||||
<a class="flex flex-col items-center justify-center text-on-surface-variant dark:text-on-surface-variant px-2 py-1 min-h-[48px] hover:bg-surface-container-low dark:hover:bg-surface-container-low hover:text-primary-fixed dark:hover:text-primary-fixed active:scale-95 duration-100 ease-out transition-all" href="#dash">
|
||||
<span class="material-symbols-outlined text-2xl" data-icon="speed">speed</span>
|
||||
<span class="text-label-caption font-label-caption">Dash</span>
|
||||
</a>
|
||||
<!-- Item 2: Map (Inactive) -->
|
||||
<a class="flex flex-col items-center justify-center text-on-surface-variant dark:text-on-surface-variant px-2 py-1 min-h-[48px] hover:bg-surface-container-low dark:hover:bg-surface-container-low hover:text-primary-fixed dark:hover:text-primary-fixed active:scale-95 duration-100 ease-out transition-all" href="#map">
|
||||
<span class="material-symbols-outlined text-2xl" data-icon="navigation">navigation</span>
|
||||
<span class="text-label-caption font-label-caption">Map</span>
|
||||
</a>
|
||||
<!-- Item 3: Activity (Inactive) -->
|
||||
<a class="flex flex-col items-center justify-center text-on-surface-variant dark:text-on-surface-variant px-2 py-1 min-h-[48px] hover:bg-surface-container-low dark:hover:bg-surface-container-low hover:text-primary-fixed dark:hover:text-primary-fixed active:scale-95 duration-100 ease-out transition-all" href="#activity">
|
||||
<span class="material-symbols-outlined text-2xl" data-icon="analytics">analytics</span>
|
||||
<span class="text-label-caption font-label-caption">Activity</span>
|
||||
</a>
|
||||
<!-- Item 4: Garage (Inactive) -->
|
||||
<a class="flex flex-col items-center justify-center text-on-surface-variant dark:text-on-surface-variant px-2 py-1 min-h-[48px] hover:bg-surface-container-low dark:hover:bg-surface-container-low hover:text-primary-fixed dark:hover:text-primary-fixed active:scale-95 duration-100 ease-out transition-all" href="#garage">
|
||||
<span class="material-symbols-outlined text-2xl" data-icon="two_wheeler">two_wheeler</span>
|
||||
<span class="text-label-caption font-label-caption">Garage</span>
|
||||
</a>
|
||||
<!-- Item 5: Settings (ACTIVE - mapped exactly to style_active_navigation) -->
|
||||
<a class="flex flex-col items-center justify-center bg-surface-container-high dark:bg-surface-container-high text-primary-container dark:text-primary-container rounded-lg px-2 py-1 min-h-[48px] active:scale-95 duration-100 ease-out shadow-[0_0_12px_rgba(0,229,255,0.2)]" href="#settings">
|
||||
<span class="material-symbols-outlined text-2xl" data-icon="settings" style="font-variation-settings: 'FILL' 1;">settings</span>
|
||||
<span class="text-label-caption font-label-caption font-bold">Settings</span>
|
||||
</a>
|
||||
</nav>
|
||||
<!-- Lightweight Inline Tactical Micro-Interactions -->
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
// Audio or haptic tactical feedback mock for glove clicks
|
||||
const tacticalButtons = document.querySelectorAll('button, .glove-toggle');
|
||||
tacticalButtons.forEach(btn => {
|
||||
btn.addEventListener('click', () => {
|
||||
if (window.navigator && window.navigator.vibrate) {
|
||||
window.navigator.vibrate(30);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body></html>
|
||||
|
|
@ -0,0 +1,357 @@
|
|||
<!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, viewport-fit=cover" name="viewport"/><meta content="mobile_tab" name="shell-type"/><link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" rel="stylesheet"/><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&family=JetBrains+Mono:wght@600;700&family=Space+Grotesk:wght@600;700&display=swap" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/><style>@layer base{html,body{width:100vw;margin:0;padding:0;background-color:#101419;color:#e0e2ea;}body{overscroll-behavior:none;}.pb-safe{padding-bottom:env(safe-area-inset-bottom,0px);}.pt-safe{padding-top:env(safe-area-inset-top,0px);}main>:first-child{margin-top:0!important;}main>:last-child{margin-bottom:0!important;}}::-webkit-scrollbar{display:none;}</style><script src="https://cdn.tailwindcss.com"></script><script id="tailwind-config">tailwind.config = { darkMode: "class", theme: { extend: { colors: { "on-primary-fixed-variant": "#004f58", "tertiary": "#f2e9ff", "surface-container-highest": "#32353b", "on-tertiary-container": "#6834d1", "on-error-container": "#ffdad6", "outline": "#849396", "surface-variant": "#32353b", "inverse-surface": "#e0e2ea", "on-primary-fixed": "#001f24", "secondary-fixed-dim": "#b4c5ff", "primary": "#c3f5ff", "primary-fixed-dim": "#00daf3", "on-primary": "#00363d", "on-tertiary-fixed": "#23005c", "on-primary-container": "#00626e", "on-secondary-fixed": "#00174b", "tertiary-container": "#d9c8ff", "on-background": "#e0e2ea", "error-container": "#93000a", "on-tertiary": "#3c0091", "primary-container": "#00e5ff", "tertiary-fixed": "#e9ddff", "on-tertiary-fixed-variant": "#5516be", "on-error": "#690005", "error": "#ffb4ab", "on-secondary": "#002a78", "surface-tint": "#00daf3", "secondary": "#b4c5ff", "tertiary-fixed-dim": "#d0bcff", "inverse-primary": "#006875", "outline-variant": "#3b494c", "inverse-on-surface": "#2d3036", "surface-dim": "#101419", "on-surface": "#e0e2ea", "secondary-container": "#0053db", "surface-container-lowest": "#0b0e13", "on-secondary-container": "#cdd7ff", "secondary-fixed": "#dbe1ff", "primary-fixed": "#9cf0ff", "on-secondary-fixed-variant": "#003ea8", "surface": "#101419", "on-surface-variant": "bac9cc", "surface-container-high": "#272a30", "surface-container": "#1d2025", "surface-container-low": "#181c21", "surface-bright": "#36393f", "background": "#101419" }, borderRadius: { "DEFAULT": "0.25rem", "lg": "0.5rem", "xl": "0.75rem", "full": "9999px" }, spacing: { "gutter": "1rem", "space-xs": "0.25rem", "space-sm": "0.5rem", "space-xl": "2rem", "space-md": "1rem", "gutter-lg": "1.5rem", "space-lg": "1.5rem", "margin-lg": "2rem", "margin": "1rem" }, fontFamily: { "body-lg": ["Inter"], "headline-lg": ["Space Grotesk"], "headline-sm": ["Space Grotesk"], "label-caption": ["Inter"], "telemetry-metric-lg": ["JetBrains Mono"], "telemetry-metric-md": ["JetBrains Mono"], "body-md": ["Inter"], "display-hero": ["Space Grotesk"], "telemetry-metric-lg-mobile": ["JetBrains Mono"], "display-hero-mobile": ["Space Grotesk"], "headline-md": ["Space Grotesk"], "label-data": ["JetBrains Mono"] }, fontSize: { "body-lg": ["16px", { lineHeight: "24px", fontWeight: "500" }], "headline-lg": ["32px", { lineHeight: "40px", letterSpacing: "-0.02em", fontWeight: "700" }], "headline-sm": ["20px", { lineHeight: "28px", fontWeight: "600" }], "label-caption": ["11px", { lineHeight: "14px", letterSpacing: "0.05em", fontWeight: "600" }], "telemetry-metric-lg": ["48px", { lineHeight: "48px", letterSpacing: "-0.04em", fontWeight: "700" }], "telemetry-metric-md": ["28px", { lineHeight: "32px", letterSpacing: "-0.02em", fontWeight: "600" }], "body-md": ["14px", { lineHeight: "20px", fontWeight: "400" }], "display-hero": ["56px", { lineHeight: "60px", letterSpacing: "-0.03em", fontWeight: "700" }], "telemetry-metric-lg-mobile": ["36px", { lineHeight: "36px", letterSpacing: "-0.03em", fontWeight: "700" }], "display-hero-mobile": ["40px", { lineHeight: "44px", letterSpacing: "-0.02em", fontWeight: "700" }], "headline-md": ["24px", { lineHeight: "32px", letterSpacing: "-0.01em", fontWeight: "600" }], "label-data": ["12px", { lineHeight: "16px", letterSpacing: "0.08em", fontWeight: "600" }] } } } };</script><style>
|
||||
body {
|
||||
min-height: max(884px, 100dvh);
|
||||
}
|
||||
</style>
|
||||
</head><body class="bg-surface font-body-md text-body-md text-on-surface flex flex-col min-h-screen"><header class="fixed top-0 w-full z-50 pt-safe bg-surface/80 backdrop-blur-xl shadow-[0_1px_8px_rgba(0,0,0,0.04)]"><div class="h-16 px-gutter flex items-center justify-between"><div class="flex items-center gap-space-sm"><div class="w-2.5 h-2.5 rounded-full bg-primary-container shadow-[0_0_8px_#00e5ff] animate-pulse"></div><div class="flex flex-col"><span class="font-headline-sm text-headline-sm uppercase tracking-tight text-primary leading-none">MOTORSIGNAL HUD</span><div class="flex items-center gap-space-xs mt-0.5"><span class="font-label-data text-label-data text-primary-fixed-dim uppercase">20Hz LOCK</span><span class="text-outline-variant font-label-data text-label-data">•</span><span class="font-label-data text-label-data text-on-surface-variant">RT-CAN</span></div></div></div><div class="flex items-center gap-space-xs"><button aria-label="Warning Alerts" class="min-w-[44px] min-h-[44px] flex items-center justify-center rounded-lg text-error hover:bg-surface-container active:scale-95 transition-all"><span class="material-symbols-outlined text-xl">warning</span></button><button aria-label="Telemetry Diagnostics" class="min-w-[44px] min-h-[44px] flex items-center justify-center rounded-lg text-primary hover:bg-surface-container active:scale-95 transition-all"><span class="material-symbols-outlined text-xl">sensors</span></button><div class="w-8 h-8 rounded-full bg-primary flex items-center justify-center ml-space-xs"><span class="material-symbols-outlined text-on-primary text-[18px]">person</span></div></div></div></header><main class="flex flex-col relative w-full pt-16 pb-24 bg-surface min-h-screen"><div class="flex flex-col w-full pb-8">
|
||||
<!-- Interactive Live Status Ribbon -->
|
||||
<div class="px-gutter pt-space-sm pb-space-xs">
|
||||
<div class="bg-surface-container-low rounded-xl p-space-md shadow-md">
|
||||
<div class="flex items-center justify-between gap-space-sm">
|
||||
<div class="flex items-center gap-space-sm min-w-0">
|
||||
<div class="relative flex h-3 w-3 items-center justify-center shrink-0">
|
||||
<span class="animate-ping absolute inline-flex h-full w-full rounded-full bg-primary opacity-75"></span>
|
||||
<span class="relative inline-flex rounded-full h-2 w-2 bg-primary"></span>
|
||||
</div>
|
||||
<span class="font-headline-sm text-headline-sm uppercase tracking-tight text-on-surface truncate">RAW TELEMETRY STREAM</span>
|
||||
</div>
|
||||
<div class="bg-primary/10 rounded-full px-2.5 py-1 flex items-center gap-1.5 shrink-0">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-primary animate-pulse"></span>
|
||||
<span class="font-label-caption text-label-caption text-primary tracking-wider uppercase">20Hz KALMAN LOCK</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Realtime Buffer Stats Grid -->
|
||||
<div class="grid grid-cols-3 gap-space-xs mt-space-md pt-space-xs">
|
||||
<div class="bg-surface-container rounded-lg p-2 flex flex-col justify-between">
|
||||
<span class="font-label-caption text-label-caption text-outline uppercase truncate">Drop Buffer</span>
|
||||
<span class="font-label-data text-label-data text-primary font-semibold mt-1">0 Frames</span>
|
||||
<span class="font-label-caption text-[10px] text-outline-variant leading-none mt-0.5">0.00% drop rate</span>
|
||||
</div>
|
||||
<div class="bg-surface-container rounded-lg p-2 flex flex-col justify-between">
|
||||
<span class="font-label-caption text-label-caption text-outline uppercase truncate">Bus Latency</span>
|
||||
<div class="flex items-baseline gap-1 mt-1">
|
||||
<span class="font-telemetry-metric-md text-base leading-none text-on-surface font-bold" id="metric-latency">11</span>
|
||||
<span class="font-label-data text-[10px] text-outline">ms</span>
|
||||
</div>
|
||||
<span class="font-label-caption text-[10px] text-outline-variant leading-none mt-0.5">CAN BUS v2.0B</span>
|
||||
</div>
|
||||
<div class="bg-surface-container rounded-lg p-2 flex flex-col justify-between">
|
||||
<span class="font-label-caption text-label-caption text-outline uppercase truncate">RTK State</span>
|
||||
<span class="font-label-data text-label-data text-secondary font-semibold mt-1 truncate">L1+L5 FIX</span>
|
||||
<span class="font-label-caption text-[10px] text-outline-variant leading-none mt-0.5">DGPS FIXED</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- SECTION 1: 3-AXIS ACCELEROMETER READOUTS -->
|
||||
<section class="px-gutter mt-space-md">
|
||||
<div class="flex items-center justify-between mb-space-xs">
|
||||
<div class="flex items-center gap-space-xs">
|
||||
<span class="material-symbols-outlined text-primary text-lg">view_in_ar</span>
|
||||
<h2 class="font-headline-sm text-headline-sm uppercase text-on-surface">3-Axis Accelerometer</h2>
|
||||
</div>
|
||||
<span class="font-label-caption text-label-caption text-outline uppercase">ICM-42688P • 50ms</span>
|
||||
</div>
|
||||
<!-- Accel Cards Stack -->
|
||||
<div class="flex flex-col gap-space-xs">
|
||||
<!-- Lateral X -->
|
||||
<div class="bg-surface-container rounded-xl p-space-md flex items-center justify-between shadow-sm">
|
||||
<div class="flex flex-col min-w-0 pr-2">
|
||||
<div class="flex items-center gap-1.5">
|
||||
<span class="font-label-data text-label-data text-primary font-bold">ROLL [X]</span>
|
||||
<span class="font-label-caption text-label-caption text-outline truncate">LATERAL FORCE</span>
|
||||
</div>
|
||||
<div class="flex items-baseline gap-1 mt-1">
|
||||
<span class="font-telemetry-metric-lg-mobile text-telemetry-metric-lg-mobile text-primary tracking-tight" id="accel-x">+0.04</span>
|
||||
<span class="font-label-data text-label-data text-outline">m/s²</span>
|
||||
</div>
|
||||
<span class="font-label-caption text-label-caption text-outline-variant mt-0.5">±0.004 g-bias</span>
|
||||
</div>
|
||||
<!-- Waveform SVG Trace -->
|
||||
<div class="w-28 h-10 bg-surface-container-lowest rounded-lg p-1 shrink-0 flex items-center">
|
||||
<svg class="w-full h-full overflow-visible" preserveaspectratio="none" viewbox="0 0 100 30">
|
||||
<path class="animate-pulse" d="M0,15 Q15,13 30,17 T60,14 T85,16 L100,15" fill="none" stroke="#00daf3" stroke-linecap="round" stroke-width="2"></path>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Longitudinal Y -->
|
||||
<div class="bg-surface-container rounded-xl p-space-md flex items-center justify-between shadow-sm">
|
||||
<div class="flex flex-col min-w-0 pr-2">
|
||||
<div class="flex items-center gap-1.5">
|
||||
<span class="font-label-data text-label-data text-secondary-fixed font-bold">PITCH [Y]</span>
|
||||
<span class="font-label-caption text-label-caption text-outline truncate">LONGITUDINAL</span>
|
||||
</div>
|
||||
<div class="flex items-baseline gap-1 mt-1">
|
||||
<span class="font-telemetry-metric-lg-mobile text-telemetry-metric-lg-mobile text-on-surface tracking-tight" id="accel-y">-0.82</span>
|
||||
<span class="font-label-data text-label-data text-outline">m/s²</span>
|
||||
</div>
|
||||
<span class="font-label-caption text-label-caption text-outline-variant mt-0.5">-0.084 g Brake</span>
|
||||
</div>
|
||||
<!-- Amber Waveform SVG Trace -->
|
||||
<div class="w-28 h-10 bg-surface-container-lowest rounded-lg p-1 shrink-0 flex items-center">
|
||||
<svg class="w-full h-full overflow-visible" preserveaspectratio="none" viewbox="0 0 100 30">
|
||||
<path d="M0,15 Q20,26 40,8 T75,22 L100,15" fill="none" stroke="#b4c5ff" stroke-linecap="round" stroke-width="2"></path>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Vertical Z -->
|
||||
<div class="bg-surface-container rounded-xl p-space-md flex items-center justify-between shadow-sm">
|
||||
<div class="flex flex-col min-w-0 pr-2">
|
||||
<div class="flex items-center gap-1.5">
|
||||
<span class="font-label-data text-label-data text-primary-fixed-dim font-bold">GRAVITY [Z]</span>
|
||||
<span class="font-label-caption text-label-caption text-outline truncate">EARTH VERTICAL</span>
|
||||
</div>
|
||||
<div class="flex items-baseline gap-1 mt-1">
|
||||
<span class="font-telemetry-metric-lg-mobile text-telemetry-metric-lg-mobile text-primary-fixed font-bold tracking-tight" id="accel-z">+9.79</span>
|
||||
<span class="font-label-data text-label-data text-outline">m/s²</span>
|
||||
</div>
|
||||
<span class="font-label-caption text-label-caption text-outline-variant mt-0.5">+0.998 g Earth G</span>
|
||||
</div>
|
||||
<!-- Stable Waveform SVG Trace -->
|
||||
<div class="w-28 h-10 bg-surface-container-lowest rounded-lg p-1 shrink-0 flex items-center">
|
||||
<svg class="w-full h-full overflow-visible" preserveaspectratio="none" viewbox="0 0 100 30">
|
||||
<path d="M0,15 L20,15 L35,14 L50,16 L70,15 L100,15" fill="none" stroke="#c3f5ff" stroke-linecap="round" stroke-width="2"></path>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Vector Sum Pill -->
|
||||
<div class="bg-surface-container-low rounded-lg px-space-md py-2.5 flex items-center justify-between">
|
||||
<div class="flex items-center gap-1.5">
|
||||
<span class="material-symbols-outlined text-outline text-base">functions</span>
|
||||
<span class="font-label-caption text-label-caption uppercase text-outline">Vector Sum Magnitude</span>
|
||||
</div>
|
||||
<span class="font-telemetry-metric-md text-sm text-on-surface font-bold tracking-tight">9.82 m/s² <span class="text-outline font-normal">(1.002 G)</span></span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- SECTION 2: 3-AXIS GYROSCOPE & QUATERNION -->
|
||||
<section class="px-gutter mt-space-lg">
|
||||
<div class="flex items-center justify-between mb-space-xs">
|
||||
<div class="flex items-center gap-space-xs">
|
||||
<span class="material-symbols-outlined text-primary text-lg">screen_rotation</span>
|
||||
<h2 class="font-headline-sm text-headline-sm uppercase text-on-surface">3-Axis Angular Gyro</h2>
|
||||
</div>
|
||||
<span class="font-label-caption text-label-caption text-primary-fixed-dim uppercase">FUSED KALMAN</span>
|
||||
</div>
|
||||
<div class="bg-surface-container rounded-xl p-space-md shadow-sm">
|
||||
<div class="grid grid-cols-3 gap-space-sm divide-surface-container-highest">
|
||||
<!-- Roll -->
|
||||
<div class="flex flex-col">
|
||||
<span class="font-label-caption text-label-caption text-outline uppercase truncate">Roll (X) Lean</span>
|
||||
<span class="font-telemetry-metric-md text-base text-primary font-bold mt-1" id="gyro-roll">+0.02</span>
|
||||
<span class="font-label-caption text-[10px] text-outline leading-tight mt-0.5">rad/s</span>
|
||||
<span class="font-label-caption text-[10px] text-outline-variant mt-1">1.15°/s (0.0° B)</span>
|
||||
</div>
|
||||
<!-- Pitch -->
|
||||
<div class="flex flex-col">
|
||||
<span class="font-label-caption text-label-caption text-outline uppercase truncate">Pitch (Y) Dive</span>
|
||||
<span class="font-telemetry-metric-md text-base text-on-surface font-bold mt-1" id="gyro-pitch">-0.01</span>
|
||||
<span class="font-label-caption text-[10px] text-outline leading-tight mt-0.5">rad/s</span>
|
||||
<span class="font-label-caption text-[10px] text-outline-variant mt-1">-0.57°/s comp</span>
|
||||
</div>
|
||||
<!-- Yaw -->
|
||||
<div class="flex flex-col">
|
||||
<span class="font-label-caption text-label-caption text-outline uppercase truncate">Yaw (Z) Rate</span>
|
||||
<span class="font-telemetry-metric-md text-base text-primary-fixed-dim font-bold mt-1" id="gyro-yaw">0.00</span>
|
||||
<span class="font-label-caption text-[10px] text-outline leading-tight mt-0.5">rad/s</span>
|
||||
<span class="font-label-caption text-[10px] text-outline-variant mt-1">Dead-reckon</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Quaternion Array & Sensor Temp -->
|
||||
<div class="bg-surface-container-lowest rounded-lg p-2.5 mt-space-md flex flex-col gap-1.5">
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="font-label-caption text-[10px] uppercase text-outline tracking-wider">Quaternion Orientation [q0, q1, q2, q3]</span>
|
||||
<div class="flex items-center gap-1">
|
||||
<span class="material-symbols-outlined text-[12px] text-secondary">device_thermostat</span>
|
||||
<span class="font-label-data text-[10px] text-secondary">36.4°C DIE</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="font-telemetry-metric-md text-xs text-on-surface tracking-tighter truncate bg-surface-container-high/40 p-1.5 rounded">
|
||||
q = [<span class="text-primary font-semibold">0.9998</span>, 0.0012, -0.0008, 0.0175]
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- SECTION 3: DUAL-BAND RTK GNSS MATRIX -->
|
||||
<section class="px-gutter mt-space-lg">
|
||||
<div class="flex items-center justify-between mb-space-xs">
|
||||
<div class="flex items-center gap-space-xs">
|
||||
<span class="material-symbols-outlined text-primary text-lg">satellite_alt</span>
|
||||
<h2 class="font-headline-sm text-headline-sm uppercase text-on-surface">Dual-Band GNSS Matrix</h2>
|
||||
</div>
|
||||
<span class="font-label-caption text-label-caption text-primary font-semibold">L1 + L5 RTK</span>
|
||||
</div>
|
||||
<div class="bg-surface-container rounded-xl p-space-md shadow-sm flex flex-col gap-space-md">
|
||||
<!-- Sat Lock & HDOP Bar -->
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-2">
|
||||
<div class="w-2.5 h-2.5 rounded-full bg-primary animate-ping"></div>
|
||||
<span class="font-body-md text-body-md text-on-surface font-semibold">18 Sats Locked</span>
|
||||
<span class="font-label-caption text-label-caption text-outline">(±0.8m acc)</span>
|
||||
</div>
|
||||
<div class="bg-surface-container-high px-2 py-0.5 rounded text-right">
|
||||
<span class="font-label-data text-label-data text-primary">HDOP 0.72</span>
|
||||
<span class="font-label-caption text-[10px] text-outline block leading-none">IDEAL</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Constellation Breakdown Badges -->
|
||||
<div class="flex flex-wrap gap-1.5">
|
||||
<div class="bg-surface-container-lowest px-2.5 py-1 rounded-md flex items-center gap-1.5">
|
||||
<span class="font-label-caption text-label-caption text-outline">GPS</span>
|
||||
<span class="font-label-data text-label-data text-primary font-bold">8</span>
|
||||
</div>
|
||||
<div class="bg-surface-container-lowest px-2.5 py-1 rounded-md flex items-center gap-1.5">
|
||||
<span class="font-label-caption text-label-caption text-outline">GLONASS</span>
|
||||
<span class="font-label-data text-label-data text-on-surface font-bold">4</span>
|
||||
</div>
|
||||
<div class="bg-surface-container-lowest px-2.5 py-1 rounded-md flex items-center gap-1.5">
|
||||
<span class="font-label-caption text-label-caption text-outline">GALILEO</span>
|
||||
<span class="font-label-data text-label-data text-secondary font-bold">4</span>
|
||||
</div>
|
||||
<div class="bg-surface-container-lowest px-2.5 py-1 rounded-md flex items-center gap-1.5">
|
||||
<span class="font-label-caption text-label-caption text-outline">BEIDOU</span>
|
||||
<span class="font-label-data text-label-data text-outline font-bold">2</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Lat / Long Readout -->
|
||||
<div class="bg-surface-container-lowest rounded-lg p-space-sm flex flex-col gap-1">
|
||||
<div class="flex items-center justify-between text-outline font-label-caption text-[10px] uppercase">
|
||||
<span>Target Coordinates</span>
|
||||
<span>DGPS Centimeter Reference</span>
|
||||
</div>
|
||||
<div class="font-telemetry-metric-md text-sm text-on-surface font-semibold tracking-tight">
|
||||
LAT 37.3861° N, LONG 122.0839° W
|
||||
</div>
|
||||
<div class="flex items-center justify-between pt-1 text-outline font-label-caption text-label-caption">
|
||||
<span>ALT: <span class="text-on-surface font-bold">3,420 FT</span> (1,042.4 m)</span>
|
||||
<span>VEL: <span class="text-primary font-bold">0.0 MPH</span> (Stationary)</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Carrier to Noise C/N0 -->
|
||||
<div class="flex flex-col gap-1.5">
|
||||
<div class="flex justify-between items-center font-label-caption text-label-caption">
|
||||
<span class="text-outline uppercase">Carrier-to-Noise Density (C/N0)</span>
|
||||
<span class="text-primary font-bold font-label-data text-label-data">44 dB-Hz</span>
|
||||
</div>
|
||||
<div class="w-full bg-surface-container-highest rounded-full h-2 overflow-hidden flex">
|
||||
<div class="bg-primary h-full rounded-full transition-all duration-500" style="width: 78%"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- SECTION 4: LOCAL PERSISTENCE DRIFT ENGINE -->
|
||||
<section class="px-gutter mt-space-lg">
|
||||
<div class="flex items-center justify-between mb-space-xs">
|
||||
<div class="flex items-center gap-space-xs">
|
||||
<span class="material-symbols-outlined text-primary text-lg">database</span>
|
||||
<h2 class="font-headline-sm text-headline-sm uppercase text-on-surface">Local Persistence</h2>
|
||||
</div>
|
||||
<span class="font-label-caption text-label-caption text-outline uppercase">Schema 7 • WAL</span>
|
||||
</div>
|
||||
<div class="bg-surface-container rounded-xl p-space-md shadow-sm">
|
||||
<div class="grid grid-cols-2 gap-space-sm">
|
||||
<div class="bg-surface-container-low rounded-lg p-space-sm flex flex-col justify-between">
|
||||
<span class="font-label-caption text-label-caption text-outline uppercase truncate">Telemetry Vectors</span>
|
||||
<span class="font-label-data text-label-data text-on-surface font-bold mt-1">1,428,500</span>
|
||||
<span class="font-label-caption text-[10px] text-outline-variant mt-0.5">142.8 MB WAL file</span>
|
||||
</div>
|
||||
<div class="bg-surface-container-low rounded-lg p-space-sm flex flex-col justify-between">
|
||||
<span class="font-label-caption text-label-caption text-outline uppercase truncate">Sessions Stored</span>
|
||||
<span class="font-label-data text-label-data text-primary font-bold mt-1">48 Verified</span>
|
||||
<span class="font-label-caption text-[10px] text-outline-variant mt-0.5">Ready for Export</span>
|
||||
</div>
|
||||
<div class="bg-surface-container-low rounded-lg p-space-sm flex flex-col justify-between">
|
||||
<span class="font-label-caption text-label-caption text-outline uppercase truncate">Outbox Replication</span>
|
||||
<span class="font-label-data text-label-data text-secondary font-bold mt-1">0 Pending</span>
|
||||
<span class="font-label-caption text-[10px] text-outline-variant mt-0.5">R2 Synced Edge</span>
|
||||
</div>
|
||||
<div class="bg-surface-container-low rounded-lg p-space-sm flex flex-col justify-between">
|
||||
<span class="font-label-caption text-label-caption text-outline uppercase truncate">Write Cadence</span>
|
||||
<span class="font-label-data text-label-data text-primary-fixed-dim font-bold mt-1">20 writes/sec</span>
|
||||
<span class="font-label-caption text-[10px] text-primary mt-0.5">[PASSED NOMINAL]</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- ACTION BUTTONS: Glove-friendly min-h-[52px] with high feedback -->
|
||||
<section class="px-gutter mt-space-lg flex flex-col gap-space-sm">
|
||||
<!-- Primary Calibrate Action -->
|
||||
<button class="w-full min-h-[52px] bg-primary text-on-primary rounded-xl font-headline-sm text-headline-sm uppercase flex items-center justify-center gap-space-sm shadow-[0_0_20px_rgba(0,229,255,0.35)] active:scale-[0.98] transition-transform select-none" id="btn-calibrate">
|
||||
<span class="material-symbols-outlined text-2xl font-bold">adjust</span>
|
||||
<span>Calibrate IMU Zero-Offset</span>
|
||||
</button>
|
||||
<!-- Secondary Export Diagnostics Button -->
|
||||
<button class="w-full min-h-[48px] bg-surface-container text-on-surface hover:bg-surface-container-high rounded-xl font-headline-sm text-headline-sm uppercase flex items-center justify-center gap-space-sm shadow-sm active:scale-[0.98] transition-transform select-none" id="btn-export">
|
||||
<span class="material-symbols-outlined text-xl text-outline">file_download</span>
|
||||
<span>Export Diagnostics (.Zip/JSON)</span>
|
||||
</button>
|
||||
<!-- Calibration Alert Banner (Micro-Interaction Target) -->
|
||||
<div class="hidden bg-primary/10 rounded-lg p-space-sm flex items-center gap-space-sm text-primary transition-all" id="calibration-toast">
|
||||
<span class="material-symbols-outlined text-lg animate-spin">refresh</span>
|
||||
<span class="font-label-data text-label-data">ZERO-BIAS RE-ALIGNMENT COMPLETE • GYRO OFFSET: 0.000 rad/s</span>
|
||||
</div>
|
||||
</section>
|
||||
<!-- SYSTEM CHECK FOOTER -->
|
||||
<footer class="px-gutter mt-space-lg mb-space-sm flex flex-col items-center justify-center text-center">
|
||||
<div class="font-label-data text-[10px] text-outline uppercase tracking-wider bg-surface-container-low px-3 py-1.5 rounded-full">
|
||||
SYS_CHECK: OK | IMU_SAMPLE_CLOCK: 20.001 Hz | NODE_ID #MTR-6050-B7
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
<script>
|
||||
// Real-time jitter simulator to emulate true 20 Hz IMU sensor streaming
|
||||
(function() {
|
||||
const elLatency = document.getElementById('metric-latency');
|
||||
const elAccelX = document.getElementById('accel-x');
|
||||
const elAccelY = document.getElementById('accel-y');
|
||||
const elAccelZ = document.getElementById('accel-z');
|
||||
const elGyroRoll = document.getElementById('gyro-roll');
|
||||
const elGyroPitch = document.getElementById('gyro-pitch');
|
||||
const btnCalibrate = document.getElementById('btn-calibrate');
|
||||
const toast = document.getElementById('calibration-toast');
|
||||
|
||||
// 20Hz interval simulation (every 50ms)
|
||||
setInterval(() => {
|
||||
// Small jitter for accelerometer
|
||||
const jitterX = (0.04 + (Math.random() * 0.008 - 0.004)).toFixed(2);
|
||||
const jitterY = (-0.82 + (Math.random() * 0.01 - 0.005)).toFixed(2);
|
||||
const jitterZ = (9.79 + (Math.random() * 0.02 - 0.01)).toFixed(2);
|
||||
|
||||
if (elAccelX) elAccelX.textContent = (jitterX >= 0 ? '+' : '') + jitterX;
|
||||
if (elAccelY) elAccelY.textContent = (jitterY >= 0 ? '+' : '') + jitterY;
|
||||
if (elAccelZ) elAccelZ.textContent = '+' + jitterZ;
|
||||
|
||||
// Small jitter for angular rates
|
||||
const rollJitter = (0.02 + (Math.random() * 0.004 - 0.002)).toFixed(2);
|
||||
const pitchJitter = (-0.01 + (Math.random() * 0.004 - 0.002)).toFixed(2);
|
||||
|
||||
if (elGyroRoll) elGyroRoll.textContent = '+' + rollJitter;
|
||||
if (elGyroPitch) elGyroPitch.textContent = pitchJitter;
|
||||
|
||||
// Occasional latency flicker between 10-12ms
|
||||
if (Math.random() > 0.85 && elLatency) {
|
||||
elLatency.textContent = (Math.random() > 0.5 ? '10' : '12');
|
||||
} else if (elLatency) {
|
||||
elLatency.textContent = '11';
|
||||
}
|
||||
}, 50);
|
||||
|
||||
// Calibrate button micro-interaction
|
||||
if (btnCalibrate && toast) {
|
||||
btnCalibrate.addEventListener('click', () => {
|
||||
toast.classList.remove('hidden');
|
||||
btnCalibrate.disabled = true;
|
||||
btnCalibrate.classList.add('opacity-75');
|
||||
|
||||
setTimeout(() => {
|
||||
toast.classList.add('hidden');
|
||||
btnCalibrate.disabled = false;
|
||||
btnCalibrate.classList.remove('opacity-75');
|
||||
}, 2800);
|
||||
});
|
||||
}
|
||||
})();
|
||||
</script></main><nav class="fixed bottom-0 w-full z-50 pb-safe bg-surface/80 backdrop-blur-xl shadow-[0_1px_8px_rgba(0,0,0,0.04)]" data-active-classes="text-primary-container font-headline-sm scale-105"><div class="flex justify-between items-center h-16 px-gutter"><a class="flex flex-col items-center justify-center min-w-[48px] min-h-[48px] text-on-surface-variant hover:text-on-surface transition-all" data-path="live-dashboard" href="#"><span class="material-symbols-outlined text-2xl">speed</span><span class="font-label-caption text-label-caption tracking-wider uppercase mt-1">Dash</span></a><a class="flex flex-col items-center justify-center min-w-[48px] min-h-[48px] text-on-surface-variant hover:text-on-surface transition-all" data-path="tactical-map" href="#"><span class="material-symbols-outlined text-2xl">explore</span><span class="font-label-caption text-label-caption tracking-wider uppercase mt-1">Map</span></a><a class="flex flex-col items-center justify-center min-w-[48px] min-h-[48px] text-on-surface-variant hover:text-on-surface transition-all" data-path="telemetry-activity" href="#"><span class="material-symbols-outlined text-2xl">timeline</span><span class="font-label-caption text-label-caption tracking-wider uppercase mt-1">Activity</span></a><a class="flex flex-col items-center justify-center min-w-[48px] min-h-[48px] text-on-surface-variant hover:text-on-surface transition-all" data-path="paddock-garage" href="#"><span class="material-symbols-outlined text-2xl">two_wheeler</span><span class="font-label-caption text-label-caption tracking-wider uppercase mt-1">Garage</span></a><a aria-current="page" class="flex flex-col items-center justify-center min-w-[48px] min-h-[48px] transition-all text-primary-container font-headline-sm scale-105" data-path="can-diagnostics" href="#"><span class="material-symbols-outlined text-2xl">tune</span><span class="font-label-caption text-label-caption tracking-wider uppercase mt-1">Diag</span></a></div></nav></body></html>
|
||||
|
|
@ -0,0 +1,157 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<html class="dark" lang="en"><head><meta charset="utf-8"/><meta content="width=device-width, initial-scale=1.0" name="viewport"/><meta content="web_blank" name="shell-type"/><link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" rel="stylesheet"/><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&family=JetBrains+Mono:wght@600;700&family=Space+Grotesk:wght@600;700&display=swap" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/><style>@layer base{html,body{margin:0;padding:0;}body{overscroll-behavior:none;}main>:first-child{margin-top:0!important;}main>:last-child{margin-bottom:0!important;}}::-webkit-scrollbar{display:none;}</style><script src="https://cdn.tailwindcss.com"></script><script id="tailwind-config">tailwind.config={darkMode:"class",theme:{extend:{"colors":{"inverse-primary":"#006875","tertiary":"#f2e9ff","primary-fixed-dim":"#00daf3","tertiary-fixed":"#e9ddff","surface-tint":"#00daf3","on-primary":"#00363d","on-error-container":"#ffdad6","on-error":"#690005","on-primary-container":"#00626e","on-secondary-container":"#cdd7ff","on-primary-fixed-variant":"#004f58","on-tertiary-container":"#6834d1","on-surface":"#e0e2ea","surface-container":"#1d2025","on-secondary-fixed":"#00174b","on-tertiary-fixed-variant":"#5516be","outline-variant":"#3b494c","on-background":"#e0e2ea","primary-container":"#00e5ff","secondary-fixed":"#dbe1ff","surface":"#101419","error":"#ffb4ab","on-secondary":"#002a78","surface-container-lowest":"#0b0e13","on-tertiary":"#3c0091","outline":"#849396","error-container":"#93000a","surface-dim":"#101419","on-tertiary-fixed":"#23005c","primary":"#c3f5ff","secondary-container":"#0053db","inverse-on-surface":"#2d3036","inverse-surface":"#e0e2ea","secondary":"#b4c5ff","secondary-fixed-dim":"#b4c5ff","tertiary-container":"#d9c8ff","surface-container-highest":"#32353b","tertiary-fixed-dim":"#d0bcff","surface-bright":"#36393f","surface-container-low":"#181c21","on-secondary-fixed-variant":"#003ea8","surface-container-high":"#272a30","surface-variant":"#32353b","background":"#101419","on-surface-variant":"#bac9cc","primary-fixed":"#9cf0ff","on-primary-fixed":"#001f24"},"borderRadius":{"DEFAULT":"0.25rem","lg":"0.5rem","xl":"0.75rem","full":"9999px"},"spacing":{"space-sm":"0.5rem","gutter-lg":"1.5rem","gutter":"1rem","space-lg":"1.5rem","space-md":"1rem","space-xl":"2rem","space-xs":"0.25rem","margin":"1rem","margin-lg":"2rem"},"fontFamily":{"body-md":["Inter"],"display-hero-mobile":["Space Grotesk"],"headline-sm":["Space Grotesk"],"body-lg":["Inter"],"telemetry-metric-lg":["JetBrains Mono"],"label-data":["JetBrains Mono"],"headline-md":["Space Grotesk"],"display-hero":["Space Grotesk"],"telemetry-metric-lg-mobile":["JetBrains Mono"],"headline-lg":["Space Grotesk"],"label-caption":["Inter"],"telemetry-metric-md":["JetBrains Mono"]},"fontSize":{"body-md":["14px",{"lineHeight":"20px","fontWeight":"400"}],"display-hero-mobile":["40px",{"lineHeight":"44px","letterSpacing":"-0.02em","fontWeight":"700"}],"headline-sm":["20px",{"lineHeight":"28px","fontWeight":"600"}],"body-lg":["16px",{"lineHeight":"24px","fontWeight":"500"}],"telemetry-metric-lg":["48px",{"lineHeight":"48px","letterSpacing":"-0.04em","fontWeight":"700"}],"label-data":["12px",{"lineHeight":"16px","letterSpacing":"0.08em","fontWeight":"600"}],"headline-md":["24px",{"lineHeight":"32px","letterSpacing":"-0.01em","fontWeight":"600"}],"display-hero":["56px",{"lineHeight":"60px","letterSpacing":"-0.03em","fontWeight":"700"}],"telemetry-metric-lg-mobile":["36px",{"lineHeight":"36px","letterSpacing":"-0.03em","fontWeight":"700"}],"headline-lg":["32px",{"lineHeight":"40px","letterSpacing":"-0.02em","fontWeight":"700"}],"label-caption":["11px",{"lineHeight":"14px","letterSpacing":"0.05em","fontWeight":"600"}],"telemetry-metric-md":["28px",{"lineHeight":"32px","letterSpacing":"-0.02em","fontWeight":"600"}]}}}};</script></head><body class="bg-surface-container-lowest text-on-surface font-body-md text-body-md min-h-screen flex flex-col justify-between relative overflow-x-hidden selection:bg-primary-container selection:text-on-primary"><div class="absolute inset-0 pointer-events-none opacity-20 bg-[radial-gradient(#00daf3_1px,transparent_1px)] [background-size:24px_24px]"></div><div class="absolute inset-0 pointer-events-none bg-[radial-gradient(ellipse_80%_50%_at_50%_-20%,rgba(0,229,255,0.15),transparent)]"></div><header class="relative z-20 w-full bg-surface-container-lowest/80 backdrop-blur-md"><div class="w-full px-gutter-lg py-space-md flex flex-wrap items-center justify-between gap-space-md"><div class="flex items-center gap-space-md"><img alt="Brand logo. - Primary color: #00e5ff
|
||||
- Font: spaceGrotesk
|
||||
- Mode: dark
|
||||
- Roundness: rounded-md
|
||||
" class="h-8 w-auto object-contain" src="https://lh3.googleusercontent.com/aida/AEtjO1VyjwCl13wJcsQT-sMTi-VRmFxtZ-9XIra_-xqqK4kTFuOW8p1wBa1sxe4tYYuCb6dn_KEKD4eafHUh8YVgowbEvhZZs8cw7zL-NoUhnJvkrvVr2L3D6B7AbSXsYPHpoPD3cGefuUyVyNzO6s5TraxSTMpmQ31_ZNphdAPtB96fnxjTpL5y_m4qrKjJwN1LMV2eblQNfn-ubgQY5A0ier_SAIa3satIVrBXUeDO5Tg8mutucmfwYgVCrA"/><div class="flex flex-col"><span class="font-headline-sm text-headline-sm uppercase tracking-wider text-on-surface leading-none">MotorSignal</span><span class="font-label-caption text-label-caption text-on-surface-variant uppercase tracking-widest">Telemetry Core Systems</span></div></div><div class="flex items-center gap-space-lg"><div class="flex items-center gap-space-xs bg-surface-container-low px-space-md py-space-xs rounded"><span class="w-2 h-2 rounded-full bg-primary-container animate-pulse"></span><span class="font-label-data text-label-data text-primary-fixed">20HZ KALMAN SYNC ACTIVE</span></div><div class="hidden sm:flex items-center gap-space-xs bg-surface-container-low px-space-md py-space-xs rounded"><span class="material-symbols-outlined text-primary-fixed-dim text-[16px]">lock</span><span class="font-label-data text-label-data text-on-surface-variant">SECURE_PORT: 443</span></div><div class="w-8 h-8 rounded-full bg-primary flex items-center justify-center"><span class="material-symbols-outlined text-on-primary text-[18px]">person</span></div></div></div></header><main class="relative z-10 flex-1 flex items-center justify-center w-full px-gutter-lg py-space-xl"><div class="flex flex-col w-full relative">
|
||||
<div class="relative w-full max-w-7xl mx-auto flex flex-col items-center justify-center min-h-[calc(100vh-14rem)] py-space-xl">
|
||||
<!-- Ambient Tactical Grid & Oscilloscope Wave Overlay (Self-contained) -->
|
||||
<div class="absolute inset-0 pointer-events-none flex items-center justify-center overflow-hidden">
|
||||
<!-- Glow Nodes -->
|
||||
<div class="absolute w-[500px] h-[500px] rounded-full bg-primary-container/10 blur-[120px] -top-20"></div>
|
||||
<div class="absolute w-[400px] h-[400px] rounded-full bg-secondary-container/15 blur-[100px] -bottom-24"></div>
|
||||
<!-- Vector Telemetry Waveform -->
|
||||
<svg class="w-full max-w-5xl h-64 opacity-25 text-primary-fixed-dim" fill="none" viewbox="0 0 1000 200">
|
||||
<path class="animate-pulse" d="M0 100 H200 L230 40 L260 160 L290 80 L310 120 L330 100 H550 L580 20 L610 180 L640 60 L670 140 L700 100 H1000" stroke="currentColor" stroke-dasharray="4 4" stroke-width="1.5"></path>
|
||||
<path d="M0 100 H210 L235 60 L265 140 L285 90 L305 110 L325 100 H560 L585 45 L615 155 L635 80 L665 120 L695 100 H1000" stroke="currentColor" stroke-width="0.75"></path>
|
||||
</svg>
|
||||
</div>
|
||||
<!-- Centered Tactical Recovery Console Card -->
|
||||
<div class="relative w-full max-w-[480px] bg-surface-container-low/90 backdrop-blur-xl rounded-xl shadow-2xl p-space-lg md:p-space-xl z-10 transition-all duration-300">
|
||||
<!-- Tactical Corner Targeting Accents (Precision HUD) -->
|
||||
<div class="absolute -top-1 -left-1 w-4 h-4 border-t-2 border-l-2 border-primary-container"></div>
|
||||
<div class="absolute -top-1 -right-1 w-4 h-4 border-t-2 border-r-2 border-primary-container"></div>
|
||||
<div class="absolute -bottom-1 -left-1 w-4 h-4 border-b-2 border-l-2 border-primary-container"></div>
|
||||
<div class="absolute -bottom-1 -right-1 w-4 h-4 border-b-2 border-r-2 border-primary-container"></div>
|
||||
<!-- Protocol Metadata Header -->
|
||||
<div class="flex items-center justify-between gap-space-xs bg-surface-container-lowest px-space-md py-space-xs rounded-lg mb-space-lg">
|
||||
<div class="flex items-center gap-space-xs">
|
||||
<span class="relative flex h-2 w-2">
|
||||
<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 w-2 bg-primary-container"></span>
|
||||
</span>
|
||||
<span class="font-label-data text-label-data text-primary-fixed tracking-widest uppercase">SYS.RECOVERY // P-14</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-space-xs">
|
||||
<span class="material-symbols-outlined text-[14px] text-primary-fixed-dim">verified</span>
|
||||
<span class="font-label-caption text-label-caption text-on-surface-variant uppercase tracking-wider">ENCRYPTED DISPATCH</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Icon & Screen Identification -->
|
||||
<div class="flex flex-col items-center text-center mb-space-lg">
|
||||
<div class="relative mb-space-md">
|
||||
<div class="absolute inset-0 rounded-full bg-primary-container/20 blur-md"></div>
|
||||
<div class="relative w-16 h-16 rounded-full bg-surface-container flex items-center justify-center text-primary-container shadow-inner">
|
||||
<span class="material-symbols-outlined text-[32px]">lock_reset</span>
|
||||
</div>
|
||||
</div>
|
||||
<h1 class="font-headline-md text-headline-md uppercase text-on-surface tracking-tight mb-space-xs">
|
||||
Recover Account Access
|
||||
</h1>
|
||||
<p class="font-body-md text-body-md text-on-surface-variant max-w-sm">
|
||||
Enter your registered telemetry callsign or email endpoint to authorize cryptographic one-time clearance token.
|
||||
</p>
|
||||
</div>
|
||||
<!-- Interactive Form Module -->
|
||||
<form class="space-y-space-md" id="recoveryForm" onsubmit="handleRecoverySubmit(event)">
|
||||
<!-- Input Group -->
|
||||
<div class="flex flex-col gap-space-xs">
|
||||
<div class="flex items-center justify-between">
|
||||
<label class="font-label-data text-label-data text-on-surface uppercase tracking-wider" for="recovery-endpoint">
|
||||
PILOT EMAIL ENDPOINT / TELEMETRY ID
|
||||
</label>
|
||||
<span class="font-label-caption text-label-caption text-primary-fixed-dim bg-surface-container-high px-space-xs py-0.5 rounded uppercase">
|
||||
AES-256 SYNC
|
||||
</span>
|
||||
</div>
|
||||
<div class="relative flex items-center">
|
||||
<span class="absolute left-space-md material-symbols-outlined text-outline text-[20px] pointer-events-none">
|
||||
alternate_email
|
||||
</span>
|
||||
<input autocomplete="email" class="w-full h-[52px] pl-11 pr-space-md bg-surface-container-lowest text-on-surface placeholder:text-outline font-label-data text-label-data rounded-lg focus:outline-none focus:bg-surface-container transition-all" id="recovery-endpoint" name="endpoint" placeholder="pilot@motorsignal.io or callsign" required="" type="text"/>
|
||||
</div>
|
||||
<p class="font-label-caption text-label-caption text-on-surface-variant mt-1 flex items-center gap-space-xs">
|
||||
<span class="material-symbols-outlined text-[13px] text-outline">schedule</span>
|
||||
<span>Cryptographic one-time token will expire in 10 minutes. Check primary and secondary relay vaults.</span>
|
||||
</p>
|
||||
</div>
|
||||
<!-- Primary Action CTA -->
|
||||
<button class="w-full min-h-[52px] bg-primary-container text-on-primary font-headline-sm text-headline-sm uppercase tracking-wider rounded-lg flex items-center justify-center gap-space-sm hover:brightness-110 active:scale-[0.99] transition-all cursor-pointer shadow-lg" id="submitBtn" type="submit">
|
||||
<span class="font-headline-sm text-[16px] tracking-widest" id="btnText">SEND RECOVERY CODE</span>
|
||||
<span class="material-symbols-outlined text-[18px]" id="btnIcon">arrow_forward</span>
|
||||
</button>
|
||||
</form>
|
||||
<!-- Feedback / Confirmation Toast Container (Dynamic State) -->
|
||||
<div class="hidden mt-space-md p-space-md bg-surface-container rounded-lg flex items-start gap-space-md" id="statusToast">
|
||||
<span class="material-symbols-outlined text-primary-fixed text-[20px] mt-0.5">check_circle</span>
|
||||
<div class="flex flex-col">
|
||||
<span class="font-label-data text-label-data text-primary-fixed uppercase tracking-wider">DISPATCH COMMENCED</span>
|
||||
<span class="font-body-md text-body-md text-on-surface-variant text-[13px]">One-time PIN routing through mesh relay. Verify inbox node headers.</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Security Hardware Token Secondary Route -->
|
||||
<div class="mt-space-lg bg-surface-container-lowest p-space-md rounded-lg flex items-start gap-space-sm">
|
||||
<span class="material-symbols-outlined text-primary-fixed-dim text-[20px] mt-0.5 shrink-0">key</span>
|
||||
<p class="font-body-md text-body-md text-on-surface-variant text-[12px] leading-relaxed">
|
||||
Hardware Token Verification available via <span class="text-primary-fixed font-medium">YubiKey NFC</span> or
|
||||
<span class="text-primary-fixed font-medium">20Hz Authenticator App</span> if email dispatch channels are restricted or offline.
|
||||
</p>
|
||||
</div>
|
||||
<!-- Split Auxiliary Links -->
|
||||
<div class="mt-space-lg pt-space-md flex flex-col sm:flex-row items-center justify-between gap-space-sm font-label-data text-label-data text-on-surface-variant">
|
||||
<a class="flex items-center gap-space-xs text-primary-fixed hover:text-primary-container transition-colors group" href="#/login">
|
||||
<span class="material-symbols-outlined text-[16px] group-hover:-translate-x-1 transition-transform">arrow_back</span>
|
||||
<span>RETURN TO SIGN IN</span>
|
||||
</a>
|
||||
<a class="text-on-surface-variant hover:text-on-surface transition-colors flex items-center gap-space-xs" href="#/support">
|
||||
<span class="material-symbols-outlined text-[14px]">contact_support</span>
|
||||
<span>OPS SUPPORT</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Telemetry System Diagnostics Monospace Ribbon Below Card -->
|
||||
<div class="mt-space-lg flex flex-wrap items-center justify-center gap-x-space-lg gap-y-space-xs text-on-surface-variant font-label-data text-label-data opacity-60">
|
||||
<div class="flex items-center gap-space-xs">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-primary-fixed"></span>
|
||||
<span>NODE: CENTRAL-US-01</span>
|
||||
</div>
|
||||
<span>//</span>
|
||||
<div class="flex items-center gap-space-xs">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-primary-fixed"></span>
|
||||
<span>LATENCY: 12ms</span>
|
||||
</div>
|
||||
<span>//</span>
|
||||
<div>SHA-512 ROUTING ACTIVE</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Interactive Validation Script -->
|
||||
<script>
|
||||
function handleRecoverySubmit(event) {
|
||||
event.preventDefault();
|
||||
const btn = document.getElementById('submitBtn');
|
||||
const btnText = document.getElementById('btnText');
|
||||
const btnIcon = document.getElementById('btnIcon');
|
||||
const toast = document.getElementById('statusToast');
|
||||
const input = document.getElementById('recovery-endpoint');
|
||||
|
||||
if (!input.value) return;
|
||||
|
||||
// Loading State Simulation
|
||||
btn.disabled = true;
|
||||
btn.classList.add('opacity-80', 'cursor-not-allowed');
|
||||
btnText.innerText = 'TRANSMITTING TOKEN...';
|
||||
btnIcon.innerText = 'sync';
|
||||
btnIcon.classList.add('animate-spin');
|
||||
|
||||
setTimeout(() => {
|
||||
btnText.innerText = 'DISPATCH TRANSMITTED';
|
||||
btnIcon.innerText = 'done_all';
|
||||
btnIcon.classList.remove('animate-spin');
|
||||
toast.classList.remove('hidden');
|
||||
input.disabled = true;
|
||||
}, 950);
|
||||
}
|
||||
</script>
|
||||
</div></main><footer class="relative z-20 w-full bg-surface-container-lowest/80 backdrop-blur-md"><div class="w-full px-gutter-lg py-space-md flex flex-wrap items-center justify-between gap-space-md text-on-surface-variant"><div class="flex flex-wrap items-center gap-space-md"><span class="flex items-center gap-space-xs font-label-data text-label-data text-primary"><span class="material-symbols-outlined text-[16px] text-primary-fixed-dim">verified_user</span>SEC-LEVEL 4 // AES-GCM-256</span><span class="hidden md:inline-block font-label-data text-label-data text-outline">|</span><span class="font-label-data text-label-data">FIPS 140-3 COMPLIANT</span></div><div class="font-label-caption text-label-caption tracking-normal">© 2024 MotorSignal Motorsport Telemetry Systems. Restricted Access Node.</div></div></footer></body></html>
|
||||
|
|
@ -0,0 +1,638 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<html class="dark" lang="en"><head><meta charset="utf-8"/><meta content="width=device-width, initial-scale=1.0" name="viewport"/><meta content="web_standard" name="shell-type"/><link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" rel="stylesheet"/><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&family=JetBrains+Mono:wght@600;700&family=Space+Grotesk:wght@600;700&display=swap" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/><style>@layer base{html,body{margin:0;padding:0;}body{overscroll-behavior:none;}main>:first-child{margin-top:0!important;}main>:last-child{margin-bottom:0!important;}}::-webkit-scrollbar{display:none;}</style><script src="https://cdn.tailwindcss.com"></script><script id="tailwind-config">tailwind.config={darkMode:"class",theme:{extend:{colors:{"surface":"#101419","inverse-on-surface":"#2d3036","on-tertiary-fixed":"#23005c","surface-dim":"#101419","inverse-surface":"#e0e2ea","surface-variant":"#32353b","on-primary-fixed":"#001f24","surface-container-highest":"#32353b","on-tertiary":"#3c0091","inverse-primary":"#006875","primary":"#c3f5ff","secondary-fixed-dim":"#b4c5ff","surface-container-lowest":"#0b0e13","on-secondary-fixed":"#00174b","on-surface-variant":"#bac9cc","surface-container-low":"#181c21","error":"#ffb4ab","on-tertiary-container":"#6834d1","outline-variant":"#3b494c","secondary":"#b4c5ff","on-primary":"#00363d","on-surface":"#e0e2ea","tertiary":"#f2e9ff","on-error-container":"#ffdad6","secondary-container":"#0053db","primary-fixed":"#9cf0ff","primary-fixed-dim":"#00daf3","on-secondary-container":"#cdd7ff","on-tertiary-fixed-variant":"#5516be","surface-container-high":"#272a30","secondary-fixed":"#dbe1ff","on-background":"#e0e2ea","error-container":"#93000a","primary-container":"#00e5ff","surface-tint":"#00daf3","on-primary-fixed-variant":"#004f58","surface-bright":"#36393f","tertiary-container":"#d9c8ff","on-error":"#690005","on-secondary":"#002a78","on-secondary-fixed-variant":"#003ea8","surface-container":"#1d2025","background":"#101419","tertiary-fixed-dim":"#d0bcff","outline":"#849396","tertiary-fixed":"#e9ddff","on-primary-container":"#00626e"},borderRadius:{"DEFAULT":"0.25rem","lg":"0.5rem","xl":"0.75rem","full":"9999px"},spacing:{"space-xl":"2rem","gutter-lg":"1.5rem","gutter":"1rem","margin-lg":"2rem","space-md":"1rem","space-xs":"0.25rem","space-sm":"0.5rem","space-lg":"1.5rem","margin":"1rem"},fontFamily:{"headline-lg":["Space Grotesk"],"headline-sm":["Space Grotesk"],"telemetry-metric-lg":["JetBrains Mono"],"body-md":["Inter"],"body-lg":["Inter"],"display-hero":["Space Grotesk"],"label-caption":["Inter"],"label-data":["JetBrains Mono"],"headline-md":["Space Grotesk"],"display-hero-mobile":["Space Grotesk"],"telemetry-metric-md":["JetBrains Mono"],"telemetry-metric-lg-mobile":["JetBrains Mono"]},fontSize:{"headline-lg":["32px",{"lineHeight":"40px","letterSpacing":"-0.02em","fontWeight":"700"}],"headline-sm":["20px",{"lineHeight":"28px","fontWeight":"600"}],"telemetry-metric-lg":["48px",{"lineHeight":"48px","letterSpacing":"-0.04em","fontWeight":"700"}],"body-md":["14px",{"lineHeight":"20px","fontWeight":"400"}],"body-lg":["16px",{"lineHeight":"24px","fontWeight":"500"}],"display-hero":["56px",{"lineHeight":"60px","letterSpacing":"-0.03em","fontWeight":"700"}],"label-caption":["11px",{"lineHeight":"14px","letterSpacing":"0.05em","fontWeight":"600"}],"label-data":["12px",{"lineHeight":"16px","letterSpacing":"0.08em","fontWeight":"600"}],"headline-md":["24px",{"lineHeight":"32px","letterSpacing":"-0.01em","fontWeight":"600"}],"display-hero-mobile":["40px",{"lineHeight":"44px","letterSpacing":"-0.02em","fontWeight":"700"}],"telemetry-metric-md":["28px",{"lineHeight":"32px","letterSpacing":"-0.02em","fontWeight":"600"}],"telemetry-metric-lg-mobile":["36px",{"lineHeight":"36px","letterSpacing":"-0.03em","fontWeight":"700"}]}}}};</script></head><body class="bg-surface font-body-md text-on-surface antialiased"><header class="fixed top-0 left-0 w-full z-50 bg-surface-container-lowest/90 backdrop-blur-xl shadow-[0_1px_8px_rgba(0,0,0,0.04)]"><div class="h-20 w-full px-gutter-lg flex items-center justify-between gap-gutter"><div class="flex items-center gap-space-lg"><div class="flex items-center gap-space-sm"><img alt="Brand logo. - Primary color: #00e5ff
|
||||
- Font: spaceGrotesk
|
||||
- Mode: dark
|
||||
- Roundness: rounded-md
|
||||
" class="h-8 w-auto object-contain" src="https://lh3.googleusercontent.com/aida/AEtjO1VyjwCl13wJcsQT-sMTi-VRmFxtZ-9XIra_-xqqK4kTFuOW8p1wBa1sxe4tYYuCb6dn_KEKD4eafHUh8YVgowbEvhZZs8cw7zL-NoUhnJvkrvVr2L3D6B7AbSXsYPHpoPD3cGefuUyVyNzO6s5TraxSTMpmQ31_ZNphdAPtB96fnxjTpL5y_m4qrKjJwN1LMV2eblQNfn-ubgQY5A0ier_SAIa3satIVrBXUeDO5Tg8mutucmfwYgVCrA"/><div class="flex flex-col"><span class="font-headline-sm text-headline-sm uppercase tracking-wider text-primary">MotorSignal</span><span class="font-label-caption text-label-caption uppercase tracking-widest text-on-surface-variant">Telemetry Cloud</span></div></div><div class="hidden xl:flex items-center gap-space-sm pl-space-md"><div class="flex items-center gap-space-xs px-space-sm py-space-xs rounded bg-surface-container-low"><span class="w-2 h-2 rounded-full bg-primary-container animate-pulse"></span><span class="font-label-data text-label-data uppercase text-primary">20Hz Kalman Sync Active</span></div><div class="flex items-center gap-space-xs px-space-sm py-space-xs rounded bg-surface-container-low"><span class="material-symbols-outlined text-primary text-base">lock</span><span class="font-label-data text-label-data uppercase text-on-surface-variant">443 Encrypted</span></div></div></div><nav class="hidden lg:flex items-center gap-space-xs" data-active-classes="bg-primary-container text-on-primary-container font-headline-sm rounded-lg"><a class="px-space-md py-space-sm rounded-lg font-body-md text-body-md text-on-surface-variant hover:bg-surface-container-high hover:text-on-surface transition-colors" data-path="dashboard" href="#">Dashboard</a><a class="px-space-md py-space-sm rounded-lg font-body-md text-body-md text-on-surface-variant hover:bg-surface-container-high hover:text-on-surface transition-colors" data-path="telemetry" href="#">Telemetry</a><a class="px-space-md py-space-sm rounded-lg font-body-md text-body-md text-on-surface-variant hover:bg-surface-container-high hover:text-on-surface transition-colors" data-path="rides" href="#">Rides</a><a class="px-space-md py-space-sm rounded-lg font-body-md text-body-md text-on-surface-variant hover:bg-surface-container-high hover:text-on-surface transition-colors" data-path="garage" href="#">Garage</a><a aria-current="page" class="px-space-md py-space-sm transition-colors bg-primary-container text-on-primary-container font-headline-sm rounded-lg" data-path="cloud-portal" href="#">Cloud Portal</a><a class="px-space-md py-space-sm rounded-lg font-body-md text-body-md text-on-surface-variant hover:bg-surface-container-high hover:text-on-surface transition-colors" data-path="system-status" href="#">System Status</a></nav><div class="flex items-center gap-space-md"><a class="flex items-center gap-space-sm px-space-sm py-space-xs rounded-xl bg-surface-container-low hover:bg-surface-container-high transition-colors" data-path="rider-profile" href="#"><div class="flex flex-col text-right hidden sm:flex"><span class="font-label-data text-label-data text-primary uppercase">@ApexMarcus</span><span class="font-label-caption text-label-caption text-secondary-fixed uppercase tracking-wider">PRO RIDER</span></div><img alt="Profile" class="w-8 h-8 rounded-full object-cover" src="https://lh3.googleusercontent.com/aida/AEtjO1WVxZBfZMbTdHeRSt73fWRy6gjWk3_qTm8SSSfoWQnQsHYP2ngztRX-GwRDxracXqrxt42j0x_3rYX-Deu1wGtF7R_qj3ZMExn0d6mErdfGFPGmEtddnnmd0i_Ez6Mv8kj3AYzks1N9Gq4hr9VObylWxDqngSG4Yi5vS-Sj7j3tfyZc_6dknnGpnnb5vC4PQmhuUp58_MzZvopIwkRWq0S27smUu_5zRLguTCXTKrFUEw9TiLBSRA4aXu4"/></a></div></div></header><main class="w-full pt-20 bg-surface min-h-[calc(100vh-5rem)]"><div class="flex flex-col w-full">
|
||||
<!-- Subtle Tactical Grid Overlay -->
|
||||
<div class="relative w-full overflow-hidden px-gutter lg:px-gutter-lg py-space-lg flex flex-col gap-space-xl">
|
||||
<!-- Ambient Backdrop Photon Emitters -->
|
||||
<div class="absolute -top-32 left-1/4 w-[620px] h-[360px] bg-primary-container/10 blur-[130px] rounded-full pointer-events-none"></div>
|
||||
<div class="absolute top-80 right-10 w-[480px] h-[320px] bg-secondary-container/15 blur-[140px] rounded-full pointer-events-none"></div>
|
||||
<!-- 1. TOP RIDER MASTHEAD -->
|
||||
<div class="relative w-full rounded-xl bg-surface-container-lowest p-space-lg flex flex-col xl:flex-row xl:items-center justify-between gap-space-lg shadow-xl">
|
||||
<div class="flex flex-col md:flex-row md:items-center gap-space-lg">
|
||||
<!-- Avatar with Cyan HUD Glow Ring -->
|
||||
<div class="relative w-28 h-28 shrink-0">
|
||||
<div class="absolute inset-0 rounded-full bg-primary-container/20 blur-md animate-pulse"></div>
|
||||
<img alt="ApexMarcus Pro Rider Helmet Avatar" class="relative z-10 w-full h-full object-cover rounded-full" src="https://lh3.googleusercontent.com/aida/AEtjO1WVxZBfZMbTdHeRSt73fWRy6gjWk3_qTm8SSSfoWQnQsHYP2ngztRX-GwRDxracXqrxt42j0x_3rYX-Deu1wGtF7R_qj3ZMExn0d6mErdfGFPGmEtddnnmd0i_Ez6Mv8kj3AYzks1N9Gq4hr9VObylWxDqngSG4Yi5vS-Sj7j3tfyZc_6dknnGpnnb5vC4PQmhuUp58_MzZvopIwkRWq0S27smUu_5zRLguTCXTKrFUEw9TiLBSRA4aXu4"/>
|
||||
<div class="absolute bottom-0 right-0 z-20 w-8 h-8 rounded-full bg-surface-container-lowest flex items-center justify-center">
|
||||
<span class="material-symbols-outlined text-primary-container text-lg" style="font-variation-settings: 'FILL' 1;">verified</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Identity & Metadata -->
|
||||
<div class="flex flex-col gap-space-xs">
|
||||
<div class="flex flex-wrap items-center gap-space-sm">
|
||||
<h1 class="font-headline-lg text-headline-lg text-on-surface tracking-tight uppercase">@ApexMarcus</h1>
|
||||
<span class="px-space-sm py-0.5 rounded bg-primary-container/20 text-primary-container font-label-data text-label-data uppercase tracking-wider flex items-center gap-1 shadow-[0_0_12px_rgba(0,229,255,0.4)]">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-primary-container animate-ping"></span>
|
||||
PRO RIDER
|
||||
</span>
|
||||
<span class="px-space-sm py-0.5 rounded bg-surface-container-high text-on-surface-variant font-label-caption text-label-caption uppercase tracking-wider">
|
||||
TELEMETRY ID: MK-8924
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-space-xs text-on-surface-variant font-body-md text-body-md">
|
||||
<span class="material-symbols-outlined text-primary text-base">two_wheeler</span>
|
||||
<span>Pacific Coast Riders MC // Road Captain</span>
|
||||
<span class="text-outline">/</span>
|
||||
<span class="font-label-data text-label-data text-primary uppercase">BAY AREA SECTOR 04</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-space-md pt-space-xs">
|
||||
<span class="font-label-caption text-label-caption uppercase text-outline">HARDWARE MESH: SENA 50S + 20HZ KALMAN IMU</span>
|
||||
<span class="w-1 h-1 rounded-full bg-outline"></span>
|
||||
<span class="font-label-caption text-label-caption uppercase text-primary">ENCRYPTED WAL RUNNING</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Quick Action Cockpit Buttons -->
|
||||
<div class="flex flex-wrap items-center gap-space-md shrink-0">
|
||||
<a class="px-space-lg py-space-sm h-12 rounded-lg bg-surface-container-high hover:bg-surface-variant text-on-surface font-headline-sm text-headline-sm transition-all flex items-center gap-space-xs shadow-md" href="#">
|
||||
<span>Public Profile View</span>
|
||||
<span class="material-symbols-outlined text-primary text-base">north_east</span>
|
||||
</a>
|
||||
<button class="px-space-lg py-space-sm h-12 rounded-lg bg-primary-container hover:bg-primary-fixed-dim text-on-primary-container font-headline-sm text-headline-sm transition-all flex items-center gap-space-xs shadow-[0_0_18px_rgba(0,229,255,0.45)] active:scale-[0.98]">
|
||||
<span class="material-symbols-outlined text-on-primary-container text-lg" style="font-variation-settings: 'FILL' 1;">speed</span>
|
||||
<span class="uppercase tracking-wider">Cockpit HUD Launch ⚡</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 2. LIFETIME TELEMETRY COUNTERS (HIGH-CONTRAST BENTO) -->
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 xl:grid-cols-4 gap-gutter-lg">
|
||||
<!-- Metric 1: Total Miles -->
|
||||
<div class="rounded-xl bg-surface-container-low p-space-lg flex flex-col justify-between relative overflow-hidden group hover:bg-surface-container transition-all">
|
||||
<div class="flex items-center justify-between text-on-surface-variant">
|
||||
<div class="flex items-center gap-space-xs">
|
||||
<span class="material-symbols-outlined text-primary text-lg">conversion_path</span>
|
||||
<span class="font-label-data text-label-data uppercase tracking-widest text-outline">ODOMETER LIFETIME</span>
|
||||
</div>
|
||||
<span class="px-space-xs py-0.5 rounded bg-surface-container-highest text-primary font-label-caption text-label-caption uppercase">DRIFT CORRECTED</span>
|
||||
</div>
|
||||
<div class="my-space-md">
|
||||
<div class="font-telemetry-metric-lg text-telemetry-metric-lg text-primary tracking-tight">12,480</div>
|
||||
<div class="font-label-caption text-label-caption uppercase text-on-surface-variant tracking-wider">Statute Miles Logged</div>
|
||||
</div>
|
||||
<div class="flex items-center justify-between text-outline font-label-data text-label-data">
|
||||
<span>HIGH-PRECISION GNSS</span>
|
||||
<span class="text-primary">99.88% L1/L5 RTK</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Metric 2: Max Lean Arc -->
|
||||
<div class="rounded-xl bg-surface-container-low p-space-lg flex flex-col justify-between relative overflow-hidden group hover:bg-surface-container transition-all">
|
||||
<div class="flex items-center justify-between text-on-surface-variant">
|
||||
<div class="flex items-center gap-space-xs">
|
||||
<span class="material-symbols-outlined text-primary-container text-lg">screen_rotation</span>
|
||||
<span class="font-label-data text-label-data uppercase tracking-widest text-outline">PEAK CAMBER</span>
|
||||
</div>
|
||||
<span class="px-space-xs py-0.5 rounded bg-primary-container/20 text-primary-container font-label-caption text-label-caption uppercase">APEX SCRAPER</span>
|
||||
</div>
|
||||
<div class="my-space-md flex items-end justify-between">
|
||||
<div>
|
||||
<div class="font-telemetry-metric-lg text-telemetry-metric-lg text-primary-container tracking-tight">54.2°</div>
|
||||
<div class="font-label-caption text-label-caption uppercase text-on-surface-variant tracking-wider">Right Camber // Saratoga Gap</div>
|
||||
</div>
|
||||
<!-- Lean Angle Mini Gauge SVG -->
|
||||
<div class="w-16 h-12 flex items-center justify-center">
|
||||
<svg class="w-full h-full stroke-current text-primary-container" fill="none" viewbox="0 0 60 40">
|
||||
<path d="M 5 35 A 25 25 0 0 1 55 35" stroke="currentColor" stroke-linecap="round" stroke-opacity="0.2" stroke-width="4"></path>
|
||||
<path d="M 5 35 A 25 25 0 0 1 48 16" stroke="currentColor" stroke-linecap="round" stroke-width="4"></path>
|
||||
<circle cx="48" cy="16" fill="currentColor" r="3"></circle>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center justify-between text-outline font-label-data text-label-data">
|
||||
<span>IMU: 20Hz 6-AXIS</span>
|
||||
<span class="text-primary-container">KALMAN FILTERED</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Metric 3: Cloud Sessions -->
|
||||
<div class="rounded-xl bg-surface-container-low p-space-lg flex flex-col justify-between relative overflow-hidden group hover:bg-surface-container transition-all">
|
||||
<div class="flex items-center justify-between text-on-surface-variant">
|
||||
<div class="flex items-center gap-space-xs">
|
||||
<span class="material-symbols-outlined text-secondary text-lg">cloud_done</span>
|
||||
<span class="font-label-data text-label-data uppercase tracking-widest text-outline">CLOUD WAL SYNC</span>
|
||||
</div>
|
||||
<span class="px-space-xs py-0.5 rounded bg-secondary/15 text-secondary font-label-caption text-label-caption uppercase">CLOUDFLARE R2</span>
|
||||
</div>
|
||||
<div class="my-space-md">
|
||||
<div class="font-telemetry-metric-lg text-telemetry-metric-lg text-secondary tracking-tight">48</div>
|
||||
<div class="font-label-caption text-label-caption uppercase text-on-surface-variant tracking-wider">Zero-loss Sessions Verified</div>
|
||||
</div>
|
||||
<div class="flex items-center justify-between text-outline font-label-data text-label-data">
|
||||
<span>PARQUET + WAL LOGS</span>
|
||||
<span class="text-secondary">E2EE INTEGRITY PASS</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Metric 4: Lateral G-Force -->
|
||||
<div class="rounded-xl bg-surface-container-low p-space-lg flex flex-col justify-between relative overflow-hidden group hover:bg-surface-container transition-all">
|
||||
<div class="flex items-center justify-between text-on-surface-variant">
|
||||
<div class="flex items-center gap-space-xs">
|
||||
<span class="material-symbols-outlined text-primary text-lg">explore</span>
|
||||
<span class="font-label-data text-label-data uppercase tracking-widest text-outline">PEAK LATERAL</span>
|
||||
</div>
|
||||
<span class="px-space-xs py-0.5 rounded bg-surface-container-highest text-primary font-label-caption text-label-caption uppercase">TRACTION MAX</span>
|
||||
</div>
|
||||
<div class="my-space-md">
|
||||
<div class="font-telemetry-metric-lg text-telemetry-metric-lg text-on-surface tracking-tight">1.24<span class="text-headline-md text-primary ml-1">G</span></div>
|
||||
<div class="font-label-caption text-label-caption uppercase text-on-surface-variant tracking-wider">Dual Compound Pirelli SC1</div>
|
||||
</div>
|
||||
<div class="flex items-center justify-between text-outline font-label-data text-label-data">
|
||||
<span>DECEL PEAK</span>
|
||||
<span class="text-primary">-1.38G STO PULL</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 3. TACTICAL FOUR-TAB NAVIGATION -->
|
||||
<div class="flex flex-col gap-space-lg">
|
||||
<div class="flex items-center justify-between overflow-x-auto pb-space-xs">
|
||||
<div class="flex items-center gap-space-xs p-1.5 rounded-xl bg-surface-container-lowest shrink-0" id="tactical-tabs">
|
||||
<button class="tab-trigger px-space-lg py-space-sm rounded-lg font-headline-sm text-headline-sm transition-all bg-primary-container text-on-primary-container shadow-[0_0_14px_rgba(0,229,255,0.3)]" data-tab="tab-rides">
|
||||
My Cloud Rides (48)
|
||||
</button>
|
||||
<button class="tab-trigger px-space-lg py-space-sm rounded-lg font-headline-sm text-headline-sm transition-all text-on-surface-variant hover:text-on-surface hover:bg-surface-container-high" data-tab="tab-garage">
|
||||
My Garage (2 Active)
|
||||
</button>
|
||||
<button class="tab-trigger px-space-lg py-space-sm rounded-lg font-headline-sm text-headline-sm transition-all text-on-surface-variant hover:text-on-surface hover:bg-surface-container-high" data-tab="tab-billing">
|
||||
Subscription & Billing
|
||||
</button>
|
||||
<button class="tab-trigger px-space-lg py-space-sm rounded-lg font-headline-sm text-headline-sm transition-all text-on-surface-variant hover:text-on-surface hover:bg-surface-container-high" data-tab="tab-privacy">
|
||||
Data & Privacy (GDPR)
|
||||
</button>
|
||||
</div>
|
||||
<div class="hidden lg:flex items-center gap-space-sm shrink-0">
|
||||
<span class="font-label-caption text-label-caption uppercase text-outline">BUFFER SYNC:</span>
|
||||
<div class="flex items-center gap-1.5 px-space-sm py-1 rounded bg-surface-container-high text-primary font-label-data text-label-data">
|
||||
<span class="w-2 h-2 rounded-full bg-primary animate-pulse"></span>
|
||||
LIVE 20Hz INGESTION
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- TAB 1: MY CLOUD RIDES (DEFAULT VIEW) -->
|
||||
<div class="tab-panel flex flex-col gap-space-lg" id="tab-rides">
|
||||
<!-- Filter Toolbar -->
|
||||
<div class="rounded-xl bg-surface-container-low p-space-md flex flex-wrap items-center justify-between gap-space-md">
|
||||
<div class="flex flex-wrap items-center gap-space-md flex-1 min-w-[300px]">
|
||||
<!-- Search Input -->
|
||||
<div class="relative flex-1 min-w-[220px]">
|
||||
<span class="material-symbols-outlined absolute left-3 top-1/2 -translate-y-1/2 text-outline text-lg">search</span>
|
||||
<input class="w-full h-11 pl-10 pr-4 rounded-lg bg-surface-container-lowest text-on-surface font-body-md text-body-md placeholder:text-outline focus:outline-none focus:ring-1 focus:ring-primary-container" placeholder="Search routes, waypoints, track tags..." type="text"/>
|
||||
</div>
|
||||
<!-- Date Range Selector -->
|
||||
<div class="relative">
|
||||
<button class="h-11 px-space-md rounded-lg bg-surface-container-lowest hover:bg-surface-container-high text-on-surface font-body-md text-body-md flex items-center gap-space-sm">
|
||||
<span class="material-symbols-outlined text-primary text-base">calendar_today</span>
|
||||
<span>Last 30 Days</span>
|
||||
<span class="material-symbols-outlined text-outline text-sm">expand_more</span>
|
||||
</button>
|
||||
</div>
|
||||
<!-- Bike Filter -->
|
||||
<div class="relative">
|
||||
<button class="h-11 px-space-md rounded-lg bg-surface-container-lowest hover:bg-surface-container-high text-on-surface font-body-md text-body-md flex items-center gap-space-sm">
|
||||
<span class="material-symbols-outlined text-primary text-base">sports_motorsports</span>
|
||||
<span>All Motorcycles</span>
|
||||
<span class="material-symbols-outlined text-outline text-sm">expand_more</span>
|
||||
</button>
|
||||
</div>
|
||||
<!-- Pace Filter -->
|
||||
<div class="relative">
|
||||
<button class="h-11 px-space-md rounded-lg bg-surface-container-lowest hover:bg-surface-container-high text-on-surface font-body-md text-body-md flex items-center gap-space-sm">
|
||||
<span class="material-symbols-outlined text-primary text-base">tune</span>
|
||||
<span>Pace 3 & 4 (Aggressive)</span>
|
||||
<span class="material-symbols-outlined text-outline text-sm">expand_more</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-space-xs font-label-data text-label-data text-on-surface-variant">
|
||||
<span>SHOWING:</span>
|
||||
<span class="text-primary font-bold">3 SESSIONS FILTERED</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Responsive Grid of Telemetry Ride Cards -->
|
||||
<div class="grid grid-cols-1 lg:grid-cols-3 gap-gutter-lg">
|
||||
<!-- RIDE CARD 1 -->
|
||||
<div class="rounded-xl bg-surface-container-low flex flex-col justify-between overflow-hidden shadow-lg group hover:bg-surface-container transition-all">
|
||||
<!-- Map Telemetry Preview -->
|
||||
<div class="relative w-full h-48 bg-surface-container-lowest overflow-hidden">
|
||||
<div class="w-full h-full bg-cover bg-center opacity-40 group-hover:scale-105 transition-transform duration-500" data-location="Skyline Boulevard, California" style="background-image: url('https://lh3.googleusercontent.com/aida-public/AB6AXuDUuhDgY1HhrMdPi379ODvUvab2rzRNiTqGeHOv60f8cFjvVByfPnrPF7rKtttYaTuAiPahS7NeRjo21PoCOvnrkzDdDcnNFmzCk8gsWyM6cYnjQyINqraLiFZ6oqn_TWslYBDo9WgCxWyU8go0ynY5VMS0Fg6_PbQBOC0jMyuBagMlutdutCUXHuAu9QS4XISWXzVbgUgovgUC-5gbPxUaqSWNYZ4JX-JpYf3CUWB_lWj9t67MazZn')"></div>
|
||||
<!-- Neon Cyan Track Line SVG Overlay -->
|
||||
<svg class="absolute inset-0 w-full h-full pointer-events-none p-4" fill="none" viewbox="0 0 320 180">
|
||||
<path class="drop-shadow-[0_0_8px_#00e5ff]" d="M 20 140 Q 60 160 100 110 T 160 80 T 220 50 T 290 30" stroke="#00e5ff" stroke-linecap="round" stroke-linejoin="round" stroke-width="3"></path>
|
||||
<circle class="animate-pulse" cx="20" cy="140" fill="#00e5ff" r="4"></circle>
|
||||
<circle cx="290" cy="30" fill="#ffb4ab" r="4"></circle>
|
||||
</svg>
|
||||
<!-- Header Badges Overlay -->
|
||||
<div class="absolute top-3 left-3 flex items-center gap-space-xs">
|
||||
<span class="px-space-xs py-0.5 rounded bg-surface-container-lowest/90 backdrop-blur-md text-error font-label-caption text-label-caption uppercase tracking-wider">
|
||||
2024 DUCATI PANIGALE V4 S
|
||||
</span>
|
||||
</div>
|
||||
<div class="absolute top-3 right-3">
|
||||
<span class="px-space-xs py-0.5 rounded bg-primary-container/20 backdrop-blur-md text-primary-container font-label-data text-label-data">
|
||||
OCT 27, 2024
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Card Content Body -->
|
||||
<div class="p-space-lg flex flex-col gap-space-md flex-1 justify-between">
|
||||
<div>
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="font-label-caption text-label-caption uppercase text-outline">SESSION #0948-CS</span>
|
||||
<span class="font-label-caption text-label-caption uppercase text-primary">KALMAN L5 SYNCED</span>
|
||||
</div>
|
||||
<h3 class="font-headline-sm text-headline-sm text-on-surface mt-1 group-hover:text-primary transition-colors">
|
||||
Skyline to Santa Cruz Coastal Arc
|
||||
</h3>
|
||||
</div>
|
||||
<!-- 4-Telemetry Value Cluster -->
|
||||
<div class="grid grid-cols-2 gap-space-sm p-space-sm rounded-lg bg-surface-container-lowest">
|
||||
<div>
|
||||
<div class="font-label-caption text-label-caption uppercase text-on-surface-variant">DISTANCE</div>
|
||||
<div class="font-telemetry-metric-md text-telemetry-metric-md text-on-surface">84.2 <span class="font-label-caption text-label-caption text-primary">MI</span></div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="font-label-caption text-label-caption uppercase text-on-surface-variant">DURATION</div>
|
||||
<div class="font-telemetry-metric-md text-telemetry-metric-md text-on-surface">1h 42m</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="font-label-caption text-label-caption uppercase text-on-surface-variant">MAX LEAN</div>
|
||||
<div class="font-telemetry-metric-md text-telemetry-metric-md text-primary-container">51.4°</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="font-label-caption text-label-caption uppercase text-on-surface-variant">AVG PACE</div>
|
||||
<div class="font-telemetry-metric-md text-telemetry-metric-md text-on-surface">52.8 <span class="font-label-caption text-label-caption text-outline">MPH</span></div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Quick Action Row -->
|
||||
<div class="flex items-center gap-space-xs pt-space-xs">
|
||||
<button class="flex-1 py-2 px-space-xs rounded bg-surface-container-high hover:bg-surface-variant text-on-surface font-label-data text-label-data transition-all flex items-center justify-center gap-1">
|
||||
<span class="material-symbols-outlined text-sm">download</span> GPX
|
||||
</button>
|
||||
<button class="flex-1 py-2 px-space-xs rounded bg-primary-container/20 hover:bg-primary-container/30 text-primary-container font-label-data text-label-data transition-all flex items-center justify-center gap-1 shadow-[0_0_10px_rgba(0,229,255,0.2)]">
|
||||
<span class="material-symbols-outlined text-sm">database</span> CSV (20Hz)
|
||||
</button>
|
||||
<a class="p-2 rounded bg-surface-container-high hover:bg-surface-variant text-primary transition-all flex items-center justify-center" href="#" title="Forensic Telemetry Replay">
|
||||
<span class="material-symbols-outlined text-lg">timeline</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- RIDE CARD 2 -->
|
||||
<div class="rounded-xl bg-surface-container-low flex flex-col justify-between overflow-hidden shadow-lg group hover:bg-surface-container transition-all">
|
||||
<!-- Map Telemetry Preview -->
|
||||
<div class="relative w-full h-48 bg-surface-container-lowest overflow-hidden">
|
||||
<div class="w-full h-full bg-cover bg-center opacity-40 group-hover:scale-105 transition-transform duration-500" data-location="Saratoga Gap, California" style="background-image: url('https://lh3.googleusercontent.com/aida-public/AB6AXuCf0xPDEt6FJNCoF9sxIsYlIq19M0AmoXa2FzLmS_rgJmhBwHZrvcHejaT5F2_Eaa6T4USK7vhP4K4WqoO10cwE18ADAzB9tgVmSyA8Jc-CaUFYL7x1SogYnfozi0aI_4joSux_CePJx7o1o9pPWDXk622ztJbSRpUT4I7sla2hlSjGMU0YAhuS9UndH09p7rx0bMJTa7sOsWwlF7THuE_c3-Zy7ZV551DMtx56mLezg-w_Xvhkj5Pk')"></div>
|
||||
<!-- Sharp Switchback Track Line Overlay -->
|
||||
<svg class="absolute inset-0 w-full h-full pointer-events-none p-4" fill="none" viewbox="0 0 320 180">
|
||||
<path class="drop-shadow-[0_0_8px_#00e5ff]" d="M 30 150 L 120 130 L 70 90 L 220 80 L 170 40 L 290 30" stroke="#00e5ff" stroke-linecap="round" stroke-linejoin="round" stroke-width="3"></path>
|
||||
<circle class="animate-pulse" cx="30" cy="150" fill="#00e5ff" r="4"></circle>
|
||||
<circle class="drop-shadow-[0_0_6px_#f2e9ff]" cx="220" cy="80" fill="#f2e9ff" r="5"></circle>
|
||||
<circle cx="290" cy="30" fill="#ffb4ab" r="4"></circle>
|
||||
</svg>
|
||||
<!-- Header Badges Overlay -->
|
||||
<div class="absolute top-3 left-3 flex items-center gap-space-xs">
|
||||
<span class="px-space-xs py-0.5 rounded bg-surface-container-lowest/90 backdrop-blur-md text-error font-label-caption text-label-caption uppercase tracking-wider">
|
||||
2024 DUCATI PANIGALE V4 S
|
||||
</span>
|
||||
</div>
|
||||
<div class="absolute top-3 right-3">
|
||||
<span class="px-space-xs py-0.5 rounded bg-primary-container/20 backdrop-blur-md text-primary-container font-label-data text-label-data">
|
||||
OCT 20, 2024
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Card Content Body -->
|
||||
<div class="p-space-lg flex flex-col gap-space-md flex-1 justify-between">
|
||||
<div>
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="font-label-caption text-label-caption uppercase text-outline">SESSION #0947-AP</span>
|
||||
<span class="px-space-xs py-0.5 rounded bg-primary-container/20 text-primary font-label-caption text-label-caption uppercase">PR VERIFIED</span>
|
||||
</div>
|
||||
<h3 class="font-headline-sm text-headline-sm text-on-surface mt-1 group-hover:text-primary transition-colors">
|
||||
Saratoga Gap Apex Sprint
|
||||
</h3>
|
||||
</div>
|
||||
<!-- 4-Telemetry Value Cluster -->
|
||||
<div class="grid grid-cols-2 gap-space-sm p-space-sm rounded-lg bg-surface-container-lowest">
|
||||
<div>
|
||||
<div class="font-label-caption text-label-caption uppercase text-on-surface-variant">DISTANCE</div>
|
||||
<div class="font-telemetry-metric-md text-telemetry-metric-md text-on-surface">28.5 <span class="font-label-caption text-label-caption text-primary">MI</span></div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="font-label-caption text-label-caption uppercase text-on-surface-variant">DURATION</div>
|
||||
<div class="font-telemetry-metric-md text-telemetry-metric-md text-on-surface">42m 10s</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="font-label-caption text-label-caption uppercase text-on-surface-variant">MAX LEAN</div>
|
||||
<div class="font-telemetry-metric-md text-telemetry-metric-md text-primary-container">54.2° <span class="font-label-caption text-label-caption text-primary">PR</span></div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="font-label-caption text-label-caption uppercase text-on-surface-variant">AVG PACE</div>
|
||||
<div class="font-telemetry-metric-md text-telemetry-metric-md text-on-surface">48.1 <span class="font-label-caption text-label-caption text-outline">MPH</span></div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Quick Action Row -->
|
||||
<div class="flex items-center gap-space-xs pt-space-xs">
|
||||
<button class="flex-1 py-2 px-space-xs rounded bg-surface-container-high hover:bg-surface-variant text-on-surface font-label-data text-label-data transition-all flex items-center justify-center gap-1">
|
||||
<span class="material-symbols-outlined text-sm">download</span> GPX
|
||||
</button>
|
||||
<button class="flex-1 py-2 px-space-xs rounded bg-primary-container/20 hover:bg-primary-container/30 text-primary-container font-label-data text-label-data transition-all flex items-center justify-center gap-1 shadow-[0_0_10px_rgba(0,229,255,0.2)]">
|
||||
<span class="material-symbols-outlined text-sm">database</span> CSV (20Hz)
|
||||
</button>
|
||||
<a class="p-2 rounded bg-surface-container-high hover:bg-surface-variant text-primary transition-all flex items-center justify-center" href="#" title="Forensic Telemetry Replay">
|
||||
<span class="material-symbols-outlined text-lg">timeline</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- RIDE CARD 3 -->
|
||||
<div class="rounded-xl bg-surface-container-low flex flex-col justify-between overflow-hidden shadow-lg group hover:bg-surface-container transition-all">
|
||||
<!-- Map Telemetry Preview -->
|
||||
<div class="relative w-full h-48 bg-surface-container-lowest overflow-hidden">
|
||||
<div class="w-full h-full bg-cover bg-center opacity-40 group-hover:scale-105 transition-transform duration-500" data-location="Auburn, California" style="background-image: url('https://lh3.googleusercontent.com/aida-public/AB6AXuDlXOKV6-aA-wkmtVM-TB0rIai1Ce-AOaVubWsR5htjlNnQDlvk8dOyPKgLYfnxXUcJ5npEK-mcyuJzXVHB7UJA3XOBdZFiFdE7zv1hAiFpND4wAAphb6EAdmRTI0CK_9d94lqf0hhFbgNSLpwIgpjIXlQG8iVz6T5ZQ90Wed2so3bffufW30pMmUk40cd0HHKA-3xHOTusWa_kjN5RnoV-kPBqjjTFHS3trmLdzQbAe047eIBp4Met')"></div>
|
||||
<!-- Mountain Elevation Profile Track Overlay -->
|
||||
<svg class="absolute inset-0 w-full h-full pointer-events-none p-4" fill="none" viewbox="0 0 320 180">
|
||||
<path class="drop-shadow-[0_0_8px_#b4c5ff]" d="M 20 140 L 70 120 L 110 70 L 160 90 L 220 30 L 270 60 L 300 40" stroke="#b4c5ff" stroke-linecap="round" stroke-linejoin="round" stroke-width="3"></path>
|
||||
<circle class="animate-pulse" cx="20" cy="140" fill="#b4c5ff" r="4"></circle>
|
||||
<circle cx="220" cy="30" fill="#c3f5ff" r="4"></circle>
|
||||
<circle cx="300" cy="40" fill="#ffb4ab" r="4"></circle>
|
||||
</svg>
|
||||
<!-- Header Badges Overlay -->
|
||||
<div class="absolute top-3 left-3 flex items-center gap-space-xs">
|
||||
<span class="px-space-xs py-0.5 rounded bg-surface-container-lowest/90 backdrop-blur-md text-secondary font-label-caption text-label-caption uppercase tracking-wider">
|
||||
2023 KTM 890 ADVENTURE R
|
||||
</span>
|
||||
</div>
|
||||
<div class="absolute top-3 right-3">
|
||||
<span class="px-space-xs py-0.5 rounded bg-primary-container/20 backdrop-blur-md text-primary-container font-label-data text-label-data">
|
||||
OCT 12, 2024
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Card Content Body -->
|
||||
<div class="p-space-lg flex flex-col gap-space-md flex-1 justify-between">
|
||||
<div>
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="font-label-caption text-label-caption uppercase text-outline">SESSION #0942-ADV</span>
|
||||
<span class="font-label-caption text-label-caption uppercase text-secondary">RIDGE RUNNER</span>
|
||||
</div>
|
||||
<h3 class="font-headline-sm text-headline-sm text-on-surface mt-1 group-hover:text-primary transition-colors">
|
||||
Sierra Foothills ADV Ridge
|
||||
</h3>
|
||||
</div>
|
||||
<!-- 4-Telemetry Value Cluster -->
|
||||
<div class="grid grid-cols-2 gap-space-sm p-space-sm rounded-lg bg-surface-container-lowest">
|
||||
<div>
|
||||
<div class="font-label-caption text-label-caption uppercase text-on-surface-variant">DISTANCE</div>
|
||||
<div class="font-telemetry-metric-md text-telemetry-metric-md text-on-surface">142.6 <span class="font-label-caption text-label-caption text-secondary">MI</span></div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="font-label-caption text-label-caption uppercase text-on-surface-variant">DURATION</div>
|
||||
<div class="font-telemetry-metric-md text-telemetry-metric-md text-on-surface">3h 15m</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="font-label-caption text-label-caption uppercase text-on-surface-variant">MAX LEAN</div>
|
||||
<div class="font-telemetry-metric-md text-telemetry-metric-md text-on-surface">38.2°</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="font-label-caption text-label-caption uppercase text-on-surface-variant">ELEVATION GAIN</div>
|
||||
<div class="font-telemetry-metric-md text-telemetry-metric-md text-primary">+6,420 <span class="font-label-caption text-label-caption text-outline">FT</span></div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Quick Action Row -->
|
||||
<div class="flex items-center gap-space-xs pt-space-xs">
|
||||
<button class="flex-1 py-2 px-space-xs rounded bg-surface-container-high hover:bg-surface-variant text-on-surface font-label-data text-label-data transition-all flex items-center justify-center gap-1">
|
||||
<span class="material-symbols-outlined text-sm">download</span> GPX
|
||||
</button>
|
||||
<button class="flex-1 py-2 px-space-xs rounded bg-primary-container/20 hover:bg-primary-container/30 text-primary-container font-label-data text-label-data transition-all flex items-center justify-center gap-1 shadow-[0_0_10px_rgba(0,229,255,0.2)]">
|
||||
<span class="material-symbols-outlined text-sm">database</span> CSV (20Hz)
|
||||
</button>
|
||||
<a class="p-2 rounded bg-surface-container-high hover:bg-surface-variant text-primary transition-all flex items-center justify-center" href="#" title="Forensic Telemetry Replay">
|
||||
<span class="material-symbols-outlined text-lg">timeline</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- TAB 2: MY GARAGE (INLINE MODULE PREVIEW) -->
|
||||
<div class="tab-panel hidden flex flex-col gap-space-lg" id="tab-garage">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex flex-col">
|
||||
<h2 class="font-headline-md text-headline-md text-on-surface">Active Hangar Vehicles</h2>
|
||||
<p class="font-body-md text-body-md text-on-surface-variant">Telemetry sync profiles and maintenance telemetry bindings.</p>
|
||||
</div>
|
||||
<button class="h-11 px-space-md rounded-lg bg-primary-container text-on-primary-container font-headline-sm text-headline-sm flex items-center gap-space-xs shadow-md">
|
||||
<span class="material-symbols-outlined text-base">add_circle</span>
|
||||
<span>+ Add Motorcycle</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-gutter-lg">
|
||||
<!-- Bike 1 -->
|
||||
<div class="p-space-lg rounded-xl bg-surface-container-low flex flex-col gap-space-md">
|
||||
<div class="flex items-start justify-between">
|
||||
<div>
|
||||
<span class="font-label-caption text-label-caption text-primary uppercase">PRIMARY TRACK TELEMETRY</span>
|
||||
<h3 class="font-headline-sm text-headline-sm text-on-surface">2024 Ducati Panigale V4 S</h3>
|
||||
<span class="font-label-data text-label-data text-outline">VIN: ZDM14BKW7PB019284</span>
|
||||
</div>
|
||||
<span class="px-space-sm py-1 rounded bg-tertiary-container/30 text-on-tertiary-container font-label-caption text-label-caption uppercase tracking-wider">
|
||||
Desmo Service Due in 380 MI
|
||||
</span>
|
||||
</div>
|
||||
<div class="grid grid-cols-3 gap-space-sm p-space-sm rounded-lg bg-surface-container-lowest">
|
||||
<div>
|
||||
<div class="font-label-caption text-label-caption uppercase text-on-surface-variant">LOGGED MILES</div>
|
||||
<div class="font-telemetry-metric-md text-telemetry-metric-md text-on-surface">6,420</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="font-label-caption text-label-caption uppercase text-on-surface-variant">ECU PROTOCOL</div>
|
||||
<div class="font-telemetry-metric-md text-telemetry-metric-md text-primary">CAN 2.0B</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="font-label-caption text-label-caption uppercase text-on-surface-variant">CHAIN HEALTH</div>
|
||||
<div class="font-telemetry-metric-md text-telemetry-metric-md text-secondary">92%</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center justify-between text-outline font-label-data text-label-data pt-space-xs">
|
||||
<span class="flex items-center gap-1 text-primary"><span class="w-2 h-2 rounded-full bg-primary animate-pulse"></span> OBD-II BLE Dongle Linked</span>
|
||||
<button class="text-primary hover:underline uppercase">Diagnostic Logs ↗</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Bike 2 -->
|
||||
<div class="p-space-lg rounded-xl bg-surface-container-low flex flex-col gap-space-md">
|
||||
<div class="flex items-start justify-between">
|
||||
<div>
|
||||
<span class="font-label-caption text-label-caption text-secondary uppercase">ENDURO / BACKCOUNTRY</span>
|
||||
<h3 class="font-headline-sm text-headline-sm text-on-surface">2023 KTM 890 Adventure R</h3>
|
||||
<span class="font-label-data text-label-data text-outline">VIN: VBKMRA400PM591024</span>
|
||||
</div>
|
||||
<span class="px-space-sm py-1 rounded bg-primary-container/20 text-primary font-label-caption text-label-caption uppercase tracking-wider">
|
||||
Optimal // Chain Tension Nominal
|
||||
</span>
|
||||
</div>
|
||||
<div class="grid grid-cols-3 gap-space-sm p-space-sm rounded-lg bg-surface-container-lowest">
|
||||
<div>
|
||||
<div class="font-label-caption text-label-caption uppercase text-on-surface-variant">LOGGED MILES</div>
|
||||
<div class="font-telemetry-metric-md text-telemetry-metric-md text-on-surface">8,110</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="font-label-caption text-label-caption uppercase text-on-surface-variant">ECU PROTOCOL</div>
|
||||
<div class="font-telemetry-metric-md text-telemetry-metric-md text-primary">K-LINE ISO</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="font-label-caption text-label-caption uppercase text-on-surface-variant">AIR FILTER</div>
|
||||
<div class="font-telemetry-metric-md text-telemetry-metric-md text-primary">CLEAN</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center justify-between text-outline font-label-data text-label-data pt-space-xs">
|
||||
<span class="flex items-center gap-1 text-primary"><span class="w-2 h-2 rounded-full bg-primary animate-pulse"></span> OBD-II BLE Dongle Linked</span>
|
||||
<button class="text-primary hover:underline uppercase">Diagnostic Logs ↗</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- TAB 3: SUBSCRIPTION & BILLING -->
|
||||
<div class="tab-panel hidden flex flex-col gap-space-lg" id="tab-billing">
|
||||
<div class="grid grid-cols-1 lg:grid-cols-3 gap-gutter-lg">
|
||||
<!-- Plan Card -->
|
||||
<div class="lg:col-span-2 p-space-lg rounded-xl bg-surface-container-low flex flex-col justify-between gap-space-lg">
|
||||
<div class="flex flex-col gap-space-xs">
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="px-space-sm py-0.5 rounded bg-primary-container text-on-primary-container font-label-data text-label-data uppercase tracking-wider">
|
||||
ACTIVE TIER
|
||||
</span>
|
||||
<span class="text-primary font-telemetry-metric-md text-telemetry-metric-md">$14.99 <span class="text-body-md text-on-surface-variant font-body-md">/ month</span></span>
|
||||
</div>
|
||||
<h3 class="font-headline-lg text-headline-lg text-on-surface mt-2">MotorSignal PRO Multi-Telemetry Tier</h3>
|
||||
<p class="font-body-md text-body-md text-on-surface-variant">
|
||||
Full 20Hz continuous Kalman sync, raw Parquet/GPX/CSV exports, multi-bike hangar access, and instant cloud crash alerts.
|
||||
</p>
|
||||
</div>
|
||||
<!-- Cloudflare R2 Vault Gauge -->
|
||||
<div class="flex flex-col gap-space-xs p-space-md rounded-lg bg-surface-container-lowest">
|
||||
<div class="flex items-center justify-between font-label-data text-label-data">
|
||||
<span class="text-on-surface uppercase">CLOUDFLARE R2 TELEMETRY VAULT</span>
|
||||
<span class="text-primary">1.4 GB / 10.0 GB (14% ALLOCATED)</span>
|
||||
</div>
|
||||
<div class="w-full h-2 rounded-full bg-surface-container-high overflow-hidden">
|
||||
<div class="h-full bg-primary-container w-[14%] rounded-full shadow-[0_0_8px_#00e5ff]"></div>
|
||||
</div>
|
||||
<span class="font-label-caption text-label-caption text-outline">Includes encrypted WAL chunks & video telemetry overlays.</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between pt-space-xs">
|
||||
<span class="font-body-md text-body-md text-on-surface-variant">Auto-renews on <strong class="text-on-surface">Nov 14, 2024</strong> (Stripe •••• 4022)</span>
|
||||
<button class="px-space-md py-2 rounded-lg bg-surface-container-high hover:bg-surface-variant text-on-surface font-headline-sm text-headline-sm">
|
||||
Manage Payment Method
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Invoices Module -->
|
||||
<div class="p-space-lg rounded-xl bg-surface-container-low flex flex-col gap-space-md">
|
||||
<h3 class="font-headline-sm text-headline-sm text-on-surface">Recent Receipts</h3>
|
||||
<div class="flex flex-col divide-y divide-surface-container-highest">
|
||||
<div class="py-space-sm flex items-center justify-between">
|
||||
<div>
|
||||
<div class="font-label-data text-label-data text-on-surface">OCT 14, 2024</div>
|
||||
<div class="font-label-caption text-label-caption text-outline">INV-2024-10-88</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-space-sm">
|
||||
<span class="font-label-data text-label-data text-primary">$14.99</span>
|
||||
<button class="p-1 rounded hover:bg-surface-container-high text-on-surface-variant" title="Download PDF"><span class="material-symbols-outlined text-base">download</span></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="py-space-sm flex items-center justify-between">
|
||||
<div>
|
||||
<div class="font-label-data text-label-data text-on-surface">SEP 14, 2024</div>
|
||||
<div class="font-label-caption text-label-caption text-outline">INV-2024-09-51</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-space-sm">
|
||||
<span class="font-label-data text-label-data text-primary">$14.99</span>
|
||||
<button class="p-1 rounded hover:bg-surface-container-high text-on-surface-variant" title="Download PDF"><span class="material-symbols-outlined text-base">download</span></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="py-space-sm flex items-center justify-between">
|
||||
<div>
|
||||
<div class="font-label-data text-label-data text-on-surface">AUG 14, 2024</div>
|
||||
<div class="font-label-caption text-label-caption text-outline">INV-2024-08-12</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-space-sm">
|
||||
<span class="font-label-data text-label-data text-primary">$14.99</span>
|
||||
<button class="p-1 rounded hover:bg-surface-container-high text-on-surface-variant" title="Download PDF"><span class="material-symbols-outlined text-base">download</span></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- TAB 4: DATA & PRIVACY (GDPR) -->
|
||||
<div class="tab-panel hidden flex flex-col gap-space-lg" id="tab-privacy">
|
||||
<div class="p-space-lg rounded-xl bg-surface-container-low flex flex-col gap-space-lg">
|
||||
<div class="flex flex-col md:flex-row md:items-center justify-between gap-space-md">
|
||||
<div>
|
||||
<h2 class="font-headline-md text-headline-md text-on-surface">Cryptographic Telemetry Safeguards</h2>
|
||||
<p class="font-body-md text-body-md text-on-surface-variant">Full self-custody compliance, continuous zero-knowledge encryption, and instant export.</p>
|
||||
</div>
|
||||
<button class="h-12 px-space-lg rounded-lg bg-surface-container-highest hover:bg-primary-container hover:text-on-primary-container text-primary font-headline-sm text-headline-sm transition-all flex items-center gap-space-xs shadow-md">
|
||||
<span class="material-symbols-outlined text-lg">archive</span>
|
||||
<span>Export All Telemetry Data (.TAR.GZ)</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-gutter-lg pt-space-xs">
|
||||
<div class="p-space-md rounded-lg bg-surface-container-lowest flex flex-col gap-space-xs">
|
||||
<div class="flex items-center gap-space-xs text-primary font-label-data text-label-data uppercase">
|
||||
<span class="material-symbols-outlined text-base">key</span>
|
||||
HARDWARE 2FA (YUBIKEY)
|
||||
</div>
|
||||
<div class="font-body-md text-body-md text-on-surface">YubiKey 5C NFC Slot 1 Verified</div>
|
||||
<span class="font-label-caption text-label-caption text-outline">Enforced on all GPX/WAL forensic downloads.</span>
|
||||
</div>
|
||||
<div class="p-space-md rounded-lg bg-surface-container-lowest flex flex-col gap-space-xs">
|
||||
<div class="flex items-center gap-space-xs text-primary font-label-data text-label-data uppercase">
|
||||
<span class="material-symbols-outlined text-base">shield_lock</span>
|
||||
VAULT ENCRYPTION
|
||||
</div>
|
||||
<div class="font-body-md text-body-md text-on-surface">AES-256-GCM Envelope Seal</div>
|
||||
<span class="font-label-caption text-label-caption text-outline">Root key derived locally on physical IMU unit.</span>
|
||||
</div>
|
||||
<div class="p-space-md rounded-lg bg-surface-container-lowest flex flex-col gap-space-xs">
|
||||
<div class="flex items-center gap-space-xs text-primary font-label-data text-label-data uppercase">
|
||||
<span class="material-symbols-outlined text-base">fingerprint</span>
|
||||
CRYPTOGRAPHIC KEY ID
|
||||
</div>
|
||||
<div class="font-telemetry-metric-md text-telemetry-metric-md text-on-surface">0x9AF8..C104</div>
|
||||
<span class="font-label-caption text-label-caption text-outline">Signed via Secp256k1 Curve.</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
// Simple tab switching logic for tactical tab bar
|
||||
const triggers = document.querySelectorAll('.tab-trigger');
|
||||
const panels = document.querySelectorAll('.tab-panel');
|
||||
|
||||
triggers.forEach(btn => {
|
||||
btn.addEventListener('click', () => {
|
||||
const targetId = btn.getAttribute('data-tab');
|
||||
|
||||
// Update Tab Styles
|
||||
triggers.forEach(t => {
|
||||
t.className = "tab-trigger px-space-lg py-space-sm rounded-lg font-headline-sm text-headline-sm transition-all text-on-surface-variant hover:text-on-surface hover:bg-surface-container-high";
|
||||
});
|
||||
btn.className = "tab-trigger px-space-lg py-space-sm rounded-lg font-headline-sm text-headline-sm transition-all bg-primary-container text-on-primary-container shadow-[0_0_14px_rgba(0,229,255,0.3)]";
|
||||
|
||||
// Show/Hide Panels
|
||||
panels.forEach(p => {
|
||||
if (p.id === targetId) {
|
||||
p.classList.remove('hidden');
|
||||
} else {
|
||||
p.classList.add('hidden');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
</script></main><footer class="w-full bg-surface-container-lowest py-space-lg"><div class="w-full px-gutter-lg flex flex-col md:flex-row items-center justify-between gap-space-md"><div class="flex items-center gap-space-md"><span class="font-label-data text-label-data uppercase tracking-wider text-on-surface-variant">© 2024 MOTORSIGNAL DYNAMICS CORP.</span><span class="hidden sm:inline font-label-data text-label-data text-outline">|</span><span class="font-label-data text-label-data text-on-surface-variant">NODE-ID: CLOUD-ORBIT-09</span></div><div class="flex items-center gap-space-sm"><div class="flex items-center gap-space-xs px-space-sm py-space-xs rounded bg-surface-container-high"><span class="material-symbols-outlined text-primary text-sm">verified_user</span><span class="font-label-data text-label-data text-primary uppercase">SEC-LEVEL 4 CRYPTOGRAPHIC COMPLIANCE</span></div><span class="font-label-caption text-label-caption text-outline uppercase">TLS 1.3 / E2EE</span></div></div></footer></body></html>
|
||||
|
After Width: | Height: | Size: 46 KiB |
|
After Width: | Height: | Size: 58 KiB |
|
After Width: | Height: | Size: 56 KiB |
|
After Width: | Height: | Size: 71 KiB |
|
After Width: | Height: | Size: 36 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 60 KiB |
|
After Width: | Height: | Size: 60 KiB |
|
After Width: | Height: | Size: 74 KiB |
|
After Width: | Height: | Size: 57 KiB |
|
After Width: | Height: | Size: 58 KiB |
|
After Width: | Height: | Size: 55 KiB |
|
After Width: | Height: | Size: 61 KiB |
|
After Width: | Height: | Size: 59 KiB |
|
After Width: | Height: | Size: 38 KiB |
|
After Width: | Height: | Size: 48 KiB |
|
After Width: | Height: | Size: 66 KiB |
|
After Width: | Height: | Size: 101 KiB |
|
After Width: | Height: | Size: 78 KiB |
|
After Width: | Height: | Size: 96 KiB |
|
After Width: | Height: | Size: 134 KiB |
|
After Width: | Height: | Size: 118 KiB |
|
After Width: | Height: | Size: 99 KiB |
|
After Width: | Height: | Size: 123 KiB |
|
After Width: | Height: | Size: 116 KiB |
|
After Width: | Height: | Size: 90 KiB |
|
After Width: | Height: | Size: 106 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 58 KiB |
|
After Width: | Height: | Size: 58 KiB |
|
After Width: | Height: | Size: 80 KiB |
|
After Width: | Height: | Size: 57 KiB |
|
After Width: | Height: | Size: 50 KiB |
|
After Width: | Height: | Size: 48 KiB |
|
After Width: | Height: | Size: 44 KiB |
|
After Width: | Height: | Size: 54 KiB |
|
After Width: | Height: | Size: 41 KiB |
|
After Width: | Height: | Size: 49 KiB |