- selection: clearAllGames() wipes seen/caught for every game but keeps
the global favorites/notes record.
- Progress view: a "Reset caught / seen…" action (custom dialog) that
calls clearAllGames — the soft, favorites-preserving reset. Settings →
"Clear tracking data" stays as the full wipe (now spells out that it
also drops favorites and notes, and points here for the softer one).
- Swept the remaining window.confirm / window.alert calls
(Settings clear-tracking, clear-cache, backup import result;
ShinyView delete-hunt) onto chooseDialog for a consistent look.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Ve7HLspzeG2xDPtJQ8vmu
Progress view "Your games" now has an Edit mode: tap a game to open a
dialog to **reset** its caught/seen (keeps it listed) or **remove** it
from the list (also clears its bucket). The currently-selected game can't
be removed (it'd re-add on next launch) — reset only. New
`clearGame(vgKey)` in the selection store.
Lighthouse pass (headless, local): SEO 100, a11y 96, best-practices 96.
- add public/robots.txt (SEO 92 → 100)
- ProgressRing: keep the aria-label in sync with the visible count
(fixes label-content-name-mismatch)
- .type-chip: text-shadow for white-on-bright-type-colour legibility,
0.68 → 0.7rem
Still open (design calls, see notes): type-chip colour contrast is
~2–3.7:1 for the lighter types (white on the canonical type colours);
some sub-12px labels; performance is dominated by the ~1 MB snapshot and
the ~1000-card grid.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Ve7HLspzeG2xDPtJQ8vmu
Pure formatting — no behaviour change. Verified: build passes, all 14
routes render, service worker active, no console errors.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Ve7HLspzeG2xDPtJQ8vmu
The reference links sat in their own strip under the header, reading as an
afterthought, and "Compare" appeared both there and as a Team mode.
- Reference links (Natures / Type chart / Breeding) now share one bar with
the Coverage/Compare/Calc switch — quiet text links on the right, so
they're still one tap away but clearly secondary chrome, not a pasted-on
row. Right-aligned on wide screens, wrapping under the switch on mobile.
- Removed the standalone "Compare" reference link. The Team's own Compare
mode now carries a "Compare any Pokémon →" link to #/compare in its
intro line, so the free-form compare tool is reachable in context and
only one "Compare" label is ever visible.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Ve7HLspzeG2xDPtJQ8vmu
- Unown's first slot is now "A" (its base sprite is the A shape), not
"Default". Other letter/pattern sets keep "Default".
- The grey-out for uncaught entries applied to the whole tile, dimming
the label text to ~0.55 opacity — unreadable in dark mode. Move the
grayscale/opacity to just the sprite; the label stays full-contrast.
- Sprites 40 -> 60px, grid cell min 68 -> 88px.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Ve7HLspzeG2xDPtJQ8vmu
The Natures / Type chart / Compare / Breeding links under the Team header
were plain dot-separated text. Make them a row of pill chips with small
accent icon badges (.toollinks / .toollink).
Progress by game showed a caught total for all 32 version groups the
moment anything was marked, since the tracking model is one unified
caught record. Add a "played games" set (pdx.playedGames, vg keys),
auto-marked when a game is selected or a save is imported (savedex now
returns candidate versionGroups per generation). #/progress leads with a
"Your games" section and tucks the rest behind a "Show all other games"
toggle (persisted). Included in JSON export/import.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Ve7HLspzeG2xDPtJQ8vmu
Button "Import from a game save" now sits on its own line with the
description "A .sav / .srm from a Gen 1–3 game." beneath it, instead of a
long inline sentence. The dialog already names the detected game and
offers merge vs replace.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Ve7HLspzeG2xDPtJQ8vmu
- The save-import dialog body is now just "N seen · N caught in this
save." — the button labels carry the merge/replace meaning.
- "colour" → "color" throughout (the visible "Accent color" field, plus
comments and README for consistency).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Ve7HLspzeG2xDPtJQ8vmu
- Save import now opens a small choice dialog (new lib/dialog.js) instead
of a confirm(): "Add to my Pokédex" (merge, keeps everything) or
"Replace mine with this". Replace resets seen/caught to exactly the
save but keeps favourites and notes (new selection.replaceFlags). The
dialog also explains that caught state is shared across games, so an
imported save only ever adds species that game has and they count
toward the National Dex too — no per-game caught flag, by design.
- The dex-feed progress ring is now an <a href="#/progress"> with a
hover/press nudge — tapping it opens the per-game breakdown.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Ve7HLspzeG2xDPtJQ8vmu
- onSwipe: before claiming a horizontal page-swipe, walk up from the
touch target for an overflow-x auto/scroll ancestor that can still
scroll that way (tab strip, moves list, coverage grid) and bail if
found — sliding those no longer flips to the next Pokémon.
- segThumb: retry placement until the seg is laid out, and observe it for
resizes, so the sliding pill is positioned on first paint instead of
only after the first click. Dropped the :has() selector for a
JS-applied .seg--thumbed class.
- New lib/sheet-drag.js: drag the game sheet / Pokémon picker down by its
header to dismiss (past ~110px or a flick), else it springs back.
Header gets touch-action:none + a grab cursor.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Ve7HLspzeG2xDPtJQ8vmu
New lib/anim.js (countUp, fadeSlideIn, segThumb), all reduced-motion
aware:
- Shared-element morph: tapping a card tags its art with
view-transition-name; the detail skeleton now renders the real sprite
at hero size (router passes the match, animates the skeleton mount), so
the sprite flies from the grid into the hero and the skeleton→content
swap is seamless.
- Segmented controls (Team / Search / Breeding) get a sliding pill that
measures each button and eases between them.
- Count-ups: the dex-feed progress number and the detail Stats total
tick up.
- Detail tab content fades/rises on switch.
- Global :active scale-press on buttons/chips/rows, plus soft
background/border transitions.
- Hero sprite has a slow idle bob.
- Router swallows the AbortError when a fast follow-up nav skips an
in-flight view transition.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Ve7HLspzeG2xDPtJQ8vmu
build-snapshot: a new pass fetches /pokemon/:id/encounters for every
species and records, per game, the versions it has wild encounters in —
when that's a non-empty strict subset of the game's versions,
species.exclusiveIn[vg] holds them. Wild-only, so gift/trade/evolution
exclusives are missed.
Card: with a specific game selected, shows a "<Version> only" pill
(e.g. Seedot -> "Ruby only", Lotad -> "Sapphire only"). 220 species
flagged across all games; nothing shown in National mode.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Ve7HLspzeG2xDPtJQ8vmu
New store + view (linked from Settings > Your data): one card per active
hunt with a big +1 counter, the method's odds, and the running cumulative
chance (1 - (1-p)^count). Nine methods with shiny-charm variants
(Full odds, Masuda, SOS, Radar, DexNav, Catch Combo, Dynamax Adventure,
Mass/Massive Outbreak). "Found it" marks the Pokémon caught and clears
the hunt; per-hunt notes field.
Also: JSON export/import now covers team, formTracking and shinyHunts
alongside settings/selection; openPokemonPicker gains a `closeAfterPick`
option (used by the shiny + breeding single-pick flows).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Ve7HLspzeG2xDPtJQ8vmu
Two modes, linked from the Team header:
- Egg groups — browse every species in each of the 14 breedable egg
groups (offline, from the snapshot's eggGroups).
- Can breed with — pick a Pokémon and get its compatible partners
(shared egg group; Ditto pairs with everything; genderless pairs only
with Ditto; Undiscovered can't breed), plus its family's egg moves
(walks evolves-from to the base stage — Pikachu shows Pichu's), each
linking to the move page (which already lists who can learn it).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Ve7HLspzeG2xDPtJQ8vmu
New view (linked from Settings > Your data): the unified caught record
counted against every game's dex at once — National total on top, then
each version group grouped by generation with a seen/caught bar and
X / Y count. Tapping a game switches the active version group and jumps
to the dex.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Ve7HLspzeG2xDPtJQ8vmu
Extracted the Team Compare table into components/CompareTable.js and
reused it for a new #/compare route: its own picker (up to 4 Pokémon,
persisted in ui.compareIds), gen-aware types, per-stat max highlight.
Linked from the Team header alongside Natures / Type chart. TeamView's
Compare tab now just calls CompareTable too.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Ve7HLspzeG2xDPtJQ8vmu
- Rasterised the SVG to pwa-192 / pwa-512 / pwa-maskable-512 (logo in the
safe zone, full-bleed background) and a real apple-touch-icon.png;
manifest now lists PNG "any" + a dedicated "maskable".
- Manifest shortcuts: Team, Search, Type chart.
- lib/install.js captures beforeinstallprompt so the app can offer
installation itself — a one-time toast, and an "Install app" button in
Settings (falls back to a "use your browser menu" hint where the event
never fires, e.g. iOS).
- index.html: apple-touch-icon PNG + apple-mobile-web-app meta.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Ve7HLspzeG2xDPtJQ8vmu
New #/types route (linked from the Team header alongside Natures): the
full 18x18 attack/defend grid, gen-aware from the selected game — drops
Fairy pre-Gen 6, Steel/Dark pre-Gen 2, and applies the Gen 1 / pre-Gen 6
quirks the type-chart module already models. Tap a type on either edge to
highlight its row+column and get an offensive + defensive breakdown as
type chips.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Ve7HLspzeG2xDPtJQ8vmu
The "Learned by N Pokémon" fact was a dead number. Now the move page
renders that list as a clickable sprite grid (links to each Pokémon),
with a filter box once it's more than ~24 long.
PokéAPI's learned_by_pokemon is flat across all games, so for a specific
game it's narrowed to species that existed by that generation — a
"Crystal" view of Surf shows 69 Gen 1–2 Pokémon, not the full 231. Not
perfectly game-exact (a mon that only gained the move in a later gen can
slip through) but far better than guess-and-check. National ("all") shows
the unfiltered list.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Ve7HLspzeG2xDPtJQ8vmu
The selection store already had a note field and setNote() (from the
JSON export/import work) but nothing in the UI ever wrote to it. Adds:
- PokemonDetail: an auto-resizing textarea under the Seen/Caught/Team
row. Saves debounced (500ms) as you type, immediately on blur, and
flushes any unsaved keystrokes on teardown so navigating away right
after typing never loses them. A brief "Saved" flash confirms the
write.
- Card: a small 📝 mark on any card whose Pokémon has a note.
- DexGrid: a "Notes" filter chip (same pattern as Caught/Favorites) to
browse everything you've annotated.
Notes already ride along in the existing settings/selection JSON
export-import, so no changes needed there.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Ve7HLspzeG2xDPtJQ8vmu
Extends the existing filter drawer (type/gen) with four more:
- Ability — snapshot abilities already carry a reverse pokemon[] index,
so this is a plain lookup, no new data needed.
- Egg group — options derived from the species list's own eggGroups.
- Min BST — a number field; hard filter, distinct from sorting by BST.
- Fully evolved only — new species.evolvesFromId field (from
pokemon-species' evolves_from_species, already fetched during the
snapshot build, so no extra requests). "Fully evolved" is computed
client-side as "no other species points here via evolvesFromId" —
correctly handles branching lines (Eevee's evolutions all count as
fully evolved; Eevee itself doesn't).
All four persist via the ui store and count toward the filter badge, same
as the existing filters.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Ve7HLspzeG2xDPtJQ8vmu
New "Calc" mode alongside Coverage/Compare. Pick (or quick-pick from your
current team) an attacker, a move, and a defender; get a damage range, %
of the defender's HP, hits-to-KO, and STAB/effectiveness badges.
- src/lib/damage-calc.js: the standard Gen 3+ stat and damage formulas
(statAt, calcDamage), evaluated across the 85–100% roll.
- Move data is era-accurate: picking a move fetches it live for
past_values (power/type/class changes), reusing MovesList's
forGeneration (now exported) via a snapshot-shaped shim so the instant
preview and the refined post-fetch result use the same code path.
- Level/nature/EV inputs per side (defaults: level 100, neutral nature,
0 EV, 31 IV assumed) plus a crit toggle.
- Explicitly out of scope and called out in the UI: items, abilities,
weather, terrain — this is a base-stats estimate, not a battle-exact
number.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Ve7HLspzeG2xDPtJQ8vmu
New tab on the detail page — "<Species> Dex" — for any species with more
than one cosmetic form: a checklist grid (sprite + label + tap-to-toggle)
tracking which appearances you've caught, separate from the species' own
caught flag. Persisted in a new pdx.formTracking store keyed by form slug.
Only offered when the species is actually in the currently selected
game's dex (reuses the page's existing prev/next row lookup), so Unown
gets its dex in HeartGold/SoulSilver but not in Sword/Shield, where it
was never released.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Ve7HLspzeG2xDPtJQ8vmu
Coverage was hardcoded to Gen 9. Now it reads the selected game: only
that generation's types get rows (no Fairy pre-Gen 6, no Steel/Dark
pre-Gen 2), member typings are era-accurate via the snapshot's pastTypes,
and the type chart / STAB maths run at the game's generation. Compare's
Type row follows suit. The panel re-renders on a game switch.
New "Weak spots" block above the grid: types that hit 2+ members
super-effectively, or that a member is weak to and nobody resists (those
get a "0 resist" flag), each listing the exposed members. Plus a
"no resist to" line for types the whole team only takes neutrally but
can't wall. The grid itself swaps the plain "weak" count for a diverging
resist/weak bar and tints rows where 2+ members are weak.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Ve7HLspzeG2xDPtJQ8vmu
Pull sprite-only variants into the snapshot — Unown letters, Vivillon
patterns, Furfrou trims, seasonal Deerling/Sawsbuck, Flabébé-line colours,
Alcremie decorations, Pikachu caps (278 across 50 species). They share the
base Pokémon's typing/stats/abilities/learnset, so they carry only
{ slug, id, name, sprite } and never trigger a /pokemon fetch.
build-snapshot.mjs: cosmetic varieties (previously dropped) and the
/pokemon-form entries for species with >1 form now land in
species.cosmeticForms.
PokemonDetail: a single <select> "Appearance" dropdown, separate from the
mechanical form pills, that swaps only the hero artwork + label. Picking a
cosmetic look while a mechanical form is active reverts to base first.
Card "+N forms" badge counts cosmetic variants too.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Ve7HLspzeG2xDPtJQ8vmu
- Snapshot: each species gains a forms[] list (slug, form id, label,
category, types, stats, BST, height, weight) built from its non-default
varieties — 264 forms across 203 species (Megas, G-max, regional,
alt formes; cosmetic-only forms filtered out). Snapshot ~914 KB.
- Detail page: a form switcher (Base + each form). Selecting a form
re-fetches its /pokemon and rebuilds the type-dependent parts —
hero name/types/artwork, --type theming, stat bars + total, defensive
matchups, STAB coverage, abilities, EV yield, held items, and learnset.
Species-level data (flavour, breeding, evolution) stays put.
- Grid cards show a '+N forms' badge.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Snapshot bakes an abilities index (373: name, generation, effect, and the
species that have it). Snapshot ~872 KB / 133 KB gzip.
- Search gains an 'Abilities' tab — browse all 373 offline, filter/search by
name or effect, sort A–Z / most-Pokemon / newest
- #/ability/:id detail: effect + a grid of every Pokemon with the ability
(all from the snapshot, no fetch)
- Pokemon detail: the Abilities line is now tappable, linking to each ability
- #/natures: the full 25-nature +10%/-10% table; linked from the Team view
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Snapshot now bakes a moves index (937: type, damage class, power,
accuracy, pp, priority, generation, machine ids per version group) and an
items index (2223: id, name, category — resolved via the 54 item
categories). ~806 KB / 117 KB gzip.
- Search Moves/Items tabs show the FULL list when the query is empty:
- Moves: filter by type / damage class / 'TMs only' (for the selected
game), sort by A–Z / power / accuracy / newest; TM numbers resolve
lazily via /machine. Rich rows (type + class + power) with no fetch.
- Items: filter by category, sort A–Z / dex order; sprite + category tag.
- Result count shown; capped at 400 with a 'refine to see more' note.
- Both tabs are now fully offline (dropped the online name-index calls).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- New #/team view: a persisted lineup of up to 6 Pokémon (pdx.team store)
with a search-picker overlay, plus a Coverage/Compare toggle
- Coverage: 18x6 weakness table (colour-coded multipliers + per-type weak
count), offensive STAB gaps, team at-a-glance (avg BST, fastest, bulkiest)
- Compare: per-member column table of types + 6 stats + BST with mini bars
and row-max highlighting; scrolls horizontally past 4 members
- '+ Team' / '✓ In team' toggle on the Pokémon detail page (disabled when full)
- Nav gains a Team item; a Settings toggle ('Show Team in the navigation
bar', on by default) hides it from the bar without removing the route
- type-chart.js: defenseVector() helper
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Filter chips + sort + type/gen/random collapse behind a 'Filters & sort'
toggle on < 900px (always shown on desktop); toggle carries a badge with
the active-filter count; open state persists
- Smaller title / progress ring / search on < 560px
- Shorter dex cards on phones (tighter padding, 94px sprite): ~209px vs
~250px, so ~4-5 Pokémon fit above the fold instead of ~2-3
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Detail About tab: EV yield, base EXP, catch rate + ~%, base friendship,
growth rate + total EXP, held items; Breeding block with a gender-ratio
bar, egg groups, egg cycles/steps
- Stats tab: 'STAB coverage (attacking)' — types the Pokemon's STAB hits
hard / is walled by (data/type-chart.js offensiveSummary)
- Feed: Type and Generation filter dropdowns + a Random button; cards now
resolve typings for the selected game's generation via snapshot pastTypes
- Recently-viewed strip on the feed (ui.recent, capped at 12)
- Play-cry button on the detail hero; service worker caches PokeAPI cries
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Evolution chain is now a vertical tree (stage, then '↓ trigger' step,
then the next stage) that indents by branch depth. Never overflows a
phone; branching chains (Eevee, Wurmple) stay grouped and readable.
- Swipe left/right on the Pokémon detail page navigates prev/next in the
current dex (src/lib/swipe.js). Claims horizontal drags via
preventDefault so page scroll and the browser's edge back-gesture don't
steal them; vertical drags pass through.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Router uses the View Transitions API to cross-fade placeholder -> content
on navigation (falls back to a plain swap where unsupported or when the
user prefers reduced motion)
- Shaped shimmer skeletons for the Pokémon / move / item detail pages
(src/components/skeletons.js) so there's no layout shift on load
- Views fade+rise in; progress ring draws its arc from empty on mount;
caught / seen / favourite toggles pop when switched on
- Offline indicator pill (online/offline events) + 'Back online' toast
- All new motion gated behind prefers-reduced-motion
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Card gradient carries the primary type colour further and darker (55% ->
15% mix with surface, was 30% -> transparent); border tint up to 38%.
Reads clearly coloured in both themes while keeping text/chip contrast.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- .card__art gets 36px top padding so the sprite centres in the space
below the dex number instead of colliding with it; min-height raised to
keep short cards showing the full sprite; spot glow moved down to match
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Card sprite sits centred in the upper area (flex:1 + place-items:center)
instead of a forced margin; sprite-style / boxed sizing moved onto the
img so it stays centred
- .card__ghost number nudged to top: 2px
- Feed Back-navigation restores the raw scroll offset again (dropped the
card-anchor approach); keeps manual scrollRestoration + retry-on-reflow
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Feed remembers the opened card (ui.feedAnchor) and, on Back, scrolls that
exact card just below the sticky header via scrollIntoView + a computed
scroll-margin-top; re-corrects on webfont load and as off-screen cards
render their real height, but yields once the user scrolls
- history.scrollRestoration = 'manual' so the browser doesn't fight it;
per-session scroll memory cleared on cold launch
- Cards: ghost number nudged off the top edge; sprite dropped 10px (flex
column grows the card, so nothing overlaps); intrinsic size bumped to match
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- The dex feed remembers scrollY on teardown (ui.feedScroll) and restores
it on re-mount, so viewing a Pokémon and going back lands where you were.
Reset to top when the filter, sort, direction or game changes.
- Router no longer force-scrolls after mount; it scrolls to top on the
loading placeholder and each view manages its own position (detail pages
land at top, feed and search restore).
- .phero__back is now a rounded pill with a real 40px tap target.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Learnset 'By TM / HM' rows show the machine number for the selected game
(TM25 / HM05 / TR10), resolved from /machine when the group is expanded
- Move detail page gains a 'TM / HM' fact (marked '(latest)' when the move
isn't a machine in the currently-selected game)
- machineNumber() exported from MovesList and reused by MoveDetail
- Fresh installs now open on the National Dex (versionGroup 'all') instead
of Scarlet/Violet
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Search becomes a tabbed lookup: Pokémon (offline snapshot) / Moves /
Items. Moves + Items lazy-load a name index from PokéAPI (SW-cached) and
filter client-side; short move result sets get type/class/power chips
- MoveDetail (#/move/:id): type-themed header, power/accuracy/PP/priority,
effect text with %-substitution, target, ailment/crit/drain/stat-change
summary, learned-by count
- ItemDetail (#/item/:id): item sprite, category, cost, fling power,
attributes, held-by count, effect text
- Loose name matching (hyphens vs spaces); run-token guards stale async
renders when the query or tab changes mid-fetch
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Each game renders as a two-tone tile split in its version colours
(Scarlet/Violet, Sword/Shield, Ruby/Sapphire…), keyed by version group
with a per-generation fallback (src/data/game-colors.js)
- Clean flat split with a bottom scrim for legibility — no gloss/bubble
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Feed header: the game pill is gone (the nav Games button opens the sheet);
the active game is now a quiet text label under the title
- Settings > Theme: add Black (OLED) and Sepia alongside System/Light/Dark
- Settings > Accent colour: six swatches (red default, blue, green, amber,
violet, rose) layered over any theme via [data-accent]; persisted
- applyTheme() takes the settings object; system theme now keys off the
absence of [data-theme] so explicit light/sepia don't fight the media query
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Snapshot now carries per-species base stats + BST, height, weight, base
EXP, capture rate, growth rate, colour, egg groups, gender rate,
legendary/mythical/baby flags, and past typings (~72 KB gzip)
- Dex feed: Sort control (dex / name / BST / each stat / height / weight /
base EXP / catch rate / recently caught) with a direction toggle;
sort + filter persisted in the ui store; cards show the sorted metric
- New 'Legendary' filter chip (legendary or mythical) with a live count
- Detail hero: shiny toggle moved up beside the favourite, top of the hero
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- FlavorText: 'All Pokédex entries' disclosure listing every distinct
English entry across all games (newest first, labelled by game) — not
just the selected game's one line
- Search remembers its query and scroll position in the ui store, so Back
or re-opening the tab restores the results; header explains the scope
(matches all species; opens for the selected game / all games)
- GameSheet 'All games' option: National Dex, newest data, no generation
limits — abilities/shiny ungated, types untrimmed, evolution unpruned;
Moves/Locations prompt to pick a game
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- FlavorText: shows a version pill toggle (Sword/Shield, Scarlet/Violet…)
when the two entries differ, sliding between them; collapses identical
entries; falls back to the newest English entry, captioned
- Switching games while viewing a Pokémon now rebuilds the detail page
(router.rerender wired from a settings subscription in main.js) so
flavour text, learnset, matchups, evolution, abilities, locations and
era sprites all follow the newly selected game
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- New GameSheet: bottom drop-up overlay (backdrop / grab handle / Esc to
dismiss) summoned from the nav 'Games' button or the feed's game pill;
picking a game/sub-dex writes settings and the feed updates in place
- Removed the #/games route and GamePicker view
- Detail page remembers the last-opened tab in a new pdx.ui store and
restores it on return; selectTab guards unknown ids
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Detail page resolves a Pokemon's typing from PokeAPI past_types for the
selected game's generation (Gen 1 Magnemite is pure Electric, pre-Gen 6
Clefairy is Normal); feeds hero pills, theming and matchups
- Type chart excludes Steel/Dark (pre-Gen 2) and Fairy (pre-Gen 6) as
attacking types entirely
- Gen 1-2 game-era sprites (opaque white bg) shown as a small framed tile
on cards and the detail hero
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Feed header: large title, tappable game pill, circular progress ring,
icon-in-field search, filter chips with live counts (All/Caught/Missing/Favorites)
- Cards: left-aligned info, number chip, corner ghost number (no longer hidden
behind the sprite), top-down type gradient, staggered entrance animation;
caught toggle moved to top-left
- Detail: hide the shiny toggle for Gen 1 games (shinies are Gen 2+);
add Category (genus) to the About tab
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>