Integrate open PR contribution stack#44
Conversation
This commit addresses several mobile UX issues identified during the mobile parity audit: - Fixed overlapping labels in the timeline scrubber on mobile viewports. - Resolved clutter and overlapping labels for 3D event markers by adding deterministic vertical staggering and responsive font sizing. - Optimized the navigation rail for mobile by shifting to a horizontal bar with larger touch targets and decluttering secondary items. - Improved responsiveness of the landing page heading and CTA buttons. - Made HUD labels responsive to prevent collision on small screens. - Adjusted desktop Datapad width for better scaling on smaller desktop/tablet viewports.
This commit adds a systematic checklist for mobile parity and touch-readability as part of the mobile audit resolution.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Layers on top of the cherry-picked mobile-parity work from @theshantanujoshi to land the 3 outstanding review blockers and 4 non-blocking suggestions, so the PR can ship without further round trips. Blockers fixed: 1. NavRail mobile bar — Legends toggle was silently dropped during the parity refactor. Restored as an inline compact pill (same styling vocabulary as the AtlasToggle "mini" variant; uses the legends accent color and "L" letter glyph the desktop rail uses). 2. NavRail mobile imports — removed the unused `List` and `DotsThreeVertical` imports that were staged for the never-shipped "More menu" placeholder. (Copilot autofix already removed the unused `cn` import.) 3. DatapadDrawer Crawl button — was gated to `entity.type === "film"`, which dropped a desktop affordance from mobile (the Crawl works for every entity since buildEntityCrawl composes per-entity text). Ungated + styling synced with desktop's Datapad header button (gap-1.5, no bg fill, 2xs label). Worthwhile suggestions also applied: - AppShell crawl-open chrome bleed: switched from `{!crawlOpen && <X />}` (unmounts on every crawl, discards internal state) to `<motion.div className={crawlOpen ? "hidden" : ""}>` so NavRail + TimelineScrubber state survives the cinematic. - EntityCrawl effect cleanup: defensive `setGlobalCrawlOpen(false)` in the open-effect cleanup so the global flag stays consistent even when `open` flips false externally without going through `finish()` — would otherwise leave AppShell hiding chrome forever. - TimelineView CornerHud: era readout (the only feedback for the scrubber drag) now visible at all viewport widths; the three contextual labels stay sm:block. - AppShell sidebar grid: `minmax(260px, 22vw)` → `clamp(260px, 22vw, 400px)` since 22vw exceeds the Datapad's calibrated max on wide monitors. - NavRail mobile tablist: added `overflow-x-auto` so future tabs don't break the layout silently. Verified: tsc clean, `next build` succeeds, no new bundle bloat (/explore: 480 kB, unchanged).
# Conflicts: # components/explorer/AppShell.tsx # components/explorer/NavRail.tsx # lib/store.ts
# Conflicts: # components/explorer/NavRail.tsx
SafeDep Report SummaryNo dependency changes detected. Nothing to scan. Installation is not linked with SafeDep Tenant. Click here to optionally link your GitHub App installation with SafeDep Tenant. This report is generated by SafeDep Github App |
There was a problem hiding this comment.
Pull request overview
This PR consolidates a stack of open feature PRs into a single integration branch, combining new cinematic/gameplay experiences (Time Machine, Memory Palace, story deeplinks/sharing), visual upgrades (procedural planet shaders, May 4th takeover), and stabilization/mobile-parity fixes across the Explorer UI and global store.
Changes:
- Adds new interactive/cinematic features: Time Machine auto-scrub, Memory Palace geography game, and Story Mode URL deeplinks + share-to-clipboard.
- Introduces May the Fourth landing page takeover (banner/tagline/glyph/crosshair) and procedural climate-based planet shaders.
- Integrates supporting store/schema updates, mobile drawer parity updates, and WebGL fallback/hydration guards.
Reviewed changes
Copilot reviewed 35 out of 36 changed files in this pull request and generated 11 comments.
Show a summary per file
| File | Description |
|---|---|
| scripts/build-llm-descriptions.ts | New local script to generate missing KB long descriptions via Transformers.js model inference + caching + manifest updates. |
| package.json | Adds build:llm-descriptions script entry. |
| lib/store.ts | Extends global Zustand store for crawl visibility, story deeplinks (initial beat), Time Machine state, and Memory Palace game state/actions. |
| lib/data/positions.ts | Passes optional physical metadata through PlacedPlanet for shader selection. |
| lib/data/memory-hints.ts | Adds Memory Palace hint dataset (3 difficulties). |
| docs/mobile-checklist.md | Adds/updates mobile verification checklist used for UI parity reviews. |
| data/build/manifest.json | Adds LLM enrichment counters/timestamps to build manifest. |
| components/Wordmark.tsx | Adds forceGreen option to render May 4th green glyph variant. |
| components/timeline/TimelineView.tsx | Adds WebGL “unknown” placeholder + mobile HUD label visibility tweaks. |
| components/timeline/EventMarker.tsx | Adds deterministic label staggering + mobile-friendly label sizing. |
| components/OpeningCrawl.tsx | Hooks crawl overlay into global crawlOpen to hide chrome + improves skip button placement/size. |
| components/MayTheFourth.tsx | New May 4th hook + banner/tagline/wordmark/crosshair takeover components. |
| components/IntroCanvas.tsx | Adds WebGL “unknown” placeholder to avoid initial mismatch. |
| components/game/MemoryPalace.tsx | New Memory Palace game overlay, difficulty picker, and high score persistence. |
| components/galaxy/shaders/planet/*.ts | New shader library for planet climates (desert/ice/ocean/lava/gas-giant/forest/city) plus selector. |
| components/galaxy/shaders/planet/index.ts | Exposes shader registry + heuristic getClimateFromMetadata. |
| components/galaxy/Planet.tsx | Adds near-distance shader activation, reduced-motion uniform freezing, and in-map game guess handling. |
| components/galaxy/GalaxyCanvas.tsx | Adds WebGL “unknown” placeholder + mobile HUD label adjustments. |
| components/explorer/TimelineScrubber.tsx | Improves mobile anchor density and prevents edge label clipping. |
| components/explorer/NavRail.tsx | Adds Time Machine + Memory Palace triggers; refines desktop/mobile rail styling. |
| components/explorer/DatapadDrawer.tsx | Adds Crawl + official clip actions to mobile header; embeds EntityCrawl overlay. |
| components/explorer/Datapad.tsx | Aligns Crawl button availability with entity-type gating. |
| components/explorer/AppShell.tsx | Adds story deeplink initialization and hides chrome during crawl without unmounting. |
| components/EntityCrawl.tsx | Wires crawl overlay to global crawlOpen with defensive cleanup. |
| components/cinematic/TimeMachine.tsx | New Time Machine overlay + auto-scrub loop with event-aware slowdown + keyboard controls. |
| components/cinematic/StoryMode.tsx | Syncs story state to URL + adds share-to-clipboard UI feedback. |
| components/cinematic/index.ts | Exports Time Machine from cinematic barrel. |
| app/page.tsx | Integrates May 4th takeover components into landing page and adjusts typography/layout. |
| .vscode/settings.json | VS Code setting to ignore unknown CSS at-rules warnings. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| e.stopPropagation(); | ||
| const gameState = useSelection.getState().game; | ||
| if (gameState.active && !gameState.feedback.active) { | ||
| const isCorrect = planet.id === gameState.targetId; | ||
| useSelection.getState().submitGuess(planet.id, isCorrect); | ||
| return; | ||
| } |
| // Check distance to camera | ||
| const dist = camera.position.distanceTo(ref.current.getWorldPosition(new THREE.Vector3())); | ||
| const near = dist < NEAR_THRESHOLD; | ||
| if (near !== isNear) setIsNear(near); | ||
|
|
| { | ||
| id: "h-13", | ||
| targetId: "mandalore", | ||
| hint: "The homeworld of the galaxy's most legendary warriors, once purged by the Empire.", | ||
| difficulty: "medium", | ||
| }, |
| { | ||
| id: "h-18", | ||
| targetId: "yavin", | ||
| hint: "The jungle moon where the Rebellion launched its first great strike.", | ||
| difficulty: "medium", | ||
| }, |
| if (storyId && findStory(storyId)) { | ||
| const beatIndex = beatStr ? parseInt(beatStr, 10) : -1; | ||
| useSelection.getState().playStory(storyId, beatIndex); | ||
| if (isPaused) useSelection.getState().pauseStory(); | ||
| } |
|
|
||
| const baseSpeed = 225; | ||
| const dEra = (baseSpeed / slowdown) * dt; | ||
| next = eraRef.current + dEra; |
| onClick={() => { | ||
| // Trigger the start screen in MemoryPalace component | ||
| // via a custom event or store state. | ||
| // For now, I'll add a 'gameOpen' state to the store if needed, | ||
| // but I already have 'game.active'. | ||
| // I'll add a way to toggle the start screen. | ||
| window.dispatchEvent(new CustomEvent("holocron:open-game")); | ||
| }} |
| ## 4. Datapad (Mobile Drawer) | ||
| - [ ] **Pivot Parity**: All pivot buttons (Galaxy, Timeline, Lineage) must be present and functional. | ||
| - [ ] **Crawl Support**: Film entities must show a "Crawl" button that triggers the cinematic opening. | ||
| - [ ] **Scroll Locking**: Scrolling inside the Datapad drawer should not trigger accidental pans in the 3D canvas behind it. |
| * | ||
| * Enriches entity `long` descriptions using a local LLM (Phi-3-mini) for archive gaps. | ||
| * Target: entities in data/build/kb.json that have an empty `long` field. | ||
| * |
| onQuit, | ||
| clearFeedback | ||
| }: { | ||
| game: any; | ||
| hint: MemoryHint | null; | ||
| onNext: () => void; | ||
| onQuit: () => void; | ||
| clearFeedback: () => void; | ||
| }) { |



Accepts the open PR queue as a single verified integration branch.
Included PRs:
Integration fixes added here:
Verification: