19 Commits

Author SHA1 Message Date
d553213563 refactor(m4c): rename GameFlow coordinator to Main, move to scenes/Main.tscn
The entry-point coordinator read as an internal name ("GameFlow" buried in
scenes/flow/), so it wasn't obvious THIS is the scene that boots first — the
title screen looked like the entry point. Renamed to the Godot-conventional
Main (scenes/Main.tscn + scripts/main.gd) so the boot scene is self-evident.
TitleScreen is unchanged and still shown BY Main as its first screen.

Also drops the hand-written gd_scene uid (now matches sibling scenes) —
closes the Minor review finding. Full suite 327/327 green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 05:16:55 -05:00
583d32456a feat(m4c): GameFlow coordinator wires title -> creation -> shell 2026-07-15 04:15:28 -05:00
1ae62fe0db feat(creation): distinguish granted skills as owned, and enlarge the small text
Two F6-review follow-ups from the human's read of the running screen.

1. GRANTED skill chips now read as 'you already have this', not 'unavailable'.
   The elf's granted `perception` shared SkillChip's dim `disabled` look with the
   'picks are spent' chips, so it read as blocked. Split out a fourth state,
   SkillChipGranted — a solid gold fill, cream text, and a ✓ prefix (owned) — while
   the pool-is-spent chips keep the plain dim disabled. Applied per-chip in _bind_skills.

2. Enlarged the small mono/body/prose roles for readability on sub-1920 laptops
   (the 1920 design canvas scales DOWN on a smaller screen, so 11-13px text got
   tiny): DM prose 20->22, MONO 13->14, section labels 13->14, card title 19->20,
   card body 13->14, chips 11->12, skill chips 12->14, the two flag pills +1. Big
   serif headings unchanged.

   Two layout consequences the guards caught and I fixed, not silenced:
   - Race cards overflowed the taller blurb -> card min-height 140->180 (the overflow
     guard, which measures against the card the engine does NOT derive from the text,
     went red first; traps.md #17).
   - The 9-chip Human bonus row, wider at the bigger font, blew the whole sheet past
     the viewport -> BonusRow HBoxContainer -> HFlowContainer so it wraps instead of
     forcing the sheet wide. Nothing depends on the row's type (tests check child
     count + visibility only).

319 client tests green (theme drift guard + overflow guard included); screenshot-
verified at 1280x720: granted chip owned, no clipping, bonus row wraps cleanly.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-14 20:33:08 -05:00
63cbc8c16e fix(creation-screen): the white text, the badge on top of the roll, and a window too big for the laptop
The human's first F6 run found four defects headless GUT could not see, all
now fixed and break-proven.

1. Fifteen Labels shipped invisible. _fonts() sets a default font and size but
   never a default font_color for the base Label type, so a Label with no
   type-variation inherited Godot's built-in default — WHITE — and rendered
   white-on-parchment: the four race names, four race blurbs, and seven calling
   names, every unreadable string on the sheet. New CardTitle / CardBody roles
   (mock #3a2f1c / #6a5a3a) fix it. NOT a global default Label colour: the Title
   screen has 12 bare Labels on a dark background that rely on white.

2. The PRIMARY badge covered the rolled value. The ability card is a
   PanelContainer, and a Container force-fits its children, so the badge's
   authored anchors were dead letters — it stretched to the card's full width
   and centred over the value. Nesting it under a plain Control (not a
   Container) restores absolute positioning. The badges also carried _flat()'s
   12/6 card padding; a new tight pill stylebox matches the mock's 2px 9px.

3. Race cards overflowed their own border (108px card, 114px of content). Bumped
   to 140. The CHOSEN badge on the calling card moved from centre to the mock's
   top-right, and the ability card got its own AbilityCard variation with 16px
   top headroom for the badge (ParchmentCard is shared with the shell).

4. The default window (1600x900) was larger than a 1600x900 laptop's usable
   area, so the WM clamped it to 1589x752 and the run came up pillarboxed.
   Default is now 1280x720, resizable; the 1920x1080 design canvas is unchanged
   (canvas_items + keep scales it, so no layout number moved).

Also closes M4-b's two open copy items: the cutpurse origin fragment (it
contradicted its own blurb) and the Hint label (it omitted the roll's floor of
8, now pinned to NewGame.roll_attributes).

Guards for 1-4 are new and each was re-broken and watched go red. The overflow
guard in 3 was FIRST WRITTEN AS A TAUTOLOGY — Godot clamps Control.size up to
its combined minimum, so `min <= size` is `x <= x` — and passed against the bug,
29/29, until it was rewritten to measure against the card that clips. That is
traps.md #17 and the thirteenth cannot-fail assertion this branch has caught.

319 client tests green, content build green, theme drift guard satisfied.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-14 19:56:09 -05:00
2227d703f6 feat(creation): the character creation screen
Variant C of the mock: seven nameplate calling cards in one row, with the chosen
calling's blurb AND mechanics in a detail panel below — the one card you
committed to is the only one that talks.

Editor-first (ADR 0001): the tree is in the .tscn, the script binds. No rules
here — CreationDraft holds them, CreationCopy derives the display strings, the
prose comes from ContentDB. Emits creation_confirmed(Dictionary); M4-c
constructs. Five ability cards. Never six (§7).
2026-07-13 15:03:24 -05:00
6c496d3ed8 feat(currency): the command-bar purse reads in denominations
The seed placeholder was a flat 1240 gold — 12.4 million copper under the real
model, which is 1,240 plot points in the command bar. It reseeds to 347c, a
party carrying silver and no gold: '◈ 3s 47c'.

This is the only call site of Currency.format() — the display edge.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QYa9u7Kdxv5gX4AnwWexy8
2026-07-12 18:39:25 -05:00
f07139256b feat(title): warm shader background, pulsing glow, drifting embers
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-11 10:54:22 -05:00
a77bf03ee4 feat(title): TitleScreen composition, menu + selection, boot scene
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-11 10:47:44 -05:00
58880554c2 fix(shell): dock handle to the right edge; command bar fits
Wider consumable tiles overflowed the command bar, shoving END TURN under
the dock column. Trim the vitals min-width (230->120) and END TURN
(150->140) and separation so the row fits — END TURN lands cleanly at the
bottom-right, below the dock.

Move the dock handle to the outer (right) side per mock 2a: the menu now
sits left of the handle and slides right off-screen to hide, the handle
staying at the world's right edge. Dock sits flush to that edge.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-11 09:59:23 -05:00
fb541d05cb fix(shell): widen consumable tiles so labels fit
The 62px tiles clipped longer names (Draught, Antidote). Widen to 93px
(~1.5x) — there is room in the command bar — so labels fit while tiles stay
uniform.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-11 09:50:25 -05:00
6ef71aaa31 fix(shell): readable ink prose + uniform consumable tiles
The narration RichTextLabel had no theme styling, so it rendered near-white
and was unreadable on parchment. Add a base RichTextLabel style to the theme
(dark INK_BODY serif at 20px, italic face wired) — systemic and previews in
the editor; every parchment prose surface now reads as dark ink. Also clip
the consumable slot labels so a long name ("Antidote") can't stretch its tile
wider than the empty ones — all 8 stay a uniform 62px.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-11 09:47:21 -05:00
4698732285 refactor(shell): author shell scenes as editor-previewable node trees
Move the three shell scenes (SystemDock, NarrationBook, MainWindowShell)
from build-everything-in-_ready() to authored .tscn node trees with the
theme + type-variations set in the editor, so the layout previews and can
be arranged in the Godot editor. Scripts keep only on-load work: @onready
node refs, DM-loop wiring, the dock slide, and binding seed ShellState into
the fixed authored turn-order tokens + consumable slots.

Fixes the dock offset + over-long buttons (now fixed-width DockButtons in a
right-anchored menu). Headless probe: root 1920x1080, world/book split
1180/740, dock at the world's right edge — no collapse. Suite 138/138.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-11 09:38:22 -05:00
578b3e86c9 feat(shell): MainWindowShell assembles the frame and wires the DM loop
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-11 09:16:14 -05:00
5f1ebdf840 feat(shell): NarrationBook wired to /dm/narrate with refire + fact-harvest 2026-07-11 09:07:24 -05:00
9a02c9b038 feat(shell): SystemDock slide-in with inert screen-routing seam 2026-07-11 08:51:14 -05:00
7954c579d3 feat(theme): showcase harness — the human-eyeball proof
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 20:39:09 -05:00
73fcf2d096 feat(theme): parchment/dark-bay/vignette shader surfaces as drop-in scenes
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 20:34:52 -05:00
87f337bffd feat(client): throwaway NPC harness — drive /npc/speak on screen
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 13:02:13 -05:00
89afd85bb2 feat(client): throwaway narrate harness scene + live-smoke doc
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 10:12:21 -05:00