doxa-maps/plugin-designs
Doxa Maps fd12c7eea4 Port their base line-height (1.5); our 1.1 override was compensating for its absence
THE EIGHTH GLOBAL RULE OF THEIRS FOUND MISSING, and the same class as the
box-sizing reset: _globals.scss:14 is `body { line-height: var(--line-height-normal) }`
with $line-height-normal: 1.5, and a document-level rule does not cross a shadow
boundary. dxlife-tokens.js declared every spacing and font token and NO line-height
at all, so every text element in the clone inherited whatever the EMBEDDING PAGE
set, while theirs is deterministically 1.5.

.rd-big carried line-height:1.1 to compensate. At --font-size-4xl (59.6046px) that
is a 65.6px line box against their 89.4px — a 23.8px difference. rega measured the
consequence to the pixel: our goal cards were 24px shorter than theirs (571 vs 595),
their big number sitting ~12px lower and its label ~24px lower, the extra leading
splitting roughly half above and half below the glyphs. Theirs is
`<p class="font-size-4xl font-weight-medium">` and the .font-size-4xl utility sets
ONLY a font-size, so their number simply inherits body's 1.5.

So :host now carries their line-height and its tokens, and .rd-big's override is
gone. Their own tighter cases stay explicit and already agreed: .region-stat__value
is line-height:1 and so is our .rd-stat__value.

★ I APPLIED THIS HALF-WAY FIRST. The :host patch failed on a string mismatch while
the .rd-big patch succeeded, which left the number's line box inheriting from the
HOST PAGE — worse than the wrong-but-deterministic 1.1 it replaced. Caught because
the two patches reported separately instead of as one result.

CORRECTION TO 9009dd62, owed and measured against me: that commit claimed our goal
line "floated at three different heights" where theirs bottom-aligned. rega measured
both sides — the goal line sits 42px above the card's bottom edge on BOTH, in all
three cards, with identical gaps to the element above (0 / 73 / 120px). So margin:0
already reproduced their margin-top:auto at 1440, and the visible defect I described
did not exist. The change stands as a verbatim port of their declaration (RULE 1),
and it matters only where a card has free space — but I asserted a consequence I had
not measured, and the measurement says otherwise.

STILL DIFFERENT, reported not changed: their .font-size-4xl utility is
`clamp(var(--font-size-2xl), 6vw, var(--font-size-4xl))` where ours is a flat
var(--font-size-4xl). Identical at 1440, divergent below — at 768 theirs is 46.08px
and ours stays 59.6px. It interacts with the documented nowrap decision (a figure
must never split across lines in a 372px card), so it goes out for measurement
rather than into this commit.

Drawn verification is rega's: card heights 571 -> 595 and the two gaps around the
big number. A base line-height touches every text element in the element, and I
cannot measure layout headlessly.
2026-09-26 05:33:12 +00:00
..
all-people-groups All People Groups loads fast on a light map; the Vision Card becomes a true funnel from data 2026-09-25 07:18:30 +00:00
big-picture Translate the eight strings that had no catalogue entry, keeping their English exactly 2026-09-26 03:34:42 +00:00
cities-internet Cities list + tables: keep numbers in their previous format while numerals are held 2026-09-26 02:38:06 +00:00
country-posters "Show on map" switched the view and the map never acted: retain the request 2026-09-26 04:21:49 +00:00
dashboard-plus-grid Big Picture and Simple Research mount again: import the three locale names they use 2026-09-26 03:02:46 +00:00
demo-map Move internal files out of the repo; fix five dead links; a fuller delegation diagram 2026-09-25 05:14:10 +00:00
doxa-maps-spa Research Gallery: PPLR Data Maps and Wall of People Groups are named in all 11 languages 2026-09-25 23:41:17 +00:00
doxa-research-map The map follows the list: filter the grid and the camera goes there 2026-09-25 23:28:53 +00:00
doxa-simple-map Prayer Progress: no hardcoded English left in the map's own chrome 2026-09-26 03:34:16 +00:00
doxa-vision-card Doxa Vision Card: take the page language from profile-config lang as well as locale 2026-09-26 01:10:51 +00:00
golden-path-check golden-path-check: walk the develop-a-plugin-and-see-it-live path end to end 2026-09-22 03:55:18 +00:00
gospel-resources Gospel map: give the zero-access view an address, and say the way in on every row 2026-09-26 03:56:24 +00:00
key-cities Key Cities (gated): the map, list, tables and posters speak the reader's language 2026-09-26 03:34:30 +00:00
my-upg-100-list The prayer packet shows how its list was narrowed out of all the earth 2026-09-26 04:38:59 +00:00
people-groups-grid Match the live page's wording where we differed only by case 2026-09-25 17:08:16 +00:00
plugin-studio Plugin Studio: collapse the header to give the plugin the whole page, and bring it back in one click 2026-09-26 04:39:00 +00:00
pplr-data-maps PPLR data maps: loading d3 no longer writes into the host page's own d3 2026-09-26 04:54:42 +00:00
prayer-walk-planner Export gate reads the tree name from the build config 2026-09-25 21:32:35 +00:00
regions-dashboard Port their base line-height (1.5); our 1.1 override was compensating for its absence 2026-09-26 05:33:12 +00:00
research-dashboard Translate the eight strings that had no catalogue entry, keeping their English exactly 2026-09-26 03:34:42 +00:00
research-map-plus-grid A gate for the mistake I shipped: a name used but never bound 2026-09-26 04:21:49 +00:00
stack-demo Studio and stack-demo hand the host's language down to what they mount 2026-09-25 13:26:01 +00:00
template-bundle template-bundle: the starter's first screen is now a real map 2026-09-26 04:38:12 +00:00
upg-neighbor My UPG Neighbors: the Language Clusters lens draws its map again 2026-09-26 04:57:47 +00:00
wall-of-people-groups Wall of People Groups: nothing leaks onto the host page (no Font Awesome, no window.d3) 2026-09-26 03:34:31 +00:00
.gitkeep Rename app-profiles -> plugin-designs; build green under new naming (load-bearing paths updated, guards pass) 2026-09-17 18:18:18 +00:00
README.md plugin-designs/README: the tree is dx-maps, and a bundle's tag is its folder name 2026-09-26 01:19:53 +00:00

plugin-designs/ — where YOUR maps live

The shared template lives in ../library/ (aliased @map) — you never edit it per-map. You build your map by making a folder here, plugin-designs/<your-map>/, and composing the template's building blocks. Your folder is yours (colors, API, i18n); the template is shared (Apache-2.0, propagated to every map on the next build).

Shared vs. yours — the balance

  library/  (@map)  ── SHARED, reusable, parameterized ──►  legend · map · map-controls
        │                                                    (every map reuses these)
        │  imported by
        ▼
  plugin-designs/<your-map>/  ── YOURS ──►  the map's "main" class (the .vue profile = the Vue
        │                                  instance for that map)
        └── src/            ── YOURS ──►  this map's OWN non-reusable components, colors, API, utils

  One bundle can hold as many maps as you want — add another .vue profile and rebuild.
  • Reusable → library/. The legend, the map, the map-controls are shared, parameterized components every map reuses. Fix once, every map benefits. Never edit it to customize one map.
  • This map's own → plugin-designs/<your-map>/. It holds two things: the map's "main" class (each .vue profile is the Vue instance for that map) and that map's own non-reusable components (in src/). Nothing here leaks to another map.
  • Many maps per bundle. The bundler bundles one map or many — add another flat .vue and rebuild.

Production or experimental — every profile declares itself

Every app profile is one of two things, and experimental profiles are unlimited and encouraged — create as many as you need:

  • Experimental, not built: prefix the folder with _ — the build skips it; it just sits in code. Zero cost, zero risk.
  • Experimental, built: builds normally, but it belongs in the Experimental section of the power app's layout (nav section) — never embedded on partner surfaces.
  • Production: a real product — main sections of the power app + individually embeddable.

(The power app = the SPA layout that composes all profiles into one application.)

The pattern in one picture

plugin-designs/<your-map>/     ← one FOLDER = one BUNDLE, named after the folder
   ├── index.js               ← entry: registers the custom element, finds the profiles
   ├── overview.vue           ← one .vue = one PROFILE (flat in the folder — no profiles/ subfolder)
   └── detail.vue             ← another profile in the SAME bundle

     builds to ─────────────► public/dx-maps/<your-map>/<your-map>.js   (one file)
  • Folder name = bundle name. Folders starting with _ or . are skipped (handy for WIP).
  • Each .vue = one profile (one map screen). One bundle can hold many.
  • Pick the profile at embed time with the profile field — every profile shares one bundle:
<script src="/dx-maps/<your-map>/<your-map>.js"></script>
<your-map profile-config='{"profile":"overview","tk":"pk.eyJ..."}'></your-map>
<your-map profile-config='{"profile":"detail","tk":"pk.eyJ..."}'></your-map>

Add a map — three steps

# 1. create the folder + one profile
mkdir -p plugin-designs/<your-map>
#    index.js   ← copy doxa-simple-map/index.js, rename the tag
#    <name>.vue ← your screen, built from @map/* blocks (flat in the folder)

# 2. build
npm run build            # → public/dx-maps/<your-map>/<your-map>.js
#    (just this one:  BUNDLE=<your-map> npm run build:bundle)

# 3. embed the script tag + element (dev staging at `npm run dev` shows a paste-ready snippet)

Your three things (everything else is shared)

  • Colors — how pins are colored. Pick one the template ships (getColorStrategy('language-family')), or drop your own in plugin-designs/<your-map>/src/colors/ (start from template-bundle/src/colors/example-mode.js). Never edit @map/colors/ to recolor your map.
  • API — your map reads its data from the profile-config on the page, so the same bundle points at different data with no rebuild. DataSourceManager accepts csv (bundled file), api (one JSON URL), or rest-api (a live REST endpoint, the default). Prefer the real API over inlined JSON.
  • i18n — the template ships 11 base locales in @map/i18n/locales/. Use useI18n() for strings and RTL_LOCALES for right-to-left; add or override strings from your own profile.

The one hosting variable

The only thing that changes between hosting modes is the <script src>: a relative path when your own site serves the file, or an absolute CDN URL when a partner site serves it. The bundle is identical either way. See ../documentation/CONTRIBUTING.md for the two CDN modes and partner-site embedding.

Profile patterns (mix freely)

  • Individual — one .vue per bundle (simplest).
  • Parameterized — one profile, behavior driven by profile-config props (e.g. tabs[]).
  • Nested — one profile that renders others (workbench-style, like doxa-research-map).

See also

  • doxa-simple-map/index.js — fully commented reference bundle entry
  • template-bundle/ — minimal two-profile skeleton to copy
  • ../library/colors/README.md — the color-strategy contract
  • ../README.md — repo overview & build pipeline · ../documentation/CONTRIBUTING.md — build vs dev, CDN modes