Skip to content

Project: Build a Pokémon browser game

Build a small Pokémon website with three connected pages. The landing page introduces the game. The game page lets a player choose a starter, explore a map, meet random wild Pokémon, battle, catch Pokémon, heal, and review the caught collection. The Pokédex page provides a static reference catalog.

You will receive the product requirements and a sequence of functional checkpoints. You must decide how to structure the HTML, CSS, and JavaScript that meet those requirements. Each checkpoint links to the lesson sections that introduce the relevant concepts.

What you will practice

  • Turn a multi-page product brief into semantic HTML, shared CSS, and browser JavaScript.
  • Model player, map, encounter, battle, and collection data as deliberate application state.
  • Connect movement and battle events to state updates and rendered results.
  • Create random grass encounters while keeping each selected encounter stable in state.
  • Build responsive page and component layouts with equivalent reduced-motion behavior.
  • Plan and execute tests for deterministic behavior and controlled random behavior.
  • Create technical SEO evidence for a local multi-page website without inventing a public origin.

Create a small Pokémon game that runs in a current browser without a framework, backend, database, API, or build tool.

The game takes place in one compact area. The area includes a Pokémon Center, paths, blocked terrain, and tall grass. The player chooses one starter Pokémon and moves through the area with visible controls. Each valid move into tall grass has a documented percentage chance of starting an encounter with one Pokémon from the area’s encounter list.

During an encounter, the player can attack, throw a Poké Ball, or run. The starter and wild Pokémon have hit points. The game reports each result, prevents map movement during battle, and returns to exploration when the encounter ends. A successful catch adds the species to a caught-Pokémon collection on the game page.

The separate Pokédex page is a static reference catalog. It does not read the game state. Every Pokémon that can appear in the game must also have a Pokédex entry.

Work through one functional checkpoint at a time:

  1. Read the linked lesson sections for the active checkpoint.
  2. Write down the behavior that must work before you edit the project.
  3. Decide how to implement that behavior with the concepts from the lessons.
  4. Run the checkpoint test before you continue.
  5. Commit and push a passing version.
  6. Record what works, what remains, and the exact next action before you stop.

The links provide the technical teaching. This page does not provide finished game code or a complete implementation plan.

Use this table to find the current required stage after an interruption. Work on one stage checkpoint at a time. The detailed sections below contain the requirements, lesson links, checks, and recovery notes.

Stage Required passing result
1. Product and repository The project contract, numeric rules, private repository, board, and first checkpoint agree.
2. Static website Three semantic pages, assets, navigation, base CSS, and the initial script load work.
3. Trainer setup Valid input creates one complete initial game state; invalid input changes no game data.
4. Map movement Accepted and rejected movement, terrain, healing, status, and focus agree with state.
5. Encounters Normal and controlled grass decisions create zero or one stable allowed encounter.
6. Battle Every battle action reaches its documented state, status, stopping, and focus result.
7. Collection and Pokédex Capture updates a duplicate-free collection, the static Pokédex is complete, and reset works.
8. Responsive layout and motion The complete product works under layout pressure and with standard or reduced motion.
9. Technical SEO The three pages have verified local SEO evidence and honest public-origin limits.
10. Final evidence One identified commit passes the required tests and matches every report and demonstration.

In this project, application state means the current game data in one JavaScript object held by a variable in game.js. Read Represent interface state for the object-and-properties model. To store a value in application state means to assign that value to the relevant property in this object. The render functions then read the object and update the page to match it.

This required state exists only in the current page’s memory. The page can display copies of its values in the DOM, but the JavaScript state object remains the source of truth. The required version does not write game data to localStorage, a database, or a backend. Reloading game.html creates a new JavaScript environment and returns the game to its documented initial state. Read Trace the complete state architecture for this lifetime and the event → state update → render cycle.

In this project, persistent progress means progress that survives a page reload or later browser visit. Persistent progress is outside the required project. The optional persistence extension introduces localStorage after the complete in-memory game works. Saving a source file or recording the current project state in quality-plan.md refers to development work on disk, not saved game progress.

Use this contract for the required version. It defines what the data must represent, but it does not define property names or the complete JavaScript structure. Read Represent interface state and Represent a deliberate absence value before you create the object.

State value Required shape and meaning Initial JavaScript value Required before-setup result What can change it
Trainer name One string created from validated fictional input Empty string "" The name field is empty and no trainer is active Valid trainer submission or complete reset
Starter One changing Pokémon record with a Pokédex number, name, maximum hit points, and current hit points null No starter summary is active and exploration is unavailable Valid trainer submission, wild attack, healing, fainting, or complete reset
Map position One coordinate record with a row number and column number null No player marker or current-position result appears Valid trainer submission, accepted movement, fainting, or complete reset
Active encounter Either null or one changing wild-Pokémon record with a Pokédex number, name, maximum hit points, and current hit points null The battle interface is unavailable Successful grass check, battle action, capture, run, fainting, or complete reset
Caught collection One ordered array of caught-species records; each record has a Pokédex number and display name Empty array [] The collection shows its empty result and a total of 0 Successful capture or complete reset
Status message One string that reports the current result or next available action The trainer-setup instruction recorded in project-brief.md The polite status region shows that instruction Every accepted or rejected game action and complete reset

Use these initial values consistently. Do not use undefined, an empty object, or an empty string as another meaning for null later in the game.

The Pokédex number is the stable identity for one Pokémon species. Use that number when the game must decide whether a caught species already exists in the collection. A display name can change without changing the species identity.

Keep fixed game definitions separate from changing application state:

  • The map definition is one ordered array that records the row, column, and terrain type for every square.
  • The starter list records the Pokémon that the trainer can select. Each definition includes one unique string selection value that can also be used as the matching form-option value.
  • The encounter list records at least three wild Pokémon that can be selected.
  • Each Pokémon record used by these definitions has one Pokédex number and the values needed by the part of the game that uses it.

The active starter and active encounter are changing runtime records. Create each runtime record from a fixed starter or encounter definition. Do not use the fixed definition object itself as the changing state record. Read Keep fixed definitions separate from changing records. After one battle changes hit points, inspect the matching fixed definition. It must still contain its documented starting values. Starting the same species again must create a new runtime record with those starting values.

Do not store a second value when the game can calculate it from the required data. For example, calculate the caught total from the caught collection, determine whether a battle is active from the active encounter, and find the current terrain from the map definition and map position. Read the explanation of derived interface data before deciding that the state object needs another property.

The checkpoints ask you to compare state, rendered content, focus, and status. Use these methods when each type of evidence first appears:

  • Add a temporary Console log immediately before and after one state update when you need to compare JavaScript values. Read Open the Console and Execute input and state paths. Remove temporary logs before the checkpoint commit unless the final program deliberately needs them.
  • Inspect the relevant element in the browser’s Elements panel when you need to compare the state object with the rendered DOM.
  • Enter document.activeElement in the Console and compare it with the visible focus indicator when you need to identify keyboard focus. Read Test keyboard operation and focus.
  • Inspect the status region in the Elements or accessibility panel when you need to verify its semantic element, role, or ARIA properties. Read Inspect status changes without moving focus.

Use this focus contract for the required route:

Result Required focus position
Trainer-name validation fails Trainer-name field
Starter-choice validation fails after the name passes Starter-choice control
A valid trainer starts the game First enabled movement control
Movement ends without an encounter Activated movement control when it remains enabled; otherwise the first enabled movement control
An encounter starts Encounter heading; the next Tab stop is Attack
A battle action leaves the encounter active Activated battle control
An encounter ends First enabled movement control
Complete reset finishes Trainer-name field

The polite status region reports results without receiving focus. If a render replaces the focused control, restore focus to the new control that has the same role in the current state.

Complete Level 1 before you begin, or use this checklist with your teacher to confirm the same knowledge. If one item is unfamiliar, read its linked section before the stage that uses it.

Before Stage 3, complete the Level 2 JavaScript Foundations, DOM Events, and Interface State lessons. Before Stage 8, confirm that the responsive-layout items above pass on the current project. Ask your teacher for a prerequisite check if you can build the pages but cannot yet explain one of these terms or checks.

Starting point

Before you start

  • Complete the prerequisite check above, including the named Level 1 HTML, images, CSS, layout, responsive, validation, keyboard, Git, and browser-tool skills.
  • Use VS Code, a current browser with developer tools, Git, and a private GitHub repository.
  • Complete the Level 2 JavaScript foundations, DOM events, and interface-state lessons before you implement the game behavior.
  • Use one new project folder and repository. Do not reuse the task-board repository or copy its hidden .git folder.
  • Use only content that is suitable for this local teaching project. Do not add personal information, credentials, or unrelated private files.
Current state
You know the required product and have the relevant course material, but the Pokémon website, game state, quality evidence, and repository do not exist yet.
First action
Create the project folder, open it in VS Code, and add the required empty source and evidence files.
First checkpoint
The three HTML pages load the shared stylesheet, game.html loads its JavaScript without a Console error, every page links to the other pages, and the private repository contains the baseline commit.
Help trigger
Open the assistance section or ask for help when you cannot name the state that should change, the first Console error remains after you inspect its file and line, or the active checkpoint requires a concept that you cannot find in the linked lesson.

Begin with this structure. You can add more source files when each file has one clear responsibility.

Required project structure
pokemon-browser-game/
├── index.html
├── game.html
├── pokedex.html
├── styles.css
├── game.js
├── README.md
├── project-brief.md
├── quality-plan.md
├── interactive-test-report.md
├── technical-seo-report.md
├── presentation-plan.md
└── assets/

Do not add an analytics file until you choose the optional final analytics stage.

Starting structure for the project documents

Section titled “Starting structure for the project documents”

Create the document headings before you need to record evidence. The headings make the next recording location visible and reduce decisions during testing.

File Required starting headings or content Complete during
project-brief.md Audience and purpose, Required product route, Game-data decisions, Map contract, Battle-rule plan, and Out of scope Stage 1, then update only when an approved design decision changes
quality-plan.md Pokémon project override, Board contract, Active checkpoint, Done signal, Help trigger, and Resume note Stage 1 and after every functional checkpoint
interactive-test-report.md Product contract, Controlled setup routes, Scripted cases, Exploratory charter, Defects and repairs, and Final regression Stages 3–10
technical-seo-report.md Evidence boundary, Page evidence matrix, Repairs, and Affected regression Stage 9
README.md Project title, one-sentence purpose, required file list, and Implementation not started. Create in Stage 1 and complete in Stage 10
presentation-plan.md Project title Create in Stage 1 and complete in Stage 10

These headings are a recording structure, not additional product features. Add a subsection only when the project creates evidence that belongs there.

Requirements

The required assignment is complete when every applicable criterion below is met.

Website and navigation

  • index.html introduces the game, explains its main features, and provides clear links to the game and Pokédex.
  • game.html contains the trainer setup, map, movement controls, battle interface, game status, and caught-Pokémon collection.
  • pokedex.html contains a static catalog with at least eight Pokémon across at least three types.
  • Every Pokémon that can appear in a random encounter has a complete entry in the static Pokédex.
  • Every page has a descriptive page title, one main heading, semantic landmarks, and real links to the other pages.

Trainer setup and game state

  • The player enters a fictional trainer name and chooses one starter Pokémon through a labeled native select control in the trainer form.
  • Empty or whitespace-only names are rejected without starting the game. The error is specific, connected to the field, and followed by a useful focus result.
  • One JavaScript state object in the current page memory owns the trainer name, starter, map position, active encounter, caught Pokémon, and current status message according to the required game-data contract.
  • A documented reset control restores every state value, form result, rendered region, available control, status message, and focus target to the documented before-setup condition without reloading the page.

Map and movement

  • The map contains a Pokémon Center, a path, at least one tall-grass area, and at least one blocked terrain type.
  • A visible player marker starts at the Pokémon Center and represents the map-position property in the JavaScript state object.
  • Visible north, south, east, and west controls move the player one valid square at a time.
  • The player cannot leave the map or enter blocked terrain. A rejected move explains the result without changing the valid map-position property in the JavaScript state object.
  • Map movement is unavailable while an encounter is active.
  • Reaching the Pokémon Center restores the starter to full hit points and reports the result.

Random encounters

  • Each valid move into a tall-grass square performs exactly one encounter-chance check.
  • The project documents the chosen encounter percentage and uses the same percentage until the student deliberately changes the game design.
  • A successful chance check selects one Pokémon from a defined encounter list containing at least three species.
  • The selected wild Pokémon and its starting hit points are assigned to the active-encounter property in the JavaScript state object before the interface renders the encounter.
  • Rendering, resizing, or updating another interface region cannot reroll or replace the active encounter.
  • The project documents repeatable development tests that can produce no encounter and one known encounter without changing the final normal-play percentage.

Battle and capture

  • The encounter interface identifies the wild Pokémon, the starter, both current hit-point values, and the available actions.
  • Attack deals one documented fixed amount of damage to the wild Pokémon.
  • A surviving wild Pokémon responds with one documented fixed amount of damage to the starter.
  • A wild Pokémon at zero hit points is defeated, leaves the encounter, and is not added to the caught collection.
  • Throw Poké Ball succeeds only when the wild Pokémon is at or below the documented capture threshold.
  • A failed capture explains why the catch did not succeed and keeps the encounter state valid.
  • Run always ends the encounter and returns the player to the map without adding a caught Pokémon.
  • If the starter faints, the encounter ends, the player returns to the Pokémon Center, and the starter returns to full hit points.

Caught Pokémon and static Pokédex

  • A successful catch adds the species to a caught-Pokémon collection on game.html.
  • The caught collection and a caught-total summary render from application state.
  • Catching a species whose Pokédex number is already in the collection does not create a duplicate entry and provides a clear status message.
  • Each static Pokédex entry includes a Pokédex number, name, type or types, image with suitable alternative text, and a short description.
  • The static Pokédex remains useful without JavaScript and does not claim to show the current game progress.

Responsive design and motion

  • All three pages work at a 320 CSS-pixel viewport and at 200% browser zoom without lost content or unintended horizontal page scrolling.
  • The base CSS provides a complete narrow layout before a media query creates a wider page composition.
  • At least one repeated Pokédex or caught-Pokémon component responds to its own available width through a container query.
  • Long trainer names, Pokémon names, battle messages, labels, and controls wrap without clipping or overlap.
  • One short, finite animation reinforces movement, an encounter, an attack, or a successful catch.
  • A reduced-motion rule removes project motion while preserving the same content, state, result, status, and focus behavior.

Accessibility and safe rendering

  • Every required action works with a keyboard through native controls and visible focus indicators.
  • Game status and battle results are exposed through a suitable polite status region without moving focus to the message.
  • The current state does not depend only on color, map position, or animation.
  • Trainer input is inserted as text and cannot create HTML elements or execute code.
  • Focus remains useful after validation, game start, battle actions, caught-list rendering, and reset.

Technical constraints and quality evidence

  • Use browser-native HTML, CSS, and JavaScript without a framework, CSS framework, package dependency, backend, database, API, or build tool.
  • Keep stable DOM selections and listener registration outside functions that repeatedly render changing game regions.
  • Use event, state update, and render as the visible architecture for movement, encounters, battle actions, capture, healing, and reset.
  • Use a private GitHub repository with focused commits that identify passing functional checkpoints.
  • quality-plan.md records the product contract, active quality work, done signal, and current resume state without requiring a fixed schedule.
  • interactive-test-report.md identifies one tested commit and contains the required scripted, exploratory, repair, and regression evidence.
  • technical-seo-report.md records valid local source and rendered evidence without inventing a deployment, canonical URL, traffic, indexing, or ranking result.
  • README.md explains the product, file responsibilities, game-state model, controls, reset route, tests, known limits, and final verified commit.

Design freedom

  • Choose the game title, region, starter choices, encounter species, Pokédex entries, terrain arrangement, encounter percentage, hit-point values, damage values, and capture threshold. After the required 5 × 5 map passes, you can choose another compact rectangular map size.
  • Choose the visual direction, images, colors, typography, spacing, layout, breakpoints, component arrangements, and finite motion treatment.
  • Choose function, variable, class, and ID names when each name remains specific and consistent.
  • Add more source files when the division gives each file a clear responsibility and the README explains it.

Out of scope for the required project

  • Public deployment, user accounts, persistent game progress, a database, an API, and online multiplayer are not required.
  • Arrow-key movement, real-time movement, canvas rendering, collision physics, and procedural map generation are not required.
  • Multiple active party members, party switching, multiple attacks, type effectiveness, experience, levels, evolution, items, shops, quests, and NPC dialogue are not required.
  • Random damage, critical hits, random capture success, sound, and sprite animation are not required.
  • The optional analytics stage and every optional extension remain outside the required definition of done.

The required project is complete when one identified commit meets every applicable requirement above, passes the final self-check, exists in the private GitHub repository, and leaves a clean working tree. The game must provide one complete route from trainer setup through exploration, random encounter, battle, capture, caught-collection update, healing, reset, and continued play.

The static Pokédex, landing page, test evidence, technical SEO evidence, README, and demonstration must describe the same final product. Optional extensions and the optional analytics stage do not affect whether the required project is complete.

Level 2 · Web Construction implementation route

Section titled “Level 2 · Web Construction implementation route”

Stage 1: Define the product and open the repository

Section titled “Stage 1: Define the product and open the repository”

The linked quality-planning lesson uses a different project. Use this Pokémon-specific contract when its example and this page differ:

Part of the linked lesson Use for this project
Existing-application quality target Skip it. This project begins with empty files.
Hard deadline and schedule Skip them. This project has no required dates, duration estimate, or fixed schedule.
Target date field and date-based view Do not create them.
Four planning fields Replace them with the three fields defined below.
Lesson’s final-regression status After Stage 10 passes, move the project-specific final regression issue to Done.
Observable results, one active checkpoint, evidence, and resume note Keep and adapt these parts.

Record this table under Pokémon project override in quality-plan.md before you open the linked sections. Do not translate the example project’s dates or field names into this project.

Read the following sections with that override visible:

Write project-brief.md. Identify the intended player, the three-page product, the required game loop, the map contents, starter choices, encounter species, encounter percentage, hit-point values, damage values, capture threshold, and required finish line. Choose numeric rules that make the required battle boundaries reachable. At least one encounter species must reach exactly zero after repeated fixed attacks, and at least one must pass below zero before the game clamps the displayed value to zero.

Complete this planning table under Battle-rule plan before you implement battle behavior. Record values and action counts, not JavaScript:

Decision or required boundary Value or named species Repeatable setup or number of actions
Starter maximum hit points Your chosen value Starting state after valid trainer setup
Fixed player-attack damage Your chosen value One Attack activation
Fixed wild-response damage Your chosen value One response after a surviving wild Pokémon
Capture threshold Your chosen value State whether equality succeeds
Wild Pokémon reaches exactly zero One encounter species Number of attacks from its starting hit points
Wild Pokémon passes below zero One encounter species Number of attacks before the display clamps to zero
Capture above, at, and below the threshold One or more encounter species Number of attacks needed for each positive-hit-point boundary
Starter faints after a wild response One encounter species Starter hit points immediately before that response

Check the arithmetic on paper or in the Console. If a required boundary cannot be reached with the chosen values, revise the values now. Do not wait until the final test stage.

Write quality-plan.md. Record the first functional checkpoint, required quality areas, current active work, done signal, help trigger, and resume state. This project does not require dates, duration estimates, or a fixed schedule.

Create the private repository and a private GitHub Project. Use the setup from the linked lesson with this project-specific contract:

Field or view Required configuration
Status field Ready, In progress, Blocked, and Done
Priority field Must, Should, and Could; all required issues begin as Must
Area field Baseline, Function, Accessibility, Responsive, Source, and Regression
Quality plan view Table that shows title, status, priority, area, and repository
Work queue view Board grouped by status

Do not add a target-date field for this project unless your teacher later gives you a real delivery date. Add these six repository issues to the project:

Issue Area Required scope
Confirm the baseline and static three-page website Baseline Files, local launch, navigation, headings, images, and initial Console result
Verify the complete game loop and input boundaries Function Trainer setup, map, encounter, battle, capture, collection, healing, and reset
Verify keyboard, focus, status, and safe text Accessibility Complete keyboard route, focus contract, status semantics, and HTML-looking trainer text
Verify responsive layout, component behavior, and motion Responsive Narrow and wide layouts, 200% zoom, container query, animation, and reduced motion
Check saved source and local technical SEO Source HTML, CSS, Console, metadata, initial meaning, links, and no-public-origin boundary
Run final regression and review delivery evidence Regression Required paths, repaired defects, reports, README, presentation route, and final commit

Set the baseline issue to In progress and the other five to Ready. Keep one issue in progress at a time. Add a separate defect issue only after a test produces a repeatable conflict.

The six issues are reporting containers. They are not the size of the active coding task. Add this checklist to Verify the complete game loop and input boundaries:

  1. Trainer form and complete initial state.
  2. Static map and player marker.
  3. One accepted and one rejected direction.
  4. All movement, boundaries, and healing.
  5. Normal encounter decision.
  6. Controlled encounter modes and restoration.
  7. Attack and defeat boundaries.
  8. Capture and Run boundaries.
  9. Starter fainting and recovery.
  10. Caught collection and duplicate handling.
  11. Complete reset from every required starting state.

Only one checklist item is the active checkpoint. Record it in quality-plan.md with these labels: Parent issue, Checkpoint ID, Current state, First action, Expected result, What remains, Done signal, and Recovery check. Replace this block when you move to the next checkpoint; preserve the completed evidence in the issue or relevant report.

Create README.md now with the project title, one-sentence purpose, required file list, and the statement Implementation not started. Complete the launch, architecture, controls, reset, tests, and limits in Stage 10. Create presentation-plan.md with its title only; complete its route in Stage 10.

Do not attempt to design every optional game system before the static website exists.

Confirm that the brief and quality plan describe one bounded game. Confirm that the private repository contains every required file, the board contains the six named issues with the required fields and views, and only the baseline issue is in progress.

Checkpoint: The product boundary and recovery route are recorded

What now works
The brief, quality plan, repository, private board, required game loop, numeric game rules, done signal, and first implementation checkpoint agree; README.md and presentation-plan.md have their documented starting content.
Files changed
project-brief.md, quality-plan.md, README.md, presentation-plan.md, private GitHub Project
What remains
Build the three-page static website and confirm that its navigation and files load.
Next action
Open index.html and create the landing page landmarks, heading, product explanation, and navigation.
If it does not work
If the brief continues to grow, compare the new idea with the required and out-of-scope lists. Move non-required mechanics to the extension list before implementation begins.

Stage 2: Build the static three-page website

Section titled “Stage 2: Build the static three-page website”

Before you implement the pages, read:

Use teacher-supplied Pokémon images, images that you save from a documented source, or assets that you create. Store the project copies inside assets/ before you link to them. Under Game-data decisions in project-brief.md, record each file name, the Pokémon it represents, and where the project copy came from. This record is for repeatable project setup; it does not add a publication requirement.

Build the semantic HTML for index.html, game.html, and pokedex.html before you add game behavior.

The landing page must explain the game and give the visitor clear routes to start playing or open the Pokédex. The game page must contain the trainer form, map region, movement controls, battle region, status region, and caught-Pokémon region in a logical source order. The Pokédex must contain at least eight complete static entries.

Add the shared base CSS. A visitor must be able to identify every region and move among the three pages before JavaScript changes any state.

Open all three pages from a fresh browser tab. Follow every navigation link, inspect the heading structure, confirm that each image loads with suitable alternative text, and confirm that game.js loads on game.html without a Console error.

Run one early smoke check. Set the viewport near 320 CSS pixels and confirm that the page can still scroll to every region without overlapping or clipped content. Use Tab to reach every navigation link and trainer-form control, then operate the starter choice and buttons with the keyboard. Record non-blocking layout improvements for Stage 8. Repair a missing, unreachable, or unusable control before Stage 3.

Checkpoint: The complete static product shell works

What now works
The landing page, game interface shell, and eight-entry static Pokédex load through working navigation and remain understandable before game state renders.
Files changed
index.html, game.html, pokedex.html, styles.css, game.js, assets
What remains
Validate trainer input, write the selected starter to the JavaScript state object, and render the initial game state.
Next action
Open game.html and identify the labels, controls, instructions, error output, and status output that the trainer form needs.
If it does not work
If a page is difficult to understand without CSS or JavaScript, inspect its landmarks, headings, labels, and source order before adding behavior.

Stage 3: Start the game from validated trainer input

Section titled “Stage 3: Start the game from validated trainer input”

Before you implement trainer setup, read:

Make the trainer form the only route into a new game. The player enters a fictional trainer name and chooses one starter from a native select element. The first option is an instruction with an empty value. Each real option uses the unique string selection value from one starter definition.

Connect a visible label to the trainer-name field and another visible label to the starter choice. Confirm the choice instructions and every starter name without JavaScript. In game.js, select the form, name field, starter choice, connected error output, and polite status output. Include all required selections in a missing-elements guard.

Inside the submit event, read the trimmed name string and the selected option’s current string value. During development, log both values once. Submit each starter choice and confirm that the Console shows its documented selection value. Remove the temporary log after this check.

Check: The form submits without reloading, the handler reads one name string and one starter-selection string, and keyboard input can reach and change both controls. No game state changes yet.

Check the name and starter-selection values before you create a trainer. An empty or whitespace-only name follows the name-error path. An empty starter-selection value follows a starter-choice error path. Each invalid result changes no game data, displays a specific connected error, and moves focus to the first field that needs correction.

Check: Test a missing name, missing starter, both missing, and both valid. Record which control receives focus in each invalid case. The both-valid case can still stop before creating state.

Match the selection to one starter definition

Section titled “Match the selection to one starter definition”

Use the selected string to find one starter definition with the same stable selection value. A valid option must match exactly one definition. Treat no match as an invalid setup result; do not continue by reading properties from a missing record.

Create a separate changing starter record from the matched fixed definition. Give the changing record its documented current hit points. Do not change the fixed starter definition.

Check: Each offered choice matches the intended definition. Temporarily change one option to an unknown value and confirm that it follows the invalid path, then restore the documented value. Changing the selected starter’s current hit points during this controlled check does not change the fixed definition; restore the before-setup state afterward.

Complete these results in order. Verify one result before you add the next:

  1. Valid name and starter values create every initial value from the game-data contract in one consistent state.
  2. The changing starter record and fixed starter definition remain separate.
  3. The interface renders the trainer, starter, hit points, map position, available controls, caught-collection empty result, and initial status from that state.
  4. Focus moves to the first enabled movement control after the valid render.

An invalid name must not change the JavaScript state object. A valid submission must assign the trainer name and selected starter to properties in that object. The same state update must set the initial map position, starter hit points, empty encounter, empty caught collection, and initial status message. The interface must then render from this state without reloading the page.

These values remain available while the player continues on the current game.html page. A browser reload starts a new JavaScript environment and returns the required version to its documented initial state. Do not add localStorage or another persistence system for this stage.

The visible result must make the active trainer, starter, current hit points, starting position, and next available action clear.

Test an empty name, a whitespace-only name, a missing starter choice, a valid short name and starter, a long name, and HTML-looking text. After each submission, inspect the relevant properties in the JavaScript state object and confirm the visible error, rendered text, focus position, and Console result.

Checkpoint: A valid trainer can start one game

What now works
Invalid input changes no game state, and valid fictional input creates and renders one complete initial trainer, starter, position, hit-point, and status state.
Files changed
game.html, game.js, styles.css
What remains
Connect the movement controls to the map-position property in the JavaScript state object and apply the terrain rules.
Next action
List every map coordinate and classify it as Pokémon Center, path, tall grass, or blocked terrain.
If it does not work
If the visible game and the JavaScript state object's properties disagree, compare the form event, state update, and first render in that order.

Before you implement movement, read:

Use these terms throughout this stage:

Term Meaning in this project
Movement attempt One activation of one north, south, east, or west button
Proposed destination The row and column calculated from the current position before state changes
Existing destination One map record whose row and column match the proposal
Blocked square An existing destination whose terrain does not permit entry
Valid destination An existing destination that is not blocked
Accepted movement A movement attempt that writes the valid destination coordinate to state
Rejected movement A movement attempt that preserves the previous position and reports why

Use one documented rectangular coordinate system for the required map. The coordinate system is a data contract, not a visual-style requirement:

  • The top-left square is row 0, column 0.
  • Row numbers increase downward.
  • Column numbers increase toward the right.
  • North changes the proposed row by -1.
  • South changes the proposed row by +1.
  • West changes the proposed column by -1.
  • East changes the proposed column by +1.
  • Every square has one coordinate and one terrain value: Pokémon Center, path, tall grass, or blocked.

Use a 5 × 5 map for the first required version. Use one array of 25 cell records in row-major order. Every record contains one row number, one column number, and one terrain value. After this version passes, you can change to another compact rectangular size or refactor the representation when you record the new contract and repeat the map tests.

Build and inspect the definition in this order:

  1. Record the Pokémon Center cell and use its coordinate as the player’s starting position after trainer setup.
  2. Record the remaining cells one row at a time from left to right.
  3. Confirm that the array contains 25 records, each coordinate appears once, and every row and column stays within the 0 to 4 limits.
  4. Confirm that the definition includes the Center, path, tall grass, and blocked terrain before rendering.

Render every map square from the map definition before you add movement. Each rendered square must communicate its terrain with text or another non-color label. The order of the rendered squares must match the documented row and column order.

Checkpoint: The map data produces one stable visible map

What now works
Every documented coordinate renders once with the correct terrain, the Pokémon Center appears at the documented starting coordinate, and the map remains understandable without relying on color.
Files changed
project-brief.md, game.html, game.js, styles.css
What remains
Render the player marker from the map-position state, then connect movement one direction at a time.
Next action
Set the map-position state to the Pokémon Center coordinate and render one player marker at that square.
If it does not work
If a square appears in the wrong place, compare its row, column, terrain value, and rendered order before changing movement code.

Render exactly one visible player marker at the coordinate recorded in application state. Add a text result outside the visual grid that names the current row, column, and terrain. The text result ensures that the position does not depend only on visual placement.

Change the map-position value temporarily during development and render again. Confirm that the old square loses the marker and the new square receives it. Restore the Pokémon Center coordinate before you add movement.

Use native buttons with type="button" for north, south, east, and west. Connect one visible direction control first and register its action once. That action creates one proposed destination from the current row and column. Use both proposed coordinate values to look for one cell in the map definition. Check the lookup result before changing application state:

  1. Reject the move when no cell record matches both proposed coordinate values. This is the outside-map result.
  2. Reject the move when the matching destination record has blocked terrain.
  3. Accept the move only when the lookup returns an existing destination that is not blocked.
  4. Confirm that one activation produces one result with a pointer, Enter, and Space.
  5. After the first direction passes, apply the same contract to the other three direction controls.

A rejected move keeps the previous map-position value and reports why movement failed. An accepted move changes the map-position value before rendering. After either result, the state property, player marker, position text, available controls, status message, and focus must agree.

Add movement boundaries and Pokémon Center healing

Section titled “Add movement boundaries and Pokémon Center healing”

Movement controls must not change the map-position property while an encounter is active. Reaching the Pokémon Center restores the starter to its documented maximum hit points and reports whether healing changed the value.

Move in every direction from the starting position. Test each map edge, one blocked square, one path square, one tall-grass square, and the Pokémon Center. After each action, confirm that the map-position property, player marker, position text, controls, status, and focus describe the same result. Stage 5 tests movement lock after the game can create a real active encounter.

Checkpoint: Movement respects the map state

What now works
The player moves one valid square at a time, cannot enter invalid locations, can heal at the Pokémon Center, and receives an accurate status result after every movement attempt.
Files changed
game.html, game.js, styles.css
What remains
Add one encounter roll for each accepted movement into tall grass.
Next action
Open game.js and identify the point after a grass move is accepted but before the updated game state renders.
If it does not work
If the marker and map-position property disagree, inspect the destination calculation and state update before changing the map renderer.

Before you implement encounters, read:

The random-result lesson uses a neutral review-area example. Transfer that pattern to this project by completing this table under Game-data decisions in project-brief.md. Record decisions and ranges, not JavaScript:

Boundary Record for this project
Encounter percentage The chosen whole-number percentage
Random chance range The smallest possible value and the upper value that Math.random() cannot reach
Success threshold The decimal value created from the percentage and which side of equality succeeds
Encounter-list length The number of fixed species definitions
Valid list indexes The smallest and largest valid index
Index calculation Why multiplying by the list length and rounding down cannot produce an index equal to the length

Ask for help before implementation when one table row remains unclear after you work through the linked example. This check prevents a formula from appearing to work while using the wrong probability or an invalid list index.

In this project, one encounter-chance check means that one accepted grass-movement event creates one random chance value and uses that value for its success or failure decision. Rendering, focus restoration, and later interface updates do not create another chance value for that movement event.

Keep the chance decision and species selection as two separate responsibilities:

  1. An accepted grass move creates one chance value and compares it with the documented threshold.
  2. A failed chance produces the no-encounter result. Stop this encounter decision before species selection.
  3. A successful chance creates a second random value.
  4. Convert the second value into one valid encounter-list index and read that fixed definition.
  5. Create a changing runtime record from the selected definition.
  6. Assign that record to active-encounter state before any encounter render.

Use this state-before-render trace when you inspect the implementation:

accepted grass movement
-> one chance decision
-> no encounter OR one fixed species definition
-> one new changing encounter record
-> active-encounter state update
-> encounter render

This trace describes responsibilities and order. It is not JavaScript to copy.

After an accepted move into tall grass, perform one encounter-chance check. If the check succeeds, select one Pokémon from the defined encounter list and create a separate changing encounter record from that fixed definition. Assign the changing record to the active-encounter property before rendering. If the check does not succeed, keep the player in the new grass square and report that no encounter occurred.

Do not generate a new Pokémon from inside the render process. The active wild Pokémon must remain the same until the player defeats it, catches it, runs, or faints.

Implement and verify these results in order:

  1. A move onto a non-grass square performs no encounter check.
  2. One accepted grass move performs exactly one chance check.
  3. A failed check keeps exploration active and reports no encounter.
  4. A successful check selects one allowed species.
  5. The selected species and its starting hit points enter application state before the encounter renders.
  6. Encounter rendering, unrelated rendering, and viewport changes reuse the active encounter without another random selection.
  7. Ending the encounter and later selecting the same species creates a new encounter with its documented starting hit points; the fixed definition remains unchanged.

Checkpoint: Normal grass movement creates zero or one stable encounter

What now works
A non-grass move performs no check, one accepted grass move performs one check, failure keeps exploration active, and success creates one allowed encounter that remains stable during later renders.
Files changed
game.js, game.html, project-brief.md
What remains
Add a controlled development mode that reaches a known encounter without waiting for a random result.
Next action
Document the normal, controlled no-encounter, and controlled known-encounter results before adding the development setting.
If it does not work
If one movement action performs several checks, trace the movement event and find every call that creates a random value before changing the probability formula.

A controlled encounter test replaces an unpredictable test precondition with one known result. It does not replace randomness in normal play. Use this contract:

Mode Result after the next accepted grass move
Normal mode Use the documented percentage. If it succeeds, select one species from the encounter list.
Controlled no-encounter mode Skip the random chance result and keep exploration active.
Controlled known-encounter mode Skip the random chance result and start an encounter with one documented species selected from the same encounter list.
Checkpoint version Normal mode is active. Both controlled procedures remain documented and can be enabled again for later tests.

All three modes meet at one encounter-decision boundary. That boundary produces either no encounter or one fixed species definition from the allowed encounter list. The shared code after the boundary creates the changing record, updates active-encounter state, renders, reports status, and restores focus. Do not create a separate render or battle route for controlled mode.

Choose one clearly named development setting that selects normal, controlled no-encounter, or controlled known-encounter behavior. This is a source-code configuration for development, not application state, browser storage, or player progress. Keep the setting near the fixed definitions and read it at the one decision boundary. Do not read it inside a render function or copy the mode check into several movement branches.

Before implementation, add this worksheet under Controlled setup routes in interactive-test-report.md:

Decision to record Required content
Setting location Source file and nearby definition or heading
Normal mode Exact allowed value and ordinary percentage result
Controlled no-encounter mode Exact allowed value and the no-encounter boundary result
Controlled known-encounter mode Exact allowed value, known Pokédex number, and matching encounter-list definition
Shared route after the boundary State properties, rendered regions, status, and focus that normal and controlled results use
Restoration Exact source value, reload step, source inspection, and one normal-mode trace

The known Pokédex number must match exactly one definition in the encounter list. If it matches none or several, treat the controlled setup as invalid and stop before creating encounter state. Do not change the normal encounter percentage to 0% or 100% and then rely on memory to restore it.

Complete and record these checkpoints separately:

  1. Document the setting. Record its file and location, the three allowed modes, the normal value, how the known species is selected, and the exact restoration step.
  2. Verify no encounter. From the same reset condition, enable controlled no-encounter mode and complete the grass route twice. Both routes must keep exploration active.
  3. Verify one known encounter. Enable controlled known-encounter mode and start the documented encounter twice. Both routes must create the same species with the same starting hit points. Repeat with another allowed species when a later battle boundary needs it.
  4. Restore normal mode. Restore the documented normal value and reload the page. Inspect the setting before you run another test.
  5. Verify ordinary random behavior. Add one temporary trace at the point that creates the random chance value, complete one accepted grass move, and confirm that the trace appears once. Remove the trace. Confirm that the documented normal percentage remains configured before the checkpoint commit.

Verify these separate paths:

  • Moving onto a non-grass square performs no encounter check.
  • Controlled no-encounter mode keeps exploration active.
  • Controlled known-encounter mode starts one encounter with the selected allowed species and documented starting hit points. Movement controls become unavailable before the encounter receives focus.
  • Normal mode uses the documented percentage and selects only species from the encounter list when an encounter occurs.
  • Repeated renders do not change the active wild Pokémon or its hit points.
  • The development test can reach the encounter state reliably, and normal play uses the documented percentage afterward.

Checkpoint: Tall grass can create one stable random encounter

What now works
Each accepted grass move performs one chance check, a successful check selects one allowed Pokémon, movement becomes unavailable, and the selected encounter remains stable in state across later renders.
Files changed
game.js, game.html, project-brief.md, interactive-test-report.md
What remains
Implement attack, wild response, capture, run, victory, and fainting outcomes.
Next action
Write the expected state before and after each battle action in interactive-test-report.md.
If it does not work
If the wild Pokémon changes unexpectedly, find every place that generates a random value and confirm that random selection occurs during the grass-movement event rather than during rendering.

Before you implement battle actions, read:

Use these terms throughout this stage:

Term Meaning in this project
Battle active The active-encounter state property contains one wild-Pokémon runtime record instead of null
Current opponent The wild-Pokémon runtime record in the active-encounter property
Battle action One activation of Attack, Throw Poké Ball, or Run while a battle is active
Battle phase The current valid point in one action: before the action, after player action, after an allowed wild response, or encounter ended
Terminal result Defeat, successful capture, Run, or starter fainting; no later update from the same action can occur after it

Use native buttons with type="button" for Attack, Throw Poké Ball, and Run. Each button activation must produce exactly one battle action. Make Attack work and pass its pointer and keyboard checks before you connect the other two actions.

A state transition is the complete change from one documented state before an action to one valid state after that action. It is a description of required behavior, not a JavaScript keyword or framework feature.

Copy this transition contract into interactive-test-report.md. Replace fixed damage, maximum hit points, and capture threshold with the numeric decisions from project-brief.md before implementation.

Action and starting condition Required state result Encounter and focus result
Attack; wild Pokémon survives the fixed damage Subtract the fixed attack damage from wild hit points. Then subtract the fixed wild damage from starter hit points. Report both results. Encounter remains active unless the starter faints. Focus remains on Attack.
Attack; wild Pokémon reaches or passes zero Set displayed wild hit points to zero. Do not add it to the caught collection. Do not perform a wild response. Encounter ends. Focus moves to the first enabled movement control.
Throw Poké Ball; wild hit points are above the threshold Do not change either Pokémon’s hit points or the caught collection. Report why the catch failed. Encounter remains active. Focus remains on Throw Poké Ball.
Throw Poké Ball; wild hit points are at or below the threshold Confirm the species identity. Stage 6 records it as a temporary handoff; Stage 7 updates the caught collection before the final render. Do not perform a wild response. Encounter ends. Focus moves to the first enabled movement control.
Run; encounter is active Do not change hit points or the caught collection. Report that the trainer ran. Encounter ends. Focus moves to the first enabled movement control.
Wild response makes the starter reach or pass zero Return the player to the Pokémon Center, restore the starter to maximum hit points, and report the fainting and recovery result. Encounter ends. Focus moves to the first enabled movement control.

Every battle control must be unavailable when no encounter is active. Prevent hit points from displaying below zero.

Use controlled known-encounter mode to create the same encounter for each attack test. Choose the documented encounter species whose starting hit points reach the boundary you need. Implement the surviving-wild-Pokémon branch first. Confirm that one activation applies one player attack, one wild response, one status update, and one render.

Then implement the wild-defeat branch. Test a result that reaches exactly zero and a result that would pass below zero. Both results must display zero, end the encounter, skip the wild response, and leave the caught collection unchanged.

Checkpoint: Attack has one ordered result

What now works
A surviving wild Pokémon responds once, while a defeated wild Pokémon stops at zero, ends the encounter, stays out of the caught collection, and cannot respond.
Files changed
game.html, game.js, interactive-test-report.md
What remains
Add failed capture, successful capture, and Run without changing the verified Attack order.
Next action
Start a controlled known encounter, confirm that its hit points are above the capture threshold, and implement the failed-capture result.
If it does not work
If the wild Pokémon responds after defeat, inspect the first condition after player damage and confirm that the terminal result stops the remaining action.

A handoff passes one result from one program responsibility to the next. It does not require a specific function name. Record this contract in interactive-test-report.md before you implement successful capture:

Boundary Required result
Input from battle One active encounter has passed the capture-threshold rule. Its Pokédex number and display name are still available.
Stage 6 responsibility Confirm capture once. Copy the number and name into a temporary pendingCapture record before the encounter ends. The collection and total remain unchanged at this checkpoint.
Stage 7 responsibility Move the collection decision into the successful-capture action. Compare the copied Pokédex number with the collection, add at most one record, and remove the temporary handoff property when it is no longer needed.
Final completion order Confirm capture, copy identity, update the collection at most once, end the encounter, set the added-or-already-recorded status, render from final state, and move focus to the first enabled movement control.

During Stage 6, inspect pendingCapture to prove which Pokédex number reaches this boundary. Stage 7 uses that confirmed identity in the successful-capture action and removes the temporary property. Do not clear the active encounter before you have read the species identity needed by the collection update. Do not update the collection once in the battle action and again in the renderer.

Throw Poké Ball must use the documented capture threshold. Test the failed result above the threshold before the successful result. A successful capture uses the handoff contract above. Stage 6 proves that one confirmed species reaches the boundary once. Stage 7 completes and verifies the collection change before the encounter result renders. Run always ends the encounter without changing the collection.

Checkpoint: Capture and Run preserve their boundaries

What now works
A failed catch preserves the encounter, a successful catch sends one species identity to the collection boundary, and Run ends the encounter without changing the collection; none of these actions performs an extra wild response.
Files changed
game.html, game.js, interactive-test-report.md
What remains
Complete the starter-fainting recovery and run the full battle matrix.
Next action
Start a controlled known encounter where one documented wild response will make the starter reach or pass zero hit points.
If it does not work
If capture or Run changes an unrelated value, compare the relevant transition-table row with the state immediately before and after one activation.

The fainting result occurs only after a surviving wild Pokémon responds. When the starter reaches or passes zero hit points, finish the complete recovery before rendering: return the player to the Pokémon Center, restore the starter, end the encounter, set the recovery message, and choose the focus target from the focus contract.

Start controlled known encounters and verify attack with a surviving opponent, defeat on exactly zero hit points, defeat when damage would pass below zero, a failed catch above the threshold, a successful catch at the threshold, a successful catch below the threshold, run, and starter fainting.

For each test, inspect the starter, wild Pokémon, hit points, active encounter, caught collection, position, status message, focus, and Console before the next action.

Checkpoint: One battle can reach every required outcome

What now works
Attack, wild response, defeat, failed capture, successful capture, run, and fainting each update the correct state and return the player to a valid next action.
Files changed
game.html, game.js, styles.css, interactive-test-report.md
What remains
Render the caught collection, handle duplicate species, and finish the static Pokédex relationship.
Next action
Open the successful-capture path and identify the exact point after the catch is confirmed but before the interface renders.
If it does not work
If two outcomes occur after one action, inspect the order of the condition checks and confirm that a completed outcome stops the remaining battle transition.

Stage 7: Complete the caught collection and Pokédex

Section titled “Stage 7: Complete the caught collection and Pokédex”

Before you implement the collection, read:

Begin at the capture-to-collection handoff from Stage 6. At that checkpoint, pendingCapture holds one confirmed identity after the encounter ends. Move the collection decision into the successful-capture action. Copy the active encounter’s Pokédex number and display name before you clear it; compare and update the collection before the final render. Remove pendingCapture once this direct route works, so the same capture is not stored in two places.

Render the caught-Pokémon collection and caught-total summary from state. Calculate the total from the collection instead of maintaining a second count.

Use the Pokédex number as the species identity. You can use the loop and condition patterns from the linked lessons to compare that number with existing records. You can choose another array method after you read its official reference and can explain its return value. The required behavior does not depend on choosing a specific array method.

Implement and verify these cases in order:

Starting collection Successful catch Required result
Empty First species Add one record, remove the empty result, render one caught entry, and show total 1.
Contains one species Different Pokédex number Add one record, render both species once, and show total 2.
Contains the same Pokédex number Same species again Add nothing, keep the total unchanged, and report that the species is already recorded.

For each row, inspect this order separately: capture confirmed → incoming identity read → collection compared → collection changed at most once → encounter ended → status selected → interface rendered → focus restored. The incoming identity and final collection must be visible in the evidence before you test the next row.

Checkpoint: Caught species have one stable identity

What now works
The empty result, first catch, different species, duplicate species, rendered entries, and derived total all agree with the caught-collection array.
Files changed
game.html, game.js, styles.css, interactive-test-report.md
What remains
Verify the existing static Pokédex against the encounter list and complete the full reset route.
Next action
Compare every encounter-list Pokédex number with the entries in pokedex.html.
If it does not work
If a duplicate appears, record the incoming and existing Pokédex numbers before changing the renderer. Confirm that the collection update rejects the duplicate before rendering.

The static Pokédex was built in the earlier website stage. Check it against the final encounter list now. Each encounter species must have a matching entry. The Pokédex can contain additional Pokémon that do not appear in this map. Keep the static catalog independent of the caught collection so it works without the game state or JavaScript.

Create a short comparison list in project-brief.md with one row for each encounter species and its matching static Pokédex entry. This is a content check, not a connection between the two pages at runtime.

The complete reset control must work from trainer setup, exploration, an active encounter, and a non-empty caught collection. Use one reset responsibility for every route. It must rebuild the same initial values used when game.html first loads; do not create a different reset implementation for each starting condition.

Complete the reset in this order:

Phase Required result
1. Restore state Trainer name is ""; starter, map position, and active encounter are null; caught collection is []; status is the documented trainer-setup instruction.
2. Render the before-setup interface Trainer-form values and validation are clear; the collection shows its empty result and total 0; game regions and controls have their documented unavailable or initial presentation; the status region shows the setup instruction.
3. Restore focus Focus moves to the trainer-name field after the reset render.
4. Inspect evidence State, DOM, status, controls, focus, and Console match the before-setup contract. No battle update continues after reset.

State must return to its initial values before the reset render reads it. Focus moves only after the new interface exists. Do not reload the page or clear browser storage. The required project does not use persistent game progress.

Implement RESET-01 first. Change one trainer-form value or produce one validation error while no game is active. Activate Reset once and compare every state, form, validation, rendered, status, focus, and Console result with the table above. Do not continue to the other routes until this complete setup reset passes.

Verify one reset route at a time. Return to the named starting condition before each activation:

Reset route Required starting condition Required result after one reset activation
Setup reset The form contains changed values or a validation error, but no game is active Every state property, form value, validation result, status result, and focus target matches the before-setup contract
Exploration reset A valid trainer has moved away from the starting position The trainer, starter, position, and exploration result are removed and the before-setup contract returns
Battle reset A controlled known encounter is active and at least one hit-point value has changed The encounter ends without another battle update and the before-setup contract returns
Collection reset At least one caught species appears in the collection The collection becomes empty, the derived total becomes 0, and the complete before-setup contract returns

After RESET-01 passes, reuse the same reset responsibility for exploration, battle, and collection. Do not treat the first passing route as proof for the other three. Each route begins with different changing state and rendered content. Record the exact starting condition, one activation, complete result, and next route before you change the setup.

Test the empty collection, first catch, second different species, and repeated species. Run reset separately from trainer setup, exploration, battle, and a non-empty collection. Disable JavaScript on pokedex.html and confirm that all static entries remain available. Confirm the state, totals, visible entries, status, focus, and Console result after every change.

Checkpoint: Caught progress and reference information are complete

What now works
The game renders an accurate duplicate-free caught collection and total, the static Pokédex provides complete reference entries without game state, and reset restores the same complete before-setup condition from every required starting state.
Files changed
game.html, game.js, pokedex.html, styles.css
What remains
Make all three pages responsive and add one preference-aware motion effect.
Next action
Open all three pages at a narrow viewport and record the first overflow, clipping, overlap, or unusable control.
If it does not work
If the total and collection disagree, compare the caught-collection property before and after capture before changing the renderer or summary.

Stage 8: Make the complete product responsive and motion-safe

Section titled “Stage 8: Make the complete product responsive and motion-safe”

Before you implement the responsive and motion layers, read:

Use the static Pokédex entry as the default container-query component. Use the start of an encounter as the default animation target. You can choose a caught-Pokémon entry or a different required state change if you record that choice and its expected behavior in project-brief.md before you edit the CSS.

Complete the responsive work in this order:

  1. Test the unmodified landing page, game page, and Pokédex near 320 CSS pixels. Record the first overflow, clipping, overlap, or control problem.
  2. Build a complete narrow layout for every page. Long names, messages, labels, cards, and controls must wrap without lost content.
  3. Add a wider page composition at a viewport breakpoint chosen from the content rather than a named device.
  4. Test one static Pokédex entry in a narrow container before adding a container query.
  5. Establish the query container and choose a component breakpoint from the space the entry needs.
  6. Show the same component at the same viewport width inside one narrow and one wide container. Record the different component results. This proves that the container, not the viewport, caused the change.

Checkpoint: The page and component layouts respond to the correct space

What now works
All three pages have complete narrow and wider compositions, and one repeated component changes because its own container crosses a documented content breakpoint.
Files changed
index.html, game.html, pokedex.html, styles.css, interactive-test-report.md
What remains
Add one finite state-change animation and its equivalent reduced-motion result.
Next action
Write the complete visible result of the selected state change before adding animation.
If it does not work
If the component responds only when the viewport changes, inspect which element establishes the query container and which element receives the container-query styles.

Record this contract under Game-data decisions in project-brief.md before you add motion:

Part Required decision
Static before-state The content and state before the selected transition
Trigger The one user action and state transition that can start the motion
Static after-state The complete content, controls, status, and focus result without motion
Standard-motion result The finite visual change that reinforces the completed transition
Reduced-motion result The same after-state shown immediately without the project motion
Unrelated render result Resizing, focus restoration, or rendering another region does not start the motion again

Update the state first and render the complete after-state from it. Motion belongs to the presentation of that completed transition. It must not choose the game result, delay the status or focus result, or wait for an animation-end event before the state becomes valid. If rendering replaces the animated element, the new element must still show the correct static state without starting motion for an unrelated render.

Complete the motion work in this order:

  1. Trigger the selected state change without animation. Confirm that the state, static styles, text, status message, controls, and focus communicate the complete result.
  2. Add one short, finite animation that runs only for the documented trigger and reinforces the result. Do not make the animation responsible for completing the state change.
  3. Add the reduced-motion rule. It must remove the project motion and show the same result immediately.
  4. Trigger the state in standard and reduced-motion modes. Compare content, state, function, status, focus, and Console results.
  5. Resize the page and cause one unrelated render after the animation ends. Confirm that neither action starts the motion again or changes the completed state.

Test the landing page, trainer setup, map, battle, caught collection, and Pokédex near 320 CSS pixels, at a wide viewport, and at 200% browser zoom. Test the repeated component inside narrow and wide containers. Repeat the selected state change with standard and reduced motion, then confirm that resizing and one unrelated render do not start the motion again.

Checkpoint: The complete game adapts without losing behavior

What now works
All pages, controls, long content, game states, and repeated components work in narrow, wide, zoomed, standard-motion, and reduced-motion conditions, and unrelated renders do not repeat the selected motion.
Files changed
index.html, game.html, pokedex.html, styles.css, interactive-test-report.md
What remains
Complete technical SEO and run the full quality evidence route.
Next action
Open technical-seo-report.md and record that this project has no approved public origin.
If it does not work
If an interaction fails only after a layout change, restore the failing viewport and inspect source order, focus, overflow, and the first changed CSS condition before changing JavaScript.

Before you complete the SEO work, read:

Use this initial-HTML contract before you inspect or repair the pages:

Page Meaning that must exist in saved HTML before JavaScript runs
index.html Game title, product introduction, main features, and crawlable routes to the game and Pokédex
game.html Page purpose, trainer setup, game-region headings, visible controls or control instructions, and crawlable site navigation; changing game results can depend on JavaScript
pokedex.html Catalog purpose, all required Pokémon entries, and crawlable site navigation; the catalog must remain useful without JavaScript

Create one report row for each page and each evidence group below. Add a Page column so a result for one page cannot be mistaken for evidence about all three pages.

Evidence group What to inspect and record
HEAD Saved title, description, language, character encoding, viewport, and valid head structure
HTML Saved main heading, landmarks, initial page meaning, and useful no-script result
LINK Saved anchor destinations and rendered keyboard link behavior
RENDER Rendered heading, description of visible purpose, and any difference from saved HTML
VALIDATE Relevant HTML validation result and the repair or explanation for each message
BOUNDARY No-public-origin decision and whether canonical, crawl, index, traffic, and ranking checks are blocked or not applicable

Audit all rows before editing. Repair one evidence group at a time, then update its actual result. Each page needs an accurate title, useful description, valid head content, one descriptive main heading, useful initial meaning, and crawlable navigation links.

The game remains local. State that no approved public origin exists. Do not add a canonical URL, deployment result, index result, traffic claim, or ranking claim for an invented location. Record live-only checks as blocked or not applicable according to the lesson and teacher direction.

After every SEO repair, repeat the affected navigation, trainer, game, and responsive checks.

Confirm that every required page-and-evidence row has an actual result. Confirm that the saved source, no-script result, rendered DOM, link behavior, validation result, and technical SEO report agree for all three pages. Confirm that the game remains fully usable after the final SEO change.

Checkpoint: The local product has honest technical SEO evidence

What now works
All three pages have valid and specific local SEO signals, useful initial meaning, crawlable navigation, and an explicit no-public-origin boundary.
Files changed
index.html, game.html, pokedex.html, technical-seo-report.md
What remains
Execute the complete interaction, accessibility, responsive, source, and regression test set.
Next action
Open interactive-test-report.md, identify the candidate final commit, and restore the documented initial state.
If it does not work
If the report depends on a public URL, return to the publication boundary and separate local source evidence from unavailable public-origin evidence.

Stage 10: Test, repair, document, and present the result

Section titled “Stage 10: Test, repair, document, and present the result”

Before you execute the final quality route, read:

Identify one candidate final commit and test it from the documented reset state. Add these columns to interactive-test-report.md: ID, Candidate commit, Setup ID, Reset or precondition, Action, Expected result, Actual result, Restoration result, Status, and Evidence or defect issue. Use Not run for an unexecuted case. Use Not needed when a case changes no controlled setting. Do not use Pass until the actual result and required restoration match every part of the expected result.

Complete a setup route before you run the cases that name it. Do not prepare all fourteen routes at once. Record one route, use it for its connected cases, restore the project, and then continue to the next needed route.

Use this worksheet for every setup ID under Controlled setup routes:

Field What to record
Setup ID and purpose The ID and the one state it must produce
Build from The earlier setup route that supplies the starting state
Exact actions Trainer and starter values, mode, map moves, and battle actions in order
Precondition proof Relevant position, species identity, hit points, collection, mode, status, and Console result
Used by Test IDs that can start from this route
Restoration Complete reset, normal-mode restoration, reload, and the evidence needed before unrelated work

Build the routes in these families. A route can reuse an earlier route instead of repeating every action in its written instructions.

Setup ID Build from State that the recorded route must produce Required restoration
S0 Direct page load Complete before-setup state with normal encounter mode active Not needed; this is the restoration target
S1 S0 Active trainer at the Pokémon Center with a full-health starter and no encounter Complete reset to S0
S2 S1 Player beside one named map edge or blocked square Complete reset to S0
S3 S1 plus a recorded damage route Damaged starter beside the Pokémon Center with no active encounter Complete reset to S0
S4 S1 Controlled no-encounter mode active before an accepted grass move Restore normal mode, reload, and complete reset to S0
S5 S1 Controlled known-encounter mode active before an accepted grass move Restore normal mode, reload, and complete reset to S0

Each route below begins with S5, enters the documented known encounter, and uses only the actions needed to reach its named hit-point boundary.

Setup ID State that the recorded route must produce Required restoration
S6 The next Attack leaves both Pokémon above zero Restore normal mode, reload, and complete reset to S0
S7 The next Attack makes wild hit points exactly zero Restore normal mode, reload, and complete reset to S0
S8 The next Attack would make wild hit points less than zero Restore normal mode, reload, and complete reset to S0
S9 Wild hit points are above the capture threshold Restore normal mode, reload, and complete reset to S0
S10 Wild hit points are exactly at the capture threshold Restore normal mode, reload, and complete reset to S0
S11 Wild hit points are positive and below the capture threshold Restore normal mode, reload, and complete reset to S0
S12 The next Attack leaves the wild Pokémon active and its response makes the starter faint Restore normal mode, reload, and complete reset to S0
Setup ID Build from State that the recorded route must produce Required restoration
S13 S10 or S11, followed by one successful capture Exploration is active and one documented species is already in the caught collection; record the current encounter mode Restore normal mode, reload, and complete reset to S0

Use the battle-rule plan to write the exact species and action count for S6–S12. If the chosen values cannot produce one of these states, stop and revise the battle-rule plan before testing. Do not edit ordinary rules during a test merely to force a result.

After a route is recorded, run only its connected case or short group of cases. Complete the restoration column and confirm S0 before you start an unrelated family. If restoration fails, stop and repair or document that failure before later results inherit the wrong state.

Use the following required test matrix. Keep separate rows even when one browser route lets you execute several rows in sequence.

ID Setup ID or precondition Action and required evidence
LOAD-01 S0 Open each page directly; verify its title, main heading, navigation, loaded assets, and initial Console result.
TRAIN-01 S0; starter selected Submit an empty name and then a whitespace-only name in separate resets; verify rejection, connected error, unchanged state, focus, safe text, and Console result.
TRAIN-02 S0; valid name entered and instruction option selected Submit; verify the specific starter-choice error, unchanged state, focus on the choice, and Console result.
TRAIN-03 S0 Submit a valid short fictional name and starter; verify the complete initial state, exploration interface, status, controls, and focus.
TRAIN-04 S0 Submit the documented long-name example and a valid starter; verify state, rendered text, wrapping, status, focus, and Console result.
TRAIN-05 S0 Submit the documented HTML-looking name and a valid starter; verify that it appears only as text and creates no element or executable behavior.
MOVE-01 S1 Follow the documented route with accepted north, south, east, and west moves; compare coordinate state, marker, position text, terrain, status, and focus after each move.
MOVE-02 S2 for each named boundary Attempt one outer-edge or blocked-terrain move; verify that the valid coordinate and marker do not change and the specific rejection is reported.
HEAL-01 S3 Enter the Center; verify the accepted coordinate, full hit points, rendered values, status, focus, and Console result.
ENCOUNTER-01 S4 Move on non-grass and into grass; verify no check on non-grass, exactly one decision on accepted grass movement, active exploration, status, focus, and Console result.
ENCOUNTER-02 S5 Enter grass twice in separate reset routes; verify the selected allowed species and starting hit points, one stable active encounter, disabled movement, status, focus, and Console result.
ENCOUNTER-03 S0 after normal-mode restoration Trigger normal encounters; verify the documented percentage, allowed species, stable encounter during rendering or resizing, and Console result.
DATA-01 S5 using one previously battled species Start the same species again; verify fresh starting hit points and unchanged fixed starter and encounter definitions.
ATTACK-01 S6 Attack once; verify ordered damage, both hit-point values, active encounter, status, controls, focus, and Console result.
ATTACK-02 S7 Attack once; verify exact-zero display, no wild response, no collection change, ended encounter, status, and focus.
ATTACK-03 S8 Attack once; verify clamped zero display, no wild response, no collection change, ended encounter, status, and focus.
CATCH-01 S9 Throw a Poké Ball; verify failure, unchanged hit points and collection, active encounter, status, and focus.
CATCH-02 S10 Throw a Poké Ball; verify successful capture at equality, ended encounter, species identity, collection entry, total, status, and focus.
CATCH-03 S11 Throw a Poké Ball; verify successful capture below the threshold, ended encounter, species identity, collection entry, total, status, and focus.
RUN-01 S6 Run; verify unchanged hit points and collection, ended encounter, restored movement, status, and focus.
FAINT-01 S12 Attack; verify the wild response, Center coordinate, healed starter, ended encounter, unchanged collection, recovery status, and focus.
COLLECTION-01 S0 then one documented successful-capture route Verify the empty result, first recorded species, one rendered record, and derived total 1.
COLLECTION-02 S13; prepare a different species Catch it; verify both species render once and the derived total becomes 2.
COLLECTION-03 S13; prepare the same species Catch it; verify no duplicate record, unchanged total, duplicate status, and focus.
RESET-01 S0 with changed form or validation state Reset once; verify the complete before-setup state, DOM, controls, status, focus, and Console result.
RESET-02 S1 after at least one accepted move Reset once; verify the same complete before-setup result.
RESET-03 S6 after one changed battle value Reset once; verify the encounter stops and the same complete before-setup result returns without another battle update.
RESET-04 S13 Reset once; verify the empty collection, total 0, and the same complete before-setup result.
KEYBOARD-01 S0 Use only the keyboard for navigation, trainer setup, movement, encounter actions, capture, healing, and reset; verify visible focus and no keyboard trap.
STATUS-01 One invalid and one accepted setup, movement, battle, catch, and reset result Verify that the polite status region exposes each result without receiving focus and that focus matches the focus contract.
LAYOUT-01 Each required page and game state Test near 320 CSS pixels, a wide viewport, and 200% zoom; verify readable content, wrapping, reachable controls, and no unintended horizontal page scroll.
COMPONENT-01 Same repeated component in narrow and wide containers at one viewport width Verify the documented component change and record evidence that the container caused it.
MOTION-01 Selected state ready to trigger Trigger it in standard and reduced-motion modes; verify equivalent state, content, function, status, focus, and Console results, then confirm that resizing and one unrelated render do not repeat it.
SOURCE-01 Candidate source saved Record HTML validation, VS Code CSS diagnostics, all three SEO page matrices, navigation, and unresolved Console errors; repair or explain each relevant result.

Run one exploratory charter after the scripted paths. Record actual results before repairing source. A confirmed defect needs a focused issue, one cause at a time, a repair commit, the original-path retest, and connected regression evidence.

After every required case and affected regression passes, move Run final regression and review delivery evidence to Done. This project-specific result overrides the linked lesson’s instruction to leave that issue ready for later SEO or analytics changes. If you later start the optional analytics stage, create a separate extension issue and rerun only the affected source, privacy, interaction, and regression checks.

Complete README.md against the verified product and commit. It must explain how to open the local project, what each file owns, the state and render architecture, all controls, the complete reset route, the controlled encounter test and its normal-mode restoration, the test reports, known limits, recovery information, and the final verified commit.

Before you prepare the demonstration, read:

Complete presentation-plan.md. The default format is a live walkthrough for your teacher. Prepare a recording only when your teacher requests one. Record the audience, purpose, candidate commit, exact start state, five-part route, required tabs or tools, controlled encounter method, normal-mode restoration, recovery route, and final state.

Use this five-part route:

  1. Context: Show the landing page, the product purpose, and navigation to the game and Pokédex.
  2. Normal product route: Validate the trainer form, start the game, move, trigger the controlled encounter, show a surviving attack, catch the Pokémon, and inspect the caught collection.
  3. Reference and responsive result: Open the static Pokédex, show its no-script value, and demonstrate the viewport-based and container-based layout results.
  4. Quality decision: Show keyboard focus, reduced motion, one test row, and the honest no-public-origin SEO boundary.
  5. Recovery and finish: Restore normal encounter mode, complete the reset route, show the final commit in the reports and repository, and end in the documented before-setup state.

Confirm that the source, reports, README, private board, repository, and demonstration all identify the same final commit. Confirm that every required issue is closed, the final regression passes, the remote contains the commit, and the working tree is clean.

Checkpoint: One final commit has a complete evidence chain

What now works
The required website, game loop, Pokédex, accessibility, responsive behavior, motion behavior, tests, repairs, SEO evidence, documentation, repository, and demonstration agree on one verified commit.
Files changed
source files, README.md, quality-plan.md, interactive-test-report.md, technical-seo-report.md, presentation-plan.md
What remains
Submit and demonstrate the required project. Optional extensions remain separate.
Next action
Show the verified local project, evidence files, private repository, and final demonstration route to your teacher.
If it does not work
If two evidence files name different source states, identify the later change and repeat the affected tests against one candidate final commit before submission.

Self-check

Complete these checks against the required result.

  1. Open index.html, game.html, and pokedex.html from a fresh browser tab and confirm that all navigation links work in both directions.
  2. Submit empty and whitespace-only names, a missing starter choice, valid short and long inputs, and HTML-looking trainer text; confirm the documented error, state, text, focus, and Console results.
  3. Confirm that the map definition, coordinate state, visible marker, position text, terrain, controls, status, and focus agree after accepted and rejected movement.
  4. Confirm that one accepted grass move makes one chance decision, a successful chance uses a separate value for one valid list index, encounter state exists before rendering, controlled modes use the shared state route, and normal mode is restored before the final commit.
  5. Test every documented battle transition from its controlled starting state and confirm the required update order, stopping condition, status, and focus.
  6. Confirm that one successful capture passes one species identity through the collection handoff before rendering, caught species render once, duplicate identities are rejected, and the total comes from the collection.
  7. Reset separately from trainer setup, exploration, an active encounter, and a non-empty collection, then confirm that each route uses the same state → render → focus order and reaches the complete before-setup contract.
  8. Disable JavaScript on pokedex.html and confirm that all required reference information remains available.
  9. Use only the keyboard to complete trainer setup, movement, battle, capture, healing, navigation, and reset with visible and useful focus.
  10. Confirm that status changes are programmatically exposed without taking focus, every result matches the focus contract, and no state depends only on color, position, or motion.
  11. Run the core game at a 320 CSS-pixel viewport, at a wide viewport, and at 200% browser zoom without lost content or unintended horizontal page scrolling.
  12. Show the same repeated component in narrow and wide containers at one viewport width and confirm that its own container causes the documented change.
  13. Run the selected state change with standard and reduced motion, confirm the same immediate content, state, function, status, and focus result, and verify that resizing or an unrelated render does not repeat the motion.
  14. Validate the saved HTML, review CSS diagnostics in VS Code, and resolve or explain every relevant message.
  15. Complete every row in the required test matrix, the exploratory charter, confirmed repair retests, and the final regression against one identified commit.
  16. Confirm that the technical SEO report contains every required page-and-evidence row and separates local evidence from unavailable public-origin evidence.
  17. Read the README from the position of a person opening the project for the first time and confirm that its launch, architecture, controls, reset, test, limit, and recovery instructions are complete.
  18. Follow presentation-plan.md from its exact start state and confirm that the normal route, quality evidence, recovery route, and final state are repeatable.
  19. Confirm that the final commit exists on the private remote, the required board contains no unresolved item, and git status reports a clean working tree.

The requirements and checkpoints remain visible above. Open one assistance level when you want more structure. The assistance identifies the next required result and relevant evidence; it does not provide the finished game code.

Assistance 1 — Find the next unfinished result

Open the active stage and begin at its first heading, contract row, or numbered result that you have not verified. Write three lines in quality-plan.md: the starting state, the one result you are building, and the check that will prove it. Open only the lesson sections linked above that subgoal. When its check passes, record the result before you choose the next row.

Assistance 2 — Use the question for the active stage

For the map, ask: What coordinate exists before the move, what coordinate is requested, and what terrain or boundary accepts or rejects it? For an encounter, ask: Did an accepted grass move perform one chance check, which valid list index was selected, and which record became the stable active encounter? For battle, ask: What is the complete before-state, which one action occurs, which updates happen in order, and which result stops later updates? For the collection, ask: Which Pokédex number identifies the incoming species, and is that number already present? For reset, ask: Which changing state, DOM result, control, status, and focus value still differs from the before-setup contract? For layout or motion, ask: Is the change caused by the viewport, the component container, or the motion preference? For evidence, ask: Which report row names this page, starting state, action, expected result, actual result, and source state?

Assistance 3 — Write one event trace before editing code

Copy the active contract row into quality-plan.md. Under it, write these labels: Before, Action, Rejected when, State updates in order, Stop when, Rendered regions, Status, Focus, and Test evidence. Fill each label with the project requirement, not JavaScript syntax. Use Trace the complete state architecture for the event, state, and render boundaries. Ask your teacher to review any blank or conflicting label. Implement only after the required result is unambiguous, then test that one trace before adding the next behavior.

Stop after a functional checkpoint passes. Commit and push the passing version. Before a longer interruption, update the resume section in quality-plan.md with what works, what remains, the last passing commit, the first failing or unfinished test, the exact next action, and the file, function, selector, browser state, or report row to open when you return.