style(player): wrap card in cross-hatch frame on all 4 sides

The BAMBOORAFT physical sheet has the ✚✚✚ blue border running
around the entire card edge, not just between mini-cards. Adds
matching top/bottom/left/right frames using the existing
.section-divider plus a new .section-divider-vertical. Drops the
thin slate outer border (replaced by the hatch frame) and the
per-cell border-r/border-b lines (the white-on-blue contrast already
delineates cells, matching the flat physical-paper look). Outer
wrapper rounded-md instead of rounded-2xl to feel more like
a printed card edge.
This commit is contained in:
tiennm99 committed 2026-04-27 00:41:18 +07:00
1 parent 5ba5ceddee
commit 09bb48c275
2 files changed
+65 -43

No files matched your search

+14 -3
View File
@@ -33,8 +33,8 @@ body {
gap: 0;
}
/* Decorative cross-hatch divider between mini-cards on the player sheet,
echoing the ✚✚✚ blue borders on a Tân Tân BAMBOORAFT card. */
/* Decorative cross-hatch borders that frame and segment the player
sheet, echoing the ✚✚✚ blue borders on a Tân Tân BAMBOORAFT card. */
.section-divider {
height: 8px;
background-image: repeating-linear-gradient(
@@ -45,8 +45,19 @@ body {
);
background-color: rgb(227 242 253 / 0.7);
}
.section-divider-vertical {
width: 8px;
background-image: repeating-linear-gradient(
0deg,
transparent 0 6px,
#1e88e5 6px 8px,
transparent 8px 14px
);
background-color: rgb(227 242 253 / 0.7);
}
@media (prefers-color-scheme: dark) {
.section-divider {
.section-divider,
.section-divider-vertical {
background-color: rgb(13 71 161 / 0.4);
}
}
+51 -40
View File
@@ -162,50 +162,61 @@
<div class="relative">
<div
aria-label="Bảng lô tô"
class="rounded-2xl overflow-hidden shadow-xl shadow-slate-200/50 dark:shadow-black/30 border border-slate-200 dark:border-slate-700"
class="rounded-md overflow-hidden shadow-xl shadow-slate-200/50 dark:shadow-black/30"
>
{#each SECTIONS as startRow, sectionIdx (sectionIdx)}
{#if sectionIdx > 0}
<div class="section-divider" aria-hidden="true"></div>
{/if}
<div class="section-label">{SECTION_LABELS[sectionIdx]}</div>
<div class="loto-grid">
{#each grid.slice(startRow, startRow + 3).flat() as num, idx (idx)}
{@const row = startRow + Math.floor(idx / 9)}
{@const col = idx % 9}
{@const hasNumber = num > 0}
{@const isCrossed = hasNumber && !!crossed[row]?.[col]}
{@const rowComplete = hasNumber && rowCompleteness[row]}
{#if !hasNumber}
<div
aria-hidden="true"
class="relative aspect-[3/5] border-r border-b border-slate-300/60 dark:border-slate-700/60"
style:background-color="var(--empty-cell-bg)"
></div>
{:else}
<button
type="button"
aria-label="Số {num}{isCrossed ? ', đã đánh dấu' : ''}"
aria-pressed={isCrossed}
onclick={() => handleCellClick(row, col)}
class="tan-tan-num relative flex items-center justify-center
aspect-[3/5] text-2xl sm:text-3xl
border-r border-b border-slate-300/60 dark:border-slate-700/60
transition-all select-none cursor-pointer
focus:outline-none focus:ring-2 focus:ring-inset focus:ring-indigo-400
{isCrossed
? rowComplete
? 'cell-crossed bg-emerald-100 dark:bg-emerald-900/40 text-emerald-600 dark:text-emerald-400'
: 'cell-crossed bg-red-50 dark:bg-red-950/30 text-red-500 dark:text-red-500'
: 'bg-white dark:bg-slate-800 text-black dark:text-slate-100 hover:bg-indigo-50 dark:hover:bg-indigo-950/30 hover:text-indigo-600 dark:hover:text-indigo-400'}"
>
{num}
</button>
<!-- Top frame -->
<div class="section-divider" aria-hidden="true"></div>
<div class="flex">
<!-- Left frame -->
<div class="section-divider-vertical" aria-hidden="true"></div>
<div class="flex-1">
{#each SECTIONS as startRow, sectionIdx (sectionIdx)}
{#if sectionIdx > 0}
<div class="section-divider" aria-hidden="true"></div>
{/if}
<div class="section-label">{SECTION_LABELS[sectionIdx]}</div>
<div class="loto-grid">
{#each grid.slice(startRow, startRow + 3).flat() as num, idx (idx)}
{@const row = startRow + Math.floor(idx / 9)}
{@const col = idx % 9}
{@const hasNumber = num > 0}
{@const isCrossed = hasNumber && !!crossed[row]?.[col]}
{@const rowComplete = hasNumber && rowCompleteness[row]}
{#if !hasNumber}
<div
aria-hidden="true"
class="relative aspect-[3/5]"
style:background-color="var(--empty-cell-bg)"
></div>
{:else}
<button
type="button"
aria-label="Số {num}{isCrossed ? ', đã đánh dấu' : ''}"
aria-pressed={isCrossed}
onclick={() => handleCellClick(row, col)}
class="tan-tan-num relative flex items-center justify-center
aspect-[3/5] text-2xl sm:text-3xl
transition-all select-none cursor-pointer
focus:outline-none focus:ring-2 focus:ring-inset focus:ring-indigo-400
{isCrossed
? rowComplete
? 'cell-crossed bg-emerald-100 dark:bg-emerald-900/40 text-emerald-600 dark:text-emerald-400'
: 'cell-crossed bg-red-50 dark:bg-red-950/30 text-red-500 dark:text-red-500'
: 'bg-white dark:bg-slate-800 text-black dark:text-slate-100 hover:bg-indigo-50 dark:hover:bg-indigo-950/30 hover:text-indigo-600 dark:hover:text-indigo-400'}"
>
{num}
</button>
{/if}
{/each}
</div>
{/each}
</div>
{/each}
<!-- Right frame -->
<div class="section-divider-vertical" aria-hidden="true"></div>
</div>
<!-- Bottom frame -->
<div class="section-divider" aria-hidden="true"></div>
</div>
{#if toast}