15 Commits

Author SHA1 Message Date
a437f539fc Animation pass: shared-element morph, sliding tabs, count-ups
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
2026-09-10 09:22:08 -04:00
b15ee3dd7f Shiny hunt tracker (#/shiny)
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
2026-09-09 19:06:46 -04:00
48cb471489 Breeding helper (#/breeding)
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
2026-09-09 19:01:24 -04:00
53f4f4381d Per-game caught breakdown (#/progress)
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
2026-09-09 18:52:01 -04:00
5f6414528e Compare any two Pokémon — standalone #/compare view
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
2026-09-09 18:48:27 -04:00
cfa30c987f Add a standalone interactive type chart page
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
2026-09-09 18:12:31 -04:00
4b9bc5c0ab Settings: text size, reduce motion, landing screen, haptics
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
2026-09-04 12:35:26 -04:00
415cf3edec Abilities lookup + detail; Natures reference
- 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>
2026-08-28 11:00:14 -04:00
ddc84c2a48 Team Builder + Compare views
- 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>
2026-08-28 10:33:52 -04:00
1d35f2d433 Motion pass: view transitions, skeletons, micro-interactions
- 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>
2026-08-28 08:36:41 -04:00
b0e3655dbf Restore feed scroll position on Back; enlarge the detail back button
- 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>
2026-08-27 17:40:13 -04:00
0f00b50198 Move & item lookup: tabbed Search + detail pages
- 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>
2026-08-27 13:51:51 -04:00
0665d0f2ef Both-version flavour text; refresh detail page on game switch
- 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>
2026-08-27 12:54:11 -04:00
5144f760f5 Games as an overlay sheet; remember the detail tab
- 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>
2026-08-27 12:37:16 -04:00
cd2655011f Scaffold Pokedex PWA (Vite + Workbox)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-27 10:54:36 -04:00