Commit Graph
6 Commits
Author SHA1 Message Date
FrankandClaude Sonnet 5 2ccbf4ca67 Add shared multiplayer gear puzzle (Chamber of Motion)
Players open a no-login link and see live cursors and dragged gear
pieces synced in real time, backed by a small Workerman WebSocket
relay (src/Command/PuzzleRelayCommand.php) run alongside symfony
serve - no Docker/Mercure hub needed. The board renders the wall
artwork with a spare-gears tray, and a "Reset puzzle" button (visible
only to logged-in users, verified server-side via a signed token) lets
the DM wipe the shared state for everyone.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-12 13:24:42 +02:00
FrankandClaude Sonnet 5 90345ecd38 Storyline: split the chapter page, dock the notes at the bottom
The chapter page now fills the viewport as two horizontal panes: the
chapter scrolls in the top ~2/3, the notes sit in a fixed dock in the
bottom ~1/3, always visible while you read. Drag the divider to change
the ratio, click the "Chapter notes" header to collapse the dock to a
bar; both the height and the collapsed state persist in localStorage.

- base.html.twig: add a {% block body_class %} hook on <body>.
- chapter.html.twig sets body class "storyline-chapter-page"; the split
  layout CSS is scoped to it and falls back to normal stacked flow under
  768px wide or 560px tall.
- app.js publishes the navbar height as --app-nav-h so the split can size
  itself to viewport-minus-navbar even when the navbar wraps.
- new chapter_notes Stimulus controller: drag-resize + collapse + persist.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-08 19:00:49 +02:00
FrankandClaude Sonnet 5 cbe4b0a0e1 Combat tracker: multiple named encounters
- Encounter entity; Combatant now belongs to an encounter (ON DELETE
  CASCADE). Migration adds encounter_id, rehoming any existing combatants.
- /tracker lists encounters (name, count, last updated) with a "New
  encounter" form; /tracker/{id} is the HP tracker for one encounter.
- Encounters can be renamed, have their combatants cleared, or be deleted.
- The Enemies list gains an encounter picker next to "Add to tracker"
  (existing encounter or "— New encounter —", which prompts for a name);
  an encounter's "Add enemies" link pre-selects it via ?encounter=.
- Routes for combatant HP/remove moved under /tracker/combatant/ to keep
  the numeric {id} for encounters.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-06 19:24:37 +02:00
FrankandClaude Sonnet 5 9854e6c034 Add combat HP tracker
- one running tracker (Combatant rows); no encounters to manage
- Enemies list gets a "Track" column (checkbox + count) and an
  "Add to tracker" button; picking N of an enemy makes "Goblin 1..N",
  numbering continues if some are already on the tracker
- /tracker: per-combatant current/max HP with an HP bar, Damage / Heal
  by amount, remove one, "Clear all". HP is clamped to [0, max];
  0 HP shows a "Down" badge. Stats are snapshotted from the Enemy on add.
- "Tracker" nav item; tracker_picker Stimulus controller; app.js gains a
  data-format="pick" cell renderer

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-06 19:16:12 +02:00
FrankandClaude Sonnet 5 ed22b81e97 Art: full-image thumbnails, detail page with copy-to-clipboard
- gallery thumbnails now object-fit: contain (whole image, letterboxed),
  and a card links to the new detail page instead of the raw file
- /art/{id} detail page: large uncropped image, "Open full size",
  "Delete" (moved here from the gallery), and "Copy image"
- clipboard Stimulus controller copies the image to the OS clipboard
  (converts non-PNG via canvas) for pasting into WhatsApp etc.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-06 16:53:49 +02:00
FrankandClaude Sonnet 5 9f6763040e Scaffold Symfony 8 app with Bootstrap/DataTables and Docker stack
- Symfony 8.1 webapp skeleton on PHP 8.5 (AssetMapper/importmap, no Node)
- Form-login gate: User entity, security.yaml, SecurityController,
  app:user:create command, initial migration (user + messenger_messages)
- Bootstrap 5 + DataTables layout (base/login/home templates); any
  table.datatable is auto-initialised
- trusted_proxies/headers wired for the shared Nginx Proxy Manager
- Docker (servers only): docker-compose.yml (php:8.5-fpm-alpine,
  nginx:1.30-alpine, mariadb:12.3; host ports 8085/3310; external
  docker_default network) + docker/{Dockerfile,php.ini,nginx,setup.sh,restart.sh}
- .env with CHANGEME placeholders (no secrets), .gitattributes enforces
  LF so the deploy scripts stay runnable on Linux

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-06 14:11:36 +02:00