{
	"schemaVersion": "1.0.0",
	"readme": "README.md",
	"modules": [
		{
			"kind": "javascript-module",
			"path": "index.js",
			"declarations": [
				{
					"kind": "class",
					"name": "GameScreen",
					"tagName": "game-screen",
					"customElement": true,
					"superclass": {
						"name": "HTMLElement",
						"package": "global:"
					},
					"description": "Logical pixel viewport. Put layers, tilemaps and sprites directly inside. Graphics clip to the viewport and paint in DOM order.",
					"attributes": [
						{
							"name": "width",
							"type": {
								"text": "number"
							},
							"default": "128",
							"description": "Logical width. Minimum 1."
						},
						{
							"name": "height",
							"type": {
								"text": "number"
							},
							"default": "96",
							"description": "Logical height. Minimum 1."
						},
						{
							"name": "camera-x",
							"type": {
								"text": "number"
							},
							"default": "0",
							"description": "Camera offset in logical pixels. Direct tilemap layers scroll in CSS. Copied to direct bitmap layers on upgrade, insertion, and change."
						},
						{
							"name": "camera-y",
							"type": {
								"text": "number"
							},
							"default": "0",
							"description": "Camera offset in logical pixels. Direct tilemap layers scroll in CSS. Copied to direct bitmap layers on upgrade, insertion, and change."
						}
					],
					"cssProperties": [
						{
							"name": "--game-screen-width",
							"default": "32rem",
							"description": "Maximum rendered width of the responsive viewport."
						},
						{
							"name": "--game-screen-background",
							"default": "#171a29",
							"description": "Color or CSS background behind the graphics."
						}
					],
					"x-markup": [
						{
							"name": "data-world-viewport",
							"description": "Marks the screen that a world projects into depth. Give that screen tabindex=\"0\" so the world can focus it at launch."
						}
					]
				},
				{
					"kind": "class",
					"name": "GameLayer",
					"tagName": "game-layer",
					"customElement": true,
					"superclass": {
						"name": "HTMLElement",
						"package": "global:"
					},
					"description": "Repeating bitmap sampled into a canvas on demand. The first direct img supplies the texture and accessible alternative. A missing, failed or loading image leaves the authored fallback. Put inside a game-screen. Layer resolution defaults to 128 by 96 and is stretched to the viewport. A direct game-screen layer containing a game-tilemap scrolls the map with CSS. Extend the layer beyond the screen when scrolling should reveal more tiles. In a game-world, the perspective mode projects a CSS ground plane and scenery layers use factor and drift for parallax.",
					"attributes": [
						{
							"name": "mode",
							"type": {
								"text": "\"plain\" | \"affine\" | \"scanlines\" | \"columns\" | \"road\" | \"perspective\""
							},
							"default": "plain",
							"description": "Plain repeats the image. Affine applies one centered transform. Scanlines offset each row; columns offset each column. Road leaves the top third transparent and increases zoom by row toward the viewer, repeating along the texture’s vertical axis. Unknown modes use plain."
						},
						{
							"name": "width",
							"type": {
								"text": "number"
							},
							"default": "128",
							"description": "Canvas width. Rounded and clamped to 1–512."
						},
						{
							"name": "height",
							"type": {
								"text": "number"
							},
							"default": "96",
							"description": "Canvas height. Rounded and clamped to 1–512."
						},
						{
							"name": "scroll-x",
							"type": {
								"text": "number"
							},
							"default": "0",
							"description": "Local horizontal scroll in logical pixels. Positive values move the layer left."
						},
						{
							"name": "scroll-y",
							"type": {
								"text": "number"
							},
							"default": "0",
							"description": "Local vertical scroll in logical pixels. Positive values move the layer up in orthographic modes, or advance texture depth in road mode."
						},
						{
							"name": "camera-x",
							"type": {
								"text": "number"
							},
							"default": "0",
							"description": "Camera offset in logical pixels. Managed by the screen when directly nested in one."
						},
						{
							"name": "camera-y",
							"type": {
								"text": "number"
							},
							"default": "0",
							"description": "Camera offset in logical pixels. Managed by the screen when directly nested in one."
						},
						{
							"name": "factor",
							"type": {
								"text": "number"
							},
							"default": "1",
							"description": "Multiplier for both camera offsets. Applied before adding local scroll."
						},
						{
							"name": "scale",
							"type": {
								"text": "number"
							},
							"default": "1",
							"description": "Base texture scale, clamped to 0.125–16. Road mode multiplies this by depth."
						},
						{
							"name": "angle",
							"type": {
								"text": "number"
							},
							"default": "0",
							"description": "Clockwise degrees around the center. Affine mode only."
						},
						{
							"name": "amplitude",
							"type": {
								"text": "number"
							},
							"default": "0",
							"description": "Maximum strip offset in logical pixels. Scanlines, columns, and road only."
						},
						{
							"name": "phase",
							"type": {
								"text": "number"
							},
							"default": "0",
							"description": "Position within the offset wave in degrees. Scanlines, columns, and road only."
						},
						{
							"name": "drift",
							"description": "Forward parallax drift used when this layer is a direct child of a world stage.",
							"type": {
								"text": "number"
							},
							"default": "0.05"
						},
						{
							"name": "cell-size",
							"description": "World width and depth of a tile in a perspective layer.",
							"type": {
								"text": "number"
							},
							"default": "4"
						}
					],
					"cssProperties": [
						{
							"name": "--palette-0",
							"description": "First floor color on a perspective layer."
						},
						{
							"name": "--palette-1",
							"description": "Second floor color on a perspective layer."
						},
						{
							"name": "--palette-2",
							"description": "First cycling grid color on a perspective layer."
						},
						{
							"name": "--palette-3",
							"description": "Second cycling grid color on a perspective layer."
						},
						{
							"name": "--cycle-rate",
							"default": "5",
							"description": "Number of palette changes per second on a perspective layer."
						}
					]
				},
				{
					"kind": "class",
					"name": "GameSprite",
					"tagName": "game-sprite",
					"customElement": true,
					"superclass": {
						"name": "HTMLElement",
						"package": "global:"
					},
					"description": "A sprite references a pattern bank or contains its own image. Outside a world, x/y/width/height/scale preserve the original logical-screen API. Within a world, x/y/z/size map to CSS 3D transforms. Sprite sheets animate with CSS keyframes and steps(). Player, enemy and scenery behavior is authored on the same graphics record. Native enemy labels can contain checkbox controls for script-free targeting.",
					"attributes": [
						{
							"name": "x",
							"type": {
								"text": "number"
							},
							"default": "0",
							"description": "Left edge in logical pixels."
						},
						{
							"name": "y",
							"type": {
								"text": "number"
							},
							"default": "0",
							"description": "Top edge in logical pixels."
						},
						{
							"name": "width",
							"type": {
								"text": "number"
							},
							"default": "8",
							"description": "Unscaled bitmap width. Minimum 1."
						},
						{
							"name": "height",
							"type": {
								"text": "number"
							},
							"default": "8",
							"description": "Unscaled bitmap height. Minimum 1."
						},
						{
							"name": "scale",
							"type": {
								"text": "number"
							},
							"default": "1",
							"description": "Size multiplier from the top-left corner, clamped to 0.125–16."
						},
						{
							"name": "flip-x",
							"type": {
								"text": "boolean"
							},
							"description": "Presence mirrors the bitmap horizontally."
						},
						{
							"name": "frames",
							"description": "Number of consecutive sheet frames. CSS steps through them. A player selects a bank frame from input.",
							"type": {
								"text": "number"
							},
							"default": "1"
						},
						{
							"name": "fps",
							"description": "CSS sprite playback rate.",
							"type": {
								"text": "number"
							},
							"default": "8"
						},
						{
							"name": "start-x",
							"description": "Initial horizontal position, clamped to authored bounds.",
							"type": {
								"text": "number"
							},
							"default": "0"
						},
						{
							"name": "start-y",
							"description": "Initial height, clamped to authored bounds.",
							"type": {
								"text": "number"
							},
							"default": "1.1"
						},
						{
							"name": "min-x",
							"description": "Minimum horizontal position, bounded to -10–10.",
							"type": {
								"text": "number"
							},
							"default": "-2.7"
						},
						{
							"name": "max-x",
							"description": "Maximum horizontal position, bounded to -10–10 and at least min-x.",
							"type": {
								"text": "number"
							},
							"default": "2.7"
						},
						{
							"name": "min-y",
							"description": "Minimum height, bounded to -2–10.",
							"type": {
								"text": "number"
							},
							"default": "0.3"
						},
						{
							"name": "max-y",
							"description": "Maximum height, bounded to -2–10 and at least min-y. Equal vertical bounds constrain an actor to the ground.",
							"type": {
								"text": "number"
							},
							"default": "2.4"
						},
						{
							"name": "speed",
							"description": "Movement world units per second, clamped to 0.1–12.",
							"type": {
								"text": "number"
							},
							"default": "3.2"
						},
						{
							"name": "max-health",
							"description": "Initial shield capacity, integer 1–99.",
							"type": {
								"text": "number"
							},
							"default": "5"
						},
						{
							"name": "radius",
							"description": "Collision radius in world units, clamped to 0.05–1.",
							"type": {
								"text": "number"
							},
							"default": "0.18"
						},
						{
							"name": "size",
							"description": "Billboard height in world units.",
							"type": {
								"text": "number"
							},
							"default": "1.2"
						},
						{
							"name": "fire-rate",
							"description": "Seconds between player shots, clamped to 0.06–2.",
							"type": {
								"text": "number"
							},
							"default": "0.16"
						},
						{
							"name": "shot-speed",
							"description": "Forward shot speed, clamped to 20–180.",
							"type": {
								"text": "number"
							},
							"default": "70"
						},
						{
							"name": "recovery",
							"description": "Invulnerability after a hit, seconds clamped to 0.1–5.",
							"type": {
								"text": "number"
							},
							"default": "1.2"
						},
						{
							"name": "health",
							"description": "For a player, reflected remaining shield. For an enemy, the authored number of shots needed to destroy it (default 1).",
							"type": {
								"text": "number"
							}
						},
						{
							"name": "at",
							"description": "Forward distance at which the first enemy spawns.",
							"type": {
								"text": "number"
							},
							"default": "30"
						},
						{
							"name": "interval",
							"description": "Distance between spawns, clamped to 1–1000.",
							"type": {
								"text": "number"
							},
							"default": "35"
						},
						{
							"name": "count",
							"description": "Number of enemies, integer 0–50.",
							"type": {
								"text": "number"
							},
							"default": "1"
						},
						{
							"name": "behavior",
							"description": "straight, sine, dive, or chase.",
							"type": {
								"text": "string"
							},
							"default": "straight"
						},
						{
							"name": "z",
							"description": "World depth. CSS translate3d projects it through the screen perspective.",
							"type": {
								"text": "number"
							},
							"default": "60"
						},
						{
							"name": "spread",
							"description": "Alternating offset to either side of x, clamped to 0–5.",
							"type": {
								"text": "number"
							},
							"default": "0"
						},
						{
							"name": "sway",
							"description": "Horizontal amplitude for sine or dive motion.",
							"type": {
								"text": "number"
							},
							"default": "1"
						},
						{
							"name": "frequency",
							"description": "Sine angular frequency, clamped to 0–8.",
							"type": {
								"text": "number"
							},
							"default": "2"
						},
						{
							"name": "dive-rate",
							"description": "Height lost per second in dive movement, clamped to 0–2.",
							"type": {
								"text": "number"
							},
							"default": "0.45"
						},
						{
							"name": "tracking",
							"description": "Chase response coefficient, clamped to 0–3.",
							"type": {
								"text": "number"
							},
							"default": "0.8"
						},
						{
							"name": "score",
							"description": "Points awarded on destruction, rounded 0–10000.",
							"type": {
								"text": "number"
							},
							"default": "100"
						},
						{
							"name": "fire-delay",
							"description": "Delay before the first shot, seconds clamped to 0.1–20.",
							"type": {
								"text": "number"
							},
							"default": "1.2"
						},
						{
							"name": "spacing",
							"description": "World distance between repeating copies, clamped to 2–200.",
							"type": {
								"text": "number"
							},
							"default": "16"
						},
						{
							"name": "offset",
							"description": "Initial world distance, clamped to 0–200.",
							"type": {
								"text": "number"
							},
							"default": "0"
						},
						{
							"name": "actor",
							"description": "Contextual behavior in a world: player, scenery, or enemy. Rendering uses the same sprite primitive.",
							"type": {
								"text": "string"
							}
						},
						{
							"name": "tileset",
							"description": "ID of a pattern bank. Its image provides equal-sized, row-major sprite frames.",
							"type": {
								"text": "string"
							}
						},
						{
							"name": "aspect",
							"description": "Frame width divided by frame height for CSS world sizing.",
							"type": {
								"text": "number"
							},
							"default": "1"
						},
						{
							"name": "frame",
							"description": "Reflected selected frame for a player sprite.",
							"type": {
								"text": "number"
							}
						},
						{
							"name": "position-x",
							"description": "Reflected player center coordinate, separate from the image base x/y.",
							"type": {
								"text": "number"
							}
						},
						{
							"name": "position-y",
							"description": "Reflected player center altitude.",
							"type": {
								"text": "number"
							}
						},
						{
							"name": "priority",
							"type": {
								"text": "integer"
							},
							"default": "0",
							"description": "Stacking order in a flat screen. Higher values paint above lower values. Equal values paint in document order. Perspective worlds order sprites by depth."
						},
						{
							"name": "invulnerable",
							"type": {
								"text": "boolean"
							},
							"description": "Reflected during player recovery after a hit. The world stylesheet flashes the pilot sheet while this attribute is present."
						}
					],
					"events": [
						{
							"name": "game-shot",
							"type": {
								"text": "CustomEvent<{ x: number, y: number }>"
							},
							"description": "Bubbles and is composed. Emitted on each accepted shot."
						},
						{
							"name": "game-player-hit",
							"type": {
								"text": "CustomEvent<{ health: number, source: \"enemy\" | \"projectile\" }>"
							},
							"description": "Bubbles and is composed. Emitted on an accepted hit, after applying one point of damage and the recovery interval."
						},
						{
							"name": "game-enemy-hit",
							"type": {
								"text": "CustomEvent<{ remaining: number, destroyed: boolean, score: number }>"
							},
							"description": "Bubbles and is composed. Emitted from the wave for each accepted player shot. Score increases once when an enemy is destroyed."
						}
					],
					"x-markup": [
						{
							"name": "data-native-target",
							"description": "On the label wrapping a target checkbox and sprite image, enables pointer targeting without JavaScript."
						}
					]
				},
				{
					"kind": "class",
					"name": "GameTilemap",
					"tagName": "game-tilemap",
					"customElement": true,
					"superclass": {
						"name": "HTMLElement",
						"package": "global:"
					},
					"description": "A viewport-filling CSS grid. Use one element per cell, in row-major order, and style the cell or include an image. Cells beyond the declared grid are clipped. Layout uses typed CSS attr(). In a world, child game-tile elements name bank indices. Background maps use CSS atlas positions and may provide background-image, --sheet-columns and --sheet-rows for native rendering. Indexed ground maps repeat in the projected layer.",
					"attributes": [
						{
							"name": "columns",
							"type": {
								"text": "number"
							},
							"default": "16",
							"description": "Positive integer number of tile columns."
						},
						{
							"name": "rows",
							"type": {
								"text": "number"
							},
							"default": "12",
							"description": "Positive integer number of tile rows."
						},
						{
							"name": "tileset",
							"description": "Pattern-bank ID for tile references.",
							"type": {
								"text": "string"
							}
						},
						{
							"name": "palette",
							"description": "Palette ID for indexed patterns.",
							"type": {
								"text": "string"
							}
						},
						{
							"name": "encoding",
							"description": "Optional indices means whitespace-separated row-major tile indices. Otherwise use child game-tile cells.",
							"type": {
								"text": "string"
							}
						}
					],
					"cssProperties": [
						{
							"name": "--sheet-columns",
							"description": "Pattern-bank column count."
						},
						{
							"name": "--sheet-rows",
							"description": "Pattern-bank row count."
						}
					]
				},
				{
					"kind": "class",
					"name": "GameFlow",
					"tagName": "game-flow",
					"customElement": true,
					"superclass": {
						"name": "HTMLElement",
						"package": "global:"
					},
					"description": "Owns direct game-scene children. Use a document fragment link to select a scene, including without scripting. Browser history restores the scene. The start or first named scene is used when the fragment is absent or unknown.",
					"attributes": [
						{
							"name": "start",
							"type": {
								"text": "string"
							},
							"description": "ID of the initial scene. Put data-start on the same scene for the stylesheet fallback."
						},
						{
							"name": "scene",
							"type": {
								"text": "string"
							},
							"description": "Reflects the selected scene after upgrade. Set to a direct scene ID to navigate. Invalid values are restored to the scene selected by the current fragment or start."
						}
					],
					"events": [
						{
							"name": "game-scene-change",
							"type": {
								"text": "CustomEvent<{ scene: string, previous: string }>"
							},
							"description": "Bubbles and is composed. Emitted after switching between two named scenes. Initial selection is silent."
						}
					]
				},
				{
					"kind": "class",
					"name": "GameScene",
					"tagName": "game-scene",
					"customElement": true,
					"superclass": {
						"name": "HTMLElement",
						"package": "global:"
					},
					"description": "A scene contains ordinary light DOM. Within a game, use a document-unique id and tabindex=\"-1\" for focus after navigation. Outside a game it renders normally.",
					"attributes": [
						{
							"name": "id",
							"type": {
								"text": "string"
							},
							"description": "Fragment identifier for links and the game start and scene attributes."
						},
						{
							"name": "data-start",
							"type": {
								"text": "boolean"
							},
							"description": "Author this on one direct scene as the stylesheet’s default scene."
						},
						{
							"name": "active",
							"type": {
								"text": "boolean"
							},
							"description": "Reflected by the owning game after upgrade."
						}
					]
				},
				{
					"kind": "class",
					"name": "GameMenu",
					"tagName": "game-menu",
					"customElement": true,
					"superclass": {
						"name": "HTMLElement",
						"package": "global:"
					},
					"description": "Contains native fragment links, typically in a nav. Optional data-key attributes on links map KeyboardEvent.key values to actions while a link in that menu has focus. Modified clicks and nested menus keep their native ownership.",
					"events": [
						{
							"name": "game-action",
							"type": {
								"text": "CustomEvent<{ scene: string }>"
							},
							"description": "Dispatched from the chosen link before fragment navigation. Bubbles, is composed and is cancelable. The detail contains the fragment text without #, including any percent-encoding."
						}
					],
					"x-markup": [
						{
							"name": "data-key",
							"description": "On a descendant fragment link, adds a shortcut while focus is inside the menu. Use the KeyboardEvent.key value."
						}
					]
				},
				{
					"kind": "class",
					"name": "GameModal",
					"tagName": "game-modal",
					"customElement": true,
					"superclass": {
						"name": "HTMLElement",
						"package": "global:"
					},
					"description": "Coordinates one direct dialog child. Use native show-modal commands or the open attribute after upgrade. Escape and method=dialog preserve native behavior. A missing dialog is inert until inserted.",
					"attributes": [
						{
							"name": "open",
							"type": {
								"text": "boolean"
							},
							"description": "Presence opens the dialog, removal closes it. Reflected from native toggles. At initialization an already-open native dialog is adopted."
						}
					],
					"events": [
						{
							"name": "game-modal-change",
							"type": {
								"text": "CustomEvent<{ open: boolean }>"
							},
							"description": "Bubbles and is composed. Emitted for a changed open state after initialization. Native toggle notifications can coalesce."
						}
					]
				}
			],
			"exports": [
				{
					"kind": "js",
					"name": "GameScreen",
					"declaration": {
						"name": "GameScreen",
						"module": "index.js"
					}
				},
				{
					"kind": "custom-element-definition",
					"name": "game-screen",
					"declaration": {
						"name": "GameScreen",
						"module": "index.js"
					}
				},
				{
					"kind": "js",
					"name": "GameLayer",
					"declaration": {
						"name": "GameLayer",
						"module": "index.js"
					}
				},
				{
					"kind": "custom-element-definition",
					"name": "game-layer",
					"declaration": {
						"name": "GameLayer",
						"module": "index.js"
					}
				},
				{
					"kind": "js",
					"name": "GameSprite",
					"declaration": {
						"name": "GameSprite",
						"module": "index.js"
					}
				},
				{
					"kind": "custom-element-definition",
					"name": "game-sprite",
					"declaration": {
						"name": "GameSprite",
						"module": "index.js"
					}
				},
				{
					"kind": "js",
					"name": "GameTilemap",
					"declaration": {
						"name": "GameTilemap",
						"module": "index.js"
					}
				},
				{
					"kind": "custom-element-definition",
					"name": "game-tilemap",
					"declaration": {
						"name": "GameTilemap",
						"module": "index.js"
					}
				},
				{
					"kind": "js",
					"name": "GameFlow",
					"declaration": {
						"name": "GameFlow",
						"module": "index.js"
					}
				},
				{
					"kind": "custom-element-definition",
					"name": "game-flow",
					"declaration": {
						"name": "GameFlow",
						"module": "index.js"
					}
				},
				{
					"kind": "js",
					"name": "GameScene",
					"declaration": {
						"name": "GameScene",
						"module": "index.js"
					}
				},
				{
					"kind": "custom-element-definition",
					"name": "game-scene",
					"declaration": {
						"name": "GameScene",
						"module": "index.js"
					}
				},
				{
					"kind": "js",
					"name": "GameMenu",
					"declaration": {
						"name": "GameMenu",
						"module": "index.js"
					}
				},
				{
					"kind": "custom-element-definition",
					"name": "game-menu",
					"declaration": {
						"name": "GameMenu",
						"module": "index.js"
					}
				},
				{
					"kind": "js",
					"name": "GameModal",
					"declaration": {
						"name": "GameModal",
						"module": "index.js"
					}
				},
				{
					"kind": "custom-element-definition",
					"name": "game-modal",
					"declaration": {
						"name": "GameModal",
						"module": "index.js"
					}
				},
				{
					"kind": "custom-element-definition",
					"name": "game-world",
					"declaration": {
						"name": "GameWorld",
						"module": "world.js"
					}
				},
				{
					"kind": "js",
					"name": "GameWorld",
					"declaration": {
						"name": "GameWorld",
						"module": "world.js"
					}
				},
				{
					"kind": "custom-element-definition",
					"name": "game-stage",
					"declaration": {
						"name": "GameStage",
						"module": "world.js"
					}
				},
				{
					"kind": "js",
					"name": "GameStage",
					"declaration": {
						"name": "GameStage",
						"module": "world.js"
					}
				},
				{
					"kind": "custom-element-definition",
					"name": "game-palette",
					"declaration": {
						"name": "GamePalette",
						"module": "world.js"
					}
				},
				{
					"kind": "js",
					"name": "GamePalette",
					"declaration": {
						"name": "GamePalette",
						"module": "world.js"
					}
				},
				{
					"kind": "custom-element-definition",
					"name": "game-tileset",
					"declaration": {
						"name": "GameTileset",
						"module": "world.js"
					}
				},
				{
					"kind": "js",
					"name": "GameTileset",
					"declaration": {
						"name": "GameTileset",
						"module": "world.js"
					}
				},
				{
					"kind": "custom-element-definition",
					"name": "game-tile",
					"declaration": {
						"name": "GameTile",
						"module": "world.js"
					}
				},
				{
					"kind": "js",
					"name": "GameTile",
					"declaration": {
						"name": "GameTile",
						"module": "world.js"
					}
				},
				{
					"kind": "custom-element-definition",
					"name": "game-input",
					"declaration": {
						"name": "GameInput",
						"module": "game-input.js"
					}
				},
				{
					"kind": "js",
					"name": "GameInput",
					"declaration": {
						"name": "GameInput",
						"module": "game-input.js"
					}
				}
			]
		},
		{
			"kind": "javascript-module",
			"path": "world.js",
			"declarations": [
				{
					"kind": "class",
					"name": "GameWorld",
					"tagName": "game-world",
					"customElement": true,
					"superclass": {
						"name": "HTMLElement",
						"package": "global:"
					},
					"description": "Coordinates an HTML/CSS perspective world. Pattern banks supply tilemaps and sprites. The screen contains ordered stages, layer tilemaps and the player sprite. CSS owns 3D projection, palette changes, scrolling, transitions and sprite animation. Native inputs support course motion, steering, targeting and sector choice without JavaScript. Upgrade adds fixed-step movement, aimed projectiles, collisions and controller input. The simulation pauses on blur or hidden tabs.",
					"attributes": [
						{
							"name": "state",
							"description": "Reflected runtime state: loading, ready, playing, paused, won, lost, or error.",
							"type": {
								"text": "string"
							}
						},
						{
							"name": "score",
							"description": "Reflected total score, reset when restarting.",
							"type": {
								"text": "number"
							}
						},
						{
							"name": "stage",
							"description": "Reflected ID of the current stage.",
							"type": {
								"text": "string"
							}
						}
					],
					"events": [
						{
							"name": "game-world-change",
							"type": {
								"text": "CustomEvent<{ state: string, score: number, health: number, stage: string }>"
							},
							"description": "Bubbles and is composed. Emitted on state changes."
						},
						{
							"name": "game-world-error",
							"type": {
								"text": "CustomEvent<{ reason: \"assets-or-definitions\" }>"
							},
							"description": "Bubbles and is composed. Reports an incomplete world, failed image, invalid sheet or unknown sprite reference."
						}
					],
					"x-listens": [
						{
							"name": "game-input",
							"type": "CustomEvent<{ x: number, y: number, fire: boolean, source: string, command?: string }>",
							"description": "Listens to descendant input. Valid finite axes and a boolean fire are required. Controls in nested worlds retain ownership."
						}
					],
					"cssProperties": [
						{
							"name": "--distance-blur",
							"default": "0px",
							"description": "Optional sprite blur per depth unit beyond 80, applied by CSS."
						}
					],
					"x-markup": [
						{
							"name": "data-world-controls",
							"description": "Wrap launch, pause, and movement buttons in this container. The stylesheet shows it after the world is ready."
						},
						{
							"name": "data-world-status",
							"description": "Text updated for loading failure, stage changes, pause, victory, and defeat. Use role=\"status\" to announce changes."
						},
						{
							"name": "data-world-hud",
							"description": "Contains the instrument outputs. The native stylesheet displays only score before upgrade."
						},
						{
							"name": "data-world-shield, data-world-score, data-world-sector, data-world-progress",
							"description": "Optional output hooks for health, points, stage name, and percent of the current stage completed."
						},
						{
							"name": "data-world-controller",
							"description": "Optional text hook for the active controller or keyboard/touch."
						},
						{
							"name": "data-world-poster",
							"description": "Marks an image the world can skip while decoding gameplay artwork."
						},
						{
							"name": "data-native-controls",
							"description": "Marks the native controls and instructions that remain visible until full controls are ready."
						},
						{
							"name": "data-native-run, data-native-pause",
							"description": "Mark checkboxes for running the course and pausing its CSS animations."
						},
						{
							"name": "data-axis",
							"description": "Use x or y on a radio input with value -1, 0, or 1 to move the native player in that direction."
						},
						{
							"name": "data-stage-choice",
							"description": "On a radio input, selects the stage with the same data-stage-index while native controls are active."
						},
						{
							"name": "data-native-cleared, data-native-victory",
							"description": "Mark text shown when all targets are cleared in the stage or course, respectively."
						}
					]
				},
				{
					"kind": "class",
					"name": "GameStage",
					"tagName": "game-stage",
					"customElement": true,
					"superclass": {
						"name": "HTMLElement",
						"package": "global:"
					},
					"description": "Ordered world stage inside game-screen. Contains game-layer tilemaps, palette and pattern-bank definitions, and scenery/enemy game-sprite records. Score and shield carry between stages. CSS native sector controls can select stages before upgrade.",
					"attributes": [
						{
							"name": "id",
							"description": "Document-unique stage identifier.",
							"type": {
								"text": "string"
							}
						},
						{
							"name": "name",
							"description": "Readable name used by the instruments and status.",
							"type": {
								"text": "string"
							}
						},
						{
							"name": "length",
							"description": "Stage distance in world units, clamped to 10–10000.",
							"type": {
								"text": "number"
							},
							"default": "480"
						},
						{
							"name": "speed",
							"description": "Forward world units per second, clamped to 1–60.",
							"type": {
								"text": "number"
							},
							"default": "18"
						},
						{
							"name": "draw-distance",
							"description": "Scenery far plane, clamped to 10–160.",
							"type": {
								"text": "number"
							},
							"default": "90"
						},
						{
							"name": "repair",
							"description": "Shield restored when entering this stage, capped at max-health.",
							"type": {
								"text": "number"
							},
							"default": "1"
						},
						{
							"name": "sky",
							"description": "Top sky CSS color.",
							"type": {
								"text": "string"
							},
							"default": "#182b55"
						},
						{
							"name": "haze",
							"description": "Sky color near the horizon.",
							"type": {
								"text": "string"
							},
							"default": "#d6b8b9"
						},
						{
							"name": "active",
							"description": "Reflected presence on the current stage.",
							"type": {
								"text": "boolean"
							}
						}
					],
					"events": [
						{
							"name": "game-stage-change",
							"type": {
								"text": "CustomEvent<{ stage: string, index: number, name: string }>"
							},
							"description": "Bubbles and is composed. Emitted from the stage on entry, including initialization and restart. Index is zero-based."
						}
					],
					"x-markup": [
						{
							"name": "data-stage-index",
							"description": "Native stage number. The starter stylesheet shows the first stage by default and supports native radio selections for indices 1 and 2."
						}
					]
				},
				{
					"kind": "class",
					"name": "GamePalette",
					"tagName": "game-palette",
					"customElement": true,
					"superclass": {
						"name": "HTMLElement",
						"package": "global:"
					},
					"description": "Palette RAM record. Whitespace-separated colors define the indexed pattern colors. CSS variables --palette-0 through --palette-3 provide the native rendering values. The sample cycles the two grid entries using step-end keyframes.",
					"attributes": [
						{
							"name": "id",
							"description": "Document-unique bank reference.",
							"type": {
								"text": "string"
							}
						},
						{
							"name": "colors",
							"description": "Whitespace-separated #rrggbb colors.",
							"type": {
								"text": "string"
							}
						},
						{
							"name": "cycle-start",
							"description": "First rotating palette entry.",
							"type": {
								"text": "number"
							},
							"default": "2"
						},
						{
							"name": "cycle-rate",
							"description": "Palette changes per second, reflected in the authored CSS --cycle-rate.",
							"type": {
								"text": "number"
							},
							"default": "5"
						}
					],
					"events": []
				},
				{
					"kind": "class",
					"name": "GameTileset",
					"tagName": "game-tileset",
					"customElement": true,
					"superclass": {
						"name": "HTMLElement",
						"package": "global:"
					},
					"description": "Pattern bank shared by background tilemaps and sprites. A direct image stores equal-sized tiles in row-major order. Alternatively, child game-tile records contain whitespace-separated palette indices. Pattern banks are data and are hidden visually.",
					"attributes": [
						{
							"name": "id",
							"description": "Document-unique bank reference.",
							"type": {
								"text": "string"
							}
						},
						{
							"name": "tile-width",
							"description": "Pattern width in pixels, integer 1–64.",
							"type": {
								"text": "number"
							},
							"default": "8"
						},
						{
							"name": "tile-height",
							"description": "Pattern height in pixels, integer 1–64.",
							"type": {
								"text": "number"
							},
							"default": "8"
						}
					],
					"events": []
				},
				{
					"kind": "class",
					"name": "GameTile",
					"tagName": "game-tile",
					"customElement": true,
					"superclass": {
						"name": "HTMLElement",
						"package": "global:"
					},
					"description": "In a tileset, this record contains row-major pixel palette indices. In a tilemap, its index references one pattern-bank entry. Native atlas rendering uses CSS image positions. A hardware interpreter can read the same index and palette data.",
					"attributes": [
						{
							"name": "index",
							"description": "Zero-based pattern-bank index.",
							"type": {
								"text": "number"
							},
							"default": "0"
						}
					],
					"events": [],
					"cssProperties": [
						{
							"name": "--tile-x",
							"description": "Pattern-bank column for CSS atlas rendering."
						},
						{
							"name": "--tile-y",
							"description": "Pattern-bank row for CSS atlas rendering."
						}
					]
				}
			],
			"exports": [
				{
					"kind": "js",
					"name": "GameWorld",
					"declaration": {
						"name": "GameWorld",
						"module": "world.js"
					}
				},
				{
					"kind": "js",
					"name": "GameStage",
					"declaration": {
						"name": "GameStage",
						"module": "world.js"
					}
				},
				{
					"kind": "js",
					"name": "GamePalette",
					"declaration": {
						"name": "GamePalette",
						"module": "world.js"
					}
				},
				{
					"kind": "js",
					"name": "GameTileset",
					"declaration": {
						"name": "GameTileset",
						"module": "world.js"
					}
				},
				{
					"kind": "js",
					"name": "GameTile",
					"declaration": {
						"name": "GameTile",
						"module": "world.js"
					}
				}
			]
		},
		{
			"kind": "javascript-module",
			"path": "game-input.js",
			"declarations": [
				{
					"kind": "class",
					"name": "GameInput",
					"tagName": "game-input",
					"customElement": true,
					"superclass": {
						"name": "HTMLElement",
						"package": "global:"
					},
					"description": "Owns native buttons with data-action=start|pause|restart|left|right|up|down|fire. Arrow keys/WASD move, Space fires, P/Escape pause. Held pointers support multi-touch. Discovers the first available gamepad at rest and polls axes/buttons every 50 ms. Disconnect hands ownership to the next connected pad or native controls. Modified keys and text entry remain native.",
					"attributes": [
						{
							"name": "deadzone",
							"description": "Stick deadzone, clamped to 0–0.9. Values outside it are rescaled.",
							"type": {
								"text": "number"
							},
							"default": "0.18"
						},
						{
							"name": "fire-button",
							"description": "Gamepad fire-button index, integer 0–31. Right trigger also fires.",
							"type": {
								"text": "number"
							},
							"default": "0"
						}
					],
					"events": [
						{
							"name": "game-input",
							"type": {
								"text": "CustomEvent<{ x: number, y: number, fire: boolean, source: string, command?: string }>"
							},
							"description": "Bubbles and is composed. Emitted when normalized axes, fire state, source or command change. Axes are -1–1. Commands match button actions."
						},
						{
							"name": "game-controller-change",
							"type": {
								"text": "CustomEvent<{ index: number, connected: boolean, name: string, mapping: string }>"
							},
							"description": "Bubbles and is composed. Reports player-one controller acquisition or loss. index=-1 means native controls. Browser standard mapping uses axes 0/1, D-pad 12–15, trigger 7 and Start 9."
						}
					],
					"x-markup": [
						{
							"name": "data-action",
							"description": "On a button, names an input command. Use start, pause, restart, left, right, up, down, or fire. A world treats pause as a toggle."
						}
					]
				}
			],
			"exports": [
				{
					"kind": "js",
					"name": "GameInput",
					"declaration": {
						"name": "GameInput",
						"module": "game-input.js"
					}
				}
			]
		}
	]
}
