1## World model23Create one world record for each catalog pack, including the core pack:45```js6{7 id: 'tidewater',8 number: 4,9 packId: 'tidewater',10 name: 'Tidewater',11 author: '...',12 glyph: '๐',13 tagline: 'Everything floats until it does not.',14 accent: 'sink',15 origin: 'bundled',16 registrationIndex: 3,17 sheets: ['tidewater:sheet-1'],18 levelCount: 9,19 completedCount: 2,20}21```2223`number` is one-based in display and follows the final world order. The world24record is derived from the catalog, not duplicated in level data. A pack may25have multiple sheet records, but every sheet has exactly one `worldId`/`packId`.26The core pack is world 1 and owns its own sheet range. No bundled pack is27implicitly folded into the core world.2829The layout API should expose both `worlds` and `sheets`, plus lookup helpers for30world by pack ID, sheet by ID, and node by global level ID. Each sheet keeps the31existing fifteen-cell serpentine auto layout and links to the previous and next32sheet in the same world. A world boundary is represented separately from an33intra-world sheet boundary so callers can animate or announce it later.3435## Ordering and registration3637The catalog order is the source of truth:38391. core;402. bundled packs in registration order;413. local and URL/imported packs in install order.4243The currently approved default bundle is core, Crossword, Crate Works, then44Tidewater. Clockwork joins only after W12 custom-property presentation review;45Garden Basics and Word Lab remain importable examples outside the default46INDEX. This is a registration choice, not an INDEX hard-coded ID rule.4748Replacing a pack preserves its position. Forking an imported pack appends the49fork as a new imported world. Removing an imported pack removes its world and50its sheets while preserving the relative order of all remaining worlds.5152The layout must not infer world identity from `origin`, a hard-coded ID set, or53the active level. This prevents a newly bundled or imported pack from silently54joining core.5556## Manifest world metadata5758`manifest.world` is optional. When present it is an object with these fields:5960- `glyph`: exactly one grapheme cluster, counted with `Intl.Segmenter` using61 `granularity: 'grapheme'`, and no more than 16 UTF-16 code units. This permits62 visible emoji such as `โ๏ธ`, ZWJ sequences, and flags while restricting the63 card to one glyph;64- `tagline`: at most 80 characters, one source line with no newline, sentence65 case, and no `ยท` (U+00B7). The diagnostic for the middle dot is explicit:66 `Tagline can't use ยท; use a comma or a dash.`;67- `accent`: an optional token from `you`, `push`, `stop`, `win`, `sink`,68 `defeat`, or `tick`.6970World identity is presentation metadata, so an invalid optional field produces71a nonblocking W11 note and does not reject the pack. The world falls back to72the first palette glyph, no tagline, and the default `--fg` path. Missing73`manifest.world` uses the same defaults. Invalid gameplay fields continue to74reject the complete pack atomically through the existing pack validator.75Normalized metadata and notes are available through catalog pack records and76pack-service views without changing share identity or level IDs.7778## Progress and chapter unlocking7980Solved state remains keyed by `{ packId, levelId }`. World completion is the81 count of solved levels whose `packId` matches that world, over that world's82 level count. Unlocking is evaluated in world order within each world: its83 opener is always available and each later proof requires the previous proof in84 the same world. Solving or selecting a proof in one world cannot unlock a85 proof in another world.8687The active INDEX state must carry `worldId`, `worldIndex`, `sheetId`, and88`nodeId`. World switching selects the first available node in the destination89world, preserving that world's current cursor when one exists. If no proof in a90world is available, its opener remains the selectable boundary target and the91existing locked-node indication applies.9293## Navigation contract9495`Q` and `E` switch one world left or right. Gamepad LB/RB map to the same96actions. Touch uses a two-finger horizontal swipe and must resolve one switch97per gesture. Switching at the first/last world is a no-op with the existing98blocked-navigation feedback and does not alter progress or the active proof.99100Walking from the terminal node of a world's final sheet in its path-forward101direction enters the first node of the next world. Walking backward from the102first node enters the final node of the previous world. There is no wraparound.103Intra-world sheet crossings continue to use the current path boundary behavior104and must not be mistaken for a world change.105106## Presentation seam107108The INDEX scene receives a pure view model containing:109110- `worldNumber`, `worldCount`, `worldName`, `worldGlyph`, `worldTagline`,111 `worldAccent`;112- `completedCount`, `levelCount`, and the current world-strip position;113- `enteredWorldBefore`, `worldCardRequested`, and `cardOrigin` (`index` or114 `workshop`).115116The first entry into a world and Workshop PLAY request a card once per session117and then settle on the world sheet. The card displays the glyph, name, tagline,118author, and an ENTER action. The follow-up presentation change owns its exact119geometry, copy fitting, and 280ms camera ease; the engine must only emit stable120world transition and card-request state.121122## Compatibility and migration123124Existing progress keys remain valid. Catalog callers that only ask for flat125levels continue to receive the same ordered level records. The layout migration126updates callers that assumed built-ins shared a core sheet range. Imported127packs without `manifest.world` remain valid and receive normalized default128metadata.129130## Verification and designer handoff131132Physical keyboard Q/E is handled by the stage action router; gamepad LB/RB and133two-finger gestures enter through the shared input intent path. The local and134public world-index browser fixtures exercised Q/E, first/last boundary135feedback, Core โ Crossword โ Crate Works โ Tidewater order, Workshop PLAY,136mobile touch, and reduced motion without page errors. Focused map/input tests137cover world and sheet edges, cursor restoration after removal, independent138opener locks and completion counts, and stable pack/local progress keys.139140The designer accepted the header, strip, world cards, and four-world bundle on1412026-09-24 in `docs/design-inbox.md`. The separate presentation change has142been archived. The complete 30-proof sequential world gate, 373-test Node143suite, production build, and local Gift/Workshop/share browser flow passed144before public revision 13 at `https://fcbc.n.zip/`. The live145`game-presentation` and `level-packs` specs contain no obsolete built-in146sheet-1 grouping rule; this change's merged spec now owns per-pack worlds.