Start the wrapped filter line on the same edge as the one above it
The dashboard ships eight filter dropdowns. Seven fit on the first line and Status wraps to a second — centred, not aligned with Prayer above it. A lone centred control under a left-aligned row does not read as a layout decision, it reads as a mistake. Measured on the shipped dashboard at three viewports, line-2 left edge against line-1: 1440px 36 vs 636, six hundred pixels adrift; 1280px 16 vs 556; 1024px 33 vs 132. Never aligned at any width. The cause is `justify-content: space-evenly`, which I kept when wrapping landed here earlier today. The comment defending it is about a SCROLLER — a single line that could push its first item to a negative offset, which `safe` rescues — and that reasoning does not survive wrapping, because space-evenly distributes EACH LINE independently. Seven items distribute across the width; one item lands in the middle. flex-start keeps every line on one edge at any width. The `safe` keyword goes with it: it exists to rescue centred and space-* distributions from negative offsets, and flex-start cannot produce one, so keeping it would preserve a guard against a hazard the change removes. Now 14 / 14 / 14 at all three viewports, matching the row's own left edge, and the regenerated screenshot shows Status sitting directly beneath Prayer. Blast radius checked before editing, since this is the high-bar library zone: SearchFilterHeader is consumed by research-dashboard only. check:synced-css passes, so the two CSS copies remain byte-identical. Nine gates pass and verify:gate1 is unchanged at 13/13 against 2,107 live records. Separately noted, not fixed here: check:filter-width fails on HEAD too — verified by stashing this edit and re-running. It reports "UNMEASURED: no .filter-dropdown__trigger found in the composed tree", and that class DOES exist (FilterDropdown.vue:278), so the selector is right and the gate is not reaching the page — the same stale-navigation family as the tab-order gate fixed earlier. Left for its own commit rather than bundled into a styling change.
|
Before Width: | Height: | Size: 1.2 MiB After Width: | Height: | Size: 1.2 MiB |
|
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 1.7 MiB After Width: | Height: | Size: 1.6 MiB |
|
Before Width: | Height: | Size: 1.7 MiB After Width: | Height: | Size: 1.6 MiB |
|
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 903 KiB After Width: | Height: | Size: 904 KiB |
|
Before Width: | Height: | Size: 974 KiB After Width: | Height: | Size: 974 KiB |
|
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 1 MiB |
|
Before Width: | Height: | Size: 1.2 MiB After Width: | Height: | Size: 1.2 MiB |
|
Before Width: | Height: | Size: 925 KiB After Width: | Height: | Size: 922 KiB |
|
|
@ -324,12 +324,22 @@ function onClearAll() { emit('clear-all') }
|
|||
Wrapping is the right lever rather than shrinking the dropdowns: their fixed 168px width is itself
|
||||
a Driver decision ("filters not so wide"), and a flexible width was what made them jump as a
|
||||
selection changed. So the row now flows onto a second line when it must.
|
||||
The justify-content pair below is KEPT for the reason its own comment gives — `safe` degrades
|
||||
space-evenly to flex-start rather than pushing the first item to a negative offset. That hazard
|
||||
applied to a scroller and costs nothing here, so it stays rather than being simplified away. */
|
||||
★ AND START THE WRAPPED LINE ON THE SAME LEFT EDGE (2026-09-23). `space-evenly` was kept here
|
||||
when wrapping landed, on the reasoning that `safe` made it harmless. That reasoning was about a
|
||||
SCROLLER — a single line that could push its first item to a negative offset — and it does not
|
||||
survive wrapping: space-evenly distributes EACH LINE independently, so a final line holding one
|
||||
orphan centres that orphan under the seven above it.
|
||||
MEASURED at three viewports on the shipped dashboard, line-2 left edge vs line-1:
|
||||
1440px line1 x=36 line2 x=636 — 600px adrift
|
||||
1280px line1 x=16 line2 x=556 — 540px adrift
|
||||
1024px line1 x=33 line2 x=132 — 99px adrift
|
||||
A lone centred "Status" control under a left-aligned row does not read as a layout decision, it
|
||||
reads as a bug — which is the bar this is held to. flex-start keeps every line on one edge, so a
|
||||
wrapped row looks like a grid at any width. The `safe` keyword is dropped with it: it exists to
|
||||
rescue centred/space-* distributions from negative offsets, and flex-start cannot produce one. */
|
||||
.sfh__filters-row {
|
||||
display: flex; flex-wrap: wrap; align-items: center; gap: var(--dx-filter-gap, 10px);
|
||||
justify-content: space-evenly; justify-content: safe space-evenly;
|
||||
justify-content: flex-start;
|
||||
overflow-x: clip; padding-bottom: 2px;
|
||||
scrollbar-width: thin; -webkit-overflow-scrolling: touch;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <dashboard-plus-grid> custom element. -->
|
||||
<script src="../../dashboard-plus-grid.js" integrity="sha384-xpa86HoTmKX01/ckN2L2cQbAry77D2mlRbWKagjx1VIUkoygkRor9SFt8t8vuWNM" crossorigin="anonymous"></script>
|
||||
<script src="../../dashboard-plus-grid.js" integrity="sha384-/qhSKrIAbbUgEn7TNhtn6VuqpE3ApxLg8otkL8MD4KexFyTVrnmvztqD81Ourj1W" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <dashboard-plus-grid> custom element. -->
|
||||
<script src="../dashboard-plus-grid.js" integrity="sha384-xpa86HoTmKX01/ckN2L2cQbAry77D2mlRbWKagjx1VIUkoygkRor9SFt8t8vuWNM" crossorigin="anonymous"></script>
|
||||
<script src="../dashboard-plus-grid.js" integrity="sha384-/qhSKrIAbbUgEn7TNhtn6VuqpE3ApxLg8otkL8MD4KexFyTVrnmvztqD81Ourj1W" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
2
public/doxa-maps/index.html
generated
8
public/doxa-maps/manifest.json
generated
|
|
@ -189,7 +189,7 @@
|
|||
"bundle": "dashboard-plus-grid",
|
||||
"scriptUrl": "./dashboard-plus-grid/dashboard-plus-grid.js",
|
||||
"output": "doxa-maps/dashboard-plus-grid/dashboard-plus-grid.js",
|
||||
"integrity": "sha384-xpa86HoTmKX01/ckN2L2cQbAry77D2mlRbWKagjx1VIUkoygkRor9SFt8t8vuWNM",
|
||||
"integrity": "sha384-/qhSKrIAbbUgEn7TNhtn6VuqpE3ApxLg8otkL8MD4KexFyTVrnmvztqD81Ourj1W",
|
||||
"elements": [
|
||||
"dashboard-plus-grid"
|
||||
],
|
||||
|
|
@ -205,7 +205,7 @@
|
|||
"scriptUrl": "./dashboard-plus-grid/dashboard-plus-grid.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./dashboard-plus-grid/dashboard-plus-grid/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./dashboard-plus-grid/dashboard-plus-grid.js\" integrity=\"sha384-xpa86HoTmKX01/ckN2L2cQbAry77D2mlRbWKagjx1VIUkoygkRor9SFt8t8vuWNM\" crossorigin=\"anonymous\"></script>\n<dashboard-plus-grid profile-config='{\"profile\":\"dashboard-plus-grid\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></dashboard-plus-grid>"
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./dashboard-plus-grid/dashboard-plus-grid.js\" integrity=\"sha384-/qhSKrIAbbUgEn7TNhtn6VuqpE3ApxLg8otkL8MD4KexFyTVrnmvztqD81Ourj1W\" crossorigin=\"anonymous\"></script>\n<dashboard-plus-grid profile-config='{\"profile\":\"dashboard-plus-grid\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></dashboard-plus-grid>"
|
||||
},
|
||||
"instances": [
|
||||
{
|
||||
|
|
@ -764,7 +764,7 @@
|
|||
"bundle": "research-dashboard",
|
||||
"scriptUrl": "./research-dashboard/research-dashboard.js",
|
||||
"output": "doxa-maps/research-dashboard/research-dashboard.js",
|
||||
"integrity": "sha384-c4mIRnGTwxFLVHbA8tH6u7YiWvIXG8k7ocJHbtQYiUE8Nv/mWD9/GNFnpWsL1dM6",
|
||||
"integrity": "sha384-7deBWTaAE1237o9NDmPofHmH+1/3OXG+9lOkAlrPqTbCgSHe6TqRFvBlZX7JZ7iv",
|
||||
"elements": [
|
||||
"research-dashboard-map"
|
||||
],
|
||||
|
|
@ -780,7 +780,7 @@
|
|||
"scriptUrl": "./research-dashboard/research-dashboard.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./research-dashboard/research-dashboard/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./research-dashboard/research-dashboard.js\" integrity=\"sha384-c4mIRnGTwxFLVHbA8tH6u7YiWvIXG8k7ocJHbtQYiUE8Nv/mWD9/GNFnpWsL1dM6\" crossorigin=\"anonymous\"></script>\n<research-dashboard-map profile-config='{\"profile\":\"research-dashboard\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></research-dashboard-map>"
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./research-dashboard/research-dashboard.js\" integrity=\"sha384-7deBWTaAE1237o9NDmPofHmH+1/3OXG+9lOkAlrPqTbCgSHe6TqRFvBlZX7JZ7iv\" crossorigin=\"anonymous\"></script>\n<research-dashboard-map profile-config='{\"profile\":\"research-dashboard\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></research-dashboard-map>"
|
||||
},
|
||||
"bundle": "research-dashboard"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <research-dashboard-map> custom element. -->
|
||||
<script src="../research-dashboard.js" integrity="sha384-c4mIRnGTwxFLVHbA8tH6u7YiWvIXG8k7ocJHbtQYiUE8Nv/mWD9/GNFnpWsL1dM6" crossorigin="anonymous"></script>
|
||||
<script src="../research-dashboard.js" integrity="sha384-7deBWTaAE1237o9NDmPofHmH+1/3OXG+9lOkAlrPqTbCgSHe6TqRFvBlZX7JZ7iv" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||