On a map with the legend sheet the engine's credit keeps its top-start
corner, now above the scroll-edge strips, and folds to its (i) 3 s after it
first shows expanded. The full-width sheet, the 'dxmaps:legend-sheet' event
and the hidden MapLibre logo control stay.
The engine's credit moves from the top corner to the end side just above the
sheet, and folds to its (i) four seconds after it first shows expanded. The
logo corner sits beside the menu button, and MapLibre's optional logo control
is hidden. The sheet announces itself with a 'dxmaps:legend-sheet' event
(bubbling, composed), so the layout can lift its round menu button above it.
The sheet takes the full width while the layout says it lifts the button
(--map-fab-sheet-inset); otherwise it stays beside the button. The older
corner rules are scoped to .lm-on, so they end with the last sheet.
The shared region/country map lifted its bottom corners by the gallery's round-button clearance whenever
that button rendered. That suits a map that fills the screen, but the Regions maps sit in the page flow,
so on a phone the credit floated 80-100 px up the map. The lift is removed; the full-height maps keep
their own clearance in the mobile legend.
Two phone legend fixes in LegendMobile.
The rule that moves the engine's bottom corners to the top lives in CSS injected
once into the host's shadow root and never removed. Cities with Internet mounts
the sheet only for its phone people-group card, so after "back to legend" its
credit stayed at the top, under the map's own legend (measured at 390: 1 of 11
points visible). The move is now scoped to a class on the host that is set while
at least one LegendMobile is mounted, counted so the desktop legend's hidden twin
cannot clear it early.
A drag on the sheet's handle fell through to whatever scrolls behind the map:
on UPG-100's Map view a downward drag on the collapsed sheet scrolled its pane
column 655px back to the list. The handle (the drag strip, the title rows, and
the whole sheet while collapsed) now has touch-action:none, and a collapsed sheet
holds the gesture as a backstop. A tap still reaches the caret.
Every other caller of the in-place print moves onto the phone path the poster wall already uses:
printImageBlob (the map's poster/download dialog and research-map) prints the page itself on a phone,
and the gospel tree, the prayer-walk planner and the wall of people groups call printDocument. A caller
without its own progress dialog gets a shared Print bar when the tap has expired, labelled through the
caller's own translator. Desktop keeps the in-place frame unchanged. Source only; the bundles are rebuilt
when it lands.
At the top of a phone map the credit shares the edge with the map's control
column, and at 10px it took two lines. It is now 8.5px, capped 44px short of
the column (35px wide at 390), which fits the whole MapLibre licence text on one
line (294px against about 302px of room, measured at 390). It still wraps rather
than clips, so a longer credit shows whole on two lines instead of losing terms.
- The closed phone drawer casts no shadow. Parked off-screen at
translateX(-100%), its 28px blur still darkened the start edge of every
map (measured at 390: the left 30px about 22 luminance levels darker
than with the shadow off, a repeat shot identical). The shadow now
belongs to the open drawer only; in Arabic the same rule covers the
drawer parked off the right edge.
- A row with disabled (a desktop-only map on a phone, e.g. Big Picture)
renders greyed, with aria-disabled and a not-allowed cursor; its badge
keeps its accent colour. pick() is unchanged, so the consumer still
receives the click and can say why the row does not open.
Both CSS copies change identically.
- Simple Research: the list follows a region, religion or language
chosen on the map, and the map follows a search of the list (a single
pin opens that group's detail, it does not filter the list). Its
takeaway and example-packet strings are gone with the row's takeaway.
- Prayer Progress: the groups on DOXA's prayer list, not every unreached
people group; prayer coverage on every preset, engagement and adoption
on the full map; the takeaway links to the group's prayer page (the map's
Share shares the map, not a group).
- Regions: every country except India prints (China does); the posters,
packets and card decks are printed from each region's "View country
posters" wall, not the country dashboard, and there is no poster share.
- Cities with Internet: banded by the share of people using the internet
(mobile use is shown, it does not set the band); India also by state
from its 2019-21 survey; low means few online, not no one.
Each locale quotes its own label for the Regions button. The per-map
owners supplied the corrections from their code. i18n parity, never-
translated and keys-exist pass.
Every bottom placement of the engine's credit failed a reader on a phone: under
the open sheet it was covered, lifted above the sheet it floated mid-map, and
in a strip below the sheet it pushed the legend off the map's bottom edge. On a
phone both engines' bottom corners now move to the top corner on the start
side, opposite the map's own control column (left; right in RTL), and the sheet
sits flush at the map's bottom, starting beside the round menu button
(--map-fab-beside) so the button covers none of it. The move is !important so a
plugin's own lift of its bottom corners cannot push the credit off the top.
Desktop is unchanged.
On a phone there is no room for "The dot marks where this people is found, not
a town or a boundary" beside the legend, so the caption chip under the sheet is
gone: the sentence shows in no resting state (collapsed, or open with nothing
selected). A tapped dot's detail view keeps its note inside the sheet, where it
explains shared dots, and the tree's own copy stays off. The credit strip under
the sheet is the bottom controls alone again. Desktop is unchanged.
A host may move the engine's credit to the TOP of the map (a phone layout with the sheet flush at the
bottom). creditFloor() would then have used a credit near y=10 as the floor, and syncAttribClearance()
would have reserved the whole map height (capped at 120px), so the pill lifted itself for nothing. Now
a credit in the upper half of the pill's layout parent is not counted: no floor, and the 20px default
clearance. Every credit is at the bottom today, so this changes nothing yet.
Every bundle rebuilt (PinHint ships through ProfileLoader), composites after their children, then the
tree and SRI.
On a partner page or a standalone preset page the ⓘ control rendered nothing, because only the
gallery answered it and the ⓘ's text lived in the gallery's settings. Now the map carries its info
(plugin-designs/doxa-simple-map/src/mapInfo.js) and a host only adds placement:
- MapInfoButton gains an opt-in `standalone` prop. When no host answers and the map carries info, it
asks the map for a popup of its own (the 'standalone' event). If a real host appears later, the
map's popup is dropped and the host takes over. Never inside the gallery (its panes carry
data-doxa-gallery): there the gallery alone decides, its own info:false included.
- MapInfo gains `popupOnly` (with trigger 'control'): no floating button, since the map's control is
the only button; it answers that control from inside the map, points at it once per page load,
and opens the same popup (the bottom sheet on phones). It announces itself as local, so the
control can tell it from a real host.
- Prayer Progress mounts that popup beside its control column, only when asked.
Per preset: the text describes the prayer map, so a map that shows the Prayer tab has info (the full
profile and the prayer preset); the engagement-only and adoption-only presets have none and show no
ⓘ, as before. A host's profile-config info:false removes the ⓘ. Every other MapInfoButton consumer
is unchanged (standalone is off by default).
doxa-simple-map grows by 20,590 bytes raw (5,699 gzipped), for compiling MapInfo. Rebuilt
doxa-simple-map and doxa-maps-spa, then tree + SRI.
This reverts d83c89f28. On a phone the gallery's menu is again the round ☰
button in the pane's bottom corner (bottom-left; bottom-right in Arabic), with
no bar above the pane. While it shows, the layout again publishes
--map-fab-clearance and --map-fab-beside, and the maps keep their credits,
wordmarks, pin captions and search boxes clear of the button through them.
- It is dismissed when the reader taps a pin, the gesture it teaches. The signals are
uiStore.selectedPeopleGroup (the maps that select through uiStore.selectPeopleGroup) or a
'dxmaps:pin-selected' event inside the map's root (a map with its own selection). It was left
standing over the detail card that the tap had opened. A pan still does not dismiss it.
- Wide, the pill reached the gallery's round menu button (bottom-left). Its bottom now takes the
larger of the credit clearance and --map-fab-clearance, which the layout publishes only while the
button is rendered.
- Every bundle rebuilt (PinHint ships through ProfileLoader), composites after their children, then
the tree and SRI.
Every poster, prayer list and card deck printed from a hidden iframe (openPrintFrame), and phone browsers
do not honour a print() inside a subframe: no print dialog ever opened on a phone. printDocument() keeps
that iframe path unchanged on desktop; on a phone or tablet it mounts the document into the page under a
print-only stylesheet that hides everything else, and calls the page's own window.print(). When preparing
the document outlasted the tap's activation, the wall's progress dialog shows a Print button so the print
comes from a fresh tap. The poster wall (Regions, UPG-100, Country Posters) is the first user.
- left:50% alone capped the absolutely placed pill at HALF the map, about 195px at 390, so the
sentence broke into four lines. width:max-content, with max-width 16px short of each edge, lets it
take the width it needs: at most two lines on a phone, never touching the sides.
- z-index 2147482000 -> 12. In the gallery, plugin content shares one stacking context with
VerticalTabsLayout's chrome (the menu button at 15, the drawer at 20, and 1000 while it is open on
a phone), so the pill painted over the open drawer. 12 keeps it above the map's own base layers
(canvas, scroll edges 2, control column 10) and below that chrome.
- The pill's lines are centred.
On phones (up to 767px) the "What can this map do?" panel opened as a full-screen page: a few
lines of text at the top of an empty white screen, reading as a new page rather than a panel.
It is now a bottom sheet:
- it sizes to its content, up to 70% of the small viewport (svh, so a collapsing URL bar does not
resize it), and scrolls inside, with its scroll kept to itself;
- the close button is 44px and stays in view in the sheet's header;
- the dimmed map above it stays visible, and a tap there closes the panel, as Escape does.
Desktop is unchanged. Rebuilt doxa-maps-spa (the only bundle that compiles MapInfo.vue), then
tree + SRI.
Every map whose ⓘ is its own control (MapInfo trigger 'control') now gets the same pointer:
it shows the first time that control is on screen in a page load, and goes for the rest of the
load once the reader opens the popup or leaves the tab. A full reload shows it again. This is
page-load memory, never storage, so the popup offers no checkbox in control mode: the "Keep
tooltip turned on" box and its string (all 11 locales) are removed, along with the pointerKeep
prop that selected this model per tab. Floating-mode maps keep their stored model and their
"don't point again" box, unchanged.
Leaving the tab is read from the pane (hidden or inert), on the control's intersection change
and the existing 1.5 s measurement tick.
Rebuilt doxa-simple-map (it ships the mapInfo catalogue) and doxa-maps-spa, then tree + SRI.
Prayer Progress draws its control column only once the style and the people-group data are in,
which on a slow phone can take longer than any fixed wait, and then the gallery's floating ⓘ
appeared and was swapped for the control. Now the map announces at mount that a control is on its
way ('dxmaps:mapinfo-pending'), and MapInfo waits for the map instead of a clock.
- A known failure (the map reports an error) or an unmount before the map is ready withdraws the
announcement, and the floating ⓘ shows at once.
- While a control is pending, the 30 s wait becomes a 90 s backstop (time on screen), so an
unreported failure still gets a floating ⓘ.
- A map that never announces anything keeps the 30 s wait, and pages with no MapInfo are unchanged.
Rebuilt doxa-simple-map and doxa-maps-spa, then tree + SRI.
The dashboard header gains an info button ("What can this map do for you?") to
the left of Share. Both are rounded squares at the vertical tabs' radius
(--vtl-radius), matching the app's own roundedness; map controls stay round.
Built as a reusable, parameterized header-button form so other dashboards adopt
it by prop, not by copy:
- MapControlButton: new shape="rounded-square" (border-radius: var(--vtl-radius,8px)).
- ShareButton / MapInfoButton: a shape prop forwarded to MapControlButton;
ShareButton also squares its rotating ring so a round ring never wraps a square.
Defaults stay 'round' — every existing consumer is unchanged in behaviour.
- research-dashboard DashboardTopBar mounts the ⓘ and Share as one header-button
group, sized to the bar with the 44px tap target kept for both. DOM order
[ⓘ, Share] puts ⓘ at the logical start: left in English, right of Share in
Arabic (the flex row reverses under rtl).
- doxa-maps-spa dashboard-plus-grid tab -> trigger:'control', so the tab's
MapInfo is driven by the header ⓘ and the gallery's floating ⓘ is suppressed:
exactly one ⓘ, fail-open. No new strings (reuses mapInfo.open, 11 locales).
The control column goes back to the library's round, spaced buttons at every width; the square
grouped card read too compact, on phones most of all. The ⓘ stays the top control.
In control mode, MapInfo no longer shows its floating button before the map's control has
announced itself. The map draws its column only once it is ready (style and people-group data),
so the floating ⓘ appeared for a moment and was then replaced by the control. The wait is bounded
at 30 s of time on screen, counted only while the pane is visible and not inert: measured column
arrival times run from 7 to 19 s on a local serve, so a shorter wait expired inside a normal load
and flashed late. If no control arrives, the floating button shows, so there is still always a way
to open the popup. Once a control has announced itself, measurement alone decides, as before.
MapInfo's plain <script> block (the page-load pointer memory) now sits above <script setup>, so
check:setup-order no longer reads it as used before its definition; its explanation moves into
<script setup> so the library index keeps the component's own description. Compiled output is
unchanged by the move.
Rebuilt doxa-simple-map and doxa-maps-spa (the only bundle that compiles MapInfo.vue), then
tree + SRI.
- pointerKeep maps (Prayer Progress only) point ONCE PER PAGE LOAD: the pointer shows the first time
the map is on screen in a load. Opening the popup hides it for the rest of that load, and the next
full load shows it again. The memory is a module-scope Set (pointerDoneThisLoad), because the gallery
remounts a heavy tab's MapInfo on every switch back. It is marked when the pointer is on screen, not
on mount. Nothing about it is persisted any more (no seen write in show() or hide()).
- The keep box (still stored, per map) keeps the pointer after the popup closes and on every
appearance. A page-load pointer ignores the every-map off switch, which is not offered beside it.
- The label is "Keep tooltip turned on" (en), with de retuned to match; the other nine already say
"keep ... on".
- Rebuilt doxa-simple-map and doxa-maps-spa, then tree and fix:sri.
The floating ☰ circle sat in the bottom-left corner of whatever map was open.
It covered Simple Research's search box and the licence credit on Cities and
Gospel Resources (in Arabic, mirrored, the credit's other end). On a phone
(narrow and headerless, the circle's own condition) the ☰ now sits in a 44px
bar above the pane, beside the open view's name. The layout no longer
publishes a fab clearance, so the maps' bottom corners return to their plain
insets. Desktop and header-on layouts are unchanged.
In the detail view a thumb on the content resized the sheet whenever the
content could not scroll that way, so reading the list moved the sheet. Only
the handle (the drag strip and the title row) starts a resize now; below it
the content scrolls, in every mode.
The sheet's list gets overscroll-behavior: contain (the list only, not the
pane), so a fling that reaches its end stops there instead of scrolling the
page behind the map.
The open state was a fixed 30% of the map: a three-row legend sat in a mostly
empty sheet, and a long tree scrolled inside one. At rest in the open state the
sheet now takes its content's height, capped at 45% of the map. A drag still
sets an explicit height; the collapsed and fully open states are unchanged. The
detail view's mini image follows the open sheet's real top edge.
The start state was a race. Every map's own mount code means collapsed on a
phone, but uiStore.init() measures the breakpoint in a ResizeObserver whose
first callback runs after mount, so Simple Research read the 'desktop' default
and started open on every load at 390, while Prayer Progress started
collapsed. The sheet now applies the collapsed start state itself, once, the
first time it sees the phone breakpoint, unless a people group is selected.