Files
scrying-pool/_bmad-output/implementation-artifacts/spec-strip-reorder-spotlight-snapshots.md
T
uberwald 9e80c2c028 Add re-order, spotlight/focus, and auto-position-snapshots features
- HTML5 drag-and-drop reordering of strip participants (per-GM flag)
- Shift+click toggles spotlight focus on a participant (gold ring indicator)
- Escape exits focus mode
- Auto-save strip position on drag end + every 30s with viewport validation
- Reset strip position button in Director's Board
- French locale strings for reset button
2026-05-27 11:44:24 +02:00

5.5 KiB

title, type, created, status, baseline_commit, context
title type created status baseline_commit context
Strip: Reorder, Spotlight & Auto-Snapshots feature 2026-05-27 done 816b7951fb

Intent

Problem: Strip participants have a fixed order, no way to focus a single participant, and position is only saved on close.

Approach: Add HTML5 drag-and-drop reordering (per-GM flag), Shift+click spotlight (in-memory, one-tile focus mode), and periodic auto-save of strip position (debounced + 30s interval with viewport validation).

Boundaries & Constraints

Always:

  • Re-order: persists to game.user.setFlag('scrying-pool', 'participantOrder', string[]), per-GM only
  • Spotlight: in-memory _focusedUserId only, no socket/persistence
  • Auto-snapshots: extends existing stripState flag (left, top, width, height, savedAt), backward-compatible
  • All three features are strip-only (not Director's Board)
  • French locale strings in scrying-pool.lang.fr.json

Ask First: None

Never:

  • No external drag-and-drop libraries
  • No socket broadcasts for re-order or spotlight
  • No CSS animation framework changes

I/O & Edge-Case Matrix

Scenario Input / State Expected Output / Behavior Error Handling
Re-order: drag participant Drag start on tile Tile shows opacity: 0.3 during drag N/A
Re-order: drop between tiles Drop at new position Participant order updates, flag saved, strip re-renders Save failure silently caught
Re-order: double-click grip Double-click grip area Order resets to connection order N/A
Spotlight: Shift+click Shift+click participant Only that participant visible, others display:none in DOM, strip resized N/A
Spotlight: exit via Escape Press Escape Full list restored, _focusedUserId cleared N/A
Spotlight: exit via button Click exit-focus button (replaces DB icon) Same as Escape N/A
Auto-snapshot: drag ends mouseup after drag Debounced save to stripState flag Save failure silently caught
Auto-snapshot: 30s timer Interval fires Save current position to stripState Save failure silently caught
Auto-snapshot: position off-screen Saved position outside viewport Fall back to default position Silent fallback, no error

Code Map

  • src/ui/gm/ScryingPoolStrip.js — All three features: drag handlers, spotlight state, auto-save timer
  • styles/components/_roster-strip.less — Drag feedback (opacity: 0.3), spotlight visual state
  • templates/directors-board.hbs — Reset strip position button
  • src/ui/gm/DirectorsBoard.js — Reset position handler
  • module.js — (no changes needed, instantiates the class)
  • scrying-pool.lang.fr.json — French locale strings

Tasks & Acceptance

Execution:

  • src/ui/gm/ScryingPoolStrip.js — Add _focusedUserId, drag handlers, _savePosition, re-order in _prepareContext
  • styles/components/_roster-strip.less.sp-state-focused gold ring, drag ghost opacity
  • templates/directors-board.hbs — Reset strip position button
  • src/ui/gm/DirectorsBoard.js_onResetStripPosition() handler

Acceptance Criteria:

  • Given a strip with 3+ participants, when GM drags a participant tile to a new position, then the participant order updates and persists across re-renders
  • Given any layout, when GM Shift+clicks a participant, then other participants collapse and the focused tile shows gold state ring
  • Given spotlight mode is active, when GM presses Escape, then all participants return to normal
  • Given the strip is open, when GM drags the strip to a new position and releases, then the position is saved
  • Given a saved off-screen position, when the strip re-renders, then it appears at default coordinates

Suggested Review Order

Re-order + Spotlight core logic

Template changes

CSS

Director's Board

Locales

Verification

Commands:

  • npm run lint -- expected: 0 errors
  • npm run typecheck -- expected: 0 errors
  • npm run test -- expected: all tests pass