diff --git a/src/app/RootLayout.tsx b/src/app/RootLayout.tsx index 4a11c88..a963477 100644 --- a/src/app/RootLayout.tsx +++ b/src/app/RootLayout.tsx @@ -60,7 +60,7 @@ function CampaignSwitcher() { return ( update({ name: e.target.value })} @@ -149,13 +149,13 @@ export function CharacterSheet({ character }: { character: Character }) { -
+
{[ { icon: Shield, value: ac, label: 'Armor' }, { icon: Gauge, value: formatModifier(initiative), label: 'Init' }, { icon: Footprints, value: c.speed, label: 'Speed' }, ].map(({ icon: Ic, value, label }) => ( -
+
{value} {label} diff --git a/src/features/characters/builder/CreationWizard.tsx b/src/features/characters/builder/CreationWizard.tsx index 4b8749f..9f9dc8d 100644 --- a/src/features/characters/builder/CreationWizard.tsx +++ b/src/features/characters/builder/CreationWizard.tsx @@ -293,7 +293,7 @@ export function CreationWizard({ campaign, onClose }: { campaign: Campaign; onCl
-
Game system
+
Game system
{SYSTEM_OPTIONS.map((opt) => (
-
New here? Start from a ready-made hero
+
New here? Start from a ready-made hero
{(TEMPLATES[system] ?? []).map((t) => ( @@ -314,7 +314,7 @@ export function CreationWizard({ campaign, onClose }: { campaign: Campaign; onCl
-
Choose a class
+
Choose a class
{classes.map((c) => ( + {r.current} /{r.max} - + patch(r.id, { max: v, current: Math.min(v, r.current) })} aria-label="Max" /> setNameDraft(e.target.value)} onBlur={commitName} onKeyDown={(e) => { if (e.key === 'Enter') commitName(); }} placeholder="What should we call you?" aria-label="Your display name" className="mt-1" />
)} {inSession && (
-

Who's here ({roster.length})

+

Who's here ({roster.length})

    {roster.map((p) => (
  • diff --git a/src/features/player/MyCharacterPanel.tsx b/src/features/player/MyCharacterPanel.tsx index 7be6ed2..d19fe55 100644 --- a/src/features/player/MyCharacterPanel.tsx +++ b/src/features/player/MyCharacterPanel.tsx @@ -9,6 +9,7 @@ import { useRollStore } from '@/stores/rollStore'; import { sendPlayerRoll } from '@/lib/sync/wsSync'; import { Button } from '@/components/ui/Button'; import { Input } from '@/components/ui/Input'; +import { Meter } from '@/components/ui/Codex'; import { cn } from '@/lib/cn'; const clamp = (n: number, lo: number, hi: number) => Math.max(lo, Math.min(hi, n)); @@ -22,6 +23,7 @@ export function MyCharacterPanel({ character: c, onPatch }: { character: Charact const hpPct = c.hp.max > 0 ? clamp((c.hp.current / c.hp.max) * 100, 0, 100) : 0; const slots = c.spellcasting.slots.filter((s) => s.max > 0); + const [castMsg, setCastMsg] = useState(null); return (
    @@ -45,8 +47,8 @@ export function MyCharacterPanel({ character: c, onPatch }: { character: Charact Hit points {c.hp.current}/{c.hp.max}{c.hp.temp > 0 ? ` (+${c.hp.temp})` : ''}
-
-
50 ? 'bg-success' : hpPct > 0 ? 'bg-warning' : 'bg-danger')} style={{ width: `${hpPct}%` }} /> +
+ 50 ? 'var(--app-verdigris)' : hpPct > 0 ? 'var(--app-accent)' : 'var(--app-danger)'} height={10} />
@@ -116,12 +118,13 @@ export function MyCharacterPanel({ character: c, onPatch }: { character: Charact {s.name} {s.concentration && } -
))}
+ {castMsg &&

{castMsg}

}
)} diff --git a/src/features/settings/AssistantSettings.tsx b/src/features/settings/AssistantSettings.tsx index c240d42..fac507b 100644 --- a/src/features/settings/AssistantSettings.tsx +++ b/src/features/settings/AssistantSettings.tsx @@ -40,7 +40,7 @@ export function AssistantSettings() { return (
-

Assistant (AI)

+

Assistant (AI)

Optional. Bring your own provider and key to enable AI-grounded tips (encounter balancing, level-up routes). The assistant always works without this — it falls back to deterministic diff --git a/src/features/settings/CloudCampaigns.tsx b/src/features/settings/CloudCampaigns.tsx index 037b332..08e594d 100644 --- a/src/features/settings/CloudCampaigns.tsx +++ b/src/features/settings/CloudCampaigns.tsx @@ -38,7 +38,7 @@ export function CloudCampaigns() { if (!signedIn) { return (

-

Shared campaigns (cloud)

+

Shared campaigns (cloud)

Sign in above to publish a campaign for your players, or join one and publish your character — it stays yours and syncs when you edit it.

); @@ -48,7 +48,7 @@ export function CloudCampaigns() { return (
-

Shared campaigns (cloud)

+

Shared campaigns (cloud)

{list.length > 0 && (
    @@ -126,7 +126,7 @@ export function CloudCampaigns() { {usage?.admin && (
    -

    Admin · users & storage

    +

    Admin · users & storage

    diff --git a/src/features/world/HomebrewPage.tsx b/src/features/world/HomebrewPage.tsx index 7c016c4..48d4c60 100644 --- a/src/features/world/HomebrewPage.tsx +++ b/src/features/world/HomebrewPage.tsx @@ -79,7 +79,7 @@ function HomebrewView({ campaign }: { campaign: Campaign }) { if (list.length === 0) return null; return (
    -

    {HOMEBREW_KIND_LABEL[k]}s

    +

    {HOMEBREW_KIND_LABEL[k]}s

    {list.map((hb) => )}
    diff --git a/src/features/world/NotesPage.tsx b/src/features/world/NotesPage.tsx index 20f167d..e0f73b5 100644 --- a/src/features/world/NotesPage.tsx +++ b/src/features/world/NotesPage.tsx @@ -151,7 +151,7 @@ function NoteEditor({ {/* Rendered preview with clickable links */}
    -

    Preview

    +

    Preview

    {splitWikiLinks(body).map((part, i) => part.link ? ( @@ -172,7 +172,7 @@ function NoteEditor({ {backlinks.length > 0 && (

    -

    Linked from

    +

    Linked from

    {backlinks.map((n) => (
    diff --git a/src/lib/mechanics/conditionEffects.ts b/src/lib/mechanics/conditionEffects.ts index a06e39d..822f638 100644 --- a/src/lib/mechanics/conditionEffects.ts +++ b/src/lib/mechanics/conditionEffects.ts @@ -49,7 +49,10 @@ export const CONDITION_EFFECTS_5E: Record = { export const CONDITION_EFFECTS_PF2E: Record = { blinded: { attacksAgainst: 'advantage' }, clumsy: { statusPenalty: true }, + drained: { statusPenalty: true }, + dazzled: { attacksAgainst: 'advantage' }, enfeebled: { statusPenalty: true }, + fatigued: { statusPenalty: true }, frightened: { statusPenalty: true }, grabbed: { speedZero: true, attacksAgainst: 'advantage' }, immobilized: { speedZero: true },
    UserUsedQuota (GB, 0=default)