fix(mana/web/who): chat bubble Tailwind classes — v3 → v4 syntax

The NPC reply rendered as a fully-white bubble with invisible
white-on-white text. Three bugs in the message-bubble markup,
all from copy-pasting Tailwind v3 patterns into a v4 codebase:

  1. text-white-90 is not a valid class name in any Tailwind
     version. The opacity goes after a slash: text-white/90.
  2. bg-white + bg-opacity-5 is the v3 pattern. v4 dropped
     bg-opacity-* and folded opacity into the color via
     bg-white/5. Without it the bubble was solid white.
  3. Combining 1 and 2: solid white background + invalid text
     color → text inherited the parent's white → invisible.

Plus a Svelte-specific gotcha: class:bg-emerald-500/10={cond}
doesn't parse because Svelte's class: directive treats `/` as a
token. Use a class={...} string interpolation instead, which is
how the result banner now picks between the won and surrendered
backgrounds.

Also: rewrote the message bubble loop with an explicit
{#if msg.sender === 'user'}/{:else} branch instead of stacking
class:* directives. Less clever, more legible, and dodges the
class: + slash issue at the source.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Till JS 2026-04-09 16:56:34 +02:00
parent 56130cd3f7
commit 63e1ef8233

View file

@ -163,11 +163,9 @@
<!-- Result banner (post-game only) -->
{#if game && game.status !== 'playing'}
<div
class="border-b border-white/5 px-4 py-3"
class:bg-emerald-500={game.status === 'won'}
class:bg-opacity-10={game.status === 'won'}
class:bg-amber-500={game.status === 'surrendered'}
class:bg-amber-500-10={game.status === 'surrendered'}
class="border-b border-white/5 px-4 py-3 {game.status === 'won'
? 'bg-emerald-500/10'
: 'bg-amber-500/10'}"
>
{#if game.status === 'won'}
<p class="text-sm font-medium text-emerald-300">
@ -195,17 +193,19 @@
<div class="mx-auto flex max-w-2xl flex-col gap-3">
{#each messages as msg (msg.id)}
<div class:flex-row-reverse={msg.sender === 'user'} class="flex gap-2">
<div
class="max-w-[80%] rounded-lg px-3 py-2 text-sm leading-relaxed"
class:bg-purple-500={msg.sender === 'user'}
class:bg-opacity-20={msg.sender === 'user'}
class:text-white={msg.sender === 'user'}
class:bg-white={msg.sender === 'npc'}
class:bg-opacity-5={msg.sender === 'npc'}
class:text-white-90={msg.sender === 'npc'}
>
{msg.content}
</div>
{#if msg.sender === 'user'}
<div
class="max-w-[80%] whitespace-pre-wrap rounded-lg bg-purple-500/30 px-3 py-2 text-sm leading-relaxed text-white"
>
{msg.content}
</div>
{:else}
<div
class="max-w-[80%] whitespace-pre-wrap rounded-lg bg-white/5 px-3 py-2 text-sm leading-relaxed text-white/90"
>
{msg.content}
</div>
{/if}
</div>
{/each}
</div>