Insert-beat is a pure in-scene micro-interaction — adding choices that
lead to change-scene contradicted its purpose. Now insert-beat generates
1-3 richer beats then loops back to the original options, which is the
natural UX for "you glanced at something decorative."
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The window-level 'F' keydown listener now ignores events from INPUT,
TEXTAREA, and contentEditable elements so freeform input is not
interrupted by the presentation-mode toggle.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
User feedback: custom interactions rarely produce new story content because
the classifier heavily biased toward insert-beat (single reaction, no scene
change). Three changes to fix this:
1. Freeform text input now always triggers a full scene generation (skips
the classify step entirely) — users who type expect the story to advance.
2. Vision (background click) classifier de-biased: prompt now favors
change-scene when uncertain, and the code fallback flipped from
insert-beat to change-scene. insert-beat narrowed to pure observation.
3. Insert-beat enhanced: generates 1-3 beats (was 1) with follow-up
choices (was: loop back to original beat). Even when vision classifies
as insert-beat, the player gets richer content and new options.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Rewrites the i18n system introduced in PR #94 to use Next.js App Router
[locale] dynamic segments with SSR-rendered translations and proper
middleware locale routing.
- Add middleware locale detection: / rewrites to /zh-CN/ internally,
/en and /ja pass through, /zh-CN/... redirects to bare path
- Move all 7 pages under app/[locale]/ with SSR translation injection
- Fix server→client serialization: pre-evaluate function-valued
translations (makeSerializable) to eliminate hydration flash
- Fix language switch key flash: use hard navigation with localStorage-
only persistence, avoiding React state update before page reload
- Add <link rel="alternate" hreflang> tags for multilingual SEO
- Fix Supabase setAll overwriting locale rewrite response
- Trim locales from 22 to 3 (zh-CN/en/ja), delete 19 incomplete files
- LLM-translate 240 firstact game preset JSONs (en + ja, landscape +
portrait) and story titles via gemini-3.5-flash
- Delete 11 one-off migration scripts and outdated i18n docs
- Add useLocalePath hook and navigation utilities
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>