Port the introduction's naming and clock screens
Checks / web (push) Canceled after 0s

A new game now runs NewGame's InitGender and OakSpeech natively before
the bedroom: Boy or Girl, InitClock's hour and minute steppers with
their YES/NO confirmations, Oak's speech with Wooper, and NamePlayer's
preset names or naming field (a blank name takes CHRIS or KRIS). Texts,
menus and time strings come from a new INTRO profile table verified by
check:reference; Oak's and the player's pictures decode from
TrainerPicPointers, ChrisPic/KrisPic and TrainerPalettes.

The chosen time is kept as a minute offset from the device clock, which
time of day, the weekday, NPC hours and the daily reset now read. The
intro runs only when nothing is saved; a save made during it starts it
again. Saves gain intro and clock.minuteOffset, migrated by absence. The
shell's name and character fields are gone. Intentional change: the
steppers start at the device time rather than 10:00.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Sébastien QUEROLandClaude Opus 5.5 committed 2026-09-30 09:53:52 +02:00
1 parent 5a0fe1e313
commit b13fd20be4
28 files changed
+975 -101

No files matched your search

+1 -4
View File
@@ -22,10 +22,6 @@ export function renderShell(root: HTMLElement) {
<div id="screen-empty" class="screen-empty">
<form class="load-card" onsubmit="return false">
<p class="menu-title">NEW SESSION</p><h1>Load your Crystal ROM</h1><p>English US/Europe · Revision 1.1</p>
<div class="player-setup">
<label>Name <input id="player-name" value="CHRIS" maxlength="7" pattern="[A-Za-z0-9 -]{1,7}" autocomplete="off"></label>
<label>Character <select id="player-avatar"><option value="chris">Chris</option><option value="kris">Kris</option></select></label>
</div>
<label class="primary-button file-button" id="rom-label" for="rom-file"><span aria-hidden="true">▶</span> Choose ROM</label>
<p class="privacy-note">Opened locally. Never uploaded.</p>
</form>
@@ -41,6 +37,7 @@ export function renderShell(root: HTMLElement) {
<p id="mart-money" class="mart-money"></p>
<div class="mart-box"><p id="mart-prompt" aria-live="polite"></p><div id="mart-menu" class="mart-menu"></div></div>
</div>
<div id="intro-screen" class="intro-screen" hidden></div>
<div id="pokepic" class="pokepic" hidden><canvas id="pokepic-canvas" width="56" height="56" role="img"></canvas><button id="pokepic-next" hidden>Continue <span aria-hidden="true">▶</span></button></div>
<div id="native-dialogue" class="native-dialogue" aria-label="Dialogue" hidden><p id="dialogue-text" aria-live="polite"></p><div id="dialogue-choice" class="dialogue-choice" hidden></div><div><span id="dialogue-page"></span><button id="dialogue-next">Continue <span aria-hidden="true">▶</span></button></div></div>
<div id="pause-overlay" class="pause-overlay" hidden><span>PAUSED</span><button id="screen-resume">Continue playing</button></div>
+14 -29
View File
@@ -255,28 +255,6 @@ dialog h2 {
margin: 7px 0 12px;
font-size: 11px;
}
.player-setup {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 8px;
margin: 12px 0;
}
.player-setup label {
font-size: 10px;
font-weight: 700;
}
.player-setup input,
.player-setup select {
display: block;
width: 100%;
min-width: 0;
min-height: 44px;
margin-top: 3px;
padding: 7px;
background: #fffef5;
border: 3px double var(--ink);
border-radius: 0;
}
.primary-button,
.menu-button {
min-height: 44px;
@@ -466,6 +444,20 @@ dialog h2 {
.battle-menu .wide {
grid-column: 1 / -1;
}
/* NewGame's screens: a plain background over the world until the
introduction ends. */
.intro-screen {
position: absolute;
inset: 0;
z-index: 2;
background: #f8f8f0;
}
.intro-screen[hidden] {
display: none;
}
.intro-screen:not([hidden]) ~ .minimap-overlay {
display: none;
}
.pokepic {
position: absolute;
z-index: 3;
@@ -922,9 +914,6 @@ dialog dd {
.load-card h1 {
font-size: 16px;
}
.player-setup {
margin: 7px 0;
}
.minimap-overlay {
top: 4px;
right: 4px;
@@ -982,10 +971,6 @@ dialog dd {
grid-column: 1;
margin: 0;
}
.screen-empty .player-setup {
grid-column: 1;
margin: 0;
}
.screen-empty .primary-button {
grid-column: 2;
grid-row: 1 / 3;