design
Radar — God View · Command Center (flow)
Section titled “Radar — God View · Command Center (flow)”Brand: this product is Radar (renamed from Hermes, 2026-06-06). The product mark is the Radar “Scope Sweep” — see
patterns/radar-brand.mdand the brand sheet atcomponents/radar/. In-app it renders via the theme-awareRadarMarkcomponent (driven by--radar-*tokens). The slug/folder (hermes-web-app) and internal code identifiers (window.HERMES,HermesApp/Ops/Map) stay as-is for path/code stability — only the brand (mark + name) changed.
The interactive Radar command center. The map is the product; the glow is telemetry; every surface is offline-honest. Built from the original design brief (“Designing the God View”) and the Field Support Playbook, on top of the Rechaj design system.
Live interactive prototype: ./index.html — a self-contained, no-build React app (React 18 UMD + in-browser Babel). Open it and use the top switcher to move between God View · Dispatch · Impact, and the phone icon (top-right) to open the Field Technician mobile companion. Toggle Live / Offline (top-right) to see last-known mode.
Design directions board: ./directions.html — the exploration that set the glass-HUD-over-map language (the canvas host is design-canvas.jsx).
What this is
Section titled “What this is”Hermes is a living command center, not a dashboard. 332 riders today, tens of thousands tomorrow — every keke, battery, station, technician and KaaG unit visible at once, legible at a glance and actionable in one click. The map is not a feature inside Hermes; the map is Hermes, and every panel docks to it.
The hero is the Field Support dispatch flow — the screen that pays for Hermes. Today bikers waste 30–60 min finding a stranded rider; Hermes kills the search phase: search the rider → their keke lights up → assign the nearest technician → an SMS auto-fires the ETA → you watch the technician’s dot converge on the rider’s dot in real time. Average response drops from 60–90 min to 15–25 min.
Six principles every surface obeys
Section titled “Six principles every surface obeys”- The map is the product — near-black basemap that recedes; assets provide the light; panels dock, never replace.
- The glow is telemetry — brightness = activity, motion = movement. Status is felt before it’s read.
- One-glance triage — problems are loud, normal is quiet. Find what needs attention in two seconds.
- One-click to act — the distance between seeing and doing is one deliberate, confirmable click.
- Role-shaped, one system — seven teams, one component kit, configured per role.
- Offline-honest — never lie about freshness. Last-known positions wear their age; queued commands wear a pending badge.
Deliberate divergences from the global DESIGN.md — read before editing
Section titled “Deliberate divergences from the global DESIGN.md — read before editing”Hermes is the one Rechaj surface that runs dark. These are intentional, product-scoped overrides — documented here and in ../../DESIGN.md so they are never mistaken for drift. Everything not listed here still follows the global system exactly.
| Decision | Global rule | Why Hermes overrides it |
|---|---|---|
Near-black command surface (--canvas:#06090b) instead of light surfaces. |
Light app surfaces. | A 24/7 command center on a station tablet / dispatch phone must let the assets emit the only light. The dark basemap recedes so telemetry reads. Mirrors the dispatch-tooling genre (mission control, not a CRM). |
Hairline borders carry surface separation (--hair: rgba(255,255,255,.07)) on panels/cards. |
Cards have NO borders — box-shadow only. |
The no-stroke rule exists because shadow separates surfaces on light. On near-black, shadow is invisible; a 7%-white hairline is the correct, genre-standard separator. Borders here are recessive and uniform, never load-bearing. |
| No single-side accent stripes for state — preserved. | No border-left/top to colour-code state. |
Honored. State is encoded by the dot/badge + label, never by a coloured edge alone (the brief’s own rule: “pair colour with shape/label; never rely on hue”). The metric top-bars on Impact tiles are decorative category dividers, not state. |
Brand signal = real Rechaj green #01E46F, not the brief’s mock mint #54E6B0. |
Brand-green = #01E46F. |
The brief’s rendered palette was illustrative. We snap to the canonical brand green (logo bolt / primary.6) everywhere — active dots, primary buttons, dispatch route. Brand button stays #01E46F bg + dark #04140b text (never white-on-green). |
| Type system kept on the Rechaj stack — General Sans (UI) + JetBrains Mono (telemetry). | General Sans + JetBrains Mono. | Honored — we did not adopt the brief’s Sora/Hanken. Mono is reserved for IDs, coordinates, timestamps, SoC, ETAs — anything machine-precise. |
| Status taxonomy is locked & meaning-stable. | — | active #01E46F · warning #F5C451 · offline #FF7A6B · immobilized #B08CFF · known #7E948C · KaaG/info #34D8E6. Status colours never overlap brand usage, so “alert” is never read as “accent.” |
Still fully inherited: circular icon wells (.hm-iwell = 50%), no-emoji, 4px spacing grid, badges = 12px/500/6px/no-uppercase/-0.01em, semibold (600) headings with 700 reserved for numeric display, mobile companion at 390px, centered .dlg-shaped modals for confirmations on web (the immobilize command modal), top-center toast pill.
Theming — dark (default) + light
Section titled “Theming — dark (default) + light”Hermes ships two themes. Dark is the default command-center surface (everything above); light is additive and anchored to the canonical Rechaj light system (../../../../DESIGN.md + tokens/tokens.json: bg #fbfbfd, surface #ffffff, borders #e4e4e4/#ebebeb, text #111/#555/#888). The status taxonomy and brand green are locked and meaning-stable in both themes — only surfaces, lines, fills, the map and the markers re-point. Status colours additionally gain darkened *-ink text variants so they clear AA on white (e.g. warning amber → #9a6a00 as text, active green → #05853e).
How it works (token system). hermes-core.css :root holds the dark defaults and every theme-switchable surface flows through a token (helper tokens cover the most-repeated inline patterns: --fill* for the white-on-dark washes, --mk-* for the marker disc/glow/ring, --map-* for the basemap network, --glass-bg/-bd, --*-ink, and the toast/popup/backdrop tints). A :root[data-theme="light"] block re-points those to light values. A nested [data-theme="dark"] block re-pins the dark values for any element (not just :root), so surfaces that must stay dark in both themes can opt back in even inside a light root.
The toggle. A sun/moon control (the sun/moon glyphs in the HIcon set in hermes-map.jsx) is owned by HermesApp (hermes-app.jsx), which sets document.documentElement.setAttribute('data-theme', …) and persists the choice to localStorage (default dark). It lives in the module switcher (top-left), so it’s reachable on every module incl. Impact/KaaG. (A second copy briefly sat in the ops top-right cluster but was removed — it was redundant with the switcher one and crowded the top bar.)
The map (the hard surface). Dark follows “the basemap recedes so assets provide the light; the glow is telemetry.” On light a glow doesn’t read, so the basemap becomes a cool off-white surface (--map-canvas) with darker roads (--map-road/--map-road-exp) and water (--map-water), and the markers flip from “glowing dot on near-black” to a bright disc with a stronger status-colour ring (1.5px) and a much tighter glow (--mk-glow 9px→5px) — the colour-and-shape token now carries the status where a halo can’t. The road/water SVG colours in hermes-map.jsx read the theme tokens; night-map water keeps its own deep tone.
Deliberately dark in both themes (documented, not drift):
- KaaG night view (
hermes-kaag.jsx) — it is night ops by design; its root is scopeddata-theme="dark"so the night map, KPI strip and sidebar stay dark under a light root. Light only affects the day surfaces. - Field Technician phone (
hermes-mobile.jsx) — a dark, one-handed, big-target field tool; the device is scopeddata-theme="dark"for the same reason. (The web app behind it themes normally.) - Impact embeddable-widget preview (
hermes-impact.jsx) — a preview of an external dark-branded widget for websites / pitch decks, so it intentionally keeps its dark gradient regardless of app theme. - The persistent top-left module switcher is global app chrome and follows the active theme (so on a light root it is light even while hovering over the dark KaaG map) — this is the one intentional theme seam.
Brief → build map (the nine screens)
Section titled “Brief → build map (the nine screens)”| # | Brief screen | Priority | In this prototype |
|---|---|---|---|
| 01 | God View command center | P0 · hero base | ✅ Full-bleed map, glowing markers, clusters, layer rail, search, KPI strip, alert bell, legend |
| 02 | Asset detail — keke / battery / VCU / station | P0 | ✅ Popup card + tabbed right-panel profile (Overview / Battery / VCU); battery as first-class collateral with lender export; station capacity |
| 03 | Field Support Dispatch console | P0 · highest ROI | ✅ Queue by priority + SLA countdown; select rider → assign nearest tech → live convergence → On-site → Resolved + NPS |
| 04 | Impact dashboard | P0 | ✅ Live CO₂ / diesel / kWh / riders / homes counters, 12-mo trend, auditable methodology, embeddable widget, CSV/PDF export |
| 09 | Field Technician mobile | P0 (mobile) | ✅ 390px overlay: incoming → navigate → diagnostic checklist → mandatory photo capture → resolve + NPS, offline-first |
| — | Immobilize / reactivate command | P0 supporting | ✅ High-friction .dlg modal: reason + audit note + safety ack; queues when offline |
| — | Offline / last-known mode | P0 supporting | ✅ Global Live/Offline toggle, non-alarming banner, age chips, pending-command badges |
| 05 | KaaG night view | P1 | ✅ Night map, units glow by power draw. Master–detail right panel: overview (“tonight’s impact” + “lit now · by draw”) → per-unit KaaG session profile on select (current-session energy-draw graph, lifetime sessions/energy/CO₂-avoided, past-sessions table). Metrics live in the top KPI strip; panel never duplicates them. (Morning-stranding card, payment-defaulters, and unit payment/remind/cap-draw removed — VCUs auto-cut at the 20% SoC floor and collections live in the core app.) |
| 06 | Activity replay | P1 | ✅ Polyline + animated keke AND full telemetry — battery SoC, motor draw (A), speed, pack voltage charted with a cursor synced to the scrubber; swap / KaaG-start / long-stop / speed / offline-gap events overlay map + SoC chart; 1×–10× scrubber + seek, 90-day window, report export, honest offline gap. Opens from the keke profile |
| 07 | Alerts feed + no-code Rule Builder | P1 | ✅ Alert feed (ack/resolve) + visual IF/THEN builder: AND/OR conditions, time window, action blocks, severity + SMS/Push/WhatsApp/Email routing, quiet-hours, draft/active/paused, live preview, 14 starter rules |
| 08 | Role-based dashboards (×7) | P1 | ✅ “View config” pattern (layers + KPI tiles per role) + 3 worked roles: Field Support, Swap Ops, Board / Exec |
States built · states still to design
Section titled “States built · states still to design”Built: God View first-paint progressive reveal (“acquiring telemetry”), loaded dense + cluster, asset selected + popup + tag, tabbed profile, dispatch located → en-route (animated) → on-site → resolved, SLA-coloured queue with breach escalation (≤5 min → red row + pulse), immobilize confirm + offline-queued, alert ack/resolve, offline banner + age chips, field app 5-step + offline pills + queued photos, impact live counters + trend + widget.
Accessibility / interaction (built in the polish pass): full keyboard operability + ARIA across markers, rail, switcher, controls and queue rows; one :focus-visible ring; /-to-search and Esc-to-dismiss; wired +/− map zoom; Technicians layer toggle; prefers-reduced-motion honoured everywhere; --muted-2 lifted to clear WCAG AA.
Built in the second round: KaaG night view, route replay, the role-based view-config (3 worked roles), the empty-in-view state, and the dispatch can’t-locate → last-known fallback state.
Built in the third round: the no-code Rule Builder (screen 07, opened from the alerts feed) and RBAC action-gating per role (the role actions list gates the dispatch / replay / immobilize commands on the asset popup + profile; Board / Exec is read-only with a note).
Still to design (backlog): true dense (30k) vs sparse stress; native tablet (834) portrait reflow — today the 1440 stage scales-to-fit (usable, letterboxed in portrait / fills landscape); full keyboard roving-tabindex across the marker field (today every marker is tabbable — fine at 77, revisit at scale); deeper RBAC (gate the dispatch console + rule-builder write access, not just the asset commands); the remaining 4 role recipes; wiring rules → the live alert feed.
File map (no build step)
Section titled “File map (no build step)”god-view/ index.html entry — loads React UMD + Babel, then the modules below hermes-core.css tokens + atoms (badges, buttons, KPI, map, popup, modal, offline) hermes-data.js seeded deterministic Lagos fleet (window.HERMES) hermes-map.jsx basemap (roads/water/heat/route) + glowing markers + icon set + brand mark hermes-ui.jsx toast, modal, asset popup, tabbed profile, immobilize command hermes-ops.jsx God View + Dispatch console + live convergence (the hero) hermes-mobile.jsx Field Technician 390px companion hermes-impact.jsx board-facing Impact dashboard hermes-kaag.jsx KaaG night view (module 4) — power/revenue/collection + lit-now-by-draw hermes-replay.jsx Activity replay overlay — scrub a rider's day (route + SoC/amps/speed/voltage telemetry), honest offline gap hermes-roles.jsx Role-based view config (ROLES, RBAC actions) + the top-right RoleSelect hermes-rules.jsx No-code Alert Rule Builder (IF/THEN, opened from the alerts feed) hermes-app.jsx shell — 1440×900 scaled stage + module switcher + role + field overlay directions.html design-directions exploration board (+ design-canvas.jsx host)Edit the source files directly; reload to see changes. Data is seeded so the map is identical across reloads.
See also
Section titled “See also”- Product design:
../../DESIGN.md· PRD:../../docs/prd.md· architecture:../../architecture.md - Global system:
../../../../DESIGN.md·../../../../PATTERNS.md - The hermes-java-api service this UI consumes (telemetry, dispatch, commands).