Prompt utilisé pour régénérer cette page :
Page: The Harp of Four Seasons - Interactive Character Sheet
Title: "The Harp of Four Seasons"
Description: "Interactive character sheet for a solo adventure gamebook"
Icon: shield-account
Tags: gamebook, rpg
Status: prototype
Category: games
Front matter: no js/scss keys (uses default convention)
HTML structure in index.md (pure HTML, NO canvas):
<section class="character-sheet">
<!-- Creation overlay (#creation-overlay) -->
<div id="creation-overlay" class="creation-overlay">
<h2>New Character</h2>
<p class="lead">Roll your stats and choose a talent to begin your adventure.</p>
Step 1 (#creation-step-roll): Roll Stats
div.creation-stats with 3 .creation-stat blocks:
HP max: .stat-formula "2d6 x 4", .stat-value#creation-hp "?"
Luck: .stat-formula "1d6", .stat-value#creation-luck "?"
Dexterity: .stat-formula "fixed", .stat-value#creation-dex "7"
<button id="btn-roll-stats" class="btn btn-primary">Roll Stats</button>
Step 2 (#creation-step-talent, hidden): Choose a Talent
div#talent-choices.talent-grid with 7 talent buttons:
<button class="talent-btn" data-talent="instinct">Instinct</button>
herbology, stealth, persuasion, observation, nimble-fingers, empathic
Step 3 (#creation-step-confirm, hidden): Ready?
<p id="creation-summary"></p>
<button id="btn-start-adventure" class="btn btn-primary">Start Adventure</button>
<!-- Sheet main (#sheet-main, hidden until character created) -->
<div id="sheet-main" class="sheet-main hidden">
Stats bar (div.stats-bar) with 4 stat-blocks:
HP: heart icon, #stat-hp-current / #stat-hp-max
Dex: sparkle icon, .stat-editable, btn-dex-minus/plus (-/+), #stat-dex
Luck: clover icon, .stat-editable, btn-luck-minus/plus (-/+), #stat-luck
Talent: star icon, #stat-talent
HP bar (div.hp-bar-container):
div#hp-bar.hp-bar > div#hp-bar-fill.hp-bar-fill
div.hp-controls with 4 buttons: btn-hp-minus (-1), btn-hp-plus (+1), btn-hp-minus5 (-5), btn-hp-plus5 (+5)
</section>
Widget files:
_actions.left.md (weight: 10, title: "Actions"):
##### Actions
nav#actions-section.actions-section:
<button id="btn-save" class="btn btn-full">Save</button>
<button id="btn-reset-char" class="btn btn-full btn-danger">New Character</button>
_inventory.right.md (weight: 10, title: "Inventory"):
##### Inventory
div#inventory-section.inventory-section:
div.purse: money bag icon, "Bolts" label, #purse-amount "0", btn-bolt-minus/btn-bolt-plus
<hr>
<ul id="item-list" class="item-list"> (populated by JS)
div.inventory-add: <input id="input-item" type="text" placeholder="Add item..." maxlength="60"> + <button id="btn-add-item">+</button>
_dice.right.md (weight: 20, title: "Dice"):
##### Dice Roller
div#dice-section.dice-section:
div.dice-display: <span id="dice-result" class="dice-result">-</span>
div.dice-controls: <button id="btn-roll-1d6" class="btn btn-primary">1d6</button> + <button id="btn-roll-2d6" class="btn btn-primary">2d6</button>
div#dice-history.dice-history (populated by JS with last 10 roll entries)
_notes.right.md (weight: 30, title: "Notes"):
##### Notes
div#notes-section.notes-section:
<textarea id="notes-area" rows="6" placeholder="Adventure notes..."></textarea>
rules.modal.md (weight: 100, title: "Rules"):
## The Harp of Four Seasons
Markdown explaining the gamebook system:
Character Stats table (HP, Dexterity, Luck)
Talents section (7 talents with descriptions)
Inventory section (bolts currency + items)
Dice section (d6-based, skill/luck/damage checks)
Architecture (1 JS file):
default.js — IIFE, imports panic from /_lib/panic_v3.js + storage from /_lib/storage_v1.js (~738 lines):
TALENTS lookup map: instinct->Instinct, herbology->Herbology, stealth->Stealth, persuasion->Persuasion,
observation->Observation, nimble-fingers->Nimble Fingers, empathic->Empathic
STORAGE_KEY: 'harp-of-four-seasons'
Character data model:
hpMax (int, from creation 2d6*4), hpCurrent (int, tracks damage)
dexterity (int, starts at 7, adjustable), luck (int, rolled 1d6, adjustable)
talent (string key from 7 options)
bolts (int, currency, min 0)
items (string[], item names)
notes (string, freeform text)
diceHistory (string[], last 10 roll descriptions)
Persistence (localStorage via storage_v1.js):
Auto-save on: stat changes, item add/remove, bolt changes, note blur, talent selection
Load on init: if valid saved character (hpMax + talent present), skip creation overlay
Reset: native confirm() dialog, remove from localStorage, reload page
Creation flow:
Step 1: btn-roll-stats click -> rollDice(2)*4 for HP, rollDice(1) for Luck
Shows results, adds .stat-rolled class, disables button, reveals Step 2 (.hidden removal)
Step 2: talent-btn click -> highlights .selected, sets character.talent, reveals Step 3
Step 3: Shows summary text in #creation-summary, btn-start-adventure -> save + switchToSheet()
switchToSheet(): hides creation-overlay (.hidden), shows sheet-main (removes .hidden), renders all
HP bar system:
Width: hpCurrent/hpMax * 100, clamped 0-100%
Color classes based on percentage: >60% hp-high (green), >30% hp-mid (yellow), >10% hp-low (orange), <=10% hp-critical (red)
All 4 classes removed then appropriate one added
Dice roller:
rollD6(): Math.floor(Math.random()*6)+1 (not crypto)
rollDice(count): returns {total, rolls[]} (sum of count d6 rolls)
Display: result number with .dice-animate CSS class (removed + re-added via offsetHeight reflow trick)
History: prepended to character.diceHistory, trimmed to 10 entries
History display: div.dice-history-entry elements in #dice-history
Event binding (bindEvents() called once on init):
HP: btn-hp-minus/plus (+-1), btn-hp-minus5/plus5 (+-5), clamp 0-hpMax
Dex: btn-dex-minus/plus (+-1, min 0)
Luck: btn-luck-minus/plus (+-1, min 0)
Bolts: btn-bolt-minus/plus (+-1, min 0)
Items: btn-add-item + Enter key on input-item (add), x button per item (remove by index)
Dice: btn-roll-1d6, btn-roll-2d6
Save: btn-save (shows "Saved!" feedback for 1200ms)
Reset: btn-reset-char (confirm dialog, remove storage, reload)
Notes: notes-area blur -> auto-save
Rendering functions:
renderStats(): Updates all stat display elements
renderHPBar(): Updates bar width + color class
renderInventory(): Renders bolts count + item list (li with x button per item)
renderDiceHistory(): Renders last 10 rolls
renderNotes(): Sets textarea value
default.scss (~415 lines):
Character sheet layout, stats bar, HP bar with color transitions,
creation overlay (centered, step-by-step flow), talent grid (button grid),
stat-editable with +/- buttons, dice section (result display with animate class),
inventory section (purse + item list), notes section (textarea),
HP color classes: .hp-high (green), .hp-mid (yellow), .hp-low (orange), .hp-critical (red)
.stat-rolled animation for rolled values
.dice-animate animation for dice results
.btn styles: btn-primary, btn-danger, btn-success, btn-tiny, btn-small, btn-full
Responsive adjustments
Important implementation notes:
- NO canvas — pure HTML/CSS character sheet (unique among all pages)
- All HTML structure defined in index.md, not JS-generated
- Creation overlay and sheet main toggled via .hidden class
- Uses /_lib/storage_v1.js for localStorage abstraction (not direct localStorage)
- Uses /_lib/panic_v3.js for logging
- Stat values clamped (HP 0-max, dex/luck min 0, bolts min 0)
- Confirm dialog for character reset (native browser confirm())
- Save button shows "Saved!" feedback text for 1200ms then reverts
- Dice uses Math.random (not crypto.getRandomValues)
- No animation loop — event-driven updates only
Page entièrement générée et maintenue par IA, sans intervention humaine.