- commit
- 6c3654dc3e84021fe6199003b6b951e6e08cfdac
- parent
- a224fc9aee96317c4ca86d06e3c7bab712867b7a
- author
- Dami <dami.etoile@gmail.com>
| A | openspec/ | 2 | + |
| A | openspec/ | 88 | ++++++++++++++++++++ |
| A | openspec/ | 38 | +++++++++ |
| A | openspec/ | 131 | ++++++++++++++++++++++++++++++ |
| A | openspec/ | 39 | +++++++++ |
@@ -0,0 +1,88 @@
1+## Source contract2+3+This change follows the accepted D20 material in `docs/design.md` and the4+designer reply headed **D20 header round 1** in `docs/design-inbox.md`, dated5+2026-09-24. `openspec/changes/add-world-index-navigation/` owns the world view6+model, request origins, world transition events, and navigation behavior. This7+change consumes those values and does not recreate them from level data.8+9+## INDEX header10+11+The desktop and mobile header uses this hierarchy, with 8px between lines:12+13+1. An 11px tracked eyebrow in `--muted`: `INDEX | WORLD NN`.14+2. The world name in `--fg`, weight 800, at 28px on desktop.15+3. The world tagline in `--muted`, falling back to `walk the path, pick a16+ proof`.17+18+The large standalone `INDEX` heading and colliding stacked world-number19+heading are removed from this presentation. World completion is shown as20+`★ n / N`, counted only for the active world. The header must fit its owning21+region at the supported desktop and 390px mobile sizes without overlapping the22+board or footer.23+24+On mobile, the world name may use the existing measured fitting helper and a25+smaller scene-approved size when needed. This change does not alter authored26+world names or the D20 world model.27+28+## World strip29+30+The desktop strip is drawn as `[Q] ◀ ● • • ▶ [E]`: keycaps flank the arrows,31+arrows are 14px, dots are 10px, and the current dot uses the normalized32+world's accent when one is present. Non-current dots use the neutral dot role.33+The strip is a visible control and its hit geometry follows the drawn control.34+35+On mobile, keycaps are omitted. The arrows remain visible 44px tap targets,36+with no change to the one-world-per-gesture behavior owned by D20.37+38+When the D20 seam reports a world switch, the sheet/camera transition uses the39+existing 280ms world ease and the current dot slides between its old and new40+positions over 110ms with the accepted back-ease. The dot and sheet use the41+same transition start, while each keeps its own duration. Reduced motion shows42+the settled dot and sheet immediately.43+44+## First-entry world card45+46+When the stage receives the D20 `world-card` request, INDEX renders the card47+over the stage with the existing iris entry choreography. The card contains:48+49+- the normalized world glyph at 96px;50+- the world name;51+- the tagline, when present;52+- `by <author>`; and53+- an ENTER action shown as a drawn keycap on keyboard layouts.54+55+The card is centered on the ink-and-signal surface and preserves the existing56+hard-edged card lip and Recursive font. The card uses the world's accent as a57+signal color while retaining neutral card surfaces. Card text is fitted and58+wrapped within the card; it must not clip at the supported desktop or mobile59+sizes.60+61+ENTER (or the equivalent confirmed card action) dismisses the card and62+returns to the settled INDEX sheet. Dismissing the card does not select or63+enter a proof. The card is shown at most once per world per session, and a64+Workshop PLAY request uses the same composition with its D20 `workshop` origin.65+On touch layouts the ENTER action keeps its visible keycap style but exposes a66+44px hit target. Reduced motion presents the settled card immediately.67+68+## Mobile INDEX footer and narration69+70+Below 760px or on a coarse pointer, INDEX does not show keyboard keycap71+instructions. Under the active proof banner it shows `tap the cat to play`,72+and the bottom thumb row exposes the menu affordance (`☰ menu`). Workshop is73+reached through that menu. Desktop retains the scene's drawn keycap and verb74+pairs.75+76+The canvas accessible label includes the active world number and name, its77+completed and total proof count, and the Q/E world-switch action on keyboard78+layouts. While the card is open, narration names the world, tagline, author,79+and the ENTER action. Pointer/touch targets and narration must refer to the80+same visible controls.81+82+## Non-goals83+84+- Changing the D20 world model, ordering, progress keys, or navigation.85+- Changing rule evaluation, actor movement, grid coordinates, or simulation86+ snapshots.87+- Adding a new world identity validator or changing pack share data.88+- Changing the board's map geometry or proof solving behavior.@@ -0,0 +1,38 @@
1+# World INDEX presentation2+3+## Why4+5+The D20 navigation change provides a stable world model, world switching6+events, and a first-entry card request. The remaining presentation contract is7+still implicit in the renderer: the INDEX header hierarchy, world strip8+controls, mobile touch affordances, and the card's entry interaction need one9+reviewable specification. The designer's 2026-09-24 D20 header review in10+`docs/design-inbox.md` is the source for the latest placement and timing11+decisions.12+13+## What changes14+15+- Define the first-entry and Workshop world card composition and ENTER input16+ without changing the D20 request seam or installing content.17+- Replace the large INDEX title stack with the accepted desktop and mobile18+ world header hierarchy.19+- Make the world strip an explicit control with desktop keycaps, mobile tap20+ targets, accent-aware dots, and synchronized 110ms dot motion during the21+ 280ms world sheet transition.22+- Define mobile INDEX footer affordances and accessible narration for world23+ identity, progress, actions, and card dismissal.24+25+## Scope boundary26+27+This change owns canvas presentation, layout, animation, hit geometry, and28+accessibility copy. It does not change engine rules, simulation state, integer29+grid coordinates, catalog identity, world ordering, navigation semantics, or30+pack validation. The world model and transition seam are defined by31+`add-world-index-navigation`.32+33+## Impact34+35+Affected modules are the INDEX and world-card renderers, their stage-owned36+presentation input/hit handling, and focused visual/accessibility tests. The37+existing D20 navigation tests and world solver remain separate verification38+gates.@@ -0,0 +1,131 @@
1+## ADDED Requirements2+3+### Requirement: INDEX SHALL present the active world as the header subject4+5+The INDEX presentation SHALL render an 11px tracked `INDEX | WORLD NN`6+eyebrow, the active world name in `--fg`, weight 800, and its muted tagline7+with 8px vertical spacing. The tagline SHALL fall back to8+`walk the path, pick a proof` when the normalized world has none. The large9+standalone INDEX heading and overlapping world-number stack SHALL not be10+rendered. The presentation SHALL also show `★ n / N`, where both counts are11+scoped to the active world view model.12+13+#### Scenario: Desktop world header establishes hierarchy14+15+- **WHEN** INDEX renders an active world on a desktop canvas16+- **THEN** the eyebrow, name, tagline, and per-world count are legible,17+ separated by the specified spacing, and do not overlap the board or world18+ strip19+20+#### Scenario: Missing tagline uses the approved fallback21+22+- **WHEN** the normalized active world has no tagline23+- **THEN** INDEX renders `walk the path, pick a proof` in the tagline region24+25+#### Scenario: Mobile header remains inside its owning region26+27+- **WHEN** INDEX renders at 390px wide28+- **THEN** the complete world name, fallback or authored tagline, and per-world29+ count remain inside the header region without covering the board or footer30+31+### Requirement: INDEX SHALL render the world strip as an actionable control32+33+The desktop strip SHALL render `[Q] ◀ ● • • ▶ [E]` with drawn Q and E keycaps,34+14px arrows, 10px dots, and one dot per world. The active dot SHALL use the35+normalized world's accent when present; inactive dots SHALL use the neutral dot36+role. On mobile or coarse pointers, keycaps SHALL be omitted and each arrow37+SHALL expose a 44px tap target. Hit geometry SHALL match the visible arrows.38+39+#### Scenario: World strip exposes adjacent actions40+41+- **WHEN** INDEX renders three worlds on desktop42+- **THEN** it shows Q, a previous arrow, three dots, a next arrow, and E in43+ that order, with the active dot accented44+45+#### Scenario: Mobile strip exposes touch targets46+47+- **WHEN** INDEX renders on a 390px canvas or a coarse pointer48+- **THEN** Q/E keycaps are absent and the previous and next arrows each have a49+ 44px tappable target50+51+#### Scenario: Dot slide follows a world transition52+53+- **WHEN** the D20 seam reports a world switch54+- **THEN** the active dot travels from its prior position to its new position55+ over 110ms with back-ease, while the world sheet uses the same transition56+ start and its 280ms ease57+58+#### Scenario: Reduced motion settles the strip59+60+- **WHEN** reduced motion is enabled during a world switch61+- **THEN** the strip renders the destination dot and sheet immediately without62+ an intermediate slide63+64+### Requirement: The first-entry world card SHALL present and dismiss world identity65+66+The INDEX SHALL consume the D20 `world-card` request and render a centered,67+hard-edged card containing the normalized glyph at 96px, name, tagline when68+present, `by <author>`, and an ENTER action. The card SHALL use the normalized69+accent as a signal color, fit all copy inside the card at desktop and mobile70+sizes, and preserve the existing iris entry choreography. ENTER or the71+equivalent confirmed pointer/touch action SHALL dismiss the card and leave the72+player on the settled INDEX sheet without selecting a proof. The card SHALL73+not install packs or mutate simulation state.74+75+#### Scenario: INDEX first entry opens a readable world card76+77+- **WHEN** D20 requests a card with origin `index`78+- **THEN** the card shows the world glyph, name, tagline, author, and ENTER79+ action without clipping80+81+#### Scenario: Workshop PLAY uses the same card presentation82+83+- **WHEN** D20 requests a card with origin `workshop`84+- **THEN** the card uses the same composition and preserves the Workshop85+ selected pack's first node for the subsequent INDEX sheet86+87+#### Scenario: Card confirmation returns to INDEX88+89+- **WHEN** the player confirms ENTER on an open world card90+- **THEN** the card closes and INDEX remains on the active world's sheet; no91+ proof move or simulation turn is recorded92+93+#### Scenario: Touch confirmation has a large target94+95+- **WHEN** the card is rendered for a coarse pointer96+- **THEN** the visible ENTER keycap remains readable and its confirmation hit97+ target is at least 44px high98+99+#### Scenario: Card motion respects reduced motion100+101+- **WHEN** reduced motion is enabled102+- **THEN** the card appears in its settled geometry without an iris intermediate103+104+### Requirement: Mobile INDEX controls SHALL use touch affordances and coherent narration105+106+Below 760px or on coarse pointers, INDEX SHALL omit keyboard keycap hints,107+render `tap the cat to play` below the active proof banner, and expose the108+bottom `☰ menu` thumb affordance. Workshop SHALL remain reached through that109+menu. The INDEX accessibility label SHALL include world number/name,110+world-scoped completion, total proof count, and the keyboard world-switch111+action where keyboard controls are available. An open card label SHALL include112+world identity, author, and its ENTER action.113+114+#### Scenario: Mobile footer removes desktop hints115+116+- **WHEN** INDEX renders below 760px or for a coarse pointer117+- **THEN** it shows the cat play prompt and menu thumb affordance without the118+ desktop ENTER, ESC, or SPACE keycap row119+120+#### Scenario: Accessibility follows the visible world state121+122+- **WHEN** the active world or its completed count changes123+- **THEN** the INDEX label names the current world and its updated `n of N`124+ proof progress, and announces Q/E switching when applicable125+126+#### Scenario: Presentation leaves simulation and grid state unchanged127+128+- **WHEN** any header, strip, card, or mobile footer presentation is measured,129+ animated, or dismissed130+- **THEN** engine rules, simulation snapshots, integer board coordinates,131+ progress keys, and pointer semantics remain unchanged@@ -0,0 +1,39 @@
1+## 1. World header and strip2+3+- [ ] 1.1 Render the accepted desktop/mobile INDEX header hierarchy from the D204+ world view model, including fallback tagline and per-world completion.5+- [ ] 1.2 Render the desktop `[Q] ◀ dots ▶ [E]` strip with accent-aware current6+ dot and visible control geometry.7+- [ ] 1.3 Add mobile 44px arrow targets, omit mobile keycaps, and keep strip hit8+ geometry aligned with the drawn controls.9+- [ ] 1.4 Synchronize the 110ms back-ease dot slide with the D20 280ms world10+ sheet transition and settle both immediately for reduced motion.11+12+## 2. World card13+14+- [ ] 2.1 Apply the accepted centered card composition: 96px glyph, name,15+ tagline, `by <author>`, accent signal, hard-edged surfaces, and ENTER action.16+- [ ] 2.2 Preserve the D20 `index` and `workshop` origins and dismiss the card17+ to the settled INDEX sheet without entering a proof or changing simulation.18+- [ ] 2.3 Fit and wrap card copy for desktop/mobile canvases, expose the 44px19+ coarse-pointer ENTER target, and settle the card under reduced motion.20+- [ ] 2.4 Add focused renderer, input, and accessibility tests for first entry,21+ Workshop PLAY, confirmation, pointer/touch parity, and one-per-session card22+ behavior.23+24+## 3. Mobile controls and narration25+26+- [ ] 3.1 Replace mobile INDEX keycap hints with `tap the cat to play` and the27+ `☰ menu` thumb affordance, keeping Workshop behind that menu.28+- [ ] 3.2 Keep INDEX and open-card accessible labels synchronized with visible29+ world identity, progress, controls, and ENTER dismissal.30+- [ ] 3.3 Verify desktop and 390x844 screenshots for hierarchy, overlap,31+ transitions, card fitting, and footer placement, including reduced motion.32+33+## 4. Verification and handoff34+35+- [ ] 4.1 Run focused presentation and browser tests without changing D2036+ navigation or engine solver behavior.37+- [ ] 4.2 Run the full Node suite and production build.38+- [ ] 4.3 Post the desktop/mobile header, strip, card, and footer evidence to39+ `docs/design-inbox.md` for designer review before release.