Skip to content

feat(ui): splash screen + main-menu design pass#53

Merged
wildcard merged 5 commits into
mainfrom
claude/cranky-kare-fbc0ca
Apr 23, 2026
Merged

feat(ui): splash screen + main-menu design pass#53
wildcard merged 5 commits into
mainfrom
claude/cranky-kare-fbc0ca

Conversation

@wildcard

Copy link
Copy Markdown
Owner

Summary

First real UI chrome pass for PNK Forever v1. Replaces the CSS-gradient placeholder main menu with a proper splash screen, wordmark, polished start-menu buttons, and systemic focus/hover motion. Dispatched via the `game-ui-artist` subagent.

This closes a long-standing gap: the menu has been a bare `linear-gradient` with a single gradient button since day one (see HANDOVER.md:235 aspiration that was never dispatched).

What landed

  • Splash screen — narrat-native `splashScreens.gameSplashScreen` (chosen over an HTML overlay so narrat's mount lifecycle owns the fade). Engine splash suppressed via `engineSplashScreen.skip: true`.
  • SVG wordmark (1 KB) — hand-authored `public/img/ui/splash/wordmark.svg`. Shown on both splash and start-menu via `font-size: 0 + background: url()` so screen readers still read "P&K Forever" while eyes see the glyph.
  • Main menu — warm radial gradient, ambient `splashGlow` keyframes (reduced-motion safe), decorative divider under the wordmark, cream-on-rose-border button treatment for Continue / New Game / Load Game / Exit.
  • Splash start button — coral gradient with hover lift + focus ring.
  • Systemic motion — all interactive elements now have focus-visible rings and hover transforms gated behind `prefers-reduced-motion`.

Why splashScreens over an HTML overlay

narrat boots into `#app` on `DOMContentLoaded` and owns the transition between splash → main-menu → script. An HTML overlay would have had to race that boot order and manually fade itself out once narrat mounted; the native `splashScreens` config lets narrat handle the sequencing.

What didn't land (known gap)

Volume-select choice styling is a no-op. The subagent wrote rose/teal card styles targeting `.nrt-choice-button`, but narrat actually emits `p.dialog-choice` with `.choice-index` / `.choice-text` children. The selectors don't match the real DOM, so the volume-select screen falls back to narrat's default dialog-text rendering (functional but unstyled).

Filing a P2 follow-up issue to retarget the CSS at the real selectors.

Verification

Verified locally via `vite preview` + Claude Preview MCP — screenshots confirm:

  1. Splash renders wordmark + "BEGIN THE STORY" button on warm radial bg.
  2. Main menu renders wordmark + 4 orange-bordered buttons + decorative divider + "Vol 1 · throwback" chip.
  3. In-game dialog box + keycap prompts (Auto/Skip/Toggle History/System/Menu) all render correctly — no regression on the existing gameplay UI.
  4. `npm run build` exits 0; CSS output 46 KB (9.5 KB gzipped).

Test plan

  • Vercel preview deploys green.
  • Splash fades into main menu cleanly (no flash of unstyled content).
  • All 4 start-menu buttons keyboard-navigable with visible focus rings.
  • Volume-select still advances the script (visual polish separately tracked).
  • No console errors during splash → menu → first scene.

Files changed

  • `v1-modern/public/img/ui/splash/wordmark.svg` (new)
  • `v1-modern/public/data/config.yaml` (+5 lines — `splashScreens` block)
  • `v1-modern/src/game.css` (+400/-34 — splash, menu, focus/hover polish)

Total new UI asset payload: ~1 KB (well under the 200 KB cap in the `game-ui-artist` agent spec).

Sacred constraints

  • No file under `v0-original-text-engine/` touched.
  • `"For Anastasia. Forever."` in `japan.narrat` untouched.
  • No API keys committed.
  • `game-artist` not called directly (subagent chose vector-only, so `art-director` wasn't needed either).

🤖 Generated with Claude Code

wildcard and others added 3 commits April 22, 2026 22:22
Hand-authored 480×120 SVG with Georgia serif P&K logotype, FOREVER
subtitle in pnk-orange, and decorative rule lines with accent dots.
Used in both game-splash and start-menu screens via CSS background.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Skip the engine splash (narrat branding) and activate the game-splash
scene with "Begin the Story" button text. Engine splash removed via
splashScreens.engineSplashScreen.skip: true.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Splash screen: warm radial bg, ambient glow animation, SVG wordmark
  replaces plain title text, themed "Begin the Story" button with
  lift-on-hover and correct z-stacking
- Main menu (#game-menu): matching radial bg, orange divider rule,
  SVG wordmark on #game-title-text, themed .main-menu-button states
- Volume-select: rose/teal left-border accent per choice, Vol. I /
  Vol. II badge via ::after, card-feel padding
- Systemic focus rings on all interactive elements via :focus-visible
- Hover motion (translateY/X + shadow) gated on prefers-reduced-motion
- Design tokens: --pnk-rose, --pnk-teal, --pnk-dark, motion vars

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@vercel

vercel Bot commented Apr 23, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
pnk-forever Ready Ready Preview, Comment Apr 23, 2026 6:01am

Request Review

@netlify

netlify Bot commented Apr 23, 2026

Copy link
Copy Markdown

Deploy Preview for p-n-k-forever ready!

Name Link
🔨 Latest commit 7388b46
🔍 Latest deploy log https://app.netlify.com/projects/p-n-k-forever/deploys/69e9b5c18430e10008a954c3
😎 Deploy Preview https://deploy-preview-53--p-n-k-forever.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e2777c7685

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread v1-modern/src/game.css
display: block !important;
width: 400px !important;
height: 100px !important;
background: url('/img/ui/splash/wordmark.svg') center/contain no-repeat !important;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Use relative URL for wordmark asset

This hard-codes the wordmark to a root-absolute path (/img/...), but this project is built with base: './' in v1-modern/vite.config.ts, so production deployments under a subpath (or opening dist/index.html directly) will resolve the image from the host root and fail to load it. Because this selector also sets font-size: 0, the fallback text is hidden, so the splash/menu title can disappear entirely in those environments. Please switch to a base-aware relative URL (and apply the same fix to the identical #game-title-text background rule).

Useful? React with 👍 / 👎.

Round 2 of the UI pass — replaces placeholder gradients with hand-painted
Gemini-generated backgrounds, softens UI copy from game-style to
anniversary-gift tone, and works around a narrat scene-mount bug that left
the splash stuck at opacity 0.

Art (art-director + game-artist / nano banana):
- splash_bg.jpg — balcony at golden dusk, sheer curtains billowing over
  a sunset view. Natural darker center band for the wordmark
- menu_bg.jpg — two coffee cups + orange-blossom letter on a sunlit
  table. Left-side shadow for the button stack
- paper_texture.png — 1024px warm-cream grain, layered at 8% opacity
  under both menu and any .pnk-paper-overlay container

Copy (game-narrative):
- Splash CTA: "Begin the Story" → "Come inside"
- Volume-picker intro: "a story kept, chapter by chapter."
- Volume options: "The original · read it the way it was first written"
  and "The full story · all the chapters, from the beach onward"

CSS fix:
- .game-scene wrappers were computing opacity: 0 because narrat's prod
  CSS only ships .narrat-transition-fade-enter-from (opacity 0) and
  -active (transition-property: opacity), but no enter-to rule to
  commit the fade-in. Added our own pnkSceneFadeIn keyframe so scenes
  fade in cleanly, with prefers-reduced-motion gate

Also adds scripts/gemini-generate-ui.mjs so future art regens are
one command away.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@wildcard

Copy link
Copy Markdown
Owner Author

[agent]

Agent: Claude Code (claude-opus-4-7)


Level-up pass — painted backgrounds, warmer copy, scene-fade fix

Pushed commit 0af31c1. Three wins + one regression fix:

Art (art-director → game-artist / nano banana)

  • Splash bg: balcony at golden dusk, sheer curtains billowing over a sunset view. Natural dark center band for the wordmark.
  • Main-menu bg: two coffee cups + orange-blossom letter on a sunlit table. Left-side shadow for the button stack.
  • Paper texture: warm-cream grain tile layered at 8% opacity under the menu.

Copy (game-narrative)

  • Splash CTA: Begin the StoryCome inside
  • Volume-picker intro: a story kept, chapter by chapter.
  • Volume options: The original · read it the way it was first written and The full story · all the chapters, from the beach onward

Regression fix

  • .game-scene wrappers were computing opacity: 0 on mount because narrat's prod CSS only ships .narrat-transition-fade-enter-from { opacity: 0 } and -active { transition-property: opacity } — no enter-to rule to commit the fade-in. Added our own pnkSceneFadeIn keyframe with prefers-reduced-motion gate.

Verified in preview (port 4173)

  • Splash ✓ (wordmark sits in the vignette, COME INSIDE button renders, "A LOVE STORY IN TWO VOLUMES" subtitle at bottom)
  • Main menu ✓ (painted coffee-cups scene, left vignette dims the button stack for legibility)
  • Intro scene ✓ (new narrative copy lands: "P. & K. — a story kept, chapter by chapter.")

Still open


Prompt used to generate this comment
Ad-hoc PR update after dispatching art-director and game-narrative sub-agents
to level up the splash + main-menu pass, then debugging a narrat Vue-transition
regression that left .game-scene stuck at opacity 0.

"A Love Story in Two Volumes" read like a movie-poster tagline.
"Tel Aviv · Kyoto · Vancouver" is grounded and specific — the three
cities the couple has actually been. Drops uppercase + reduces
letter-spacing so it reads as a quiet caption, not an advertisement.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@wildcard

Copy link
Copy Markdown
Owner Author

[agent]

Agent: Claude Code (claude-opus-4-7)


Verdict: APPROVE — ship it. No blocking issues. Sacred line intact, end-to-end playtest passed, scope is CSS + copy + new assets only.

Three parallel reviews (critic, plan-reviewer x2) converge on ready-to-merge. Two recurring concerns, both non-blocking:

  • [non-blocking][P1] v1-modern/src/game.css — the .game-scene { opacity: 1 !important; animation: pnkSceneFadeIn ... forwards } override suppresses leave transitions globally, not just enter. Scope via :not(.v-leave-active) or explicit Vue transition classes. Playtest confirmed no chapter regressions, so this is cleanup, not a gate.
  • [non-blocking][P1] v1-modern/src/game.css.nrt-choice-button:first-child::after { content: 'Vol. I' } / :nth-child(2)::after { content: 'Vol. II' } will bleed onto the first two options of every choice: block (chapter_select included). Retarget via #volume-select-choices or a .volume-card class. Already tracked in fix(ui): volume-select CSS targets wrong selectors (narrat emits p.dialog-choice) #54.
  • [non-blocking][P2] v1-modern/scripts/gemini-generate-ui.mjs:105 logs the first 8 chars of the API key — harmless but unnecessary, drop the line.
  • [non-blocking][P3] Nits: magic 420ms fade, duplicated cream literal, !important stacking.

No save/load, CI, easter-egg-keyword, or narrat-script touches. japan.narrat:200 sacred line verified untouched.


Prompt used to generate this comment
/review — synthesized from three parallel sub-agent reviews (critic, plan-reviewer x2) on PR #53.

@wildcard
wildcard merged commit 2a58ee2 into main Apr 23, 2026
8 checks passed
@wildcard
wildcard deleted the claude/cranky-kare-fbc0ca branch April 23, 2026 06:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant