Float the pin note above the sheet so the options keep the full 30%

The Driver scrolls further than he should to reach the legend options on a
phone, and the note under the legend is why — but not by pushing them down. It
was the last child of .legend-content, a natural-height sibling of a flex:1
options panel, so every pixel it took was a pixel the options' own scroller
lost. The tree got a shorter viewport and the same rows moved further away.

Moving it WITHIN the sheet would have recovered nothing, which is worth stating
because it was the obvious reading of the instruction: the sheet's open height
is fixed at 30%, so anything inside it costs the options the same wherever it
sits. Out here the note costs them nothing and they keep the whole sheet.

It is positioned off --legend-sheet-h, which a ResizeObserver already writes for
the engine's own bottom controls, so it tracks the sheet as it opens, drags and
collapses instead of assuming a height. It stays pointer-events:none with the
sheet root: it is text, nothing in it is tappable, and it must never swallow a
map drag.

The note is kept, not removed — he accepted the text and objected only to it
breaking the legend. Its scrim follows `dark` for the same reason the note
itself takes that prop: a white halo behind light text is a smear rather than
legibility.

NEEDS EYES at 390x844: whether it reads over an arbitrary basemap, which is the
one thing moving it out of a white panel puts at risk.
This commit is contained in:
Doxa Maps 2026-09-28 17:19:40 +00:00
parent b9d78e8926
commit 6970e7b63b

View file

@ -28,6 +28,13 @@ useShadowStyles(`
/* Containment root: clamps absolute children to the map area. */
.legend-sheet-root{position:absolute;inset:0;pointer-events:none;overflow:hidden;}
/* Sits just above the sheet's top edge, tracking it via --legend-sheet-h. Text only, so it stays
pointer-events:none with the root — nothing here is tappable and it must never eat a map drag.
The scrim keeps it legible over an arbitrary basemap without becoming another panel. */
.approx-pin-note--floating{position:absolute;inset-inline:0;bottom:calc(var(--legend-sheet-h,0px) + 6px);z-index:1001;margin:0 10px !important;text-align:center;pointer-events:none;text-shadow:0 1px 2px rgba(255,255,255,0.85);}
/* The note's own text colour flips with `dark`, so the scrim has to flip with it: a white halo
behind light text is a smear, not legibility. Same reason the note takes `dark` at all. */
.approx-pin-note--floating-dark{text-shadow:0 1px 2px rgba(0,0,0,0.85);}
.legend-sheet-root>*{pointer-events:auto;}
/* ── Attribution stays visible (driver bug 2026-09-16) ──
@ -723,6 +730,21 @@ onBeforeUnmount(() => {
<!-- Containment wrapper: ensures position:absolute children are clipped to the map area
and never escape the shadow DOM host / staging frame. -->
<div class="legend-sheet-root">
<!-- ★ THE NOTE FLOATS ABOVE THE SHEET, IT DOES NOT SIT INSIDE IT. It used to be the last child
of .legend-content, a natural-height sibling of a flex:1 options panel — so every pixel it
took was a pixel the options' inner scroller lost, and the reader scrolled further inside
the tree to reach the same rows. Moving it WITHIN the sheet would not have helped: the
sheet's height is fixed at 30%, so anything inside it costs the options the same either
way. Out here it costs them nothing and the options keep the full sheet.
Positioned off --legend-sheet-h, which a ResizeObserver already writes for the engine's
own bottom controls, so it tracks the sheet as it opens, drags and collapses rather than
assuming a height. -->
<ApproxPinNote
v-if="legendMode !== 'detail' && legendState !== 'collapsed'"
class="approx-pin-note--floating"
:class="{ 'approx-pin-note--floating-dark': isDark }"
:dark="isDark"
/>
<!-- Floating mini-image: fixed 16px above the sheet's resting position (30%).
The sheet slides UP over it — the image never moves. -->
<div
@ -885,7 +907,7 @@ onBeforeUnmount(() => {
</button>
</template>
</LegendRows>
<ApproxPinNote v-if="legendMode !== 'detail' && legendState !== 'collapsed'" :dark="isDark" />
</div>
</div>
</div><!-- /.legend-sheet-root -->