Commit graph

3785 commits

Author SHA1 Message Date
Doxa Maps
b3e67c7f2b Merge remote-tracking branch 'origin/development' into bundler-2/panelang 2026-09-29 19:38:36 +00:00
Doxa Maps
0adb75a0c8 Rebuild research-map-plus-grid for the locale re-forward
Step 4 of the landing preconditions names this composite alone: it is the only
source that changed.
2026-09-29 19:35:19 +00:00
Doxa Maps
cff06fb8e6 Merge origin/development into studio/deep-research 2026-09-29 19:34:32 +00:00
Doxa Maps
b0d08224c1 A live language switch never reached the panes inside Simple Research
The composite re-pushed its FILTER state to the map and the grid on every
change, and nothing else. So a host switching language moved the composite's own
chrome and stopped there: the outer element received the new profile-config,
the push re-parsed each child's EXISTING attribute, and the boot `lang` survived
every write. Measured on a live en to ar switch: the map and the grid both stayed
English while the frame around them changed.

The panes were never at fault. Each child's own chain is fully reactive -- it is
reactive to its own prop, and its prop was frozen.

The map now carries the locale in the same push that carries the filters. The
grid needs its own line, because its three linked facets travel as separate
attributes while its language travels in profile-config, which this composite
set only when a host supplied a list, and never again. And a locale change now
triggers a push at all: the existing watchers cover filter state only.

The grid write is conditional so an unchanged locale writes nothing. That
matters here more than it looks: setting a pane's attribute makes it re-filter
and emit, and the composite reads those emissions -- which is what the `pushing`
guard above exists for, after a measured round trip once cancelled a selection
the composite had just applied.

Verified two-sided by driving the real pushToChildren against stub elements:
the locale reaches both panes, and a repeat at the same locale adds no write.
Removing the map's line fails that assertion alone and leaves the grid's passing.
2026-09-29 19:30:31 +00:00
Doxa Maps
7a5c9bd9fa Merge remote-tracking branch 'origin/development' into regions/pane-config-land 2026-09-29 19:30:06 +00:00
Doxa Maps
4f44a9b23e Rebuild doxa-maps-spa with every tab's info text, and regenerate the tree 2026-09-29 19:29:36 +00:00
Doxa Maps
525ce20a10 Merge origin/development into studio/deep-research (every tab's mapInfo text) 2026-09-29 19:29:04 +00:00
Doxa Maps
bd566e0d18 Merge remote-tracking branch 'origin/development' into regions/pane-config-land 2026-09-29 19:24:39 +00:00
Doxa Maps
c6f9e11427 The info popup keeps Tab inside it, as aria-modal promises
Tab from the last control wraps to the first, and Shift+Tab from the first
to the last, reading the focused element from the shadow root.
2026-09-29 19:22:10 +00:00
Doxa Maps
19339aacbf Rebuild regions-dashboard after merging development
The pane re-forward is compiled into this bundle, and landing-preconditions
step 4 named regions-dashboard as the only consumer the library change reaches.
Built with BUNDLE=regions-dashboard, then tree, then fix:sri.
2026-09-29 19:17:46 +00:00
Doxa Maps
37f3aa1221 All seven gallery tabs carry their info entry; a tab whose text is not bundled shows no button
Each production tab reads mapInfo.tab.<tabId>.lead and .takeaway, and Regions also its note, with
the India/China reasoning beside it. Only files already in the tree are listed as examples (the
UPG-100 poster); the rest join when their shots land. A tab's button renders only when its lead
key resolves in the bundled catalogue, so a key that has not landed yet hides the button instead of
opening a popup of raw key names.
2026-09-29 19:17:42 +00:00
Doxa Maps
74d2d67f19 Every map's "what can this do for you?" text, in one catalogue area
Adds the lead and takeaway for six more maps to mapInfo, keyed by the
gallery's tab ids (cities-internet, gospel-resources, dashboard-plus-grid,
research-map-plus-grid, prayer-map, regions-dashboard), plus the Regions
note, in all eleven locales. Each map's owner wrote and checked its own
text; this commit only gathers it, because the gallery ships one area and
one lane editing its eleven files cannot collide with another.

Checked mechanically before writing: every locale present, keys free of
dots (the gallery resolves keys by splitting on them), no numerals, every
locale different from English, and every string in its own locale's
script, since a stray character from another script passes every other
catalogue gate.
2026-09-29 19:17:14 +00:00
Doxa Maps
a1d9a1e318 Merge origin/development into studio/deep-research (MapInfo as landed; upg100's files take development's side) 2026-09-29 19:16:45 +00:00
Doxa Maps
656503a28d Merge remote-tracking branch 'origin/development' into regions/pane-config-land
# Conflicts:
#	package.json
2026-09-29 19:12:46 +00:00
Doxa Maps
f0eb339512 Merge remote-tracking branch 'origin/development' into upg100/map-info2 2026-09-29 19:11:10 +00:00
Doxa Maps
93f809ebcd A map explains itself: an info button, a one-time pointer and an example popup
MapInfo (library/components/info) answers "what can this map do for
you?" with real output the map makes, pre-generated so it opens at once.
The examples are an ordered list of kinds rather than a fixed set,
because maps make different things: an image (a poster), pages (a packet
that shows its first page and expands to every page), a deck (cards that
expand from a stack to a grid) and a table (a real excerpt of the
spreadsheet a map exports, with translatable headers). An example whose
image is missing drops out quietly: no broken-image icon, no empty frame.

The pointer at the button goes for good once that map's popup has been
opened and closed; a checkbox in the popup turns it off on every map.
Both are kept in localStorage behind a guard, so private browsing cannot
break the page. On a phone the popup takes the whole screen; Escape
closes it and focus returns to the button. The pointer's motion stops
under prefers-reduced-motion.

All of its text is one new catalogue area, 'mapInfo', in all eleven
locales: the component's own words, and each map's lead, takeaway and
note as mapInfo.tab.<tabId>.<field>. One area because a bundle ships only
the areas its source names, and the gallery that mounts a popup per map
names none of the maps' own areas. This commit carries the UPG-100
map's two sentences; the other maps' follow.
2026-09-29 19:08:02 +00:00
Doxa Maps
b33d970cd4 The gallery's tab keys live in mapInfo only, so the gallery bundles that one area
A key in a map's own area either renders blank in the gallery or, named literally, pulls that map's
whole catalogue into the gallery bundle (internal/i18n-areas.mjs). Measured with areasForBundle:
development's doxa-maps-spa carries buttons, grid, messages; this branch carries buttons, grid,
mapInfo, messages, and no upgMap. The UPG-100 entry reads mapInfo.tab.upg-100.lead and .takeaway,
which upg100 adds with every tab's strings.
2026-09-29 19:05:52 +00:00
Doxa Maps
32cf3f2354 Merge remote-tracking branch 'origin/development' into exp-shepherd/simple-map-embed 2026-09-29 19:02:39 +00:00
Doxa Maps
462c0babf7 Each gallery tab can explain itself: the MapInfo button, per tab, from src/tabInfo.js
The library MapInfo (an info button, a one-time pointer and a popup of real, pre-generated output)
is mounted in each pane whose tab has an entry in src/tabInfo.js, with the gallery's live locale and
its assets base. UPG-100 is the first entry, with its poster; its packet pages and card deck join
when their files are in the tree, because a missing file would show "not available" to the audience.
Regions and the other tabs follow as their owners' keys land. profile-config info:false removes the
buttons.
2026-09-29 19:00:06 +00:00
Doxa Maps
2a7a0d88e3 Merge upg100/map-info (MapInfo) into studio/deep-research, to mount it per tab 2026-09-29 18:57:42 +00:00
Doxa Maps
2ee03f3f64 Rebuild doxa-simple-map (the tablist bar) 2026-09-29 18:57:37 +00:00
Doxa Maps
76f35d8ccd Merge origin/development into studio/deep-research 2026-09-29 18:57:33 +00:00
Doxa Maps
a85afc8b71 Prayer Progress: a multi-tab bar is a tablist, and says which tab is selected
The research page now gives this map three tabs (engagement, prayer,
adoption). With two or more tabs the bar was a row of plain buttons: a screen
reader heard three buttons, with nothing saying they are tabs or which one is
showing. The bar is now role=tablist, each button is role=tab with
aria-selected, and the buttons are type=button. A one-tab instance shows no
bar, so it is unchanged.
2026-09-29 18:56:53 +00:00
Doxa Maps
a2809b31fc Merge origin/development into studio/hygiene 2026-09-29 18:52:35 +00:00
Doxa Maps
5224e6c4d0 Merge remote-tracking branch 'origin/development' into upg100/map-info 2026-09-29 18:52:29 +00:00
Doxa Maps
baf47f2279 Rebuild my-upg-100-list for the two new upgMap strings, and regenerate the tree 2026-09-29 18:52:23 +00:00
Doxa Maps
f293cf7e99 A map explains itself: an info button, a one-time pointer and an example popup
MapInfo (library/components/info) answers "what can this map do for
you?" with real output the map makes, pre-generated so it opens at once.
The examples are an ordered list of kinds rather than a fixed set,
because maps make different things: an image (a poster), pages (a packet
that shows its first page and expands to every page), a deck (cards that
expand from a stack to a grid) and a table (a real excerpt of the
spreadsheet a map exports, with translatable headers).

The pointer at the button goes for good once that map's popup has been
opened and closed; a checkbox in the popup turns it off on every map.
Both are kept in localStorage behind a guard, so private browsing cannot
break the page. On a phone the popup takes the whole screen; Escape
closes it and focus returns to the button. The pointer's motion stops
under prefers-reduced-motion.

Its own words are a new 'mapInfo' area in all eleven locales. Each map's
lead, takeaway and note arrive as keys in that map's own area, resolved
at render so a live language switch re-translates them; the UPG-100
map's two sentences are added to upgMap in all eleven locales.
2026-09-29 18:50:57 +00:00
Doxa Maps
b33b51f874 Rebuild doxa-maps-spa for the language remount, and regenerate the tree 2026-09-29 18:50:47 +00:00
Doxa Maps
f054b487cf A live language switch remounts the gallery's tab, instead of re-setting its attribute
The gallery re-drove the visible tab by re-setting its profile-config, which works only for a map
that re-reads its whole config live. Two production maps do not: Big Picture resolves its tStatic
strings once (2 of 352 changed on en to ar, measured) and Simple Research copies its config into its
panes once (0 of 43, 0 of 105). A fresh element reads the new locale at mount, so the visible tab is
now rebuilt in the new language whatever the map does inside, the way a provider change rebuilds.
View state is lost on a language switch; that is accepted.

Hidden tabs that are still mounted (a light tab stays mounted when hidden, and select() never
remounts a mounted tab) are reset too, so their next open mounts in the new language. The old comment
said they picked it up lazily; for light tabs they did not. Tabs are reset in place, keeping the slot
ref, because a light pane renders once and releaseTab's deleted ref would never come back.
2026-09-29 18:50:13 +00:00
Doxa Maps
e7962e4ef7 Merge origin/development into studio/hygiene 2026-09-29 18:47:01 +00:00
Doxa Maps
9c78a7d0c5 Merge development into gospel/stage 2026-09-29 18:46:12 +00:00
Doxa Maps
9c6347aad6 Mark resources-map production, because a production page already ships it
resources-map.meta.json carried NO stage, so the manifest defaulted it to
experimental — while doxa-maps-spa, the gallery that becomes Deep Research,
mounts it: doxa-maps-spa.meta.json composes "gospel-resources/resources-map"
and TAB_DEFS names it as the Gospel Resources tab. The record disagreed with
what ships, and the record was the part that was wrong.

WHAT THIS CHANGES: the manifest stage, and nothing a reader sees. Verified —
the diff moves one "experimental" to one "production" and ZERO sha384 hashes.
No bundle is rebuilt and no byte of any map changes.

The stricter production gates now apply to this profile and it passes them:
gates:pre 103 PASS / 0 FAIL / 1 NOT MEASURED of 104. That is the part worth
having, because marking something production is only honest if it then has to
meet the production bar.

NOT a decision about which profile the Deep Research page SHOULD show.
gospel-dashboard is the production composite and remains the better end state;
it is not switched to today because its .gd-map is sized 80svh — a viewport
unit inside a pane that is not the viewport — which against rega's measured
panes gives the map 91% of the pane at 1440x900 and 95% at 390x844, and
because it has never been shot inside the gallery. That fix is written and
held local for after the deadline.
2026-09-29 18:42:06 +00:00
Doxa Maps
4e7dca46ae Rebuild doxa-research-map for the packet fix, drop the regions-look preview page, and regenerate the tree 2026-09-29 18:41:55 +00:00
Doxa Maps
7d816f5eab Four more gates:post reds, hidden until a failed gate printed why
- research-map.vue's openPacket read and wrote _packetBusy, a name 8ab3dc0f5 replaced with the
  reactive packetBusy ref. Reading an undeclared name throws, so the packet export threw a
  ReferenceError on every click, in doxa-research-map and in research-map-plus-grid, the production
  map that compiles it. It uses packetBusy.value now (check:no-free-identifiers).
- check:list-prop-unit and check:optional-t-equivalence read every entry of library/i18n/locales as
  a locale, and the folder has held a README.md since bba33e783. They read locale FOLDERS now.
- people-groups-grid's regions-look instance previewed two props (filters-toggle, backdrop) of a grid
  merge that is not on development, so the page showed nothing different and
  check:instance-config-keys failed. It returns with that merge.
2026-09-29 18:40:27 +00:00
Doxa Maps
10be43d2b1 README: a vibe-coder section (Studio, build, embed) and an agent section (what this repo is for)
For vibe coders: run the Plugin Studio, build one map or all of them (and the automatic copy into a sibling
DX Life site), and embed a map: every map's own embed.script in manifest.json, loaded from DX Life's
public/dx-maps. For agents: the repo builds mobilization maps, and each goal (reach a city, mobilize for
people groups, plan outreach, prayer packets and resources) is mapped to the production maps that serve
it, with the skill, the plugin rules, the landing rules and the freeze on experimental maps.
2026-09-29 18:39:36 +00:00
Doxa Maps
2a4c3ddb3d The full build also copies the maps into the sibling DX Life site, when it is there
`bun run build` now ends with `sync-dropin --from-config --if-present`. It copies public/dx-maps into the
ONE configured host path (vite.doxa-maps-build-config.json dropin.dest, default ../doxa-life/public, or
DOXA_DROPIN_DEST). No site at that path: it prints "skipped" and exits 0. Nothing else on the filesystem
is searched for repos or sites. DOXA_DROPIN=off skips it even when the site is there. Without
--if-present, a missing host is still an error, as before.
Tested: no host skips (exit 0); a host gets 1,209 files; DOXA_DROPIN=off copies nothing; the plain
command still refuses a missing host. The container's /cdn build (build-cdn.sh) does not run this chain.

On this box ../doxa-life does not exist beside the doxa-maps checkouts (DX Life lives in root-dx-life), so the step is a no-op for the fleet's builds.
2026-09-29 18:39:36 +00:00
Doxa Maps
ec2146958e Rebuild doxa-maps-spa for Deep Research, and regenerate the tree 2026-09-29 18:38:13 +00:00
Doxa Maps
b435a7a548 The gallery is Deep Research, and a host can hide its Experimental folder
DX Life publishes the gallery shell on a hidden page named Deep Research, so that is now the
default heading (profile-config.heading or the heading prop still override it), and the meta,
instance and demo page say the same.

profile-config experimental:false (or "hidden") hides the Experimental folder: the manifest is not
mined for experimental tabs, the folder has no rows, and a tab= request for one falls back to the
first visible tab. It is off only on request, so every other host keeps the folder as before.
2026-09-29 18:37:12 +00:00
Doxa Maps
cc65f40c1e Gate hygiene: three gates:post reds on development, and two things that hid failures
- check:no-orphan-gates stopped at internal/check-grid-merge-defaults.mjs, which had no script. It
  asserts defaults of three grid props that are not on development (the grid merge has not landed),
  so it is registered ON DEMAND with that reason, not chained red. Past that first arm, its chain arm
  found check:grid-image-loading and check:retry-fetch run by no chain; both depend only on code and
  pass in under 300 ms, so they join gates:pre.
- A tracked vite.config.js.timestamp-*.mjs (395 KB, eight absolute paths) failed check:no-abs-paths.
  Removed, and ignored at the source: vite writes one beside its config while it bundles it.
- check:library-index: documentation/reference-library-index.md regenerated for retryFetch.js.
- run-parallel printed a failed step's output only with --verbose: the unbraced else bound to the
  inner if. Braced; a failing step now prints why.
- The Pages workflow ran bun run build without BUILD_ALLOW=1, so build-lock refused it with exit 75
  and the workflow ran no gate at all. A CI runner is the only builder on its machine; it opts in.
2026-09-29 18:35:37 +00:00
Doxa Maps
9ccec24d29 Generalise the pane re-forward to attribute-configured panes, and gate it
sr asked to adopt usePaneConfig for research-map-plus-grid rather than write a
second fix, and found the one shape it did not cover: people-groups-grid takes
its filters as THREE separate attributes (wagf-region, religion-family,
primary-language) instead of one profile-config blob, so that composite has one
pane of each kind. The helper hardcoded 'profile-config' and gave the grid
nothing.

registerAttrs is the sibling for that shape. It shares the same entries list,
the same watchEffect, the same prune and the same write-only-on-change -- one
mechanism for all four composites rather than a fork per adopter. A helper with
a single caller has not been shown to generalise at all; this is the second
shape that showed it.

Two decisions worth recording. Each attribute is compared and written
independently, so a getter whose region changed does not rewrite the two that
did not and re-trigger the child. And the attribute NAME LIST is pinned at
registration: a later getter that omits a key CLEARS that attribute rather than
leaving a stale filter silently narrowing the grid, which is the same class of
lie as the frozen config this helper exists to fix.

The gate runs the shipped helper with real Vue, not a re-typed copy, because the
dependency-tracking hole found in review is invisible to any test that fakes
reactivity. 28 cases over both shapes. Its subject is the measurement on
development 92ca8b6e6: the outer element reached locale ar by +1.5s while every
nested host carried NO locale key at boot and still none at +15s, across four
composites -- so case 1b asserts that an ABSENT key is still a change.

Case 7 is the adopter's property rather than mine: a re-forward triggered by a
LOCALE change must produce the SAME primary-language string. gridLanguage() can
fall back to a display label, and the grid compares whole normalised values, so
a name fetched in one language matches no row in another. It does not bite today
because the surviving fallback is a value the grid itself produced, but the gate
asserts the class, not today's instance.

Mutation-tested, 7 mutations, all caught: plain array, no write-on-change guard,
skip-instead-of-prune, escaping getter throw, no per-attribute compare, omitted
key left stale, and the label-instead-of-code regression. The first two crashed
rather than naming a case, so cfgOf is null-safe now -- a gate that dies reports
"something went wrong" instead of naming the pane that stopped following.

Registered in package.json scripts and in gates:pre, verified by re-parsing the
file: one key, 104 checks. gates:pre PASS 103 FAIL 0 NM 1.
2026-09-29 18:34:49 +00:00
Doxa Maps
feb75f0f44 Merge remote-tracking branch 'origin/development' into upg100/shadow-labels 2026-09-29 17:42:58 +00:00
Doxa Maps
83fa4da4f4 Drop the region-paint gate's on-demand entry now that it is chained
The entry was marked temporary, to be deleted when the gate joined
gates:post. 6a1860539 chained it; the entry stayed behind.
2026-09-29 17:42:45 +00:00
Doxa Maps
99816626af Every shadow stylesheet gets its own label, and a gate keeps it that way
useShadowStyles keys its <style> by the label and overwrites an existing
tag with the same key, so two components sharing a label keep only the
last one's CSS in a shared shadow root. The regions list lost its sheet
this way to the region card, which had kept the list's label when it was
extracted.

check:shadow-style-labels-unique (gates:pre) fails any label two calls
share, globally rather than per shadow root, so a copied or forked
component is caught when it is copied. It reads the real parsers,
classifies every reference to the function (a rebinding, .call, a
re-export or a namespace import fails instead of hiding a call),
cross-checks the AST against the token stream, and covers the other
ways two calls share a key: unlabelled calls under the dev server's
per-component key, and a fixed label over CSS that varies per caller.

countries-map.vue, a fork of research-map.vue, carried the same label;
it is now 'countries-map', with the country-posters bundle rebuilt and
the tree regenerated. The composable's JSDoc called the label a
debugging name; it now says it is the key.
2026-09-29 17:42:44 +00:00
Doxa Maps
62a41859c9 Guard the helper's unmount hook, and give a non-setup caller a way to dispose
onBeforeUnmount only binds inside setup(). Calling usePaneConfig anywhere else
produced a Vue warning and, worse, no automatic cleanup -- the watchEffect would
outlive its caller. Found while re-running studio's own two-pane falsifier
locally: the test constructs the helper in an effectScope with no component
instance, and Vue said so.

regions-mfe is unaffected either way, because it calls the helper at <script
setup> top level where the hook is valid. The hazard is for the next adopter.

Guarded with `if (getCurrentInstance())`, the pattern useMapData.js:144 already
uses, and `dispose` is now returned so a caller outside setup has something to
call rather than silently leaking the effect.

Studio's falsifier still passes after the change: registering two panes that read
different refs and changing only pane 2's source writes pane 2 and leaves pane 1
untouched.
2026-09-29 17:36:42 +00:00
Doxa Maps
6493872170 Track every pane's getter, prune detached ones, and say when one throws
Studio's 5B review found a dependency-tracking hole by testing the helper with
real Vue rather than reading it. entries was a plain array, so the watchEffect
tracked only what the FIRST registered getter read: with two panes reading
different refs, changing pane 2's source produced ZERO writes, and pane 2 caught
up only when pane 1's source happened to change. That is this helper's own bug
reappearing for any adopter whose panes read different sources. regions-mfe is
safe today because every getter reads the same cfg and spec -- which is exactly
why a reading could not find it.

entries is now shallowReactive, so register() re-runs the effect and every
getter is tracked. Also from the review:
  - stale entries are PRUNED, not skipped: an adopter that rebuilds its pane
    column would otherwise keep detached elements and re-run their getters on
    every pass forever;
  - a getter that throws is reported once per entry instead of being swallowed,
    since silence recreates the symptom this helper exists to fix;
  - the unused `tag` parameter is gone -- a documented check that does not exist
    misleads the next adopter;
  - the host argument now documents that it must be in the SAME tree as the
    panes, because Element.contains() does not cross a shadow boundary and
    passing the custom element would silently skip every write.

regions-dashboard rebuilt so public/ is servable at this sha for the browser
A/B. It is the only bundle that compiles the helper.
2026-09-29 17:32:33 +00:00
Doxa Maps
89bf1feb54 A composite's panes follow the outer profile-config, instead of freezing at mount
regions-mfe built each pane by creating the child element and writing its
profile-config once, inside onMounted, and nothing rewrote it. The pane is handed
a JSON STRING rather than a reactive object, so a later change to the OUTER
element's profile-config updated the composite's own cfg and reached nothing
below it. regions-dashboard is kept alive by v-show rather than remounted, so the
one code path that would have rewritten the attribute never runs again and the
panes stay in the old language for the whole session.

The leaf was never at fault: ProfileLoader's config is a computed over its prop,
lang is a computed over config, and a watchEffect drives appI18n on every change.
Every link is reactive -- it simply never receives a new prop.

library/composables/usePaneConfig.js owns the missing half: a composite registers
each pane element with a getter for its config, and a watchEffect re-forwards
whenever any reactive source that getter reads changes. It writes only when the
serialised config actually differs, because setting profile-config re-parses it
in the child and can remount what it drives -- an unconditional write per tick
would be a rerender loop. Stale elements (a rebuilt pane column) are skipped.

It is a library helper rather than three copies because regions-mfe, upg-100-mfe
and country-posters-mfe all assemble a config and set the attribute once; they
differ only in which keys they inherit, so each keeps its own
INHERITED_PAGE_KEYS and hands the result to the helper. This commit adopts it in
regions-mfe only; the other two are upg100's to adopt.

Two-sided, headlessly: a check that fails when a composite writes profile-config
on a child without re-forwarding names all THREE composites on development, and
on this branch regions-dashboard reports "re-forwarding=usePaneConfig" while the
other two still fail.

NOT VERIFIED IN A BROWSER YET. rega's LIVEDIAG is the falsifier: the nested
[profile-config] should show the OLD locale on development and the NEW one here.
2026-09-29 17:27:25 +00:00
Doxa Maps
92ca8b6e6e Merge main (cd3fb3442): the Driver's README edits to the persona table (9201398ef, cd3fb3442), his wording kept 2026-09-29 17:23:15 +00:00
cd3fb34425 Update README.md
Some checks failed
Deploy to GitHub Pages / build (push) Has been cancelled
Deploy to GitHub Pages / deploy (push) Has been cancelled
2026-09-29 17:10:50 +00:00
9201398ef9 Update README.md
Some checks are pending
Deploy to GitHub Pages / build (push) Waiting to run
Deploy to GitHub Pages / deploy (push) Blocked by required conditions
2026-09-29 17:09:39 +00:00
Doxa Maps
b5e4be4355 Merge main (b7e71a9cb): the Driver's README edit, "The people doing the mission" becomes "The people doing the work" 2026-09-29 17:07:42 +00:00