doxa-maps/library
Doxa Maps 65faa2d971 Keep the square panel together on a phone
A media query adds no specificity. The mobile block's
`.map-toolbar { gap: 6px }` is (0,1,0) exactly like
`.map-toolbar--square { gap: 0 }`, and it comes later in the sheet, so it
won: on every phone a square toolbar fell back to separate buttons inside
one ringed panel. The shape broke precisely where the Driver is most likely
to look at it.

The --no-geocoder pair is (0,2,0) and outranked the variant whatever the
order, so it needs the two-class answer.

This is the same lesson as the goal cards' gap-vs-margin: a ported mechanism
is only ported if it still WINS, and specificity is the part that decides
whether it does. Found by following the phone thread rather than by looking
at the variant again.

check:square-map-controls now asserts the override is inside the mobile
block, that the two-class form answers --no-geocoder, and -- as a control --
that the base rule really does come first, which is why the override is
needed at all. Removing it turns the gate red.

The CSS comment explaining it cost one more mistake: I wrote the selectors
in backticks, inside the template literal that holds the stylesheet. A
backtick ends the literal, which is the trap check:sfc-parse names in its own
failure text, and it caught me with it.
2026-09-27 06:04:08 +00:00
..
api The people-group list is a universal prop: the same maps can show any project's list 2026-09-26 05:16:02 +00:00
colors The legends mirror now, and their labels never became their values 2026-09-26 22:06:58 +00:00
components Keep the square panel together on a phone 2026-09-27 06:04:08 +00:00
composables Every shadow root honours prefers-reduced-motion 2026-09-27 05:05:04 +00:00
constants Every runtime CDN script and stylesheet is an exact version with an integrity hash 2026-09-26 05:50:24 +00:00
data Country names in the reader's language, for all 242 2026-09-27 04:14:31 +00:00
i18n gospel: the tables page's 14 titles and 112 column headers, in 11 locales 2026-09-27 04:14:31 +00:00
layouts Decouple the library's prose: no host-platform names in the QA widget, StackLayout or script notes 2026-09-26 17:28:45 +00:00
lists List names speak the reader's language: listLabel and listDefinition 2026-09-26 08:39:52 +00:00
maps Map labels ask for a font the engine's glyph server has: one shared helper 2026-09-25 13:48:10 +00:00
packet A packet says which list it holds, in the reader's language 2026-09-26 07:39:35 +00:00
scripts Svalbard carries its own data, not Norway's 2026-09-27 05:05:04 +00:00
stores Make the map's clustering picker real: four options, four different maps 2026-09-25 16:16:46 +00:00
styles Fiord: the MapLibre dark that actually looks like the map it replaces 2026-09-24 02:26:14 +00:00
utils Say where the country-name helper must not be used 2026-09-27 04:14:31 +00:00
vendor/cldr Country names in the reader's language, for all 242 2026-09-27 04:14:31 +00:00
index.js Move internal files out of the repo; fix five dead links; a fuller delegation diagram 2026-09-25 05:14:10 +00:00
ProfileLoader.vue Decouple the library's prose: no host-platform names in the QA widget, StackLayout or script notes 2026-09-26 17:28:45 +00:00
README.md Complete app-profiles->plugin-designs sweep across comments/docs; build green; layouts kept at root (load-bearing) 2026-09-17 18:18:19 +00:00

library/ (@map) — the shared map template

The other half of the architecture (see ../plugin-designs/README.md): every map in plugin-designs/<your-map>/ composes the reusable, parameterized pieces that live here. Fix something here and every map benefits on the next build; break something here and every map breaks — read components/WARNING.md before touching shared pieces.

Folder What lives there
ProfileLoader.vue The root of every bundle: parses profile-config, loads the profile, provides the stores + config
components/ Shared UI — map, legends, controls, popup (PeopleGroupDetail), tables, charts, hints (README)
composables/ Shared logic — map engine (useMapInstance), provider switch, shadow-DOM styles, theming
stores/ Per-instance Pinia stores (ui / map / data) — provided by ProfileLoader, injected by children
api/ Data-source registry (sources.json) + fetch layer — the JAMstack runtime wiring
colors/ Color sets maps opt into via profile-config.colorSet
i18n/ The shared string catalogs (all maps speak the same languages)
data/ Small shared datasets baked at build time (big served data lives in ../data/)
constants/ Shared constants
scripts/ Maintainer pipelines (posters, research) — not part of any bundle

The rule of thumb (same as WARNING.md): custom code in your app-profile, reusable code here — and things only move from the first to the second once they've earned it.