people-groups-grid: keep the reasons, drop the speaker

Fourteen references, each rewritten to state the requirement directly. Every
date, measurement and pixel coordinate is kept — the y=1827/y=1865 redundancy
that prompted the count line, the 2026-09-22 interoperability report behind
the Language and Status props, the 220x130 letterbox the square image
replaced, the dev-server path that showed "view more information" reaching
the wrong page, and the India click that left the grid unchanged.

Thirteen were found by a case-sensitive search and a fourteenth was not: a
line in capitals, carrying a verbatim quote, which `grep -w Driver` cannot
see. The check that catches both is `grep -wi driver`, and it now reports 0.

Two sentences broke in the first pass and were found by re-reading every
changed line rather than by the reference count: one left "the control the"
with its object removed, and one left a quotation with an unclosed quote when
the surrounding attribution went. The count was correct while the prose was
wrong, which is why the count is not the check.

check:no-new-driver-references passes. research-map-plus-grid and
dashboard-plus-grid both rebuild byte-identical.
This commit is contained in:
Doxa Maps 2026-09-29 09:46:59 +00:00
parent c0397f4004
commit 2cde9c0918

View file

@ -23,7 +23,7 @@
* …the four dropdown axes (Region / Block / People-Group / Religion) PLUS Country.
* Precedence = internal control (when shown) ELSE the incoming prop (local-else-prop).
*
* ★ COUNTRY IS PROP-ONLY, NOT A FIFTH DROPDOWN. The Driver's exclusion of Country was
* ★ COUNTRY IS PROP-ONLY, NOT A FIFTH DROPDOWN. The exclusion of Country was
* about this element's OWN CONTROLS — it ships four dropdowns, not five, and that is
* unchanged (see extractFilterOptions + the filters__panel template). What is added is a
* `countryCode` INPUT so a host that already owns a country control (the cap-4
@ -92,7 +92,7 @@ const props = defineProps({
// element's ONLY row-total and must stay. A HOST that already shows one passes false.
// MEASURED on the cap-4 composite: the same 2,107 renders FIVE times down one page — KPI (y=117),
// KPI duplicate (y=176), table bar (y=1228), table footer 'Σ 2,107 groups' (y=1827) and this
// 'Total: 2107' (y=1865). The last two sit 38px apart, which is the redundancy the Driver saw.
// 'Total: 2107' (y=1865). The last two sit 38px apart, which is the redundancy that was reported.
showTotal: { type: [Boolean, String], default: true },
// ── external filter props (used when the matching internal control is hidden) ──
@ -105,8 +105,8 @@ const props = defineProps({
// ★ COUNTRY — WHY IT WAS DROPPED, AND WHAT MAKES IT SAFE TO MAP NOW.
//
// THE DRIVER'S BUG (reported 2026-09-22): "when I click on India in the top countries nothing
// happens and the people groups grid just stays the same." That was accurate and the cause was
// THE BUG (reported 2026-09-22): clicking India in the top countries did nothing —
// the people groups grid stayed the same. That was accurate and the cause was
// NOT a wiring fault. The cap-4 composite's FACET_TO_PROP translates dashboard facet keys to
// grid props, and it mapped only four; `country_code` was one of eight facets deliberately
// DROPPED, on the standing rule that it is better to not narrow on an axis than to push a value
@ -142,8 +142,8 @@ const props = defineProps({
// ── LANGUAGE + STATUS — the tree-rail axes, added on the SAME same-field test as country ──
//
// Driver-reported 2026-09-22: the People/Place/Language/Religion tree rail "is not working with
// interoperability… with the people groups grid beneath it." Language and Status were two of the
// Reported 2026-09-22: the People/Place/Language/Religion tree rail was not interoperating with
// the people groups grid beneath it. Language and Status were two of the
// axes a click could not reach, because there was no prop for the composite's FACET_TO_PROP to
// land a value in. As with country, the honest fix is to add the real prop HERE first.
//
@ -225,8 +225,8 @@ const cfg = computed(() => {
if (!props.profileConfig) return {}
try { return JSON.parse(props.profileConfig) || {} } catch { return {} }
})
// ── THE WORLD-MAP BACKDROP BEHIND THE FILTERS (Driver, 2026-09-24) ──────────
// "there is an SVG of a map that shows up under the search bar, where the toggles are."
// ── THE WORLD-MAP BACKDROP BEHIND THE FILTERS (requested 2026-09-24) ──────────
// An SVG world map shows under the search bar, where the toggles are.
// It is DX-life's own treatment, ported rather than reinvented: UupgsList.vue puts
// `background-image: url(<images>/worldmap.svg); background-size: 60%; background-position: top`
// on the container that wraps the search box and the toggles — a BACKGROUND, not an icon beside
@ -291,9 +291,9 @@ function reflectDir() {
} catch (_) { /* no host (SSR/tests) — nothing to reflect */ }
}
watch(textDir, reflectDir)
// ★ ABSOLUTE CANONICAL DEFAULT (Driver 2026-09-23, pasted from his own browser:
// http://localhost:5174/research/pitaguari/ -- "when I click view more information it does not
// send me to the proper doxa.life page"). The old default '/research/' was ROOT-RELATIVE, so it
// ★ ABSOLUTE CANONICAL DEFAULT. Reported 2026-09-23 from a dev server at
// /research/pitaguari/: "view more information" did not
// send a reader to the proper doxa.life page. The old default '/research/' was ROOT-RELATIVE, so it
// resolved against whatever origin happened to host the element: right on doxa.life, wrong on
// every other host -- the dev server, an iframe embed, a partner site. Same defect class as the
// ../../ child-src bug: a relative default encoding an assumption about the host.
@ -425,8 +425,8 @@ const loading = ref(true)
const loadFailed = ref(false)
// OPEN BY DEFAULT. The filters ARE the feature of this grid — the canonical chain asks for
// "the same search bar + dropdowns as the UPG grid-list", so the dropdowns must be VISIBLE on
// load. Collapsed-by-default hid all four behind a text link, and the Driver reported exactly
// that: "they do not let me see the dropdowns to select them". Still collapsible (the toggle
// load. Collapsed-by-default hid all four behind a text link, which was reported as
// not letting a reader see the dropdowns to select them. Still collapsible (the toggle
// remains) — the DEFAULT is what changed.
const filtersExpanded = ref(true)
const filterOptions = ref({})
@ -617,7 +617,7 @@ function toggleExact() {
// TWO VOCABULARIES MEET HERE, AND A STRICT === SILENTLY FILTERED TO ZERO.
//
// THE BUG (Driver-reported + measured live 2026-09-22, dashboard-plus-grid leaf). Picking a
// THE BUG (reported and measured live 2026-09-22, dashboard-plus-grid leaf). Picking a
// region in the dashboard above showed "1,309" in its own chart while the grid below said
// "no people groups match this filter" — every host-driven selection produced ZERO cards.
// Neither half was broken and the event wiring was correct; the two sides simply SPELL the
@ -721,8 +721,8 @@ function extractFilterOptions() {
}
// THE FOUR AXES ONLY — Country is deliberately absent here, and that is not an oversight.
// filterOptions is what RENDERS the dropdowns (see the filters__panel template), so adding
// country_code would grow this element a FIFTH dropdown, which is exactly the control the
// Driver excluded. The new `countryCode` prop is an INPUT, not a control: it reaches the rows
// country_code would grow this element a FIFTH dropdown, which is exactly the control that was
// excluded. The new `countryCode` prop is an INPUT, not a control: it reaches the rows
// through propFilters → activeFilters → applyDropdownFilters without ever passing through here.
//
// The cross-filtering still comes out right. updateFilterOptionCounts() below iterates
@ -762,7 +762,7 @@ function updateFilterOptionCounts() {
// helper: apply a specific filter-set (used by the faceted-count cross-filter)
// Uses the same valueMatches() as applyDropdownFilters: if the two disagreed, the facet COUNTS
// would contradict the rows actually shown (a chart reading 1,309 above an empty list — exactly
// the symptom the Driver reported). One matcher, both call sites.
// the symptom that was reported). One matcher, both call sites.
function applyWith(filters, list) {
let filtered = list
for (const [field, selection] of Object.entries(filters)) {
@ -1084,7 +1084,7 @@ onMounted(() => {
<div class="pgg-body">
<!-- THE COUNT LINE, AND WHY IT HAS THREE STATES RATHER THAN TWO.
Two Driver requests point in opposite directions and BOTH are right:
Two requests point in opposite directions and BOTH are right:
(a) earlier — "the same 2,107 renders five times down one page", so the host-embedded
grid was given show-total=false and went silent;
(b) 2026-09-22 — "the people groups grid underneath should tell me how many people
@ -1219,7 +1219,7 @@ onMounted(() => {
.pgg-exact { flex: none; }
/* A CONTROL, not a text link. It was background:none + border:none + text-decoration:underline,
which reads as a hyperlink — so the four dropdowns it gates were effectively undiscoverable
(Driver-reported). Now a bordered, filled affordance in the material-light palette with a
(reported). Now a bordered, filled affordance in the material-light palette with a
filter glyph and an active-count badge, so it looks pressable and says what it is hiding. */
.filters__toggle {
background: var(--dx-elevated, #fff); border: 1px solid var(--dx-line, #d1d4cd);
@ -1256,7 +1256,7 @@ onMounted(() => {
.repel { display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; }
.font-size-sm { font-size: 0.875rem; color: var(--mut); }
/* 240px floor (was 220px) so the square image below is genuinely LARGER, not just squarer — the
Driver asked for both. auto-fill keeps the column count responsive, so this only widens cards when
both were asked for. auto-fill keeps the column count responsive, so this only widens cards when
there is room; on a narrow viewport the track still collapses to one full-width column rather than
overflowing. Paired with .uupg__image's aspect-ratio:1/1 this takes the image from a 220x130
letterbox to a 240x240 square: ~2x the visible area, and the face is no longer cropped to a band. */
@ -1275,8 +1275,8 @@ onMounted(() => {
border-radius: 12px; overflow: hidden; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
}
/* SQUARE, NOT A LETTERBOX — the image is the point of the card.
Driver-reported 2026-09-22: "the images need to be larger. They need to be more like SQUARES and
less like RECTANGLES so that you can see the people image better." The old rule was a fixed
Reported 2026-09-22: the images need to be larger, and more like squares than
rectangles, so the people image is easier to see. The old rule was a fixed
height:130px against a column that is at least 220px wide (see .grid.uupgs-list above), i.e. a
220x130 letterbox — roughly 1.7:1 — which crops a standing person to a band and renders faces small.