EU season
2025Estonia and Finland spots carry EEA classifications under the Bathing Water Directive.
HAAM produktutgave · Where the water is kept open
Swimmable Cities is a map-first prototype for urban and cold-water swimming. Estonia and Finland spots carry official 2025 EU bathing-water classifications. Taiwan spots are seeded and labelled. The app will not say it is safe to swim today.

EU season
2025Estonia and Finland spots carry EEA classifications under the Bathing Water Directive.
indicators
E. coliOfficial assessments use E. coli and intestinal enterococci. History stays on the spot.
Taiwan
SeededTaiwan spots are labelled as seeded. The app does not invent official grades for them.
non-advisory
CopyTests forbid “safe to swim today.” Check the official local notice before you enter the water.
The job
Official bathing-water portals are authoritative and hard to use when you are already standing at the railing. I wanted a spot card with data age, an official grade or a seeded label, nearby context, and a city action brief.
The card still has to send you back to today’s local notice. A prototype map that poses as a live advisory would be the wrong public object.
Live sample feeds, medical safety guarantees, and crowd-sourced bacteria were out of this pass.
At the water
Spots render without Mapbox. Interactivity needs a public token. Rain-triggered CSO is open work, not in this pass.
01
The map is first. Closest spots, city, country, and a season label sit on the card before any promise about today.
02
EU spots must carry an officialAssessment. Taiwan spots must be seeded. The UI keeps those labels distinct.
03
The sources panel cites the European Environment Agency and the Swimmable Cities movement workstreams. Data age stays visible.
04
Copy tests keep the app from saying it is safe to swim today. The last step is still the city’s own notice.
Design decisions
swim.haam.co
Data contract
If an Estonia or Finland spot is on the map, it has an official assessment. If a Taiwan spot is on the map, it is seeded and labelled. Tests enforce the split so a later edit cannot blur it.
Language
I did not want a sources footnote that a hurried reader could miss. Copy tests and the sources panel keep the non-advisory sentence in the interface.
Map
A missing Mapbox token should not erase the spots. The prototype renders without tiles; interactivity waits on a public pk. token.
The working stack
Data
EEA 2025 classifications for Estonia and Finland. Seeded Taiwan. Tests for the split.
Copy
copy.test.ts and SourcesPanel. The UI must not say safe to swim today.
Map
Tiles only. Token in .env. Prototype works without it.
Host
Vercel Vite/React map prototype. Movement name: Swimmable Cities.
In evidence
01Official EU 2025 baselines on Estonia and Finland spots
02Taiwan spots labelled as seeded
03A sources caveat that tests will fail if it disappears
04A map that still lists places when tiles are missing
Where it stops
There is no live sample engine and no rain-triggered CSO in this pass. Mapbox tiles on the public host need a token. Native swim logic is deferred.
Do not say safe to swim today. Do not call it a live water-quality product. Accessibility audit not recorded.
HAAM’s role
Baseline versus today, seeded versus official labels, city action brief, Mapbox prototype, EEA 2025 data, and copy tests. Direct work, 2026.
Optional analytics. Google Analytics and Clarity load only if allowed; form, email, and chat content are excluded.