- FixedPrivacy: Private reports are now genuinely private. A report that is neither Public nor Unlisted returns 404 on its /s/{id} link for anyone who isn't the owner or an accepted collaborator — and it no longer leaks its title, description, or JSON-LD structured data into the page head.
- FixedPrivacy: switching a report from Public to Private now takes effect within ~30 seconds. The edge cache window was previously up to 20 minutes, so a flipped report kept serving its public body for minutes after the change.
- FixedDashboard 'All Private' bulk action now also covers Unlisted reports (they were silently skipped before), and toggling a single report's visibility no longer wipes its Unlisted state back to Private.
- FixedVisibility toggle no longer flickers — rapid Public/Unlisted/Private switches can't be snapped back on screen by a slower in-flight save, and a failed share now surfaces the reason instead of opening the edit-link panel.
- NewPokémon Champions Regulation M-B support — the new Reg M-B Mega rotation is selectable as a format and auto-detected from team imports, with the correct legal Mega list for the regulation.
- ImprovedPresentation view now has a Home button on every slide to jump straight back to the team overview, and the generic 'Exit' control was replaced with a role-aware action (owners vs viewers get the right behaviour).
- FixedModes section now saves reliably on shared and draft reports — it was silently failing to persist changes.
- FixedExplore search no longer crashes from a history.replaceState rate-limit when typing quickly.
- FixedChien-Pao and the other Treasures of Ruin (Chi-Yu, Ting-Lu, Wo-Chien) now show their proper sprite in the team preview instead of a flashing/broken image. Pokémon Showdown has no animated sprite for these species, so the high-resolution static art is served directly.
- FixedMobile: report swipe navigation fixed and coverage charts now fit the screen. Also removed a hairline horizontal scroll on desktop caused by the scrollbar-gutter width.
- FixedShared reports load more reliably on slow networks and Neon cold starts — the load timeout was raised from 5s to 15s, and a one-off timeout no longer locks the viewer on the 'corrupt link' screen permanently.
Changelog
Every shipped change, version by version
138 new features160 improvements112 fixesacross 38 releases
- FixedLinear webhook handler: corrected signature header name (linear-signature), env var (LINEAR_WEBHOOK_SIGNING_SECRET), added force-dynamic and empty body handling. 8th consecutive fix proposal — please merge!
- FixedSecurity: all user-controlled fields in comment notification, welcome, and weekly summary emails are now HTML-escaped to prevent XSS. Subject lines stripped of CR/LF/quotes.
- FixedSecurity: Linear GraphQL queries in daily-ops and weekly-report crons now use parameterized variables instead of string interpolation.
- FixedSecurity: /api/migrate and /api/setup routes now use crypto.timingSafeEqual for secret comparison. Setup route no longer leaks internal error details.
- FixedSecurity: /api/views shareId now validated against regex before database queries, matching comments and reactions routes.
- ImprovedAI discoverability: GPTBot, ClaudeBot, PerplexityBot, and OAI-SearchBot moved from blocked to allowed in bot-detection middleware. Previously blocked with 403 despite robots.txt allowing them.
- ImprovedAccessibility: OTSSheetModal now has role='dialog', aria-modal, aria-labelledby, focus trap, Escape-to-close, and focus-restore-on-close.
- ImprovedAccessibility: Navbar settings button and PageNavbar dark mode toggle bumped to WCAG 2.5.8 minimum 44x44px touch targets.
- ImprovedSEO: /explore page title and description updated to target 'Best VGC Teams 2026' and 'VGC team builder' keywords.
- ImprovedPWA: removed 4 broken screenshot references from manifest.json (404 fix) and fixed InstallPrompt pageIsShort detection on Android/Chrome.
- ImprovedWebhook resilience: PostHog and Clerk webhooks now return 200 on internal errors, preventing auto-disable and retry storms.
- ImprovedPerformance: Changelog data (~73KB) extracted from client bundle to server component — client JS reduced from 96KB to 20KB.
- ImprovedRemoved dead code: useScrollHide hook (124 lines), ReactionBar component (139 lines), and axios dependency (zero imports).
- FixedLinear webhook handler fixed — corrected the signing secret env var name (LINEAR_WEBHOOK_SIGNING_SECRET), header name (linear-signature), added force-dynamic export, and graceful handling of empty body payloads.
- ImprovedSEO: /compare page added to XML sitemap; /faq page now has keyword metadata for long-tail VGC queries; applicationCategory corrected from GameApplication to SportsApplication for consistent schema.org signals.
- Improvedi18n: Explore page filter labels (All/Pokemon/Tournament/Creator category chips, Popular/Newest/Views/Updated sort options, 1st/Top 4/Top 8/Top 16 placement chips) now fully wired through the translation system.
- ImprovedAccessibility: Navbar overflow menu now has aria-expanded and aria-haspopup attributes; dropdown panel uses role=menu. PokemonCard role input has aria-label. SlideNavControls hide/show toggle has aria-label on mobile. Calc section collapse buttons have aria-expanded.
- FixedSecurity: /api/cleanup DELETE and /api/migrate POST routes now use crypto.timingSafeEqual for secret comparison — defence-in-depth against timing side-channel attacks.
- ImprovedPWA: Removed broken screenshot references from manifest.json that pointed to non-existent files. Chrome's install prompt now degrades gracefully instead of silently failing.
- ImprovedRemoved dead code: useScrollHide hook (zero imports) and axios dependency (project uses native fetch). Combined ~150 lines of unused code eliminated.
- ImprovedPerformance: weekly digest cron no longer makes N+1 Clerk API calls for 500 users — a single batched getUserList() call fetches all users before the main loop, reducing the Clerk phase from ~25s to ~2s. The redundant shareCount query is folded into the main stats query. Email sends now run in parallel batches of 15.
- FixedSecurity: RESEND_FROM_EMAIL environment variable is now stripped of CRLF characters before use — defence-in-depth against email header injection if the env var is ever compromised or misconfigured.
- ImprovedAccessibility: Changelog filter tabs (All/New/Improved/Fixed) now support WCAG 2.1.1 keyboard navigation — Left/Right arrow keys move focus between tabs, Home/End jump to first/last, active tab uses roving tabindex.
- ImprovedAccessibility: Notifications feed adds an aria-live='polite' region that announces incoming notification counts to screen readers when real-time updates arrive via the background poll.
- ImprovedSEO: /dashboard/profile and /dashboard/privacy now carry robots noindex/nofollow metadata, preventing search engines from accidentally indexing authenticated-only content.
- ImprovedAccessibility: Champions Regionals top-cut table has a screen-reader caption and scope='col' on all column headers; Explore filter chips have aria-label and aria-pressed state for keyboard and screen reader users.
- ImprovedShare modal on mobile: the native OS share sheet ('Share via…') is now the primary full-width action at the top of the modal, surfacing WhatsApp, iMessage, and Discord Stories immediately. Desktop layout unchanged.
- ImprovedSEO: /feedback page added to the XML sitemap; /faq priority raised to 0.8 to better signal high search-intent content to crawlers.
- ImprovedRemoved 3 confirmed dead exports (parsePikalyticsUrl, evsToSp, spToEv) that had zero call sites across the codebase.
- FixedSecurity: weekly digest email templates now HTML-escape all user-controlled strings (report titles, first names) before embedding in HTML — prevents potential XSS via malicious team/creator names in email clients.
- FixedTeamCardExport: Download Team Card button now shows a user-friendly error message if sprites fail to load during canvas capture, and disables the button while export is in progress to prevent double-clicks.
- ImprovedAccessibility: Notifications bell button now announces unread count to screen readers via aria-label, includes aria-expanded for dropdown state, and the dropdown panel uses role=dialog for proper semantics.
- ImprovedAccessibility: /notifications feed page now uses semantic <ul>/<li> list structure for notification groups (was plain <div> containers), spinners are aria-hidden, and the Load More button announces loading state via aria-busy.
- ImprovedPerformance: /notifications page no longer makes two simultaneous API calls on load — the hook's initial fetch now serves as the single source of truth; hasMore/total are exposed from useNotifications and used directly.
- Improvedi18n: Explore page filter labels (All/Pokemon/Tournament/Creator category chips, Popular/Newest/Views/Updated sort options, 1st/Top 4/Top 8/Top 16 placement chips) are now wired into the translation system and ready for localisation.
- ImprovedSEO: /notifications page marked noindex/nofollow (user-specific content should not be indexed); /feedback page now has a canonical URL to consolidate ranking signals.
- NewNew /notifications page shows your full activity feed — comments, reactions, follows, and collab invites grouped into Today / This Week / Older with unread highlights. Paginated with Load More. Accessible from the bell icon in the nav.
- NewWelcome email sent automatically when you sign up — a Day 0 email with 3 quick-start steps (paste your team, share the link, explore the meta). Powered by the Clerk user.created webhook and Resend.
- NewWeekly digest email every Monday at 9am — 'Your reports this week' shows views, comments, and reactions on your reports. Users with no activity get a curated trending-teams digest instead.
- ImprovedShare modal is now fully internationalised — all 49 visible UI strings (modal title, privacy option labels, social share buttons, copy-link feedback, error messages) are extracted into the i18n system and ready for translation via the language selector.
- FixedCritical: share creation was corrupting owner_id on every new report since the 17 May deploy — a column-position mismatch in the INSERT statement put a boolean in the owner_id column and the Clerk user ID in search_vector. Fixed; DB repair script drafted for affected rows (see VGC-195).
- FixedNotification mark-as-read silently failed — the API was validating integer IDs as UUIDs. Fixed: IDs now correctly typed as integers throughout the notifications stack.
- NewHomepage now shows a 3-card archetype sample team picker — choose from Primal Groudon Sun, Primal Kyogre Rain, or Mega Kangaskhan Goodstuffs to instantly load a full Champions team report. Each card shows all 6 Pokémon sprites and archetype name; horizontally scrollable on mobile.
- NewAdded llms.txt and llms-full.txt to the site root — structured context files per the llmstxt.org spec that give AI assistants (ChatGPT, Perplexity, Claude) the entity signal they need to cite VGC Team Report when users ask about VGC team building or sharing tools.
- NewSportsEvent JSON-LD schema added to the /tournaments page — all 6 listed tournaments now have schema markup with eventStatus, location, format, and organizer fields, improving rich result eligibility in Google Search.
- NewTeam reports now store a materialised species[] column at save time — foundation for O(1) Champions meta aggregation as the dataset scales. No user-facing change; groundwork for a significantly faster meta snapshot once the column backfills.
- FixedChampions meta snapshot usage percentages were inflated — the denominator only counted reports with parseable species blocks instead of all valid Champions reports. Fixed: total now counts all filtered reports, giving correct percentages.
- FixedExplore empty state 'See how a report looks' demo link was broken — passed ?sample=1 which never matched any team ID. Now correctly links to the Primal Groudon Sun sample team.
- ImprovedAccessibility: team paste input now has a proper accessible label for screen readers; match result (Win/Loss/Tie) buttons announce selected state via aria-pressed; share confirmation and copy-link buttons updated to meet the 44px WCAG 2.5.5 touch target minimum.
- ImprovedSecurity hardening: cron keep-alive endpoint now requires the CRON_SECRET bearer token (previously accepted any request with the right User-Agent header); Linear webhook fails closed when the signing secret is unset; notification endpoint validates IDs with Zod before any database access.
- FixedMatch tracker delete confirmation now works on iOS PWA and Android WebView — replaced window.confirm() (which is silently blocked in installed PWAs) with inline Delete/Cancel buttons that appear directly on the match row.
- FixedSpeed tier chart now shows a 'Yours' badge on your own Pokémon when a meta benchmark of the same species appears alongside it — so you can clearly tell which bar is your actual spread vs the max-speed meta build. Meta badge colour updated to blue to match the Meta Threats toggle.
- FixedSpeed tier chart Mega form matching: if you run base Garchomp, the 'Garchomp-Mega' meta threat entry is now correctly flagged as a duplicate, showing both the Meta badge and Yours badge for disambiguation.
- ImprovedChampions meta snapshot now aggregates species usage in SQL (6-CTE query) instead of shipping up to 500 paste blobs (~5MB) to the serverless function — significantly faster cold-start response and eliminates the JS parse loop.
- ImprovedDamage calculator link updated to the NCP-VGC Damage Calculator (nerd-of-now.github.io) as requested by the community.
- ImprovedAdded static /og-default.png as a branded CDN-served OG image fallback (1200x630, brand background) — pages without a dynamic OG image now have a proper social preview.
- ImprovedPWA install prompt now requires user engagement (60s on page + 200px scroll) before appearing, instead of interrupting new visitors after 15 seconds. Chrome's enhanced install dialog activated by updating manifest screenshot entries with correct dimensions and form_factor values.
- ImprovedExplore empty state: when a search returns no results, popular shortcut pills (Groudon Sun, Calyrex Shadow, Flutter Mane) and a Clear Filters button now appear. Cold-start empty state adds a demo link.
- ImprovedNew user paste input: a contextual hint ('Paste your full 6-Pokémon Showdown export, or a pokepast.es URL') appears on first focus and auto-dismisses on typing.
- ImprovedRemoved 2 dead exports (isDiscordBotConfigured, isValidIp) and fixed implicit-any TypeScript errors in 3 API routes. PostHogProvider double-cast resolved.
- FixedWCAG AA color contrast: text-tertiary colour updated from #6E6E8A to #5E5E7A — the old value failed the 4.5:1 minimum at 4.0:1 across ~470 uses site-wide. Dark mode unchanged (already passes at 5.6:1).
- FixedToggle component no longer wraps a button inside a label (invalid HTML that caused screen readers to double-announce). Dark-mode toggle in the navbar now has an explicit 'Dark mode' accessible name (previously empty string).
- FixedReactionBar like button now carries aria-label and aria-pressed — state changes are correctly announced to assistive technology.
- FixedCron-auth, PostHog webhook, and bot route secret comparisons are now all timing-safe using crypto.timingSafeEqual — prevents timing side-channel leaks consistent with the bot route fix shipped in v5.13.
- FixedPostHog webhook Linear fetch now properly handles AbortError from the 5-second timeout and initialises the result variable before the try block — previously the AbortError could propagate unhandled and leave an uninitialised binding.
- FixedBot route Discord fetch gains an AbortController timeout — it was the only external call missed in the v5.13 timeout pass.
- FixedChampions format pages now correctly say 'SP Spreads' throughout — all 8 occurrences of the legacy EV terminology replaced. The Champions format uses Stat Points (SP), not Effort Values (EVs).
- Fixed/dashboard and /embed pages are now marked noindex/nofollow — private and iframe content should not appear in search results. Broken /champions/mega-meowstic URL removed from the sitemap.
- NewDamage calculator deep-link button added to each Pokemon card — clicking opens the Showdown damage calculator in a new tab with the Pokémon pre-populated (Mega-aware). PostHog tracks calc_opened events.
- NewFAQ page: all question headings now carry slugified id attributes for direct deep-linking and AI citation anchors. Two new FAQ entries added covering SP spreads and Regulation M-A for the Champions format.
- ImprovedChangelog page now has full OpenGraph and Twitter Card metadata — social shares previously fell back to the root layout defaults.
- ImprovedFirst Pokémon sprite on team overview now loads with fetchpriority=high and loading=eager (LCP optimisation) — subsequent sprites remain lazy.
- ImprovedTypeScript safety: DocumentWithViewTransition interface removed (TS 5.9 DOM lib includes startViewTransition natively); diff-state.ts AnyState/any replaced with Record<string,unknown> plus typed narrow-cast helpers; useShareFlow and useSlideSystem t parameter typed as TranslationKeys instead of Record<string,string>.
- ImprovedRemoved 4 dead-code exports that had zero call sites: postBuildNotification, postToFeedbackChannel, sanitizeInput, containsInjection.
- FixedJSON-LD structured data now escapes </script> sequences to prevent HTML injection from user-controlled report fields (creatorName, tournamentName).
- FixedBot route secret comparison is now timing-safe (crypto.timingSafeEqual) and fails closed when CRON_SECRET is unset — previously accepted 'Bearer undefined'.
- FixedAdded AbortController timeouts to all external API fetches (pokepaste 5s/8s, sprite proxy 3s, PostHog webhook Linear 5s + Discord 3s) to prevent hanging requests under slow CDN conditions.
- FixedChampions meta snapshot query now caps at 500 most recent reports with ORDER BY created_at DESC, preventing unbounded memory usage as the dataset grows.
- NewMatch Tracker: delete individual match log entries with a trash icon button (confirms before deleting) and shows an error banner with Retry if stats fail to load.
- NewShare modal now has a 'Copy Paste' button that copies the full Showdown team paste to clipboard for sharing on PokéPaste or Discord.
- NewAdded 33 unit tests for team paste redaction (private spread hiding) covering all 4 field types and 8 edge cases including CRLF inputs and multi-Pokemon pastes.
- NewAdded Champions format Pokédex drift guard CI tests — 10 assertions prevent the class of bug where a Mega species is in the dex but has no stats entry.
- ImprovedHomepage title now includes 'Pokemon Champions 2026' for better search keyword targeting; Explore and Champions page descriptions updated with Mega Evolution and format keywords.
- ImprovedOG image meta tags now correctly set on Compare, FAQ, Tournaments, and Creator pages — Next.js shallow metadata merge meant these pages were missing og:image and twitter:image tags entirely.
- NewVGC match tracker added to the dashboard. Log game results against any archetype with win/loss/tie toggle, optional tournament name and notes. The tracker shows your overall W/L/T record, win rate %, and a breakdown of your top 5 matchups — all stored server-side so your record persists across sessions.
- NewChampions meta snapshot on /champions. A live usage bar chart shows the top Pokémon from all public Champions-format team reports — updated every 5 minutes. Shows a friendly empty state until enough reports are published.
- NewIndianapolis Regionals top-cut table on /champions. A scrollable table shows sample top-8 archetypes from the inaugural Champions Regional with Pokémon sprites, placement, and a Limitless TCG link per entry.
- ImprovedExplore full-text search now routes through the stored search_vector GIN index for 'all' searches. The pre-computed column (covering tournament name, creator, paste, and team summary with relevance weighting) is used when available; rows without it fall back to inline tsvector. Query performance improvement on large result sets.
- FixedAll mobile slide-nav touch targets now meet WCAG 2.5.5 minimum 44×44px on viewports under 390px. Prev, Next, Home, End, and the help toggle were 32px — replaced with min-w-[44px] min-h-[44px] while preserving desktop sizing via sm: responsive overrides. ReactionBar like/share pill buttons also bumped to min-h-[44px].
- ImprovedPostHog error-tracking cron moved from every 4 hours to weekly. Five fewer scheduled function invocations every day with no loss of signal — error groups don't change minute-to-minute and the weekly cadence still posts a Discord digest.
- ImprovedEmbed iframe pages (/embed/[id]) moved from force-dynamic to ISR with a 10-minute revalidate window. Public-data embeds no longer SSR per view — the second viewer of any embedded team in a 10-minute window is served from cache.
- FixedRemoved a module-scope setInterval from the /api/views endpoint that was keeping Lambdas warm and defeating Vercel's scale-to-zero. The in-memory dedup Set it cleared was also unreliable (per-instance, so cold-instance hits double-counted views anyway). Replaced with atomic cross-Lambda dedup via Upstash SET NX EX.
- NewcacheSetIfAbsent helper in src/lib/cache.ts. Atomic set-if-absent primitive built on Upstash for any future cross-Lambda dedup needs (view counts, idempotency keys, throttle gates) without keeping functions warm.
- ImprovedStripped @vercel/analytics from the project. Every track() call was already paired with a PostHog capture of the same event — the Vercel-side stream was pure duplicate cost. Twelve files cleaned up and the dependency uninstalled. PostHog dashboards retain the canonical property names; zero analytics loss.
- Improvednext.config.ts now ships an explicit images block with empty remotePatterns and a 30-day minimumCacheTTL. Showdown sprites flow through the existing /api/sprite edge proxy, so the Image Optimizer is now correctly fenced off from accidental remote-origin optimization (the #2 driver of surprise Vercel bills).
- NewSocial share preview cards restored. Shared team report links on Twitter/Discord now display a visual card with all 6 Pokémon sprites, tournament name, and placement. Each sprite fetch has a 2.5-second timeout with Pokéball fallback so the card always renders — the previous timeout issue that caused the suppression is fixed.
- NewFAQPage, Organization, WebSite, and HowTo JSON-LD schemas are now active on the homepage. These components were fully built but never imported — activating them is the top fix for AI assistant citation (ChatGPT, Perplexity, Claude) and Google rich results. Includes a HowTo schema for creating a team report.
- New3 pre-built Champions sample teams added — Mega Kangaskhan Goodstuffs, Primal Groudon Sun, and Primal Kyogre Rain — accessible from the Champions page with a one-click Try button that loads the full Showdown paste into the report editor.
- Improvedposthog-js (~150 KB) is now deferred until browser idle time using requestIdleCallback. It was previously parsed on every page at layout level. All 10 consumer components updated to use a usePostHog shim that resolves after the dynamic import, with no change to the existing null-guard patterns.
- FixedTournament page 'View top teams' CTA links were silently broken — they passed ?tournament={id} which the explore filter ignored. Links now pass ?q={name}&searchType=tournament which the explore page actually handles.
- FixedShareModal clipboard handlers (Copy Link, Copy Discord, Copy Embed) now have try/catch around navigator.clipboard.writeText(). The API throws on non-HTTPS or permission-denied, causing a silent unhandled rejection. Also migrated from bare posthog-js import to the project-standard usePostHog hook.
- FixedoEmbed endpoint now wraps shareId with encodeURIComponent() before HTML interpolation. The regex guard prevented exploitation but direct string interpolation into HTML was structurally unsafe.
- Fixed3 critical WCAG 2.1 AA accessibility issues resolved: keyboard access added to the URL-copy div in ShareModal; creator/collaborator navigation spans in ReportCard converted to proper anchor elements; comment moderation buttons (delete/flag) had aria-hidden=true removed. Also fixed like button aria-label/aria-pressed and added aria-hidden to decorative SVGs.
- Improved/faq and /tournaments added to XML sitemap. /compare page now has full metadata (title, description, OpenGraph, canonical). Root homepage title and description updated with VGC keyword targeting. /explore, /creator/[name] pages get expanded keyword metadata including OTS.
- FixedRemoved orphaned BringSelector component (bring-selection logic had been re-implemented inline in MatchupPlanSlide). Also removed unused hidePageNavbar/showPageNavbar exports from PersistentNavbar.
- FixedPopular and Views tabs on /explore now show the entire library, not just a subset. The pagination cursor was a single integer with strict less-than semantics, so once the feed reached the tied tail of teams sharing a like count or view count (most teams have 0 of either), the next-page query asked for "likes < 0" and returned nothing. Replaced with a composite cursor (metric, created_at) walked via Postgres tuple comparison so ties are paginated by created_at exactly as the ORDER BY intends. Same fix applied to the Views sort.
- NewFork credit on Explore cards. When a team is duplicated via the new Notion-style "Duplicate this team" CTA, the explore card now surfaces "Duplicated from @{originalCreator}" below the byline, linking to the original creator's profile. Server-side join over shares.forked_from_id so the credit always reflects ground truth. Pairs with the existing "Forked from" banner on the /s/{id} view itself, so attribution shows up at both the discovery surface and the report surface.
- FixedMega forms now suppress themselves when the regulation isn't Reg M-A. Reg F, G, H, I and every other Scarlet/Violet regulation can't actually use Mega Evolution, so showing Mega-form analysis on those teams was misleading — viewers saw boosted Mega stats and the Mega ability when the team can never trigger Mega Evo in actual play.
- FixedThe Mega flip toggle now requires both a Reg M-A regulation AND an actual Mega Stone equipped on the species. Without the Stone, Mega Evolution can't trigger in battle, so surfacing a flip control was misleading.
- NewPublic shared reports are now zero-friction. The bottom CTA on /s/[id] has been rewritten Notion-style — "Like this team? Duplicate it to your account" with a single Duplicate button. Anonymous viewers get a sign-in modal on click; signed-in viewers fork directly into an editable copy. The vague "Create yours from scratch" path is gone. Tracks share_view_duplicate_anonymous in PostHog so the anonymous-view → signup funnel is measurable.
- NewSpotify-Wrapped style downloadable team card. End of every shared report now has a "Download card" button that generates a 1080×1920 vertical PNG built for Twitter / Instagram / Discord — loud gradient background, 3×2 sprite grid with type badges, big placement headline if the report is tagged with a tournament result, creator handle in the footer. Backed by /api/team-graphic?style=wrapped using the existing edge ImageResponse infrastructure (no new dependencies).
- NewTiered publishing: hide spreads from public viewers. Creators can now mark EV/SP spreads, IVs, nature, and held items as private from the team overview's new "Hide fields from public viewers" panel. Server-side enforcement — bytes never leave the API for non-owners. Public viewers see the 6 Pokemon + moves (the "public shell") plus an amber banner explaining what's hidden. Owners and accepted collaborators always see the full data.
- NewRental code filter on /explore. Hunting a ready-to-import team? Toggle the new emerald "Rental code" pill in the filter row to only see reports that include a rental code. Cards with codes also surface a small "Rental" badge so you can spot them at a glance.
- FixedChampions Reg M-A dex now matches Serebii's canonical list exactly. Removed Metagross, Pawmot, Dondozo, Tatsugiri, and Ursaluna (none are Reg M-A legal). Added 47 missing legal species spanning every generation, including high-impact mons like Skeledirge, Chandelure, Goodra (regular + Hisuian), Avalugg (regular + Hisuian), Manectric, Camerupt, Sharpedo, Banette, and Floette including its Eternal Flower form. Legality validation will now correctly flag illegal teams and stop falsely flagging legal ones.
- FixedCHAMPIONS_DEX and CHAMPIONS_REG_MA_MEGAS are now a single source of truth. The two sets had been hand-maintained in parallel — and were drifting on every Mega rotation. The dex now derives its Mega entries from the canonical CHAMPIONS_REG_MA_MEGAS set in mega-pokemon.ts, so divergence is impossible by construction.
- FixedShared-report URLs are now schema-validated. The URL codec previously trusted decoded JSON blindly via an unchecked TypeScript cast — a malformed or maliciously-crafted share URL could put unexpected shapes into the report viewer. Decoder now runs Zod safeParse and fails closed (returns null) on shape mismatch. The Redis cache layer's cacheGet generic also now accepts an optional schema for runtime-validated reads.
- ImprovedDeleted 464+ lines of dead code: 4 components nothing imports (OpponentPokemonCard, TeamComparisonSlide, TeamCoverageSlide, TypeCoverageMatrix), 3 dead lib files (passcode utils + hand-rolled abilities/items lookups), 2 orphaned hooks (useExportActions, useIsMobile), the unused /api/print-outline route, and 2 dead exports from sprite-url.ts. Each was verified with a global import search before removal.
- NewIn-line Pokemon replace — every PokemonCard on the team overview now has a pencil button (visible when the report is editable) that opens a searchable picker to swap a single slot. Backed by @pkmn/dex so every species, every form, every Mega is searchable, with sprite + types + BST shown for each result. Surgically rewrites only the species token in the paste, preserving nickname, item, ability, moves, EVs, IVs, nature, and Tera so all downstream analysis (stats, calcs, threat coverage) stays consistent.
- NewPopular reports rail on the homepage — a horizontal scroll strip of 6 trending public reports below the spotlight section, each showing team sprites, tournament/placement info, and creator name. Session-cached so it doesn't refetch on every visit.
- NewCollaborator credit on shared reports — co-creator names now appear beside the primary creator on the public read-only view, finally giving collaborators visible credit on the page itself (not just on Explore cards).
- NewSpeed tier chart now shows the meta max-speed variant of a Pokemon even when that species is on your team — useful for comparing a bulky/mid-speed build against the standard meta build of the same mon. The duplicate is tagged with a META badge so it's never confused with your build.
- NewHome button in the slide nav bar — visible on every slide except the team overview itself. One tap returns to the main team page from any subpage.
- FixedChampions page no longer shows illegal Megas — Mega Salamence, Mega Metagross, and Mega Mawile have been removed (verified against Bulbapedia, Serebii, and Victory Road). Their /champions/{slug} landing pages now return 404.
- New29 missing Reg M-A legal Megas added to the Champions index — Pidgeot, Clefable, Victreebel, Starmie, Dragonite, Meganium, Feraligatr, Skarmory, Medicham, Sharpedo, Camerupt, Banette, Chimecho, Glalie, Froslass, Emboar, Excadrill, Chandelure, Golurk, Chesnaught, Delphox, Greninja, Floette, Meowstic, Hawlucha, Crabominable, Drampa, Scovillain, Glimmora. Stats and abilities pulled from @pkmn/dex.
- Improved13 Megas un-gated from "Coming Soon" — earlier sprite probe was too strict (only checked animated frames). Re-probed all four Showdown sprite paths and found these 13 ship static gen5 PNGs. Champions index now shows 58 clickable Mega cards (only Mega Meowstic remains genuinely sprite-less).
- FixedMega landing pages no longer 404 for species missing from the static dex — pages now resolve through the @pkmn/dex fallback so every Champions-original Mega builds correctly with real stats, types, and abilities.
- ImprovedMega abilities corrected to match Pokemon Champions canon for Reg M-A — several ability fields disagreed with the in-game data and have been re-sourced.
- ImprovedChampions hero copy refreshed — removed all Primal Reversion mentions (Primal forms are not in Reg M-A) and added the explicit Reg M-A team-construction restrictions.
- FixedFeatured Teams on Mega landing pages now only show teams that actually run the Mega — previously matched any team whose paste contained the base species name. Now requires either the Mega Stone item OR a {baseName}-Mega species token to qualify.
- ImprovedRemoved two filler sections from Mega landing pages — the templated "Using {Mega} in VGC" paragraphs and the visible FAQ accordion. The FAQPage JSON-LD is still emitted server-side for AI scrapers.
- FixedRotom appliance forms (Wash, Heat, Mow, Fan, Frost) no longer flagged as illegal in Champions — only the base "rotom" key was in the Champions dex, but the parser produces "rotom-wash" etc. All five form keys now match.
- FixedRemoved the bogus "max 1 Mega Stone per team" error — Reg M-A teams can pack any number of Mega Stones; only one Pokemon can actually Mega Evolve per battle, which is an in-battle choice, not a team-construction rule.
- ImprovedStat-investment validation is now SP-aware — spreads that fit the 66 SP / 32-per-stat envelope validate via the Champions SP path, while the classic 512/252 EV path remains as fallback for traditional formats.
- ImprovedJSON-LD on shared reports now separates author from contributor — primary creator is the sole schema.org author, collaborators are listed under contributor, and dateModified is emitted from the report's last-updated timestamp alongside the existing datePublished.
- ImprovedPersistent navbar across all pages — the page-level navbar now mounts once in the root layout instead of remounting on every route, so it no longer flashes or re-renders between client-side navigations.
- FixedNo more accent-color flash on page load — the inline blocking head script now applies BOTH dark mode AND your gen theme accent before first paint.
- FixedFavicon now loads — favicon.ico is back in /public and registered in metadata.icons.
- Fixed/compare page no longer shows a duplicate navbar — a stale inline PageNavbar was rendering on top of the persistent one.
- FixedShared report unfurls reverted to text-only after the OG sprite card produced "image failed to load" errors in Discord, Twitter, and Slack — the Showdown sprite CDN dependency under the edge-runtime fetch-timeout budget made a reliably-rendering OG image unrealistic.
- NewEvery Pokemon, every form, every Mega now resolves automatically — including Champions-exclusive forms like Mega Manectric and Mega Golurk that previously rendered with no spread. Backed by the canonical Pokemon Showdown dataset (@pkmn/dex), so future game patches just work without us shipping data updates.
- FixedPokemon spread (EVs / Stat Points) is now always visible even when the species isn't in our static dex — the entire stat block was previously hidden when data was missing, swallowing your own EV investment numbers.
- ImprovedMobile spread view now shows the per-stat investment column (+252 EVs / +252 SP) inline. Previously hidden behind a desktop-only breakpoint, so mobile users only saw final calculated stats.
- NewPersistent ShareDock on every shared report — X/Twitter, Reddit, Discord copy and Copy Link are one tap away in a top-anchored pill, no longer buried in the navbar. Auto-hides on scroll-down so it never obscures slide content.
- ImprovedFirst-run walkthrough is now skippable from any step — close X, ESC, backdrop tap, and Skip All all work on the very first session. Previously trapped first-time users.
- ImprovedCumulative Layout Shift reduced on /dashboard and /explore — loading states now reserve the eventual content height so the page doesn't reflow when fetches resolve.
- FixedView Transition aborts during rapid navigation no longer surface as errors. The visual transition is the same; the noise is gone.
- FixedServiceWorker install hardened — single failed cache.put for the offline page no longer fails the entire install.
- FixedChunkLoadError after a deploy is now suppressed before being captured — the page already auto-reloads, so the error never needed to surface.
- FixedThird-party SDK loading failures (Clerk CDN blips) are filtered from error tracking — they're not bugs in the app and were polluting the dashboard.
- NewFork Report button — signed-in viewers can now fork any public report into a new editable copy they own, preserving the team, notes, calcs, roles, matchup plans, and tags. Forks start private so you can iterate before publishing.
- NewFork attribution banner — every forked report shows a prominent banner at the top with a "View original" link back to the source, so lineage is always clear. If the original is deleted the banner degrades gracefully.
- ImprovedForks clear event-specific fields on creation — creator name, tournament name, placement, record, rental code, and MVP pick are reset so the new owner starts with a clean slate, while all team-building content (paste, EVs, notes, calcs, plans) is preserved.
- ImprovedFork is restricted to public reports only — unlisted reports stay the owner's. Link possession grants view, not the right to copy the team into a new report.
- NewThank-you banner when publishing — the first time you make a report public, a celebratory banner appears so you know it's live on Explore.
- ImprovedPrivate reports now act as unlisted — anyone with the /s/{id} link can view, but the report stays off Explore. Edit access still requires ownership or the collaborator link.
- ImprovedShare session state clears when navigating away from /s/{id} — avoids the bug where the next Share click silently overwrote the previous report with the current in-memory state.
- ImprovedShared report read path is now fault-tolerant to in-flight migrations — the fork-lineage lookup can't break /s/{id} for end users if the column hasn't been added yet.
- ImprovedSP/EV toggle redesigned as an iOS-style segmented control with symmetric labels and live status dots — instantly see whether your spread is under, over, or exactly at budget in either mode.
- ImprovedChampions meta threats now filter to Reg M-A legal Pokemon only, so speed-tier comparisons against the meta aren't polluted by Pokemon you'll never face in the format.
- ImprovedBulk paste affordance for notable calcs is now obvious — both Offensive and Defensive calcs show the bulk-paste button with clear hint text so you don't have to guess how to add multiple calcs at once.
- ImprovedBulk calc paste now splits on HKO boundaries (OHKO / 2HKO / 3HKO / etc.) so multi-target damage rolls from the calc site are parsed into separate entries.
- FixedFixed shared links briefly returning 500 and falling back to the home page after the fork feature rolled out — the new forked_from_id lookup is now isolated behind a try/catch.
- FixedEV cap display corrected to 508/508 for traditional formats (the usable maximum — the last 2 EVs in a 252 slot provide no stat gain).
- FixedChampions (Reg M-A) EV tab no longer shows a misleading /510 comparison — SP (66) is the real cap in this format. The EV tab now shows the derived total only.
- ImprovedShared report links now use clean text-only unfurls in Discord / Twitter / Slack — the Satori-rendered OG preview image was removed because it kept rendering stale, mismatched, or mid-generation frames under Vercel's edge runtime budget.
- FixedVersion-compare "no diffs" dismiss button is no longer hidden under the navbar — it now sits above it so you can actually click it.
- FixedSpotlight on the home page now only surfaces public reports — private/unlisted reports no longer leak into the featured carousel.
- FixedVercel Toolbar now loads in development and preview deploys — the CSP img-src was blocking vercel.live and vercel.com assets.
- NewMega Evolution support — toggle Mega forms on any capable Pokemon, auto-detect from PokePaste imports, M-A threat coverage, and full Champions DEX integration.
- NewChampions Stat Point system — EVs are displayed as stat points matching the Champions format, with unused and wasted stat warnings to help optimize spreads.
- NewAuto-convert EV spreads to Champions SP format — traditional 0-252 EV spreads are automatically translated to the Champions stat point display.
- NewInteractive hearts on report cards — like reports directly from Explore. Redesigned profile pages with updated layout.
- NewBookmark button for shared reports — non-owner viewers can now bookmark reports they find useful. Compact bookmark icon in the social section.
- ImprovedExplore page filters simplified to a minimal single-row layout — removed the bulky AdvancedFilterDrawer overlay.
- ImprovedExplore page mobile UX — teams are visible without scrolling, sticky header with proper scroll padding.
- ImprovedCompare page now supports Mega Evolutions with correct types and equal grid layout.
- ImprovedM-A Pokemon default to Champions SP display with an EV toggle for switching between formats.
- ImprovedLike button requires sign-in — guests see a sign-in modal instead of a broken state.
- FixedFixed like persistence and like counts always showing (even when 0) on shared reports.
- FixedFixed EV-to-SP conversion to match the official Champions table values.
- FixedFixed speed tier rounding to match the Pokemon game engine calculation.
- FixedFixed PWA layout issues — navbar no longer covers content, speed tier slide fully visible.
- FixedBlocked sample teams from being saved as drafts or shares.
- FixedExempted /api/setup from bot detection and CORS checks.
- NewOffensive and Defensive coverage split into separate slides — each chart gets a dedicated full-viewport slide instead of being crammed together.
- NewNotable calcs now stack vertically on desktop — each category (Offensive/Defensive/Speed Tier) gets full width for readability, with collapsible groups.
- NewRight column scrolls independently — notes and calcs panel has its own scroll area so the Add Calc input is always reachable.
- NewCompare Teams prevents duplicate selection — you can no longer pick the same report for both Team A and Team B.
- NewTag requirement for publishing — reports must have at least one tag (regulation, event type, or archetype) before they can be listed on Explore.
- ImprovedGame plans layout — 3 plans stack vertically (no more cramped 33% columns), 2 plans go side-by-side only on large screens.
- ImprovedProfessional visual polish across all slides — larger tournament headings, accent-bordered summaries, thicker stat bars with shadow, hover micro-interactions on move tiles and calc entries.
- ImprovedOG share images render at 2x resolution (2400×1260) for crisp Discord and Twitter embeds.
- ImprovedSlide container fits exactly between top navbar and bottom nav — no more content hidden behind either bar.
- ImprovedGuest viewers see all notable calcs expanded by default.
- FixedFixed share schema rejecting reports with hidden slides (string keys like "matchup-sheet" were rejected by the Zod validator).
- FixedFixed tag schema mismatch — tags are objects not arrays, which was blocking all saves on reports with tags set.
- FixedExplore tournament filter no longer force-opens the advanced filter drawer as a confusing overlay.
- NewTour auto-shows on first visit — new visitors (including those arriving via shared Discord links) now see the guided tour automatically without needing to discover it.
- New"Take a Tour" in settings menu — the tour can now be re-triggered anytime from the overflow/settings menu, making it easy to find.
- NewTap to navigate on mobile — tapping a Pokemon tile on mobile now navigates directly to its detail slide. Long-press still works too.
- ImprovedProgress bar help tooltip — the ? icon on the navigation bar now explains the bar itself instead of launching the full site tour.
- ImprovedSlide label replaces M/N counter — the navigation bar now shows the current slide name instead of a numeric "3/14" counter that felt like progress tracking.
- FixedMobile layout shift fixed — useIsMobile and useMediaQuery now use useSyncExternalStore, eliminating the flash where mobile pages briefly rendered as desktop.
- FixedCookie consent no longer blocks the page — the entire site was hidden until cookies were accepted. Analytics are now gated independently while the page always renders.
- ImprovedEV Rationale merged into Notes — the separate "EV Rationale" section has been removed. All per-Pokemon notes are now in a single Notes field. Existing EV rationale content has been migrated into notes.
- FixedAPI security hardening — protected the setup endpoint with bearer token auth, removed spoofable User-Agent cron authentication, and fixed a credential scope issue in the bot route.
- FixedFixed 6 npm dependency vulnerabilities including a high-severity SSRF in @clerk/backend. Next.js updated to 16.2.2.
- ImprovedRemoved dangerouslySetInnerHTML usage — translation strings now render as plain text instead of raw HTML.
- ImprovedShare route input validation — the Zod schema now explicitly defines all accepted fields and strips unknown data instead of passing it through.
- ImprovedDeduplicated report normalization — the share and migrate routes now use a single shared normalizer instead of maintaining two copies.
- FixedRate limiter no longer uses setInterval on serverless — replaced with lazy cleanup to avoid cold start issues on Vercel.
- FixedAll Pokemon are now forced to level 50 — pasting a level 100 team (or any non-50 level) no longer carries that level through to stat calculations. Stats are always computed at the VGC-standard level 50.
- NewCard-based Pokemon detail on mobile — hero header with tabbed cards (Set, Stats, Notes, Calcs) so each section gets full screen width instead of a cramped single column.
- NewDraggable progress bar — replaces dot indicators on mobile for slide navigation. Tap or drag to scrub through slides with haptic feedback and a floating label tooltip.
- NewTeam Coverage slide — offensive and defensive coverage charts are now their own dedicated slide with tabs on mobile, stacked on desktop.
- NewGame plan tabs (G1/G2/G3) — on mobile, matchup game plans display as swappable tabs instead of a long stacked list.
- NewUpdate Team re-import — "Update Team" button on the overview slide lets you paste a new PokePaste URL, Pikalytics URL, or Showdown export to replace the team without starting over.
- NewEdit mode FAB — floating action button (bottom-right) for toggling edit/view mode. Pencil = editing, eye = viewing. Works on both mobile and desktop.
- NewPull-to-refresh — custom pull-down gesture for shared reports in PWA standalone mode (where native pull-to-refresh is disabled).
- NewLong-press gesture — long-press a Pokemon card in the team overview to jump directly to its detail slide.
- NewHaptic feedback — light vibration on tab switches, edit mode toggle, share actions, and progress bar scrubbing for a native app feel.
- ImprovedOpponent team horizontal scroll — matchup plan opponents display as a swipeable horizontal strip on mobile instead of a cramped 3-column grid.
- ImprovedCoverage chart touch targets — type effectiveness cells are now 36px on mobile (up from 28px). Tap a type column header to highlight it across all Pokemon.
- ImprovedTournament mode cards redesigned — compact layout on mobile with sprite + info row and 2×2 move grid. 3-column grid on large screens.
- ImprovedNavbar decluttered — moved Tournament mode, PDF export, Version history, Collab link, and Present mode into the settings overflow menu. Navbar now shows only Share/Save + settings gear.
- ImprovedOwn reports auto-enter edit mode — authenticated owners and ?key= edit links go straight to editing. Other viewers see read-only with the FAB to toggle.
- ImprovedBottom padding increased on mobile PWA — all slide content now clears the fixed nav bar + safe area inset so calcs, notes, and game plans are fully scrollable.
- FixedFixed swipe conflict on coverage charts — horizontal scrolling inside coverage tables no longer triggers slide navigation.
- FixedFixed duplicate swipe handlers — removed the window-level touch handler that was fighting with the container-scoped one.
- FixedFixed hydration flash — mobile/desktop layouts now use CSS media queries instead of JS detection, eliminating the brief layout shift on page load.
- FixedPDF export now works reliably — print container uses a React portal to render as a direct child of <body>, fixing the blank page issue.
- FixedPDF always uses light-mode colors — all CSS variables are forced to light-mode values inside the print container, so exports are readable regardless of dark mode.
- ImprovedAll collapsed sections expand automatically in PDF — damage calc groups (Offensive, Defensive, Speed) and game plan details are forced open during export.
- ImprovedPrint styles force readable text, backgrounds, and borders — surface, text, and border colors are explicitly overridden for white paper.
- NewTournament Day mode — compact battle assistant activated via the trophy icon in the navbar. Shows condensed Pokemon cards (moves, item, ability, Tera type) and a speed tier quick reference. Works fully offline.
- NewReferral reward themes — unlock accent color themes (Ocean Blue, Emerald, Amber, Violet, Sunset) based on your total report views. Selectable on your profile page with live preview.
- NewChampions SEO pages — 32 individual landing pages for every Mega Evolution at /champions/[pokemon] with full stats, teams from explore, related Megas, and JSON-LD structured data.
- NewAccount privacy controls — toggle your creator profile between public and private from the profile settings page.
- NewPublish to Community prompt — when sharing a private report, a banner asks if you want to publish it to the Explore page.
- NewEmail notifications for comments — report owners receive a branded email via Resend when someone comments on their report.
- NewOffline cached reports — previously viewed reports load from cache at tournaments. An amber banner shows when viewing a cached version offline.
- NewPending invite badge — the Shared tab shows a purple count badge when you have collab invites waiting.
- ImprovedSocial share cards — richer OG images with gradient backgrounds, context-aware placement badges (gold/silver/bronze), adaptive sprite sizing, and a branded bottom bar.
- ImprovedDynamic sitemap — all public reports now included in the sitemap for better search engine indexing.
- ImprovedCollab notifications now include a deep link to /dashboard?tab=collab so users can accept invites directly.
- ImprovedDaily ops deduplication — the cron no longer creates duplicate Linear tickets for the same recurring issue.
- ImprovedWCAG 2.1 AA accessibility — improved text contrast, viewport zoom enabled, skip-nav target, form labels, and aria-labels on icon buttons.
- ImprovedPerformance — lazy-loaded html2canvas, jsPDF, qrcode, and social components. Removed unused @smogon/calc dependency (~500KB saved).
- FixedFixed share page not loading — internal API fields were leaking into report state.
- NewYouTube-style co-publishing — collab reports now appear on ALL collaborators' creator pages, not just the owner's. Co-creator names shown on explore cards, share pages, and SEO metadata.
- NewCollaborator consent flow — invites start as "pending". Collaborators must explicitly accept before getting edit access or public credit. Prevents fake attribution.
- NewAccept/Decline UI in dashboard — pending collab invites appear in the Shared tab with clear Accept and Decline buttons.
- NewAuto-create Linear tickets from daily ops — when the health check detects issues (site down, DB failure, SEO problems), it auto-creates tagged Linear tickets.
- ImprovedDashboard PWA polish — tabs scroll horizontally on mobile, 2-column report grid, compact header, smaller sprites, tighter spacing throughout.
- ImprovedBottom nav bar compacted — smaller icons/text, gesture bar padding in standalone PWA mode.
- ImprovedReportCard responsive — sprites scale down on mobile (32px vs 40px desktop), titles allow 2-line clamp for readability.
- ImprovedNavbar height reduced to 48px on mobile with sticky-header-standalone class for PWA status bar.
- ImprovedCollaboratorPanel shows "Pending" badge for unaccepted invites so owners know who hasn't responded.
- ImprovedShare cache invalidated when collaborators are added or removed — changes appear immediately.
- FixedFixed share page not loading — internal API fields (_version, _collaborators) were leaking into report state and breaking the paste parser.
- FixedCanonical domain redirect — vgc-team-report.vercel.app now redirects to pokemonvgcteamreport.com.
- NewPDF export — download icon in the navbar renders all slides (overview, Pokemon details, speed tiers, coverage charts, matchup plans) with page breaks via the browser print dialog.
- NewShowdown replay import — paste a replay.pokemonshowdown.com URL, pick which player's team to analyze. Extracts species, moves used, abilities, items, and Tera types from the battle log.
- NewKeyboard shortcuts for editing — press 1-9 to jump to slides, 0 for last slide, E to toggle edit mode, H to hide/show current slide, [ and ] to reorder slides.
- ImprovedVersion history only records real changes — auto-save no longer creates version entries when no data actually changed.
- ImprovedVersion diff highlights use high-contrast blue borders with "Changed" labels, readable in both light and dark mode.
- ImprovedSlide nav dots show blue indicators for slides with changes during version comparison.
- ImprovedShortcut hint overlay (press ?) updated with all new shortcuts.
- NewPer-field version diff highlighting — comparing versions now highlights only the specific sections that changed (e.g. just Notes or Calcs) instead of the entire slide.
- NewDescriptive diff banner — version comparison now lists exactly what changed (e.g. "Team summary, Notes (Pikachu), Calcs (Urshifu)") instead of vague slide counts.
- NewFeedback link added to desktop navbar — now visible next to Updates for easy access from any page.
- ImprovedWalkthrough tour spotlight visibility — accent-colored ring in light mode, white glow ring in dark mode so highlighted areas are always clear.
- ImprovedDiff labels are contextual — each highlighted section shows what changed: "Set changed", "Notes changed", "Calcs changed", "Summary changed", etc.
- NewVersion History side panel — Google Docs-style slide-out panel with timeline UI, version diffs, and one-click restore to any previous version.
- NewVersion history for your own reports — no longer limited to shared views. See and restore past versions from the home page after sharing.
- NewClock icon in the report navbar — quick-access button to open version history without digging through menus.
- NewClickable "Saved" status — tap the auto-save badge while editing to open version history instantly.
- NewPWA standalone mode styles — installed app disables rubber-band bounce, adds status bar inset, and feels native.
- NewInstall prompt redesigned as bottom sheet — full-width with scrim overlay, handle bar, and large touch targets.
- NewDynamic theme-color — status bar matches your light/dark mode instead of static red.
- ImprovedBottom tab bar upgraded — active pill indicator, icon bubbles, smoother press feedback, and Dashboard tab for signed-in users.
- ImprovedFrosted glass headers — both navbars now use backdrop-blur-2xl with saturation boost for a polished glass effect.
- Improved100dvh viewport — uses dynamic viewport height so mobile browser chrome doesn't cause layout jumps.
- ImprovedSafe area coverage — added safe-top and safe-x utilities for full edge-to-edge support on all devices.
- ImprovedSW update toast — centered and full-width on mobile with smoother entrance animation.
- ImprovedRevert button always visible on mobile — no more hover-only reveal on touch devices.
- ImprovedManifest enhanced — launch_handler reuses existing window, handle_links opens in PWA, added Create shortcut.
- NewVersion History — every edit is snapshotted. Browse past versions and revert to any point with one click.
- NewManage Access panel — Google Docs-style access control. See who has access, add/remove collaborators, revoke collab links.
- NewCollab sign-in gate — collab links now require sign-in. Unauthenticated users see a sign-up prompt.
- NewRevoke collab link — owners can regenerate the edit token to invalidate all existing collab links.
- NewCo-ownership — collaborators are promoted to co-owners with full Collab button access and dashboard visibility.
- NewChampions banner on landing page — dismissible announcement for the new Mega Evolution format.
- New+ Create button in navbar — clear entry point to build a new team report from any page.
- NewPWA update detection — shows toast when a new version is available with one-click refresh.
- ImprovedDefensive profile heatmap — 4× weaknesses now bold white-on-red with ring outline for visibility.
- ImprovedNavbar cleaned up — auth, theme, language, and settings moved into single overflow menu.
- ImprovedSign-in button visible immediately on page load (no flash while Clerk loads).
- ImprovedLanguage selector added to all page navbars.
- ImprovedAll sprite slug resolution consolidated to single source of truth — fixes broken sprites in OG images, embeds, and team graphics.
- Improved48 Mega Evolutions now in the database with full stats, types, and abilities.
- ImprovedMega Offense and Primal Weather archetypes auto-detected.
- FixedFixed walkthrough tour breaking after first step (timing race in tooltip positioning).
- FixedFixed share URL fallback creating 11KB+ URLs that browsers truncate.
- FixedFixed service worker intercepting cross-origin sprite requests and returning broken responses.
- FixedFixed inconsistent navbar width across Feedback, Privacy, and Dashboard pages.
- NewCollaborator system — invite signed-in users to co-edit your team reports.
- NewShare vs Collab separation: share links are read-only, collaborators get full edit access.
- NewCollaborator management panel — search users by name, add or remove collaborators (owner only).
- New"Shared with me" dashboard tab showing reports you've been invited to collaborate on.
- NewEdit History changelog — see who changed which sections with timestamps and version numbers.
- NewVersion snapshots — every edit saves a full snapshot of the previous state for revert capability.
- NewCollab invite notifications — collaborators are notified when invited.
- ImprovedLikes now require sign-in — anonymous users see the count with a "Sign in to like" prompt.
- ImprovedOwners can edit reports without the edit key URL — auto-detected via authentication.
- ImprovedCreator mode auto-enables when edit access is granted.
- FixedFixed CSRF middleware blocking same-origin POST requests (share, comments, reactions).
- FixedFixed CSP blocking Clerk sign-in modal, fonts, and Pokemon Showdown sprites.
- FixedFixed old reports without tags crashing when setting tags.
- NewPokemon Champions support — Mega Evolution and Primal Reversion parsing, display, and team building.
- NewRegulation M-A tag for the official Pokemon Champions competitive format.
- New35+ Mega Evolution and Primal Pokemon added with accurate stats and abilities.
- NewChampions landing page with format details, tournament calendar, and SEO optimization.
- NewReal-time collaborative editing via Server-Sent Events with live presence indicators.
- NewRedis caching layer (Upstash) for faster Explore and Share page loads.
- NewDatabase migration endpoint for batch-updating old reports to latest format.
- ImprovedLazy-loaded heavy components (SpeedTierChart, MatchupSheet, ShareModal) for faster initial page load.
- ImprovedConsistent PageFooter across all pages (Explore, Dashboard, Privacy, Compare, Creator Profile).
- ImprovedBackward-compatible data migration for old calc entries and matchup plan formats.
- ImprovedSample team updated to Champions format featuring Kangaskhan-Mega and Salamence-Mega.
- ImprovedShare text now includes #PokemonChampions #VGC2026 hashtags for organic reach.
- ImprovedVercel deployment URLs redirect to canonical custom domain.
- NewTeam Comparison page — paste two teams side-by-side to compare type coverage, speed tiers, and shared Pokemon.
- NewTags & Categories — tag reports with archetype (Rain, Trick Room, etc.), regulation, and event type.
- NewExplore filters — filter community reports by regulation, event type, and archetype tags.
- NewNotifications — get notified when someone comments, reacts, or a creator you follow posts a new report.
- NewNotification bell in navbar with unread count badge and dropdown panel.
- NewReport Templates — choose Quick Share, Tournament Report, Team Guide, or Blank when creating a report.
- NewRental Code QR — scan QR codes for rental team codes directly from reports.
- ImprovedTag pills shown on Explore report cards for quick identification.
- ImprovedTag selector with pill-style archetype multi-select and regulation/event dropdowns in creator mode.
- ImprovedDark/light mode now persists across sessions via localStorage.
- ImprovedSystem dark mode preference respected on first visit.
- NewSign in with Discord, Google, or Twitch via Clerk.
- NewDashboard — manage all your team reports in one place.
- NewClaim reports — link existing reports to your account via edit token.
- NewAuto-detect unclaimed reports from your browser localStorage.
- NewSave/bookmark reports from other creators.
- NewCreator profile editor — set bio, Twitter, Discord, YouTube.
- NewFork Team button — copy any public team and build your own version.
- NewReport management — edit, toggle public/private, delete from dashboard.
- NewBulk actions — toggle all reports public or private at once.
- NewDashboard sorting — newest, oldest, most views, by name.
- NewFeedback page with Discord webhook notifications.
- NewChangelog page with full version history.
- ImprovedSign-in nudge when editing shared reports without an account.
- ImprovedDashboard link on all pages when signed in.
- ImprovedComments disabled indicator — shows message when creator turned off comments.
- ImprovedPWA shortcuts for Explore, Dashboard, and Feedback.
- FixedXSS protection — HTML entities escaped in comments and display names.
- FixedClaim input strips whitespace from pasted edit tokens.
- ImprovedRefactored useHomePage into 3 focused hooks (useShareFlow, useSlideSystem, useExportActions).
- ImprovedMobile: IV badges visible, larger move text, wider stat bars, better grids.
- ImprovedMobile navbar overflow menu for secondary controls.
- ImprovedTouch-friendly swap button for lead/back in matchup game plans.
- ImprovedEV total shown on Pokemon cards (warns if >510).
- ImprovedComment success/error notifications.
- ImprovedSpotlight API cached in sessionStorage to reduce lag.
- FixedReduced-motion support for all animations.
- FixedKeyboard focus rings for accessibility.
- FixedDot grid background disabled on mobile for performance.
- FixedDead CSS removed (unused keyframes).
- NewExplore gallery — browse public team reports from the community.
- NewReactions — react to reports with emoji (fire, heart, brain, battle, clap).
- NewComments — leave feedback on public reports (creator-controlled).
- NewCreator profiles — auto-generated pages for every creator.
- NewView counts — track engagement on public reports.
- NewVerified creator badges with admin verification.
- NewYouTube-style visibility — private, unlisted, or public.
- NewSpotlight featured team report on landing and explore pages.
- NewWhat's New modal for first-time visitors.
- NewRandom accent colours on landing page (8 palettes).
- ImprovedLanding page redesigned to show community features.
- ImprovedAnimated GIF sprites across all cards and spotlight.
- ImprovedSEO metadata updated across all pages.
- ImprovedShare button disabled on sample team with tooltip.
- ImprovedHome logo and Build Your Own CTA on shared report views.
- FixedPNG and PDF export now works reliably (html2canvas-pro).
- FixedSprite loading for hyphenated Pokemon (Urshifu, Flutter Mane, etc.).
- NewWord filter blocks inappropriate language in comments.
- NewFlag/report button on comments with auto-remove at 3 flags.
- NewSelf-reported label on unverified placements.
- ImprovedComments off by default — creators opt-in via Share modal.
- ImprovedEV spread total shown on Pokemon cards (warns if >510).
- ImprovedMobile navbar overflow menu for secondary controls.
- ImprovedTouch-friendly swap button for lead/back in game plans.
- FixedPerformance: spotlight caches in session, view count fires once.
- FixedDot grid background disabled on mobile for better performance.
- FixedReduced-motion support for all animations.
Have an idea for the next update?
Send Feedback