Build a complete, single-file, mobile-first HTML browser gam...
Prompt
Build a complete, single-file, mobile-first HTML browser game called LexiJong (feel free to suggest a better name). It is a hybrid of Mahjong Solitaire's tile-layering/freedom mechanic and a word-search game. There are NO image assets available β every visual element (tiles, icons, backgrounds, effects) must be built with pure CSS/SVG/HTML. Output as ONE self-contained .html file (inline <style> and <script>, no external files except optionally a CDN font). Core Concept Instead of matching two identical tiles like classic Mahjong Solitaire, tiles show single letters. Players clear the board by tapping currently-exposed ("free") letter tiles in any order to spell real English words. When a valid word is formed, those tiles vanish, potentially freeing up tiles beneath/beside them. The goal is to fully clear the board before running out of moves. Core Mechanics 1. Board & Layering Generate a randomized multi-layer tile stack, visually similar to classic Mahjong Solitaire layouts (think "pyramid" or "turtle" shapes): a wide base layer of tiles arranged in a loose grid with slight overlap, and progressively smaller layers stacked on top, offset so tiles nestle into the gaps of the layer below. Each tile has a grid position (x, y) and a layer/height (z). Only place a tile on layer z+1 if both tiles it would rest on (at layer z) exist β this keeps the stack physically plausible. Total tile count: roughly 60β100 tiles depending on difficulty setting. 2. Freeness Rule (identical to real Mahjong Solitaire) A tile is selectable ("free") only if: No tile is stacked directly on top of it (nothing at the same x,y at a higher z), AND At least one of its left or right neighbor positions (same z, same y, xΒ±1) is empty. Free tiles should be visually distinct (slightly brighter, subtle glow/pulse) from locked tiles (slightly dimmed/greyed). 3. Word Selection Player taps free tiles one at a time, in any order they like (not restricted to adjacency). Each tap adds that letter to a "current word tray" at the top of the screen, in the order tapped, and visually lifts/removes that tile from the board temporarily (grey outline placeholder left behind). Tapping a tile already in the tray again removes it and returns it to the board (undo single letter). A "Clear" button empties the tray and returns all selected tiles to the board with no penalty. Minimum valid word length: 3 letters. As soon as the letters in the tray exactly match a valid dictionary word (checked automatically on every tap, any order of the tapped letters counts β check all permutations or just check the tray content as a multiset against the dictionary), auto-confirm: tiles play a satisfying clear animation, score increases, and the tray empties. If the player taps a tile and the tray still isn't a valid word, nothing bad happens β they can keep adding, remove tiles, or clear. 4. Word Validation Embed a compact curated word list directly in the JS as a Set of ~4,000β6,000 common English words, 3β7 letters long (skip obscure/offensive words). This must work fully offline with no API calls, since the game will be a static deployed file. Validation logic: given the current tray letters, check if any permutation of them forms a dictionary word. (With max ~7 letters in a tray this is computationally trivial.) 5. Letter Distribution & Difficulty Assign letters to tiles using a Scrabble-like weighted frequency table so common letters (E, A, R, T, O, I, N, S) appear far more often than rare ones (Q, Z, X, J), keeping the board playable. Bias the generator so that among tiles likely to become free early, there's a reasonable density of vowels β avoids "impossible" dead-board states as much as possible without a full solver. 6. Tools (bottom toolbar, limited uses shown as a badge counter, like the reference screenshot) Shuffle: re-randomizes the letters on all currently remaining tiles (positions/layers stay the same, only letters change) β use when no word seems possible. Limited uses, "+" badge to imply more can be earned/unlocked later. Hint: scans all currently free tiles and highlights a valid word combination if one exists (glowing outline on the relevant tiles). Limited uses with a numeric badge. Undo: reverts the last cleared word, restoring those tiles to the board. Limited uses with a numeric badge. 7. Scoring Base points per word = word length Γ 10. Letter rarity bonus: use Scrabble tile values (E=1, Q/Z=10, etc.) summed and added to score. Combo multiplier: consecutive words cleared without using Clear/Undo increases a streak multiplier (1x, 1.2x, 1.5x, 2x...). Display a top score readout styled like an "IQ meter" (playful nod to the vocabulary theme) that fills/glows as score climbs. 8. Win/Loss Win: board fully cleared. Stuck state: if no free tiles can form any word and the player has 0 shuffles left, show a "no moves left" state with an option to restart or shuffle (if available). Visual Design System (critical β no image assets exist, describe everything for CSS/SVG generation) Overall mood: warm, cozy, jade-and-lantern East-Asian aesthetic, but tiles show letters instead of Chinese characters/icons. Background: deep emerald/jade green ( #0f3d30 to #0a2b23 radial gradient, darker at edges), subtle soft-focus organic texture (like brushed silk or blurred leaves) at low opacity β can be faked with a large soft SVG blob pattern or CSS noise overlay. Add a gentle vignette darkening the corners. Tile face: rounded rectangle (border-radius ~12β14px), warm ivory/cream fill ( #f7efd9), 2β3px deep maroon/red border ( #a13a3a), soft drop shadow beneath. Letter glyph: bold, rounded sans-serif (e.g. "Nunito", "Baloo 2", or similar Google Font), dark navy color ( #22314f), centered, large enough to read clearly on mobile (~28β34px tile size). Layering depth cue: each tile stacked on a higher layer shows a visible "shadow tile" edge peeking out from behind/below (offset ~4β6px down-right) in a darker maroon ( #7a2626), exactly mimicking how physical mahjong tiles look stacked. Higher layers can also get a very subtle extra drop-shadow to read as "closer to camera." Free vs. locked tiles: free tiles get a subtle warm glow/pulse (soft gold outline, #e0b84b) and full-opacity color; locked (covered/blocked) tiles are dimmed to ~65% opacity with a slight desaturation, and blocked tiles should NOT have the glow. Selected/tray tiles: when tapped, tile lifts with a small scale-up + shadow animation and slides toward the tray. Word tray (top bar): a rounded rectangle with a glowing lime-green border ( #7ed957) divided into individual letter slots (like the reference screenshot's segmented bar), dark semi-transparent fill inside, small sparkle particle accents. Slots fill left to right as letters are tapped. Top bar buttons: circular wood-tone buttons ( #8a5a2b gradient with darker brown border) top-left (back arrow) and top-right (menu/pause), matching the warm lantern-festival palette. Bottom toolbar: three circular wood-tone buttons (shuffle icon = looping arrows, hint icon = lightbulb with a small lightning bolt, undo icon = curved back arrow), each with a small red circular badge in the top-right corner showing remaining uses. Clear animation: on a successful word, tiles briefly scale up, glow gold, then shrink and fade out with a small particle/sparkle burst; play a satisfying "pop" easing curve. Invalid/stuck feedback: gentle shake animation on the tray if the player tries to submit manually and it's not a real word (if you add a manual submit button as a fallback to auto-detect). Fonts: playful rounded font for numbers/UI (score, badges), clean bold font for tile letters (legibility > decoration). Layout: fully responsive, mobile-first (design for ~390β430px width portrait first, then scale up), safe-area padding for notches, board should auto-scale to fit viewport height without scrolling. Tech Requirements Single HTML file, vanilla JS + CSS (no build step, no frameworks required β keep it dependency-light so it deploys instantly to Vercel as a static file). Embedded word list as a JS array/Set literal (no fetch calls). All visuals via CSS/SVG β zero external image files. Touch-friendly tap targets (min ~44px). Include a restart/new-game button and a simple "how to play" modal shown on first load. Stretch Goals (optional, note as "if time allows") Daily challenge board with a shareable score. Difficulty select (Easy/Medium/Hard = fewer/more layers, stricter letter distribution). Local-storage best score / streak tracking. Theme toggle (jade/lantern default vs. a second palette)
A system prompt was added to support web rendering