feat(master): circular token style with pink/green ring per value range

Replaces the orange/red filled-square cells on the master tracking
board with a circular token treatment inspired by the Hội chợ "Các
số đã ra" panel. Each numbered cell now renders a centered circle
with a colored ring — pink for 1–49, green for 50–90 — over a
cream-yellow fill when the number has been called, or dimmed/empty
when it has not. The most recent draw keeps its red accent via a
ring-offset highlight + slight scale, so the host can still find
"vừa xổ" at a glance. Draw-order superscript stays at the cell's
top-right corner, now in muted slate (visible against both the
cream-filled and dim-empty token states).
This commit is contained in:
2026-04-27 00:17:21 +07:00
parent 5665663533
commit d54ace7f56
3 changed files with 33 additions and 17 deletions
+1 -1
View File
@@ -7,7 +7,7 @@
|------|---------|
| `src/routes/+layout.svelte` | Root HTML layout. Sets Vietnamese lang, imports Geist font, applies global flex layout. |
| `src/routes/+page.svelte` | Player page (`/`). Instructions toggle, PlayerBoard component, indigo gradient branding. |
| `src/routes/master/+page.svelte` | Host page (`/master`). Controls (new game, draw number), 11×9 last-digit-aligned master board with draw-order overlay, host's player card. |
| `src/routes/master/+page.svelte` | Host page (`/master`). Controls (new game, draw number), 11×9 last-digit-aligned master board with circular tokens (pink ring for 149, green for 5090; cream fill when called, dim when uncalled; red ring + scale on last-called) and draw-order overlay, host's player card. |
### Shared Components
| File | Purpose |
+3 -1
View File
@@ -26,7 +26,9 @@ That format is intentionally out of scope.
may keep playing further rows (game does not end).
- **Waiting state**: when a row needs only 1 number, app announces **"Chờ N"**.
- **Host (quản trò)** draws numbers from a shuffled 190 deck, tracks them on
a master board, and may also play their own card.
a master board with circular tokens (pink ring for 149, green for 5090,
cream fill on called, dim on uncalled, red ring + scale on the most
recent draw), and may also play their own card.
- **Settings**: gear icon in headers opens a modal with a color picker for
the empty/blank cell color (default brown matches physical card).
Persisted to `loto_settings`.
+29 -15
View File
@@ -213,27 +213,41 @@
{@const order = hasNumber ? callOrder.get(num) : undefined}
{@const isCalled = order !== undefined}
{@const isLast = isCalled && num === lastCalled}
{@const isLow = hasNumber && num <= 49}
<div
style:background-color={hasNumber ? null : "var(--empty-cell-bg)"}
class="relative flex items-center justify-center
aspect-square text-sm sm:text-base font-bold
aspect-square
border-r border-b border-slate-200/80 dark:border-slate-700/60
transition-colors select-none
{hasNumber
? isCalled
? isLast
? 'bg-red-500 dark:bg-red-600 text-white ring-2 ring-red-300 dark:ring-red-400 ring-inset z-10'
: 'bg-orange-500 dark:bg-orange-600 text-white'
: 'bg-white dark:bg-slate-800 text-slate-700 dark:text-slate-200'
: ''}"
bg-white dark:bg-slate-800 select-none
{isLast ? 'z-10' : ''}"
>
{hasNumber ? num : ""}
{#if isCalled}
<span
class="absolute top-0.5 right-0.5 text-[9px] sm:text-[10px] font-semibold leading-none text-white/80 tabular-nums"
{#if hasNumber}
<!-- Token: cream/beige inner, ring colored by value (pink ≤49, green ≥50). -->
<div
class="flex items-center justify-center
w-[82%] h-[82%] rounded-full
text-sm sm:text-base font-bold tabular-nums
border-[3px] transition-all
{isLow
? 'border-pink-500 dark:border-pink-400'
: 'border-emerald-500 dark:border-emerald-400'}
{isCalled
? 'bg-amber-50 dark:bg-amber-100 text-rose-700 dark:text-rose-800'
: 'bg-slate-50/60 dark:bg-slate-700/40 text-slate-400 dark:text-slate-500 opacity-60'}
{isLast
? 'ring-2 ring-red-500 dark:ring-red-400 ring-offset-1 ring-offset-white dark:ring-offset-slate-800 scale-110 shadow-md'
: ''}"
>
{order}
</span>
{num}
</div>
{#if isCalled}
<span
class="absolute top-0.5 right-0.5 text-[9px] sm:text-[10px] font-semibold leading-none text-slate-500 dark:text-slate-400 tabular-nums"
>
{order}
</span>
{/if}
{/if}
</div>
{/each}