/play arcade tweaks: Back in header (right), real word-search grid, packed bubbles
- Back moves into the header row, right-justified and level with "Play" (the in-game step-back row stays for select/play views). - Word Search motif is now a real 6×5 letter grid with BYTES "found" down the diagonal — reads as a search, not a single highlighted word. - Bubble Blaster motif is a packed bubble cluster + dashed aim line + loaded shooter (like the actual game), not an evenly-spaced grid of balls. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -41,6 +41,11 @@
|
||||
let wordStatus = $state({ 5: null, 6: null });
|
||||
let wsStatus = $state(null);
|
||||
|
||||
// Decorative Word-Search tile motif: a 6×5 letter grid with BYTES "found" down the diagonal.
|
||||
const WS_GRID = ['B', 'R', 'O', 'A', 'E', 'S', 'K', 'Y', 'I', 'M', 'U', 'H', 'G', 'E', 'T',
|
||||
'B', 'O', 'R', 'F', 'I', 'N', 'E', 'L', 'A', 'Z', 'O', 'S', 'T', 'S', 'Y'];
|
||||
const WS_HL = new Set([0, 7, 14, 21, 28]); // the diagonal B-Y-T-E-S cells
|
||||
|
||||
function readWord(v) {
|
||||
try {
|
||||
const s = JSON.parse(localStorage.getItem(`goodnews:word:${v}:${date}`) || 'null');
|
||||
@@ -274,18 +279,26 @@
|
||||
<HubBar active="games" />
|
||||
|
||||
<main class="container page" class:gameview={view === 'play'}>
|
||||
<!-- Back row under HubBar, consistent with the other hub pages. In a game it steps back
|
||||
(selection / hub); on the games landing it leaves Play (to where you came from). -->
|
||||
<button class="gameback" onclick={view === 'hub' ? leavePlay : back}>
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M15 18l-6-6 6-6" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
{view === 'hub' ? 'Back' : (view === 'play' ? 'Game Selection' : 'Play Hub')}
|
||||
</button>
|
||||
<!-- In a game, a step-back row (selection / hub). On the games landing, Back lives in the
|
||||
header row instead (right-justified, level with "Play"). -->
|
||||
{#if view !== 'hub'}
|
||||
<button class="gameback" onclick={back}>
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M15 18l-6-6 6-6" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
{view === 'play' ? 'Game Selection' : 'Play Hub'}
|
||||
</button>
|
||||
{/if}
|
||||
{#if view === 'hub'}
|
||||
<div class="arcade-head">
|
||||
<span class="eyelash" aria-hidden="true"></span>
|
||||
<h1 class="play-title">Play</h1>
|
||||
<span class="head-div" aria-hidden="true"></span>
|
||||
<p class="head-sub">A few little games, fresh every morning. Pick one and dive in.</p>
|
||||
<div class="head-left">
|
||||
<span class="eyelash" aria-hidden="true"></span>
|
||||
<h1 class="play-title">Play</h1>
|
||||
<span class="head-div" aria-hidden="true"></span>
|
||||
<p class="head-sub">A few little games, fresh every morning. Pick one and dive in.</p>
|
||||
</div>
|
||||
<button class="gameback hub-back" onclick={leavePlay}>
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M15 18l-6-6 6-6" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
Back
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="arcade">
|
||||
@@ -303,10 +316,7 @@
|
||||
|
||||
<button class="tile tile-ws" onclick={() => openGame('wordsearch')}>
|
||||
<span class="motif m-ws" aria-hidden="true">
|
||||
<span class="wrow">G A M E S</span>
|
||||
<span class="wrow hl">B Y T E S</span>
|
||||
<span class="wrow">W O R D S</span>
|
||||
<span class="wrow">S O L V E</span>
|
||||
{#each WS_GRID as ch, i}<span class="wc" class:hl={WS_HL.has(i)}>{ch}</span>{/each}
|
||||
</span>
|
||||
<span class="foot">
|
||||
<span class="t-name">Word Search</span>
|
||||
@@ -345,7 +355,20 @@
|
||||
<!-- teased, not built yet -->
|
||||
<div class="tile tile-bubble soon">
|
||||
<span class="motif m-bubble" aria-hidden="true">
|
||||
{#each ['a', 'b', 'c', 'd', 'a', 'd', 'c', 'b', 'a', 'c', 'b', 'd'] as k}<span class="bub b-{k}"></span>{/each}
|
||||
<span class="bub b-a" style="left:22px;top:16px"></span>
|
||||
<span class="bub b-b" style="left:62px;top:16px"></span>
|
||||
<span class="bub b-c" style="left:102px;top:16px"></span>
|
||||
<span class="bub b-d" style="left:142px;top:16px"></span>
|
||||
<span class="bub b-a" style="left:182px;top:16px"></span>
|
||||
<span class="bub b-d" style="left:42px;top:50px"></span>
|
||||
<span class="bub b-c" style="left:82px;top:50px"></span>
|
||||
<span class="bub b-b" style="left:122px;top:50px"></span>
|
||||
<span class="bub b-a" style="left:162px;top:50px"></span>
|
||||
<span class="bub b-b" style="left:62px;top:84px"></span>
|
||||
<span class="bub b-a" style="left:102px;top:84px"></span>
|
||||
<span class="bub b-d" style="left:142px;top:84px"></span>
|
||||
<span class="bub-aim"></span>
|
||||
<span class="bub-shooter b-c"></span>
|
||||
</span>
|
||||
<span class="ribbon">Coming soon</span>
|
||||
<span class="foot">
|
||||
@@ -472,7 +495,9 @@
|
||||
@font-face { font-family: 'Newsreader'; src: url('/fonts/newsreader-var.woff2') format('woff2'); font-weight: 400 600; font-style: normal; font-display: swap; }
|
||||
@font-face { font-family: 'Space Mono'; src: url('/fonts/space-mono-latin.woff2') format('woff2'); font-weight: 400; font-style: normal; font-display: swap; }
|
||||
|
||||
.arcade-head { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; margin: 2px 0 24px; }
|
||||
.arcade-head { display: flex; align-items: center; justify-content: space-between; gap: 16px; margin: 2px 0 24px; }
|
||||
.head-left { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; min-width: 0; }
|
||||
.hub-back { flex: none; align-self: flex-start; }
|
||||
.eyelash { width: 34px; height: 4px; border-radius: 2px; background: #f0a830; flex: none; }
|
||||
.play-title { font-family: 'Newsreader', Georgia, serif; font-weight: 600; font-size: clamp(2.4rem, 6vw, 3.1rem); color: #e5882a; letter-spacing: -0.015em; line-height: 0.9; margin: 0; }
|
||||
.head-div { width: 1px; height: 32px; background: rgba(120, 95, 50, 0.22); flex: none; }
|
||||
@@ -510,9 +535,9 @@
|
||||
.m-word { padding: 22px 22px 0; display: grid; grid-template-columns: repeat(5, 1fr); gap: 8px; align-content: start; }
|
||||
.wt { aspect-ratio: 1; box-sizing: border-box; border: 2.5px solid rgba(255, 255, 255, 0.45); border-radius: 8px; display: flex; align-items: center; justify-content: center; font-weight: 800; font-size: clamp(15px, 3.4vw, 22px); color: #cf7d1c; }
|
||||
.wt.on { background: #fff; border-color: #fff; }
|
||||
.m-ws { padding: 24px 22px 0; display: flex; flex-direction: column; gap: 6px; font-weight: 700; font-size: 15px; letter-spacing: 0.26em; }
|
||||
.wrow { display: flex; justify-content: center; color: rgba(255, 255, 255, 0.42); padding: 4px 0; }
|
||||
.wrow.hl { background: rgba(255, 255, 255, 0.93); color: #2f7fb0; border-radius: 9px; box-shadow: 0 2px 9px rgba(0, 0, 0, 0.12); }
|
||||
.m-ws { padding: 20px; display: grid; grid-template-columns: repeat(6, 1fr); gap: 5px; align-content: start; }
|
||||
.wc { aspect-ratio: 1; display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: clamp(11px, 2.6vw, 15px); color: rgba(255, 255, 255, 0.42); }
|
||||
.wc.hl { background: rgba(255, 255, 255, 0.93); color: #2f7fb0; border-radius: 7px; box-shadow: 0 2px 7px rgba(0, 0, 0, 0.12); }
|
||||
.m-bloom .petal { position: absolute; width: 42px; height: 42px; border-radius: 50%; background: #fff; color: #4f8a58; display: flex; align-items: center; justify-content: center; font-weight: 800; font-size: 18px; box-shadow: 0 3px 7px rgba(0, 0, 0, 0.1); }
|
||||
.m-bloom .pc { width: 50px; height: 50px; background: #3e7a47; color: #fff; font-size: 22px; box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2); z-index: 1; left: 50%; top: 40%; transform: translate(-50%, -50%); }
|
||||
.m-bloom .p1 { left: 50%; top: 40%; transform: translate(-50%, -50%) translate(0, -56px); }
|
||||
@@ -525,8 +550,11 @@
|
||||
.mm { aspect-ratio: 1; border-radius: 9px; background: rgba(255, 255, 255, 0.2); display: flex; align-items: center; justify-content: center; }
|
||||
.mm.flip { background: #fff; }
|
||||
.mm .dot { width: 17px; height: 17px; border-radius: 50%; background: #c0688c; }
|
||||
.m-bubble { padding: 20px; display: flex; flex-wrap: wrap; gap: 8px; align-content: flex-start; }
|
||||
.bub { width: 38px; height: 38px; border-radius: 50%; box-shadow: 0 3px 8px rgba(0, 0, 0, 0.14); }
|
||||
/* bubble shooter: a packed cluster up top, a dashed aim line, a loaded shooter below */
|
||||
.bub { position: absolute; width: 40px; height: 40px; border-radius: 50%; box-shadow: 0 3px 8px rgba(0, 0, 0, 0.16); }
|
||||
.bub-aim { position: absolute; left: 50%; top: 122px; bottom: 72px; width: 2px; transform: translateX(-50%);
|
||||
background: repeating-linear-gradient(to bottom, rgba(255, 255, 255, 0.6) 0 5px, transparent 5px 11px); }
|
||||
.bub-shooter { position: absolute; left: 50%; bottom: 50px; transform: translateX(-50%); width: 42px; height: 42px; border-radius: 50%; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.24); }
|
||||
.b-a { background: radial-gradient(circle at 32% 28%, #fff, #f0a830 62%); }
|
||||
.b-b { background: radial-gradient(circle at 32% 28%, #fff, #e8607f 62%); }
|
||||
.b-c { background: radial-gradient(circle at 32% 28%, #fff, #4fb0e0 62%); }
|
||||
|
||||
Reference in New Issue
Block a user