feat: mood text per scene + Danish translation of Fabius Bile mission

- Mood text field on scenes shown as amber italic read-aloud block
  above scene description (gated by revealed flag for players)
- Scene editor includes Mood / Read-aloud textarea
- Scene editor moved full-width below two-column grid
- Mission "The Hunt for Fabius Bile" fully translated to Danish
  ("Jagten på Fabius Bile") with Danish names, descriptions,
  objectives, complications, checks and mood text for all 10 scenes

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-24 14:48:31 +02:00
parent 7873f450da
commit d6f2f0e5c7

View File

@@ -635,6 +635,7 @@ export default function MissionTab({ authedPlayer }) {
setSceneEdit({ setSceneEdit({
title: currentScene.title || currentScene.name || '', title: currentScene.title || currentScene.name || '',
type: currentScene.type || 'combat', type: currentScene.type || 'combat',
mood: currentScene.mood || '',
description: currentScene.description || currentScene.briefing || currentScene.summary || '', description: currentScene.description || currentScene.briefing || currentScene.summary || '',
checks: (Array.isArray(currentScene.checks) ? currentScene.checks : []).map(c => ({ ...c })), checks: (Array.isArray(currentScene.checks) ? currentScene.checks : []).map(c => ({ ...c })),
enemies: (Array.isArray(currentScene.enemies) ? currentScene.enemies : []).map(e => ({ ...e })), enemies: (Array.isArray(currentScene.enemies) ? currentScene.enemies : []).map(e => ({ ...e })),
@@ -651,6 +652,7 @@ export default function MissionTab({ authedPlayer }) {
title: sceneEdit.title.trim() || undefined, title: sceneEdit.title.trim() || undefined,
name: sceneEdit.title.trim() || undefined, name: sceneEdit.title.trim() || undefined,
type: sceneEdit.type, type: sceneEdit.type,
mood: sceneEdit.mood,
description: sceneEdit.description, description: sceneEdit.description,
briefing: sceneEdit.description, briefing: sceneEdit.description,
checks: sceneEdit.checks, checks: sceneEdit.checks,
@@ -876,6 +878,11 @@ export default function MissionTab({ authedPlayer }) {
{/* #2 — scene text gated by revealed flag */} {/* #2 — scene text gated by revealed flag */}
{isGM || sceneRevealed ? ( {isGM || sceneRevealed ? (
<> <>
{currentScene.mood && (
<div className="mb-3 rounded border border-amber-500/20 bg-amber-950/20 px-4 py-3">
<p className="text-sm italic leading-relaxed text-amber-100">{currentScene.mood}</p>
</div>
)}
<p className="whitespace-pre-wrap text-slate-200">{textForScene(currentScene) || 'No scene text stored.'}</p> <p className="whitespace-pre-wrap text-slate-200">{textForScene(currentScene) || 'No scene text stored.'}</p>
{sceneObjectives.length > 0 && ( {sceneObjectives.length > 0 && (
<div className="mt-4"> <div className="mt-4">
@@ -1675,15 +1682,26 @@ export default function MissionTab({ authedPlayer }) {
</select> </select>
</div> </div>
<div className="min-w-0"> <div className="min-w-0">
<label className="mb-1 block text-xs text-slate-400">Mood / Read-aloud <span className="text-slate-500 normal-case">(vist i kursiv til spillerne)</span></label>
<textarea
value={sceneEdit.mood || ''}
onChange={e => seField('mood', e.target.value)}
rows={2}
placeholder="Kortfattet stemningssætter…"
className="w-full rounded border border-amber-800/40 bg-amber-950/10 px-3 py-2 text-sm italic text-amber-100 placeholder-slate-600"
/>
</div>
</div>
<div>
<label className="mb-1 block text-xs text-slate-400">Scene Description / Briefing</label> <label className="mb-1 block text-xs text-slate-400">Scene Description / Briefing</label>
<textarea <textarea
value={sceneEdit.description} value={sceneEdit.description}
onChange={e => seField('description', e.target.value)} onChange={e => seField('description', e.target.value)}
rows={3} rows={4}
className="w-full min-w-0 rounded border border-slate-600 bg-slate-900 px-3 py-2 text-sm text-slate-100" className="w-full rounded border border-slate-600 bg-slate-900 px-3 py-2 text-sm text-slate-100"
/> />
</div> </div>
</div>
{/* Checks + Enemies — side by side on wide screens */} {/* Checks + Enemies — side by side on wide screens */}
<div className="grid min-w-0 gap-4 xl:grid-cols-2"> <div className="grid min-w-0 gap-4 xl:grid-cols-2">