- 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
- AbilityDetail: "Pokémon with this ability" grid now gets a filter box
and the same game/generation narrowing as the move and item pages, plus
a note when the ability postdates the selected game (Libero in
Ruby/Sapphire -> "introduced in Gen 8").
- TeamView "At a glance": Fastest / Bulkiest names now link to their
Pokémon pages.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Ve7HLspzeG2xDPtJQ8vmu
Two more spots where data was shown as a dead number/label:
- ItemDetail "Held by N Pokémon" -> a clickable sprite grid, same as the
move page. held_by_pokemon carries a per-version breakdown, so a
specific game filters exactly (Leftovers in SV lists only what holds it
there, not the all-games union).
- PokemonDetail "Held items" in the Training facts were plain text; now
each links to its item detail page.
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
Gen 8+ games (Sword/Shield, Scarlet/Violet, Legends Arceus) dropped HMs
entirely, so "HMs only" there just zeroed the list with no way to see
why. buildFilters now checks whether the selected game actually has any
TM / HM machines and only renders the checkbox that applies; a filter
left stuck on from a previous game is cleared (and the "by number" sort
reverts) when it no longer has a control. SearchView also re-runs its
filters + results when the version group changes, so switching games
from the Games sheet updates it live.
"TMs only" + "HMs only" together already show the union (verified: 58 in
FRLG = 50 TMs + 8 HMs, ordered TM01…HM08).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Ve7HLspzeG2xDPtJQ8vmu
TM/HM numbers are now baked into the snapshot (build-snapshot resolves
every machine id -> "TM25" etc. in a post-pass, ~2400 lookups), so the
Search moves list no longer lazily fetches /machine per row — it shows
numbers synchronously and can sort by them.
- New "TM / HM number" sort option, shown only while a machine filter is
on, and dropped back to A–Z when neither is.
- "TMs only" now means strictly TMs; added a parallel "HMs only". Either
or both. In "All games" mode a move can be a TM in one game and an HM
in another, so machineFor picks the newest entry of a requested kind
rather than just the newest entry (fixes "HMs only" showing 0).
Removes the getMachine/mapLimit lazy-resolution path (and its now-unused
stale-token guard) from SearchView.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Ve7HLspzeG2xDPtJQ8vmu
The learnset's "By TM / HM" group was alphabetical. TM numbers aren't in
the snapshot — they resolve lazily per move via /machine/{id}, which the
group's enrichers already fetch on expand. So: await those resolutions
(fillTm is now async and stashes the label on the move), and once the
whole group is enriched, re-append the rows in TM/HM/TR-then-number order
— TM01, TM02 … HM01 …, matching the in-game list. Verified against
Charizard in FireRed/LeafGreen.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Ve7HLspzeG2xDPtJQ8vmu
Four new preferences, all in settings.js / applied via applyTheme() so
boot and live changes go through one path:
- fontScale (small/default/large): scales root font-size (92/100/115%);
the whole stylesheet is already rem-based so this alone rescales
everything.
- reduceMotion: an explicit in-app override alongside the existing
`prefers-reduced-motion` OS check, via a new
:root[data-reduce-motion="true"] rule in tokens.css mirroring the
existing media-query kill-switch. New prefersReducedMotion() helper
(checks both) replaces the three hand-rolled matchMedia checks in
router.js/Card.js/PokemonDetail.js.
- defaultRoute (dex/team/search): redirects on a genuinely hash-less
launch only (bookmark, home-screen icon, bare URL) — explicit nav
(e.g. tapping "Dex") is never touched, since it's applied once in
main.js before initRouter runs.
- haptics: a short navigator.vibrate() pulse on the same catch/seen/
favorite toggles that already play the pop animation, via a new
lib/haptics.js buzz() (no-ops without Vibration API support, e.g. iOS
Safari).
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
Every other reference page (Move/Item/Ability detail) has a '‹ back'
link; NaturesView never got one, so the only way out was the phone's
back gesture or the bottom nav. Add the same lookup__nav link, pointing
at #/team since that's the page's only current entry point.
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
Second thought on the previous commit: gating "<Species> Dex" to games
that include the species contradicted the app's own model. Caught/seen
tracking here is unified across games by design, and there's no
game-dependent data on this tab (unlike Locations/Moves, which really do
vary by game and are rightly gated) — it's the same fixed set of
letters/patterns/decorations regardless of which game is selected. Hiding
it just because you switched games to browse something else would make
already-tracked progress look lost. Show it whenever the species has
cosmetic forms, full stop.
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
onSwipe judged horizontal-vs-vertical from a single touchmove sample
compared against the start point. A fast scroll flick's first sample is
often slightly diagonal (thumb motion), so it could get claimed as a
page-swipe and every subsequent touchmove got preventDefault()'d — the
rest of the scroll silently died, so trying to reach off-screen content
in About/Stats/Evolution/etc. would instead flip to the next Pokémon.
Now vertical intent wins by default (bails, permanently, as soon as the
drag is even mildly more vertical than horizontal) and a horizontal
page-swipe only gets claimed once the drag is unambiguous
(dx > 20 && dx > 2*dy). Deliberate left/right swipes still work.
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
MovesList: a move can have several version_group_details for one game —
one per learn method, plus a Gen 1/2 data artifact that repeats a
level-up move at level 1 next to its real level (e.g. Gyarados / Dragon
Rage in Red-Blue: level 1, level 25 and a machine entry). The old
`.find()` grabbed the first, so Dragon Rage showed "Lv 1". Now collect
every matching detail, group by method, and keep the highest level per
method — a move can also legitimately land in both "By level up" and
"By TM / HM".
PokemonDetail: the recently-viewed write used the function form of
ui.set(), which *replaces* state instead of merging. Every Pokémon visit
was wiping feedScroll (so Back returned to the top of the dex) along with
the saved sort / filters / tab. Spread `...s`.
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
The cosmetic-form filter now also requires identical abilities before
dropping a variety, so gameplay-relevant look-alike formes (Basculin
Blue/White-Striped, Toxtricity Low Key) are no longer discarded.
274 forms across the snapshot (+10 'other').
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- 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>
- Detail page: base stats, type matchups (defending), evolution chain,
learnset with per-move power/type/acc/PP/effect, wild locations
- Game-aware: abilities gated to Gen 3+ (hidden to Gen 5+), type chart
applies Gen 1 / pre-Gen 6 rules, move stats use PokeAPI past_values,
pre-Gen 4 physical/special-by-type, evolution tree re-parented to the
selected generation
- Moves and evolution clickable/expandable; no horizontal scroll
- Fix: .view-host shrink-wrapped as a grid item on desktop (margin:0 auto)
- Era-accurate sprite option; Search tab relabelled as global lookup
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>