--- title: Metro Map UI Architecture created: 2026-04-08 updated: 2026-04-08 status: evolving tags: [architecture, ui, d3, metro-map, retro] sources: [resources/js/Components/MetroMap/MetroCanvas.vue, STYLE_GUIDE.md, resources/js/Components/Cli/CliBar.vue] --- # Metro Map UI Architecture The entire platform navigates via a **zoomable metro/transit map**. No sidebar, no traditional dashboard. Users explore the innovation landscape visually. ## Map Levels | Level | What You See | Lines = | Stations = | Zoom Target | |---|---|---|---|---| | 1. Strategy | Full innovation landscape | Strategic themes (Thema) | Projects | Click station → Level 2 | | 2. Project | Single project lifecycle | Lifecycle + Commitments + Documents | Phases, items | Click station → Level 3 | | 3. Detail | Individual item | (not yet implemented) | — | Click to open | ## Technical Implementation ### MetroCanvas.vue (356 LOC) - **Rendering**: D3.js 7.9 on SVG - **Zoom**: `d3.zoom()` with `scaleExtent([0.3, 5])`, pan + zoom - **Lines**: `d3.curveMonotoneX` paths connecting stations - **Stations**: Two concentric circles (outer ring = line color, inner dot = status color) - **Labels**: VT323 monospace font, positioned below stations - **Interactions**: hover → glow effect + tooltip, click → emit node-click - **Dependencies**: Dashed lines between connected stations across lines ### Data Contract (MapDataService → MetroCanvas) ```json { "lines": [ { "id": "thema-1", "name": "Waterkwaliteit", "color": "#00d2ff" } ], "nodes": [ { "id": "project-1", "entityId": 1, "entityType": "project", "name": "Sensor Netwerk", "lineId": "thema-1", "x": -200, "y": 0, "order": 1, "status": "verkenning", "description": "...", "owner": "Jan", "badge": "Verkenning", "children": 5 } ], "connections": [ { "from": "project-1", "to": "project-3" } ], "level": 1 } ``` ### Station Status Colors | Status | Color | Hex | |---|---|---| | afgerond / completed | Neon green | `#00ff88` | | actief / active | Vivid cyan | `#00d2ff` | | geparkeerd | Warning yellow | `#ffd93d` | | gestopt | Signal red | `#e94560` | | default (pending) | Dark fill | `#16213e` | ### Visual Effects - **Glow filter**: SVG `feGaussianBlur` with `stdDeviation=4`, applied on hover - **Scanline pattern**: 4px repeating lines at 8% opacity (subtle CRT effect) - **Hover transition**: 200ms radius 8→12 + glow filter - **Zoom animation**: 500ms d3 zoom transition for `zoomTo()` method ## C64 CLI Bar (CliBar.vue) Fixed at bottom of screen. Commodore 64 aesthetic: - Monospace font (Press Start 2P / VT323) - Blinking block cursor - Dark background, cyan/green text - Natural language input - Responses slide up above bar with `[AI]` prefix ## Design System ### Color Palette | Role | Hex | Usage | |---|---|---| | Background | `#1a1a2e` | Canvas, page background | | Surface | `#16213e` | Cards, tooltips, panels | | Primary | `#0f3460` | Metro lines, primary actions | | Accent (cyan) | `#00d2ff` | Active states, highlights, CLI cursor | | Accent (red) | `#e94560` | Warnings, deadlines | | Accent (green) | `#00ff88` | Success, completed | | Accent (purple) | `#7b68ee` | Knowledge, documentation | | Text primary | `#e8e8e8` | Main text | | Text secondary | `#8892b0` | Labels, secondary text | ### Fonts | Use | Font | Fallback | |---|---|---| | Map labels | VT323 | monospace | | CLI bar | Press Start 2P | VT323, monospace | | Body text | IBM Plex Sans | Inter, sans-serif | | Code | IBM Plex Mono | monospace | ## Planned Enhancements - **Zoom-to-dimension**: scroll-zoom near a station gradually cross-fades into child dimension (no click needed) - **Recursive dimensions**: every node can contain children forming a sub-metro-map, infinitely nestable - **Right-click context menu**: canvas = "New node here", station = "Edit/Delete/Add child" - **[+] FAB**: creates at current depth - **Mobile**: list fallback with metro line colors preserved