diff --git a/plugin-designs/doxa-research-map/research-map.vue b/plugin-designs/doxa-research-map/research-map.vue index b3ef9b559..17a6757e9 100644 --- a/plugin-designs/doxa-research-map/research-map.vue +++ b/plugin-designs/doxa-research-map/research-map.vue @@ -268,7 +268,7 @@ useShadowStyles(` .dg-main { font-weight:500;font-size:13px;color:#222;line-height:1.3;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:flex;align-items:center;gap:6px; } .dg-main strong { font-weight:700;overflow:hidden;text-overflow:ellipsis; } .dg-meta { margin-top:2px;display:flex;flex-wrap:wrap;gap:4px 10px;font-size:11px;color:#555;line-height:1.35; } - .dg-field strong { font-weight:600;color:#333;margin-right:2px; } + .dg-field strong { font-weight:600;color:#333;margin-inline-end:2px; } /* Round 16 — labeled category tag replacing the old emoji prefixes. */ .dg-tag { flex:none;font-size:9px;font-weight:700;text-transform:uppercase;letter-spacing:0.4px;color:#3b463d;background:rgba(59,70,61,0.10);border-radius:4px;padding:1px 5px;line-height:1.5;white-space:nowrap; } .dg-agg-label { overflow:hidden;text-overflow:ellipsis; } @@ -438,7 +438,10 @@ useShadowStyles(` map did manage to render stays visible around it. A spinner that outlives the failure reads as "slow" and the user just waits; this says the map is gone. */ .rm-error { position:absolute;top:50%;left:12px;right:12px;z-index:7;transform:translateY(-50%);text-align:center;font:13px/1.5 -apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;color:#fecaca;background:rgba(15,18,22,.95);border:1px solid rgba(254,202,202,.28);border-radius:10px;padding:12px 14px;box-shadow:0 2px 10px rgba(0,0,0,.4); } - .rm-badge { position:absolute;top:10px;right:10px;background:rgba(124,140,248,0.12);color:#7c8cf8;border:1px solid rgba(124,140,248,0.3);padding:3px 9px;border-radius:4px;font-size:11px;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;pointer-events:none;z-index:50; } + /* inset-inline-end, not right: this badge is pinned to the READING edge, so under ar it belongs on + the left. .map-scroll-edge--left/right below stay physical on purpose — those are literal screen + edges for a scroll affordance and do not mirror. */ + .rm-badge { position:absolute;top:10px;inset-inline-end:10px;background:rgba(124,140,248,0.12);color:#7c8cf8;border:1px solid rgba(124,140,248,0.3);padding:3px 9px;border-radius:4px;font-size:11px;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;pointer-events:none;z-index:50; } /* Engine badge — bottom-left, unobtrusive. Colour differs per engine so a side-by-side comparison is readable at a glance. */ .rm-provider-badge { position:absolute;bottom:8px;left:8px;z-index:50;pointer-events:none;padding:2px 8px;border-radius:999px;font:600 10px/1.6 -apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;letter-spacing:.04em;color:#fff;background:rgba(30,41,59,0.72);border:1px solid rgba(255,255,255,0.18);backdrop-filter:blur(2px); } @@ -1503,6 +1506,15 @@ function onExport(kind) { if (kind === 'poster') return openPoster() if (kind === 'packet') return openPacket() } +// ★ THE PHONE HAD NO EXPORT AT ALL, AND THE KILL-SWITCH ONLY COVERED THE DESKTOP. +// LegendDesktop takes :export-enabled="EXPORT_FEATURE_ENABLED", so turning that flag off hid the +// desktop menu — but LegendMobile is OPT-IN BY CONSTRUCTION: its exportEnabled is +// `typeof inject('onLegendExport') === 'function'` (LegendMobile.vue:393), and this profile provided +// nothing. So a reader on a phone had no way to export a poster or a packet, while the same map on a +// desktop did. country-posters already carries the guarded line; this is the missing half here. +// Providing it UNGUARDED would be the other error — the phone would then keep an affordance the +// desktop deliberately hides whenever the flag is off, which is the bug exp's card names. +provide('onLegendExport', EXPORT_FEATURE_ENABLED ? onExport : null) // ─── Packet export (printed, multi-page: map + a card per people group) ────── // Lazy-loaded on first use, the same pattern openPoster() uses. Defensive throughout: never throw