pnpm test # unit tests (parsing, verdicts, routing, reach, moderation)
pnpm smoke # end-to-end flows against `pnpm preview` on :4173
pnpm a11y # axe-core WCAG 2.2 AA scan of every main view
pnpm data:build # re-fetch OSM + ZTP data into public/data/kk-snapshot.json
```
Demo sign-in has no passwords: pick **Anna** (wheelchair), **Piotr** (stroller) or **Maria** (city
official, unlocks the City panel). Everything is stored in the browser, per account.
## What it does
| For residents and visitors | For city staff (role "Pracownik urzędu") |
| --- | --- |
| Guided profile: persona, equipment presets, limits with plain-language hints and tooltips, live preview of how many places fit | Data-quality KPIs computed from open sources, no database kept by the city |
| Fit report per place (entrance, steps, ramp/lift, width, surface, toilet, benches, baby changing) | Gaps by place type; operator-feed gap for transit stops |
| Step-free routing that avoids steps, high kerbs, steep and narrow sections, optionally cobbles; text route and barrier list | "Fix first" ranking of crossings with high or unknown kerb height, weighted by places served |
| Barrier-free reach: what you can get to in 5/10/15 min | Report moderation queue: approve → "verified by the city office" |
| Printable access card per place | Anonymous demand signals: where people look but data is missing |
| Report a correction (kept apart from OSM data, marked unverified) | CSV / GeoJSON export of the computed data |
| Saved places, text size, high contrast, reduced motion, PL/EN | |
## Routes, guidance and evidence
- **Route options:** the shortest path comes first (difficulties counted, not avoided), then variants that trade extra
distance for fewer difficulties. Each shows distance, time, overhead vs shortest, and counts of barriers / cautions /
unknown points; the best one is flagged "Recommended" and others are drawn faintly on the map.
- **Guide me:** live GPS guidance with turn prompts and barrier warnings at the top (optional voice, screen kept awake,
off-route re-routing). "Simulate GPS" walks the route for demos. Or hand the route to Google Maps / Apple Maps: waypoints
along our route keep their path close to ours, but those apps do not know the user's limits.
- **Map layers:** street map or satellite (Esri World Imagery; check its terms before production use).
- **Report evidence:** photo (EXIF stripped, downscaled), slope measured with the phone's tilt sensors, kerb height measured on
the photo against a reference object (card / A4 / ruler), or typed in. **LiDAR is not reachable from a web app** (no
LiDAR or WebXR on iOS Safari); `Measurement.method = 'lidar'` is reserved for a native iOS companion.
- **Automatic first look:** on-device CLIP zero-shot (free, private, no API key) labels the photo; rules combine it with the
claim and measurement into validity, consistency, severity and a triage lane (fast-track / review / likely reject).
It only orders the city queue. If the model cannot load the app says "No Credits left". Hosted free vision APIs
need a key (Pollinations anonymous is text-only), so none are wired in.