feat(03-03): status strip, state cards, recenter control, boot choreography — map-first, D-09 staged states

- strip.ts: six-state lamp+word left cluster, ±M / FIX Ns AGO telemetry (U+00B1 glyph), elapsed-seconds for acquiring
- cards.ts: boot/denied/lost builders from theme classes, machine-blink gantry (500ms JS duty cycle), GEO/SYS registers from strings.ts, D-06 CTA inversion (chat-fallback=btn-primary, retry=btn-secondary)
- recenter.ts: 40x40 plate w/ >=44 hit slop, orthogonal inline-SVG crosshair, three data-attribute notch states, no inline handlers
- main.ts: boot order map->session->chain (bootMap before acquireFix), null-map guards on every map consumer, ARAHARAH-LIVE emitted outside the guard, data-map=absent fallback, localeFromInitData, ASK VIA CHAT w/ D-03 revalidation, 1s tick re-running the chain at 45s staleness
- map.ts: attribution control moved bottom-left (UI-SPEC flush chip, compact)
- shell.css: attrib chip #map-scoped override (wins cascade over maplibre css), strip left cluster, recenter z-index
- vite.config.ts: define __ARAHARAH_HARNESS__ keyed on --mode harness (bare ambient global would ReferenceError in plain dev; Rule 3)
- session.test.mjs: SESS1-4 memory-token gates
This commit is contained in:
araharah-executor
2026-10-23 00:08:34 +08:00
parent c437d312f6
commit d573acc583
9 changed files with 717 additions and 16 deletions
+3 -2
View File
@@ -14,7 +14,7 @@
* screenshot toolchain (theme/scripts/screenshot.mjs) and plan 03-04's
* capture race both wait on exactly that prefix.
*/
import { Map as MapLibreMap, setWorkerUrl, GPUInitializationError, type StyleSpecification } from "maplibre-gl";
import { Map as MapLibreMap, setWorkerUrl, GPUInitializationError, AttributionControl, type StyleSpecification } from "maplibre-gl";
import "maplibre-gl/dist/maplibre-gl.css";
import workerUrl from "maplibre-gl/dist/maplibre-gl-worker.mjs?worker&url";
import ramsStyle from "@araharah/theme/basemap/liberty-rams.json";
@@ -32,8 +32,9 @@ export function bootMap(container: HTMLElement): MapLibreMap | null {
style: ramsStyle as StyleSpecification, // inlined at build time (D-14) — NEVER re-set
center: KL_CENTER,
zoom: 13,
attributionControl: { compact: true },
attributionControl: false, // added below at bottom-left (UI-SPEC §Shell Layout: flush bottom-left chip)
});
map.addControl(new AttributionControl({ compact: true }), "bottom-left");
map.on("error", (e: { error?: { message?: string } }) => {
const inner = e && e.error;
console.error("RAMS-BASEMAP-ERROR", inner && inner.message ? inner.message : inner);
+3 -3
View File
@@ -52,9 +52,9 @@ export function createPositionMarker(): {
// of the HTML <div> — an SVG element directly under a <div> is not rendered.
svg.append(circle, cone, dot);
// MapLibre owns this group's DOM once addTo(map) runs — it parents it into the
// map canvas wrapper. DO NOT document.body.appendChild(group): an un-parented
// body child has no positioning CSS and paints UNDER the `inset: 0` map, so the
// marker would be invisible even though it exists.
// map canvas wrapper. DO NOT parent this group under the document body here: an
// un-parented body child has no positioning CSS and paints UNDER the `inset: 0`
// map, so the marker would be invisible even though it exists.
group.appendChild(svg);
const marker = new Marker({ element: group }).setLngLat([0, 0]);
return {