diff --git a/plugin-designs/gospel-internet/board.vue b/plugin-designs/gospel-internet/board.vue index fa67bff25..dd96633be 100644 --- a/plugin-designs/gospel-internet/board.vue +++ b/plugin-designs/gospel-internet/board.vue @@ -188,7 +188,7 @@ useShadowStyles( 'grid-template-columns:var(--facet-w,264px) minmax(0,1fr) var(--rail-w,360px);' + 'grid-template-rows:auto auto auto minmax(0,1fr) var(--table-h,38%);' + // The charts rail runs the full height beside the map AND the table: sized to the map row alone it was - // ~300px and clipped its four charts (rega: the charts did not look good). + // ~300px and clipped its four charts. 'grid-template-areas:"top top top" "combos combos combos" "note note note" "facets map rail" "facets grid rail";' + 'font:13px/1.35 Roboto,-apple-system,"Segoe UI",sans-serif;overflow:hidden}' + '.gb-top{grid-area:top;display:flex;align-items:center;flex-wrap:wrap;gap:10px 16px;padding:10px 14px;background:#fff;border-bottom:1px solid #d1d4cd}' + diff --git a/plugin-designs/gospel-internet/scripts/build-gospel-internet.mjs b/plugin-designs/gospel-internet/scripts/build-gospel-internet.mjs index 274fe10e3..24f9a63fb 100644 --- a/plugin-designs/gospel-internet/scripts/build-gospel-internet.mjs +++ b/plugin-designs/gospel-internet/scripts/build-gospel-internet.mjs @@ -9,7 +9,7 @@ * data/tables/doxa-people-groups.json (gospel-plugin) slug, lat/lng, pray link * data/tables/country-connectivity.json (World Bank) internet %, year, mobile per 100 * data/tables/internet-by-country.json (cities-internet) top platform - * data/tables/internet-by-adm1.json (exp-shepherd) India by state, NFHS-5 + * data/tables/internet-by-adm1.json (cities-internet) India by state, NFHS-5 * data/tables/messaging-channels.json (cities-internet) top free apps per country (Apple, iOS only) * data/tables/social-platforms.json (cities-internet) social referral share per country (StatCounter) * data/tables/gospel-by-province-groups.json (gospel-plugin) each IND/CHN group's province (approximate) diff --git a/plugin-designs/gospel-internet/scripts/check-gospel-internet-render.mjs b/plugin-designs/gospel-internet/scripts/check-gospel-internet-render.mjs index d2dd3ae40..1dc993f94 100644 --- a/plugin-designs/gospel-internet/scripts/check-gospel-internet-render.mjs +++ b/plugin-designs/gospel-internet/scripts/check-gospel-internet-render.mjs @@ -7,7 +7,7 @@ * This one server-renders them (Vue's renderer, through vite's module loader, no browser, no WebGL): * every panel's setup, computeds and template run against the real table, tree and resources, and the * HTML is asserted on CONTENT the panel must show, never on the panel's own count of itself. - * onMounted does not run under SSR, so map layers are not covered here; that is the browser's (rega's). + * onMounted does not run under SSR, so map layers are not covered here; that is the browser check's job. * * `--poison` blanks the rows handed to the panels and requires the content assertions to FAIL. * Exit 0 pass · 1 fail · 75 not measured (vite could not load the modules). diff --git a/plugin-designs/gospel-internet/scripts/fetch-translation-readiness.mjs b/plugin-designs/gospel-internet/scripts/fetch-translation-readiness.mjs index 77e0f3ed2..d210abd17 100644 --- a/plugin-designs/gospel-internet/scripts/fetch-translation-readiness.mjs +++ b/plugin-designs/gospel-internet/scripts/fetch-translation-readiness.mjs @@ -13,7 +13,7 @@ * (Partial Scripture comes from eBible's index, already in data/tables, and is read by the builder.) * * Codes are mapped EXPLICITLY and every code that cannot be mapped is COUNTED and listed, never dropped - * silently (dx-shepherd's guard 3). + * silently. * Writes data/translation-readiness/snapshot.json. Refuses a much smaller snapshot than the last one. */ import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'node:fs' diff --git a/plugin-designs/gospel-internet/src/components/GiBoundedSetMap.vue b/plugin-designs/gospel-internet/src/components/GiBoundedSetMap.vue index 72af5e0ba..12457113c 100644 --- a/plugin-designs/gospel-internet/src/components/GiBoundedSetMap.vue +++ b/plugin-designs/gospel-internet/src/components/GiBoundedSetMap.vue @@ -44,7 +44,7 @@ const R = 120, SPREAD = 260 // ★ 0.095, NOT THE 0.17 DEFAULT — the same clamp as the centered chart, and the same number so the // two sets read at one scale. renderWorldCopies:false stops the engine zooming out past // log2(canvasWidth/512), so a wide, short figure cannot fit its height at 0.17 and the outermost -// groups fall outside the frame (rega, 1440: 54 outside in ar and 97 in en — the width, not RTL). +// groups fall outside the frame (measured at 1440: 54 outside in ar and 97 in en — the width, not RTL). // Kept EQUAL to GiCenteredSetMap's on purpose: a reader switching tabs compares two drawings, and a // different footprint per tab would make the same population look like a different size. const EXTENT_FRACTION = 0.095 diff --git a/plugin-designs/gospel-internet/src/components/GiCenteredSet.vue b/plugin-designs/gospel-internet/src/components/GiCenteredSet.vue index 6dacd7a40..1516589b7 100644 --- a/plugin-designs/gospel-internet/src/components/GiCenteredSet.vue +++ b/plugin-designs/gospel-internet/src/components/GiCenteredSet.vue @@ -134,7 +134,7 @@ const fmt = (n) => formatCount(Number(n) || 0) useShadowStyles( // ROW, NOT COLUMN, and overflow hidden. Stacked in a centred column the legend — a 360px card // with a 3x3 grid of 44px cells and four footer lines — is taller than the pane on its own, so - // the chart was pushed out of view entirely and the whole panel overflowed its host: rega saw + // the chart was pushed out of view entirely and the whole panel overflowed its host: it showed // the legend covering the row below and the caption drawn over the page tabs. // Every child gets min-height/min-width 0, because a flex item's default minimum is its CONTENT // size — without it an item never shrinks below its natural height and the container overflows @@ -148,10 +148,10 @@ useShadowStyles( // had this; the centered one did not, which is the kind of difference two files drift into // when the same rule is written twice. // min-height in the narrow column: a flex child with auto content can resolve to zero height, - // which is what a 0x0 chart is. rega measured exactly that at 390px. + // which is what a 0x0 chart is, as measured at 390px. // flex-basis 0, not auto. The map inside is position:absolute, so the figure has NO intrinsic // width to be sized from — with basis auto it asks for its content, the content is nothing, and - // the legend beside it takes the column. rega measured the figure at 39px across while the + // the legend beside it takes the column. The figure measured 39px across while the // decoder card had the rest. Growing from zero makes the figure take the remaining space // whatever it happens to contain. // min-width is a FLOOR, not 0. The shipped CSS was right and the figure was still 39px wide: diff --git a/plugin-designs/gospel-internet/src/components/GiCenteredSetMap.vue b/plugin-designs/gospel-internet/src/components/GiCenteredSetMap.vue index 813fa0faa..b0618c9ce 100644 --- a/plugin-designs/gospel-internet/src/components/GiCenteredSetMap.vue +++ b/plugin-designs/gospel-internet/src/components/GiCenteredSetMap.vue @@ -52,7 +52,7 @@ const EXTENT = 30 + (RING_MAX - 1) * 22 // 228 — the ring the outermo // ★ 0.095, NOT THE 0.17 DEFAULT. With renderWorldCopies:false the engine will not zoom out past the // point where ONE WORLD fills the canvas WIDTH, so the minimum zoom is log2(canvasWidth/512) and a // wide, short figure is clamped too close to fit its own height. minZoom is irrelevant; the width -// constraint wins. rega measured the symptom at 1440 — 54 groups outside the frame in ar, 97 in en, +// constraint wins. The symptom measured at 1440 — 54 groups outside the frame in ar, 97 in en, // so it was never RTL-specific. At 0.17 the drawing spans 0.34 of the Mercator square and needs // 271px of vertical room where the canvas offers 249; at 0.095 it spans 0.17 and needs 151px // against 169 available at padding 40. Checked by check:gospel-set-fit. diff --git a/plugin-designs/gospel-internet/src/components/GiCharts.vue b/plugin-designs/gospel-internet/src/components/GiCharts.vue index 8930b86fd..878a9e585 100644 --- a/plugin-designs/gospel-internet/src/components/GiCharts.vue +++ b/plugin-designs/gospel-internet/src/components/GiCharts.vue @@ -85,7 +85,7 @@ function onBar(row) { useShadowStyles( '.gic{display:flex;flex-direction:column;gap:4px;height:100%;overflow-y:auto;box-sizing:border-box;padding:10px 12px 16px;background:#fff;color:#3b463d;font:13px/1.35 Roboto,-apple-system,"Segoe UI",sans-serif;scrollbar-width:thin}' + // A flex column's children SHRINK by default: inside this scroll box they were squeezed instead of - // scrolled, so the measure toggle collapsed to a 2px line and a caveat card was cut in half (rega). + // scrolled, so the measure toggle collapsed to a 2px line and a caveat card was cut in half. '.gic > *{flex-shrink:0}' + '.gic-seg{align-self:flex-start;display:inline-flex;border:1px solid #d1d4cd;border-radius:6px;overflow:hidden;margin-bottom:4px}' + '.gic-seg button{font:inherit;font-size:12px;padding:4px 12px;min-height:26px;border:0;background:#fff;color:#3b463d;cursor:pointer}' + diff --git a/plugin-designs/gospel-internet/src/components/GiCombos.vue b/plugin-designs/gospel-internet/src/components/GiCombos.vue index 69b8fc8b0..4abcb6cde 100644 --- a/plugin-designs/gospel-internet/src/components/GiCombos.vue +++ b/plugin-designs/gospel-internet/src/components/GiCombos.vue @@ -116,7 +116,7 @@ useShadowStyles( '.gic2{grid-area:combos;display:flex;align-items:center;gap:10px;padding:6px 14px;background:#fff;border-bottom:1px solid #d1d4cd;' + 'min-width:0;font:12.5px/1.3 Roboto,-apple-system,"Segoe UI",sans-serif;color:#3b463d}' + '.gic2-h{flex:none;font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.03em;color:#6d766e}' + - // The selection side is BOUNDED at 40% (rega r82: the placeholder ran under "Try a combination"), but only + // The selection side is BOUNDED at 40% (the placeholder ran under "Try a combination"), but only // its chips and placeholder clip: they scroll or ellipsize. No overflow here and no min-width:0, so the // flex:none label sets the minimum width and is never cut ('YOUR S…' at 390, the zh/ru/hi/ar labels at 1280). '.gic2-sel{display:flex;align-items:center;gap:6px;flex:0 1 auto;max-width:40%}' + diff --git a/plugin-designs/gospel-internet/src/components/GiGrid.vue b/plugin-designs/gospel-internet/src/components/GiGrid.vue index 59bedc834..bbfbea2e3 100644 --- a/plugin-designs/gospel-internet/src/components/GiGrid.vue +++ b/plugin-designs/gospel-internet/src/components/GiGrid.vue @@ -215,7 +215,7 @@ useShadowStyles( @click="board.openGroup(r.slug)" @keydown="onRowKey($event, r)" @mouseenter="bus.setHover(r.slug)" @mouseleave="bus.setHover(null)">
- +
diff --git a/plugin-designs/gospel-internet/src/components/GiMap.vue b/plugin-designs/gospel-internet/src/components/GiMap.vue index 7f3175b33..3948ad1c5 100644 --- a/plugin-designs/gospel-internet/src/components/GiMap.vue +++ b/plugin-designs/gospel-internet/src/components/GiMap.vue @@ -363,7 +363,7 @@ useShadowStyles( 'background:rgba(255,255,255,.96);color:#3b463d;border:1px solid #d1d4cd;border-radius:10px;padding:8px 10px;' + 'font:12px/1.4 Roboto,-apple-system,"Segoe UI",sans-serif;box-shadow:0 2px 10px rgba(0,0,0,.10)}' + '.gim-lh{display:flex;align-items:center;gap:8px;font-weight:600;font-size:12px;margin-bottom:4px}' + - // a real 28px tap target (WCAG 2.5.8 wants 24): the glyph alone measured 16px (rega r75) + // a real 28px tap target (WCAG 2.5.8 wants 24): the glyph alone measured 16px '.gim-lh button{margin-inline-start:auto;border:0;background:none;color:#6d766e;cursor:pointer;font:inherit;display:inline-grid;place-items:center;width:28px;height:28px;padding:0;flex:none}' + '.gim-keys{display:flex;flex-wrap:wrap;gap:3px 10px;margin-bottom:6px}' + '.gim-key{display:inline-flex;align-items:center;gap:5px;font-size:11px}' + diff --git a/plugin-designs/gospel-internet/src/model.js b/plugin-designs/gospel-internet/src/model.js index 2144076ce..4bc27e24a 100644 --- a/plugin-designs/gospel-internet/src/model.js +++ b/plugin-designs/gospel-internet/src/model.js @@ -88,7 +88,7 @@ export const SHARE_FACETS = Object.fromEntries(Object.entries(URL_KEYS)) // MAP STATE: what a link written while the map was the default carries and only the map shows (an open or // selected people group's pin, a country or province, the province view). Such a link with no ?panel= opens -// the MAP, so old map links keep working; a bare link opens the tree (dx-shepherd ENDTOKEN-GOINT-ATTR). +// the MAP, so old map links keep working; a bare link opens the tree. const MAP_STATE = ['group', 'groups', 'country', 'province'] export const hasMapState = (q) => MAP_STATE.some((k) => q.get(k)) || q.get('view') === 'province' diff --git a/plugin-designs/gospel-internet/src/useBoard.js b/plugin-designs/gospel-internet/src/useBoard.js index 4621f5661..aae6816df 100644 --- a/plugin-designs/gospel-internet/src/useBoard.js +++ b/plugin-designs/gospel-internet/src/useBoard.js @@ -73,7 +73,7 @@ export function useBoard() { const x = readiness.value.byIso.get(r.iso639_3) // The column RANKS languages WITHOUT a New Testament (the translation question): a language that has // one scored 5 (its Bible counted as Scripture) and sorted to the top, the opposite of what a - // translation team needs (rega, pre-landing T1). Blank sorts last; the drawer still shows the signals. + // translation team needs. Blank sorts last; the drawer still shows the signals. r.open_data = x && !x.nt ? x.signals : null r.open_grammar = x && x.grammar ? x.grammar : '' r.open_scripture_books = x ? x.scripture_books : null @@ -153,7 +153,7 @@ export function useBoard() { let pendingTree = '' // A ?tree= link applies only once BOTH the tree and the rows are loaded, whichever arrives last: // setTreeNode keeps the node's languages that are on the board, and with no rows yet that is the empty - // set, so the grid restored to 0 (rega F1: "6 of 2,107" before a reload, 0 after). + // set, so the grid restored to 0 ("6 of 2,107" before a reload, 0 after). function applyPendingTree() { if (!pendingTree || !tree.value || !all.value.length) return setTreeNode(pendingTree) @@ -217,7 +217,7 @@ export function useBoard() { if (!writeUrl.value || typeof history === 'undefined') return let keep = location.search // A tree node is shared as ?tree= ALONE: its language list (hundreds of codes for a big - // family) made links that break in chat apps and SMS, the field's channel (dx-shepherd GOFAM). The + // family) made links that break in chat apps and SMS, the field's channel. The // kit writes `language` from the bus; this writer runs after it (flush:'post') and removes it while a // node is active. On load, ?tree= restores the node, which re-applies its languages itself. if (treeNode.value) { const q = new URLSearchParams(keep); q.delete('language'); keep = q.toString() ? '?' + q.toString() : '' } diff --git a/plugin-designs/gospel-resources/resources-map.vue b/plugin-designs/gospel-resources/resources-map.vue index ac05b2e8b..55435fea5 100644 --- a/plugin-designs/gospel-resources/resources-map.vue +++ b/plugin-designs/gospel-resources/resources-map.vue @@ -23,11 +23,10 @@ function setGlobal(name, value) { * on a light country — that case is the point of the map, not a rendering fault. A * country Doxa does not work is left uncoloured, not drawn as covered. * - * > design note 2026-08-01: "mapping out the gospel resources is super important for me - * > … key city posters, cities with internet, gospel resources — all these are - * > missing maps." + * Why this map exists: gospel resources had no map of their own, alongside key city posters + * and cities with internet. * - * MOBILE FIRST, deliberately. The brief asked for mobile-friendliness before this + * MOBILE FIRST, deliberately. Mobile-friendliness was a requirement before this * map existed, so it is built that way rather than retrofitted: * - one WebGL context (the ~16-cap rule; this is the app's only map pane) * - tap-to-select with a bottom SHEET, not a hover popup — hover does not exist @@ -461,12 +460,11 @@ const cardShard = (slug) => { const sxScope = (sx) => { if (!sx) return '' const n = Number(sx.parts) || 0 - /* ⚠ THE WORDS ALREADY EXISTED, TRANSLATED, and I asked for new keys without looking. rega found - gospel.charts.newTestament and gospel.charts.fullBible in all 11 locales — used by the charts - leaf — while my gospel.res.* existed nowhere, so every locale including Arabic fell back to my - English defaults, and even en read "full Bible" against the catalogue's "Full Bible". Two keys - for one word is the drift I keep fixing in other people's code; these are the same words, so - they are the same keys. Only the part count needed a new one. */ + /* ⚠ THE WORDS ALREADY EXISTED, TRANSLATED. gospel.charts.newTestament and gospel.charts.fullBible + are in all 11 locales (used by the charts leaf), while the gospel.res.* keys first added here + existed nowhere, so every locale including Arabic fell back to the English defaults, and even en + read "full Bible" against the catalogue's "Full Bible". Two keys for one word is drift; these are + the same words, so they are the same keys. Only the part count needed a new one. */ const name = n === 66 ? t('gospel.charts.fullBible') : n === 27 ? t('gospel.charts.newTestament') : n ? t('gospel.res.nParts', { n: fmt(n) }) @@ -599,7 +597,7 @@ function openFromUrl() { const country = (sp.get('country') || '').trim() /* ⚠ A COUNTRY IS AN ADDRESS TOO, and it was not one: ?country=IND did nothing at all unless a ?code came with it, because country was only ever a tie-breaker between two pins sharing a - language. The brief's second requirement — click a country, see its resources — had no URL, + language. The second requirement — click a country, see its resources — had no URL, which is precisely what a partner embeds. Accepts the ISO3 or the country's own name. */ if (!code && country) { const key = country.toUpperCase() @@ -1720,7 +1718,7 @@ function openPin(i) { * positioned by no stylesheet at all. * * ONE IMPLEMENTATION, NOT TWO. This was first fixed with a local copy built on the already- - * exported engineStylesheetUrl, because nothing shared needed changing for it. exp-shepherd + * exported engineStylesheetUrl, because nothing shared needed changing for it. The library * then exported ensureEngineCSS for the same defect on connectivity-map, so this converges * onto theirs — and theirs is the better one: it also waits on a link that is PRESENT BUT * NOT YET LOADED, a case the local copy would have skipped straight past. @@ -1820,7 +1818,7 @@ onMounted(async () => { style: resolveNamedStyle(isDark.value ? 'ink' : 'paper', grProvider).style || (isDark.value ? 'mapbox://styles/mapbox/dark-v11' : 'mapbox://styles/mapbox/light-v11'), accessToken: mapboxToken.value, - /* THE ENGINE'S OWN STRINGS, IN THE READER'S LANGUAGE (rega row 34). This leaf calls + /* THE ENGINE'S OWN STRINGS, IN THE READER'S LANGUAGE. This leaf calls `new gl.Map` directly instead of going through useMapInstance, so it did not inherit the locale map the shared composable passes — "Toggle attribution" and the canvas's accessible name "Map" stayed English under ar while every string we own was Arabic. @@ -1845,7 +1843,7 @@ onMounted(async () => { /** * ═══ THE CREDIT MUST NAME THE BASEMAP THAT IS ACTUALLY DRAWN ═════════════════════════ * - * REPORTED by rega: under ?provider=maplibre this line read "geoBoundaries · Mapbox · + * Under ?provider=maplibre this line used to read "geoBoundaries · Mapbox · * © OpenStreetMap" while the tiles came from OpenFreeMap. Crediting the wrong supplier is * worse than crediting none — it is a false statement about whose work is on screen, and * OpenFreeMap's terms ask for their credit. @@ -1869,7 +1867,7 @@ onMounted(async () => { /** * ═══ 'load' MAY HAVE ALREADY FIRED ════════════════════════════════════════════════════ * - * ⚠ THE DEFECT THIS WAS WRITTEN FOR WAS RETRACTED. rega first reported that under + * ⚠ THE DEFECT THIS WAS WRITTEN FOR WAS RETRACTED. A first reading said that under * ?provider=maplibre this map drew the basemap and nothing else; re-measured by polling * until the tiles and features were actually in, it draws 170 fills and 2,107 pins on both * engines. The original reading was taken on a fixed 18 s timer, right as the layers @@ -2085,7 +2083,7 @@ useShadowStyles( '.gm-linklist span{color:#6d766e}' + '.is-dark .gm-linklist{background:rgba(59,70,61,.6);border-color:#6d766e;color:#f3f3f1}' + '.is-dark .gm-linklist span{color:#d1d4cd}' + - /* ⚠ LOGICAL, NOT PHYSICAL (found in use, rega measured on main 52eeb0db). Under ar the five + /* ⚠ LOGICAL, NOT PHYSICAL (found in use, measured on main 52eeb0db). Under ar the five map controls mirror to the LEFT while `left:8px` kept the legend physically left, so the legend sat underneath all five of them. cities-internet shares this class name and passed for one reason: it anchors inline. Every physical left/right in this stylesheet that has a @@ -2510,7 +2508,7 @@ useShadowStyles( language. -->