doxa-maps/library
doxa-maps-88655c70 d4a8184ad7 Match the tab radius to the rest of the app, and open on the tab you were last on
The vertical tabs were a 999px stadium on a 48px row. That was a real earlier
instruction -- imitate the YouTube active row -- and it shipped, but measured
against the product it is the only thing shaped that way: the collapse button is
8px, the filter toggles are 8px, and 8px is already the most common radius in
the layout file. They now read var(--vtl-radius,8px), so a consumer has one knob
and the three surfaces cannot drift apart. The 48px Material row height is
untouched. The YouTube rationale stays in the comment as history with an explicit
note not to restore the pill from it, because a superseded rationale that still
reads as current is how a reversed decision gets quietly undone.

The .vtl-cap badge keeps its pill. The complaint was about the ratio of radius to
size -- a 16px chip at 999px is a chip, a 48px row at 999px is a stadium.

The studio opened on nothing and said "Choose an element from the list." It now
resolves a tab in priority order: the URL hash, since an explicit shareable
request should beat a remembered one; then localStorage, so a reload is not a
fresh start; then the first row, so the pane is never empty. This lives in the
studio rather than the layout because VerticalTabsLayout is controlled via
v-model:active and deliberately holds no selection state.

Storage is keyed by pathname so two shells on one origin do not fight over one
key, every access is wrapped because localStorage throws in private mode and an
exception in setup would blank the whole subtree, and the key is only written
after the row is confirmed to exist so a bad key cannot poison the next load.

Verified in the built shell on a settled tree: first load auto-selects with no
hint and stores the key; clicking big-picture moves the selection and updates
storage; a reload restores big-picture; and a deliberately poisoned key falls
back to the first tab and rewrites itself rather than rendering an empty pane.
2026-09-23 01:03:15 +00:00
..
api consolidate docs into documentation/ and deployment shells into deployment/ 2026-09-21 23:23:23 +00:00
colors Land the swarm's dashboard work: colour, rails, cascade, scroll 2026-09-22 18:57:39 +00:00
components Gate the scrim-covers-viewport rule, and say what was not verified 2026-09-22 21:54:39 +00:00
composables Remove the tile-403 on-screen banner; connect dashboard selections to the grid 2026-09-22 01:43:56 +00:00
constants doxa-maps — portable bundler for embeddable JAMstack maps 2026-09-10 01:53:07 +00:00
data docs: simplify all folder READMEs (what's here + graphic + link); migrate complex reference to docs/architecture/{data-sources,i18n,components,app-wrappers,poster-generation}.md 2026-09-11 18:50:31 +00:00
i18n consolidate docs into documentation/ and deployment shells into deployment/ 2026-09-21 23:23:23 +00:00
layouts Match the tab radius to the rest of the app, and open on the tab you were last on 2026-09-23 01:03:15 +00:00
maps Load the RTL text plugin from one place, and in the composite too 2026-09-22 19:55:58 +00:00
scripts consolidate docs into documentation/ and deployment shells into deployment/ 2026-09-21 23:23:23 +00:00
stores fix(spa): make embedded maps survive the sandboxed plugin iframe 2026-09-12 21:07:26 +00:00
styles Move the eight CARTO basemap styles to OpenFreeMap 2026-09-22 02:27:48 +00:00
utils Land the prayer facet and the scrim helper 2026-09-22 21:50:32 +00:00
index.js Brand-neutral shared VerticalTabsLayout with lazy nested-element hosting; fix cap-5 prayer tab leaf path; neutralize library identifiers; add Forgejo CI build-gate workflow 2026-09-19 17:24:30 +00:00
ProfileLoader.vue Land the swarm's dashboard work: colour, rails, cascade, scroll 2026-09-22 18:57:39 +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.