{"project":{"id":"uaUVkbu","userId":"davidyarham@gmail.com","username":null,"userPicture":null,"name":"Responsive Wordle Daily Clone","thumbnail":"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","visible":true,"contributors":"","githubRepo":null,"forkedFrom":null,"tags":"","files":{"folder":"","files":[{"name":"index.html","content":"<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  <title>Untitled</title>\n  <link rel=\"stylesheet\" href=\"style.css\">\n<script src=\"https://unpkg.com/lucide@latest\"></script>\n</head>\n<body>\n<div class=\"app-shell\">\n\t<header class=\"topbar\">\n\t\t<button class=\"icon-btn\" id=\"helpBtn\" aria-label=\"How to play\">\n      <i data-lucide=\"circle-help\"></i>\n    </button>\n\t\t<h1 class=\"title\">Wordle</h1>\n\t\t<div class=\"topbar-actions\">\n\t\t\t<button class=\"icon-btn\" id=\"statsBtn\" aria-label=\"Game status\">\n        <i data-lucide=\"bar-chart-3\"></i>\n      </button>\n\t\t\t<button class=\"icon-btn\" id=\"resetBtn\" aria-label=\"Reset game\">\n        <i data-lucide=\"rotate-ccw\"></i>\n      </button>\n\t\t</div>\n\t</header>\n\n\t<main class=\"game-wrap\">\n\t\t<section class=\"status-row\">\n\t\t\t<div class=\"status-pill\" id=\"puzzleLabel\">Daily Puzzle</div>\n\t\t\t<div class=\"status-pill\" id=\"dateLabel\"></div>\n\t\t</section>\n\n\t\t<section class=\"board-wrap\">\n\t\t\t<div id=\"board\" class=\"board\" aria-label=\"Word grid\"></div>\n\t\t</section>\n\n\t\t<section class=\"message-area\">\n\t\t\t<div id=\"toast\" class=\"toast\" aria-live=\"polite\"></div>\n\t\t</section>\n\n\t\t<section class=\"keyboard\" id=\"keyboard\" aria-label=\"On-screen keyboard\"></section>\n\t</main>\n</div>\n\n<div class=\"modal hidden\" id=\"helpModal\" aria-hidden=\"true\">\n\t<div class=\"modal-card\">\n\t\t<div class=\"modal-header\">\n\t\t\t<h2>How to play</h2>\n\t\t\t<button class=\"icon-btn close-modal\" data-close=\"helpModal\" aria-label=\"Close help\">\n        <i data-lucide=\"x\"></i>\n      </button>\n\t\t</div>\n\t\t<div class=\"modal-body\">\n\t\t\t<p>Guess the <strong>5-letter</strong> word in <strong>6</strong> tries.</p>\n\t\t\t<ul>\n\t\t\t\t<li><strong>Green</strong> means the letter is in the correct spot.</li>\n\t\t\t\t<li><strong>Yellow</strong> means the letter is in the word but in the wrong spot.</li>\n\t\t\t\t<li><strong>Gray</strong> means the letter is not in the word.</li>\n\t\t\t</ul>\n\t\t\t<div class=\"example-grid\">\n\t\t\t\t<div class=\"example-tile correct\">W</div>\n\t\t\t\t<div class=\"example-tile\">E</div>\n\t\t\t\t<div class=\"example-tile\">A</div>\n\t\t\t\t<div class=\"example-tile\">R</div>\n\t\t\t\t<div class=\"example-tile\">Y</div>\n\t\t\t</div>\n\t\t\t<p><strong>W</strong> is in the word and in the correct spot.</p>\n\t\t\t<div class=\"example-grid\">\n\t\t\t\t<div class=\"example-tile\">P</div>\n\t\t\t\t<div class=\"example-tile present\">I</div>\n\t\t\t\t<div class=\"example-tile\">L</div>\n\t\t\t\t<div class=\"example-tile\">L</div>\n\t\t\t\t<div class=\"example-tile\">S</div>\n\t\t\t</div>\n\t\t\t<p><strong>I</strong> is in the word but in the wrong spot.</p>\n\t\t\t<div class=\"example-grid\">\n\t\t\t\t<div class=\"example-tile\">V</div>\n\t\t\t\t<div class=\"example-tile\">A</div>\n\t\t\t\t<div class=\"example-tile\">G</div>\n\t\t\t\t<div class=\"example-tile absent\">U</div>\n\t\t\t\t<div class=\"example-tile\">E</div>\n\t\t\t</div>\n\t\t\t<p><strong>U</strong> is not in the word in any spot.</p>\n\t\t</div>\n\t</div>\n</div>\n\n<div class=\"modal hidden\" id=\"statsModal\" aria-hidden=\"true\">\n\t<div class=\"modal-card\">\n\t\t<div class=\"modal-header\">\n\t\t\t<h2>Game status</h2>\n\t\t\t<button class=\"icon-btn close-modal\" data-close=\"statsModal\" aria-label=\"Close status\">\n        <i data-lucide=\"x\"></i>\n      </button>\n\t\t</div>\n\t\t<div class=\"modal-body\">\n\t\t\t<div id=\"resultSummary\" class=\"result-summary\"></div>\n\t\t\t<div class=\"modal-actions\">\n\t\t\t\t<button id=\"copyBtn\" class=\"primary-btn\">\n          <i data-lucide=\"copy\"></i>\n          Copy result\n        </button>\n\t\t\t</div>\n\t\t</div>\n\t</div>\n</div>\n  <script type=\"module\" src=\"main.js\"></script>\n</body>\n</html>"},{"name":"main.js","content":"const WORD_LENGTH = 5;\nconst MAX_ROWS = 6;\nconst STORAGE_KEY = 'daily-wordle-clone-v1';\nconst ANSWERS = [\n\t'ABOUT', 'ABOVE', 'ABUSE', 'ACTOR', 'ACUTE', 'ADMIT', 'ADOPT', 'ADULT', 'AFTER', 'AGAIN',\n\t'AGENT', 'AGREE', 'AHEAD', 'ALARM', 'ALBUM', 'ALERT', 'ALIEN', 'ALIGN', 'ALIVE', 'ALLOW',\n\t'ALONE', 'ALONG', 'ALTER', 'AMONG', 'ANGER', 'ANGLE', 'ANGRY', 'APART', 'APPLE', 'APPLY',\n\t'ARENA', 'ARGUE', 'ARISE', 'ARRAY', 'ASIDE', 'ASSET', 'AUDIO', 'AUDIT', 'AVOID', 'AWARD',\n\t'AWARE', 'BADLY', 'BAKER', 'BASES', 'BASIC', 'BEACH', 'BEGAN', 'BEGIN', 'BEING', 'BELOW',\n\t'BENCH', 'BILLY', 'BIRTH', 'BLACK', 'BLAME', 'BLIND', 'BLOCK', 'BLOOD', 'BOARD', 'BOOST',\n\t'BOOTH', 'BOUND', 'BRAIN', 'BRAND', 'BREAD', 'BREAK', 'BREED', 'BRIEF', 'BRING', 'BROAD',\n\t'BROKE', 'BROWN', 'BUILD', 'BUILT', 'BUYER', 'CABLE', 'CALIF', 'CARRY', 'CATCH', 'CAUSE',\n\t'CHAIN', 'CHAIR', 'CHART', 'CHASE', 'CHEAP', 'CHECK', 'CHEST', 'CHIEF', 'CHILD', 'CHINA',\n\t'CHOSE', 'CIVIL', 'CLAIM', 'CLASS', 'CLEAN', 'CLEAR', 'CLICK', 'CLOCK', 'CLOSE', 'COACH',\n\t'COAST', 'COULD', 'COUNT', 'COURT', 'COVER', 'CRAFT', 'CRASH', 'CREAM', 'CRIME', 'CROSS',\n\t'CROWD', 'CROWN', 'CURVE', 'CYCLE', 'DAILY', 'DANCE', 'DATED', 'DEALT', 'DEATH', 'DEBUT',\n\t'DELAY', 'DEPTH', 'DOING', 'DOUBT', 'DOZEN', 'DRAFT', 'DRAMA', 'DRAWN', 'DREAM', 'DRESS',\n\t'DRILL', 'DRINK', 'DRIVE', 'DROVE', 'DYING', 'EAGER', 'EARLY', 'EARTH', 'EIGHT', 'ELITE',\n\t'EMPTY', 'ENJOY', 'ENTER', 'ENTRY', 'EQUAL', 'ERROR', 'EVENT', 'EVERY', 'EXACT', 'EXIST',\n\t'EXTRA', 'FAITH', 'FALSE', 'FAULT', 'FIBER', 'FIELD', 'FIFTH', 'FIFTY', 'FIGHT', 'FINAL',\n\t'FIRST', 'FIXED', 'FLASH', 'FLEET', 'FLOOR', 'FLUID', 'FOCUS', 'FORCE', 'FORTH', 'FORTY',\n\t'FORUM', 'FOUND', 'FRAME', 'FRANK', 'FRAUD', 'FRESH', 'FRONT', 'FRUIT', 'FULLY', 'FUNNY',\n\t'GIANT', 'GIVEN', 'GLASS', 'GLOBE', 'GOING', 'GRACE', 'GRADE', 'GRAND', 'GRANT', 'GRASS',\n\t'GREAT', 'GREEN', 'GROSS', 'GROUP', 'GROWN', 'GUARD', 'GUESS', 'GUEST', 'GUIDE', 'HAPPY',\n\t'HARRY', 'HEART', 'HEAVY', 'HENCE', 'HENRY', 'HORSE', 'HOTEL', 'HOUSE', 'HUMAN', 'IDEAL',\n\t'IMAGE', 'INDEX', 'INNER', 'INPUT', 'ISSUE', 'JAPAN', 'JIMMY', 'JOINT', 'JONES', 'JUDGE',\n\t'KNOWN', 'LABEL', 'LARGE', 'LASER', 'LATER', 'LAUGH', 'LAYER', 'LEARN', 'LEASE', 'LEAST',\n\t'LEAVE', 'LEGAL', 'LEVEL', 'LEWIS', 'LIGHT', 'LIMIT', 'LINKS', 'LIVES', 'LOCAL', 'LOGIC',\n\t'LOOSE', 'LOWER', 'LUCKY', 'LUNCH', 'LYING', 'MAGIC', 'MAJOR', 'MAKER', 'MARCH', 'MARIA',\n\t'MATCH', 'MAYBE', 'MAYOR', 'MEANT', 'MEDIA', 'METAL', 'MIGHT', 'MINOR', 'MINUS', 'MIXED',\n\t'MODEL', 'MONEY', 'MONTH', 'MORAL', 'MOTOR', 'MOUNT', 'MOUSE', 'MOUTH', 'MOVIE', 'MUSIC',\n\t'NEEDS', 'NEVER', 'NEWLY', 'NIGHT', 'NOISE', 'NORTH', 'NOVEL', 'NURSE', 'OCCUR', 'OCEAN',\n\t'OFFER', 'OFTEN', 'ORDER', 'OTHER', 'OUGHT', 'PAINT', 'PANEL', 'PAPER', 'PARTY', 'PEACE',\n\t'PETER', 'PHASE', 'PHONE', 'PHOTO', 'PIECE', 'PILOT', 'PITCH', 'PLACE', 'PLAIN', 'PLANE',\n\t'PLANT', 'PLATE', 'POINT', 'POUND', 'POWER', 'PRESS', 'PRICE', 'PRIDE', 'PRIME', 'PRINT',\n\t'PRIOR', 'PRIZE', 'PROOF', 'PROUD', 'PROVE', 'QUEEN', 'QUICK', 'QUIET', 'QUITE', 'RADIO',\n\t'RAISE', 'RANGE', 'RAPID', 'RATIO', 'REACH', 'READY', 'REFER', 'RIGHT', 'RIVAL', 'RIVER',\n\t'ROBIN', 'ROGER', 'ROMAN', 'ROUGH', 'ROUND', 'ROUTE', 'ROYAL', 'RURAL', 'SCALE', 'SCENE',\n\t'SCOPE', 'SCORE', 'SENSE', 'SERVE', 'SEVEN', 'SHALL', 'SHAPE', 'SHARE', 'SHARP', 'SHEET',\n\t'SHELF', 'SHELL', 'SHIFT', 'SHINE', 'SHIRT', 'SHOCK', 'SHOOT', 'SHORT', 'SHOWN', 'SIGHT',\n\t'SINCE', 'SIXTH', 'SIXTY', 'SIZED', 'SKILL', 'SLEEP', 'SLIDE', 'SMALL', 'SMART', 'SMILE',\n\t'SMITH', 'SMOKE', 'SOLID', 'SOLVE', 'SORRY', 'SOUND', 'SOUTH', 'SPACE', 'SPARE', 'SPEAK',\n\t'SPEED', 'SPEND', 'SPENT', 'SPLIT', 'SPOKE', 'SPORT', 'STAFF', 'STAGE', 'STAKE', 'STAND',\n\t'START', 'STATE', 'STEAM', 'STEEL', 'STEEP', 'STICK', 'STILL', 'STOCK', 'STONE', 'STOOD',\n\t'STORE', 'STORM', 'STORY', 'STRIP', 'STUCK', 'STUDY', 'STUFF', 'STYLE', 'SUGAR', 'SUITE',\n\t'SUPER', 'SWEET', 'TABLE', 'TAKEN', 'TASTE', 'TAXES', 'TEACH', 'TEETH', 'TERRY', 'TEXAS',\n\t'THANK', 'THEFT', 'THEIR', 'THEME', 'THERE', 'THESE', 'THICK', 'THING', 'THINK', 'THIRD',\n\t'THOSE', 'THREE', 'THREW', 'TIGHT', 'TIMES', 'TIRED', 'TITLE', 'TODAY', 'TOPIC', 'TOTAL',\n\t'TOUCH', 'TOUGH', 'TOWER', 'TRACK', 'TRADE', 'TRAIN', 'TREAT', 'TREND', 'TRIAL', 'TRIED',\n\t'TRIES', 'TRUCK', 'TRULY', 'TRUST', 'TRUTH', 'TWICE', 'UNDER', 'UNDUE', 'UNION', 'UNITY',\n\t'UNTIL', 'UPPER', 'UPSET', 'URBAN', 'USAGE', 'USUAL', 'VALID', 'VALUE', 'VIDEO', 'VIRUS',\n\t'VISIT', 'VITAL', 'VOICE', 'WASTE', 'WATCH', 'WATER', 'WHEEL', 'WHERE', 'WHICH', 'WHILE',\n\t'WHITE', 'WHOLE', 'WHOSE', 'WOMAN', 'WOMEN', 'WORLD', 'WORRY', 'WORSE', 'WORST', 'WORTH',\n\t'WOULD', 'WRITE', 'WRONG', 'WROTE', 'YIELD', 'YOUNG', 'YOUTH'\n];\n\nconst EXTRA_GUESSES = [\n\t'ABIDE', 'ABLED', 'ABODE', 'ABORT', 'ACHED', 'ACHES', 'ACIDS', 'ACORN', 'ACRES', 'ADDED',\n\t'ADEPT', 'ADMIN', 'ADORE', 'ADORN', 'AFOOT', 'AFTER', 'AGATE', 'AGILE', 'AGING', 'AGLOW',\n\t'AGONY', 'AISLE', 'ALIBI', 'ALLAY', 'ALLEY', 'ALLOT', 'ALOFT', 'AMASS', 'AMBER', 'AMEND',\n\t'AMISS', 'AMITY', 'AMPLE', 'AMUSE', 'ANGEL', 'ANKLE', 'ANNEX', 'ANNOY', 'ANTIC', 'ANVIL',\n\t'AORTA', 'APRON', 'ARBOR', 'ARDOR', 'ARMOR', 'AROMA', 'ARROW', 'ASHEN', 'ATLAS', 'ATOLL',\n\t'ATTIC', 'AUGUR', 'AUNTY', 'AVERT', 'AVIAN', 'AXIAL', 'BACON', 'BADGE', 'BADLY', 'BAGEL',\n\t'BALER', 'BALMY', 'BANJO', 'BARON', 'BASIN', 'BATCH', 'BATHE', 'BATON', 'BATTY', 'BAYOU',\n\t'BEADY', 'BEAST', 'BEECH', 'BEFIT', 'BEGET', 'BELCH', 'BELIE', 'BELLE', 'BICEP', 'BIDDY',\n\t'BINGE', 'BISON', 'BITTY', 'BLADE', 'BLAND', 'BLAST', 'BLAZE', 'BLEAK', 'BLEAT', 'BLEND',\n\t'BLESS', 'BLIMP', 'BLINK', 'BLISS', 'BLOAT', 'BLOND', 'BLUER', 'BLUFF', 'BLUNT', 'BLURB',\n\t'BLURT', 'BLUSH', 'BOBBY', 'BONEY', 'BONGO', 'BONUS', 'BOOST', 'BOOZY', 'BORAX', 'BORNE',\n\t'BOTCH', 'BOUGH', 'BOXER', 'BRACE', 'BRAID', 'BRAWN', 'BRINE', 'BRISK', 'BROIL', 'BROOD',\n\t'BROTH', 'BRUSH', 'BUDDY', 'BUGGY', 'BULKY', 'BUNNY', 'BURNT', 'BURST', 'BUSHY', 'BUTTE',\n\t'CABIN', 'CAMEL', 'CANDY', 'CANOE', 'CAPER', 'CARVE', 'CASTE', 'CATER', 'CATTY', 'CAULK',\n\t'CEDAR', 'CHAFE', 'CHANT', 'CHARM', 'CHEER', 'CHESS', 'CHILI', 'CHIME', 'CHIRP', 'CHOCK',\n\t'CHORD', 'CHORE', 'CIDER', 'CINCH', 'CIVIC', 'CLAMP', 'CLANG', 'CLANK', 'CLASH', 'CLASP',\n\t'CLASS', 'CLEAN', 'CLEAT', 'CLEFT', 'CLERK', 'CLIFF', 'CLIMB', 'CLING', 'CLOAK', 'CLONE',\n\t'CLOWN', 'CLUCK', 'CLUNG', 'COBRA', 'COMET', 'CONDO', 'COPSE', 'CORAL', 'CORKY', 'COUPE',\n\t'COVEN', 'CRATE', 'CRAVE', 'CRAZE', 'CREDO', 'CREEK', 'CREST', 'CROAK', 'CRONY', 'CRUMB',\n\t'CRUSH', 'CRUST', 'CRYPT', 'CUMIN', 'CURIO', 'CURRY', 'CURSE', 'CUTIE', 'DADDY', 'DAIRY',\n\t'DAISY', 'DALLY', 'DANDY', 'DANDR', 'DARER', 'DEALT', 'DEBAR', 'DECAL', 'DECAY', 'DECOR',\n\t'DECOY', 'DEFER', 'DEIGN', 'DELTA', 'DEMON', 'DENSE', 'DETER', 'DETOX', 'DINER', 'DINGY',\n\t'DITCH', 'DITTO', 'DIZZY', 'DODGE', 'DOGMA', 'DONUT', 'DOPEY', 'DOWRY', 'DOZER', 'DRIER',\n\t'DRIFT', 'DROOL', 'DROOP', 'DRUID', 'DRYER', 'DUCHY', 'DULLY', 'DUMMY', 'DUMPY', 'DUSKY',\n\t'DUSTY', 'DWARF', 'EARTH', 'EASEL', 'EATEN', 'EBONY', 'ECLAT', 'EDICT', 'EERIE', 'EGRET',\n\t'ELBOW', 'ELDER', 'ELECT', 'ELUDE', 'EMBER', 'EMCEE', 'EMOJI', 'ENACT', 'ENDOW', 'ENEMA',\n\t'ENEMY', 'ENVOY', 'EPOCH', 'EPOXY', 'EQUIP', 'ERASE', 'ERUPT', 'ESSAY', 'ETHER', 'ETHIC',\n\t'ETHOS', 'ETUDE', 'EVADE', 'EVOKE', 'EXALT', 'EXILE', 'EXPEL', 'EXTOL', 'FABLE', 'FACET',\n\t'FAINT', 'FAIRY', 'FANCY', 'FANNY', 'FARCE', 'FATTY', 'FAUNA', 'FAVOR', 'FEAST', 'FELLA',\n\t'FEMUR', 'FERRY', 'FETCH', 'FETUS', 'FEVER', 'FEWER', 'FJORD', 'FLAIR', 'FLAKE', 'FLAME',\n\t'FLANK', 'FLARE', 'FLASK', 'FLESH', 'FLICK', 'FLIER', 'FLING', 'FLOAT', 'FLOCK', 'FLOOD',\n\t'FLORA', 'FLOUR', 'FLUME', 'FLUNG', 'FLUSH', 'FOAMY', 'FOGGY', 'FOLIO', 'FORAY', 'FORGE',\n\t'FORGO', 'FORTE', 'FORUM', 'FOYER', 'FRAIL', 'FREAK', 'FREER', 'FRILL', 'FROST', 'FROTH',\n\t'FROWN', 'FUDGE', 'FUGUE', 'FULLY', 'FUNGI', 'FUNKY', 'FURRY', 'FUSSY', 'GAILY', 'GAMER',\n\t'GASSY', 'GAUDY', 'GAUGE', 'GAUNT', 'GAUZE', 'GEEKY', 'GENIE', 'GENRE', 'GHOST', 'GIDDY',\n\t'GIPSY', 'GIRTH', 'GLADE', 'GLAND', 'GLARE', 'GLEAM', 'GLIDE', 'GLINT', 'GLOAT', 'GODLY',\n\t'GOLEM', 'GOODY', 'GOOSE', 'GORGE', 'GOUGE', 'GOURD', 'GRAFT', 'GRAIL', 'GRAPH', 'GRASP',\n\t'GRATE', 'GRAVE', 'GRAVY', 'GRAZE', 'GREED', 'GRIEF', 'GRIME', 'GRIND', 'GROAN', 'GROOM',\n\t'GROPE', 'GROVE', 'GROWL', 'GRUEL', 'GRUFF', 'GUAVA', 'GUILT', 'GUMMY', 'GUSTO', 'GYPSY'\n];\n\nconst VALID_WORDS = new Set([...ANSWERS, ...EXTRA_GUESSES]);\n\nconst boardEl = document.getElementById('board');\nconst keyboardEl = document.getElementById('keyboard');\nconst toastEl = document.getElementById('toast');\nconst helpBtn = document.getElementById('helpBtn');\nconst statsBtn = document.getElementById('statsBtn');\nconst resetBtn = document.getElementById('resetBtn');\nconst helpModal = document.getElementById('helpModal');\nconst statsModal = document.getElementById('statsModal');\nconst resultSummary = document.getElementById('resultSummary');\nconst copyBtn = document.getElementById('copyBtn');\nconst dateLabel = document.getElementById('dateLabel');\n\nlet state = null;\nlet toastTimer = null;\n\nfunction getPuzzleIndex() {\n\tconst start = new Date('2024-01-01T00:00:00');\n\tconst now = new Date();\n\tconst today = new Date(now.getFullYear(), now.getMonth(), now.getDate());\n\tconst diff = Math.floor((today - start) / 86400000);\n\treturn ((diff % ANSWERS.length) + ANSWERS.length) % ANSWERS.length;\n}\n\nfunction getTodayKey() {\n\tconst now = new Date();\n\tconst y = now.getFullYear();\n\tconst m = String(now.getMonth() + 1).padStart(2, '0');\n\tconst d = String(now.getDate()).padStart(2, '0');\n\treturn `${y}-${m}-${d}`;\n}\n\nfunction buildInitialState() {\n\treturn {\n\t\tdateKey: getTodayKey(),\n\t\tanswer: ANSWERS[getPuzzleIndex()],\n\t\tguesses: Array(MAX_ROWS).fill(''),\n\t\tevaluations: Array(MAX_ROWS).fill(null),\n\t\trow: 0,\n\t\tcol: 0,\n\t\tstatus: 'playing'\n\t};\n}\n\nfunction loadState() {\n\tconst saved = localStorage.getItem(STORAGE_KEY);\n\tconst fresh = buildInitialState();\n\n\tif (!saved) return fresh;\n\n\ttry {\n\t\tconst parsed = JSON.parse(saved);\n\t\tif (parsed.dateKey !== fresh.dateKey) return fresh;\n\t\treturn {\n\t\t\t...fresh,\n\t\t\t...parsed,\n\t\t\tanswer: fresh.answer\n\t\t};\n\t} catch {\n\t\treturn fresh;\n\t}\n}\n\nfunction saveState() {\n\tlocalStorage.setItem(STORAGE_KEY, JSON.stringify(state));\n}\n\nfunction formatDate() {\n\tconst now = new Date();\n\treturn now.toLocaleDateString(undefined, {\n\t\tweekday: 'short',\n\t\tmonth: 'short',\n\t\tday: 'numeric'\n\t});\n}\n\nfunction createBoard() {\n\tboardEl.innerHTML = '';\n\tfor (let r = 0; r < MAX_ROWS; r += 1) {\n\t\tconst row = document.createElement('div');\n\t\trow.className = 'row';\n\t\tfor (let c = 0; c < WORD_LENGTH; c += 1) {\n\t\t\tconst tile = document.createElement('div');\n\t\t\ttile.className = 'tile';\n\t\t\ttile.id = `tile-${r}-${c}`;\n\t\t\trow.appendChild(tile);\n\t\t}\n\t\tboardEl.appendChild(row);\n\t}\n}\n\nfunction createKeyboard() {\n\tconst rows = [\n\t\t['Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P'],\n\t\t['A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L'],\n\t\t['ENTER', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', 'BACK']\n\t];\n\n\tkeyboardEl.innerHTML = '';\n\n\trows.forEach((letters) => {\n\t\tconst row = document.createElement('div');\n\t\trow.className = 'key-row';\n\n\t\tletters.forEach((letter) => {\n\t\t\tconst key = document.createElement('button');\n\t\t\tkey.className = 'key';\n\t\t\tkey.dataset.key = letter;\n\t\t\tkey.type = 'button';\n\t\t\tkey.setAttribute('aria-label', letter === 'BACK' ? 'Backspace' : letter);\n\n\t\t\tif (letter === 'ENTER') {\n\t\t\t\tkey.classList.add('wide');\n\t\t\t\tkey.textContent = 'Enter';\n\t\t\t} else if (letter === 'BACK') {\n\t\t\t\tkey.classList.add('wide');\n\t\t\t\tkey.innerHTML = '<i data-lucide=\"delete\"></i>';\n\t\t\t} else {\n\t\t\t\tkey.textContent = letter;\n\t\t\t}\n\n\t\t\tkey.addEventListener('click', () => handleInput(letter));\n\t\t\trow.appendChild(key);\n\t\t});\n\n\t\tkeyboardEl.appendChild(row);\n\t});\n}\n\nfunction renderBoard() {\n\tfor (let r = 0; r < MAX_ROWS; r += 1) {\n\t\tconst guess = state.guesses[r] || '';\n\t\tfor (let c = 0; c < WORD_LENGTH; c += 1) {\n\t\t\tconst tile = document.getElementById(`tile-${r}-${c}`);\n\t\t\tconst letter = guess[c] || '';\n\t\t\ttile.textContent = letter;\n\t\t\ttile.classList.toggle('filled', Boolean(letter));\n\n\t\t\ttile.classList.remove('correct', 'present', 'absent');\n\t\t\tconst evals = state.evaluations[r];\n\t\t\tif (evals && evals[c]) {\n\t\t\t\ttile.classList.add(evals[c]);\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction renderKeyboard() {\n\tconst priority = {\n\t\tabsent: 1,\n\t\tpresent: 2,\n\t\tcorrect: 3\n\t};\n\tconst map = {};\n\n\tstate.evaluations.forEach((row, r) => {\n\t\tif (!row) return;\n\t\tconst guess = state.guesses[r];\n\t\trow.forEach((status, i) => {\n\t\t\tconst letter = guess[i];\n\t\t\tif (!letter) return;\n\t\t\tif (!map[letter] || priority[status] > priority[map[letter]]) {\n\t\t\t\tmap[letter] = status;\n\t\t\t}\n\t\t});\n\t});\n\n\tdocument.querySelectorAll('.key').forEach((key) => {\n\t\tconst value = key.dataset.key;\n\t\tkey.classList.remove('correct', 'present', 'absent');\n\t\tif (map[value]) key.classList.add(map[value]);\n\t});\n}\n\nfunction showToast(message, duration = 1500) {\n\tclearTimeout(toastTimer);\n\ttoastEl.textContent = message;\n\ttoastEl.classList.add('show');\n\ttoastTimer = setTimeout(() => toastEl.classList.remove('show'), duration);\n}\n\nfunction animatePop(row, col) {\n\tconst tile = document.getElementById(`tile-${row}-${col}`);\n\ttile.classList.remove('pop');\n\tvoid tile.offsetWidth;\n\ttile.classList.add('pop');\n}\n\nfunction scoreGuess(guess, answer) {\n\tconst result = Array(WORD_LENGTH).fill('absent');\n\tconst answerChars = answer.split('');\n\tconst guessChars = guess.split('');\n\n\tfor (let i = 0; i < WORD_LENGTH; i += 1) {\n\t\tif (guessChars[i] === answerChars[i]) {\n\t\t\tresult[i] = 'correct';\n\t\t\tanswerChars[i] = null;\n\t\t\tguessChars[i] = null;\n\t\t}\n\t}\n\n\tfor (let i = 0; i < WORD_LENGTH; i += 1) {\n\t\tif (!guessChars[i]) continue;\n\t\tconst hitIndex = answerChars.indexOf(guessChars[i]);\n\t\tif (hitIndex !== -1) {\n\t\t\tresult[i] = 'present';\n\t\t\tanswerChars[hitIndex] = null;\n\t\t}\n\t}\n\n\treturn result;\n}\n\nfunction updateSummary() {\n\tlet headline = '';\n\tif (state.status === 'won') {\n\t\theadline = `You solved it in ${state.row} ${state.row === 1 ? 'try' : 'tries'}!`;\n\t} else if (state.status === 'lost') {\n\t\theadline = `Out of tries. The word was ${state.answer}.`;\n\t} else {\n\t\theadline = `You are on row ${state.row + 1} of ${MAX_ROWS}.`;\n\t}\n\n\tresultSummary.textContent = `${headline}\\n\\n${buildShareText()}`;\n}\n\nfunction buildShareText() {\n\tconst dayNumber = getPuzzleIndex() + 1;\n\tconst score = state.status === 'won' ? state.row : 'X';\n\tconst lines = state.evaluations\n\t\t.filter(Boolean)\n\t\t.map((row) => row.map((cell) => {\n\t\t\tif (cell === 'correct') return '🟩';\n\t\t\tif (cell === 'present') return '🟨';\n\t\t\treturn '⬛';\n\t\t}).join(''));\n\n\treturn `Wordle Clone ${dayNumber} ${score}/${MAX_ROWS}\\n${lines.join('\\n')}`;\n}\n\nfunction openModal(modal) {\n\tmodal.classList.remove('hidden');\n\tmodal.setAttribute('aria-hidden', 'false');\n}\n\nfunction closeModal(modal) {\n\tmodal.classList.add('hidden');\n\tmodal.setAttribute('aria-hidden', 'true');\n}\n\nfunction finishGame(status) {\n\tstate.status = status;\n\tsaveState();\n\trenderKeyboard();\n\tupdateSummary();\n\topenModal(statsModal);\n}\n\nfunction revealRow(rowIndex, evaluation) {\n\tevaluation.forEach((status, i) => {\n\t\tconst tile = document.getElementById(`tile-${rowIndex}-${i}`);\n\t\tsetTimeout(() => {\n\t\t\ttile.classList.add('flip');\n\t\t\tsetTimeout(() => {\n\t\t\t\ttile.classList.add(status);\n\t\t\t\trenderKeyboard();\n\t\t\t}, 250);\n\t\t}, i * 220);\n\t});\n\n\tconst won = evaluation.every((cell) => cell === 'correct');\n\tconst totalDelay = evaluation.length * 220 + 350;\n\n\tsetTimeout(() => {\n\t\tif (won) {\n\t\t\tshowToast('Genius!', 1800);\n\t\t\tfinishGame('won');\n\t\t} else if (state.row >= MAX_ROWS) {\n\t\t\tshowToast(state.answer, 2500);\n\t\t\tfinishGame('lost');\n\t\t} else {\n\t\t\tsaveState();\n\t\t\tupdateSummary();\n\t\t}\n\t}, totalDelay);\n}\n\nfunction submitGuess() {\n\tconst guess = state.guesses[state.row];\n\n\tif (guess.length < WORD_LENGTH) {\n\t\tshowToast('Not enough letters');\n\t\treturn;\n\t}\n\n\tif (!VALID_WORDS.has(guess)) {\n\t\tshowToast('Not in word list');\n\t\treturn;\n\t}\n\n\tconst evaluation = scoreGuess(guess, state.answer);\n\tstate.evaluations[state.row] = evaluation;\n\tstate.row += 1;\n\tstate.col = 0;\n\trevealRow(state.row - 1, evaluation);\n}\n\nfunction handleInput(input) {\n\tif (state.status !== 'playing') {\n\t\tif (input === 'ENTER') openModal(statsModal);\n\t\treturn;\n\t}\n\n\tif (input === 'ENTER') {\n\t\tsubmitGuess();\n\t\treturn;\n\t}\n\n\tif (input === 'BACK') {\n\t\tif (state.col === 0) return;\n\t\tconst current = state.guesses[state.row];\n\t\tstate.guesses[state.row] = current.slice(0, -1);\n\t\tstate.col -= 1;\n\t\trenderBoard();\n\t\treturn;\n\t}\n\n\tif (!/^[A-Z]$/.test(input)) return;\n\tif (state.col >= WORD_LENGTH) return;\n\n\tstate.guesses[state.row] += input;\n\trenderBoard();\n\tanimatePop(state.row, state.col);\n\tstate.col += 1;\n}\n\nfunction bindEvents() {\n\tdocument.addEventListener('keydown', (event) => {\n\t\tconst key = event.key;\n\t\tif (key === 'Backspace') {\n\t\t\thandleInput('BACK');\n\t\t} else if (key === 'Enter') {\n\t\t\thandleInput('ENTER');\n\t\t} else if (/^[a-zA-Z]$/.test(key)) {\n\t\t\thandleInput(key.toUpperCase());\n\t\t}\n\t});\n\n\thelpBtn.addEventListener('click', () => openModal(helpModal));\n\tstatsBtn.addEventListener('click', () => {\n\t\tupdateSummary();\n\t\topenModal(statsModal);\n\t});\n\n\tresetBtn.addEventListener('click', () => {\n\t\tlocalStorage.removeItem(STORAGE_KEY);\n\t\tstate = buildInitialState();\n\t\tinitGame();\n\t\tshowToast('Game reset');\n\t});\n\n\tdocument.querySelectorAll('.close-modal').forEach((btn) => {\n\t\tbtn.addEventListener('click', () => closeModal(document.getElementById(btn.dataset.close)));\n\t});\n\n\t[helpModal, statsModal].forEach((modal) => {\n\t\tmodal.addEventListener('click', (e) => {\n\t\t\tif (e.target === modal) closeModal(modal);\n\t\t});\n\t});\n\n\tcopyBtn.addEventListener('click', async () => {\n\t\ttry {\n\t\t\tawait navigator.clipboard.writeText(buildShareText());\n\t\t\tshowToast('Copied to clipboard');\n\t\t} catch {\n\t\t\tshowToast('Copy failed');\n\t\t}\n\t});\n}\n\nfunction initGame() {\n\tdateLabel.textContent = formatDate();\n\tcreateBoard();\n\tcreateKeyboard();\n\trenderBoard();\n\trenderKeyboard();\n\tupdateSummary();\n\tlucide.createIcons();\n\n\tif (state.status === 'won' || state.status === 'lost') {\n\t\tsetTimeout(() => openModal(statsModal), 250);\n\t}\n}\n\nstate = loadState();\nbindEvents();\ninitGame();"},{"name":"style.css","content":":root {\n\t--bg: #121213;\n\t--panel: #121213;\n\t--text: #ffffff;\n\t--muted: #818384;\n\t--border: #3a3a3c;\n\t--border-soft: #565758;\n\t--tile-empty: #121213;\n\t--tile-text: #ffffff;\n\t--correct: #538d4e;\n\t--present: #b59f3b;\n\t--absent: #3a3a3c;\n\t--key: #818384;\n\t--key-text: #ffffff;\n\t--shadow: 0 10px 30px rgba(0, 0, 0, 0.3);\n\t--radius: 12px;\n\t--gap: 6px;\n\t--board-size: min(92vw, 350px);\n}\n\n* {\n\tbox-sizing: border-box;\n}\n\nhtml,\nbody {\n\tmargin: 0;\n\tpadding: 0;\n\tbackground: var(--bg);\n\tcolor: var(--text);\n\tfont-family: Arial, Helvetica, sans-serif;\n\tmin-height: 100%;\n}\n\nbody {\n\tmin-height: 100vh;\n}\n\nbutton {\n\tfont: inherit;\n}\n\n.app-shell {\n\tmin-height: 100vh;\n\tdisplay: flex;\n\tflex-direction: column;\n\tmax-width: 560px;\n\tmargin: 0 auto;\n\tpadding: env(safe-area-inset-top, 0) 12px env(safe-area-inset-bottom, 16px);\n}\n\n.topbar {\n\theight: 56px;\n\tdisplay: grid;\n\tgrid-template-columns: 48px 1fr auto;\n\talign-items: center;\n\tborder-bottom: 1px solid #2f2f31;\n\tgap: 8px;\n}\n\n.title {\n\tmargin: 0;\n\ttext-align: center;\n\tfont-size: clamp(1.75rem, 4vw, 2.2rem);\n\tfont-weight: 800;\n\tletter-spacing: 0.04em;\n}\n\n.topbar-actions {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 4px;\n}\n\n.icon-btn {\n\twidth: 44px;\n\theight: 44px;\n\tborder: 0;\n\tbackground: transparent;\n\tcolor: var(--text);\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\tborder-radius: 10px;\n\tcursor: pointer;\n}\n\n.icon-btn:hover {\n\tbackground: rgba(255, 255, 255, 0.06);\n}\n\n.game-wrap {\n\tflex: 1;\n\tdisplay: flex;\n\tflex-direction: column;\n\tjustify-content: space-between;\n\tgap: 12px;\n\tpadding: 12px 0 18px;\n}\n\n.status-row {\n\tdisplay: flex;\n\tjustify-content: center;\n\tgap: 8px;\n\tflex-wrap: wrap;\n}\n\n.status-pill {\n\tpadding: 8px 12px;\n\tbackground: #1d1d1f;\n\tborder: 1px solid #2a2a2c;\n\tborder-radius: 999px;\n\tcolor: #d7dadc;\n\tfont-size: 0.9rem;\n}\n\n.board-wrap {\n\tdisplay: flex;\n\tjustify-content: center;\n\talign-items: center;\n\tflex: 1;\n\tmin-height: 0;\n}\n\n.board {\n\twidth: var(--board-size);\n\tdisplay: grid;\n\tgrid-template-rows: repeat(6, 1fr);\n\tgap: var(--gap);\n}\n\n.row {\n\tdisplay: grid;\n\tgrid-template-columns: repeat(5, 1fr);\n\tgap: var(--gap);\n}\n\n.tile {\n\taspect-ratio: 1;\n\tborder: 2px solid var(--border);\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\tfont-weight: 700;\n\ttext-transform: uppercase;\n\tcolor: var(--tile-text);\n\tbackground: var(--tile-empty);\n\tfont-size: clamp(1.3rem, 5vw, 2rem);\n\tuser-select: none;\n}\n\n.tile.filled {\n\tborder-color: var(--border-soft);\n}\n\n.tile.correct {\n\tbackground: var(--correct);\n\tborder-color: var(--correct);\n}\n\n.tile.present {\n\tbackground: var(--present);\n\tborder-color: var(--present);\n}\n\n.tile.absent {\n\tbackground: var(--absent);\n\tborder-color: var(--absent);\n}\n\n.tile.pop {\n\tanimation: pop 0.12s ease-in-out;\n}\n\n.tile.flip {\n\tanimation: flip 0.55s ease forwards;\n}\n\n.message-area {\n\tmin-height: 28px;\n\tdisplay: flex;\n\tjustify-content: center;\n\talign-items: center;\n}\n\n.toast {\n\topacity: 0;\n\ttransform: translateY(-4px);\n\ttransition: 0.2s ease;\n\tbackground: #ffffff;\n\tcolor: #121213;\n\tpadding: 10px 14px;\n\tborder-radius: 999px;\n\tfont-size: 0.92rem;\n\tfont-weight: 700;\n\tpointer-events: none;\n}\n\n.toast.show {\n\topacity: 1;\n\ttransform: translateY(0);\n}\n\n.keyboard {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 8px;\n\twidth: 100%;\n}\n\n.key-row {\n\tdisplay: flex;\n\tgap: 6px;\n\twidth: 100%;\n}\n\n.key {\n\tborder: 0;\n\tborder-radius: 6px;\n\tbackground: var(--key);\n\tcolor: var(--key-text);\n\tfont-weight: 700;\n\theight: clamp(48px, 8vh, 58px);\n\tflex: 1;\n\tmin-width: 0;\n\tcursor: pointer;\n\ttext-transform: uppercase;\n\tpadding: 0;\n}\n\n.key.wide {\n\tflex: 1.5;\n\tfont-size: 0.8rem;\n}\n\n.key.correct {\n\tbackground: var(--correct);\n}\n\n.key.present {\n\tbackground: var(--present);\n}\n\n.key.absent {\n\tbackground: var(--absent);\n}\n\n.modal {\n\tposition: fixed;\n\tinset: 0;\n\tbackground: rgba(0, 0, 0, 0.72);\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\tpadding: 16px;\n\tz-index: 50;\n}\n\n.modal.hidden {\n\tdisplay: none;\n}\n\n.modal-card {\n\twidth: min(100%, 420px);\n\tbackground: #1b1b1d;\n\tborder: 1px solid #2b2b2e;\n\tborder-radius: 18px;\n\tbox-shadow: var(--shadow);\n\toverflow: hidden;\n}\n\n.modal-header {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: space-between;\n\tpadding: 14px 16px;\n\tborder-bottom: 1px solid #2f2f31;\n}\n\n.modal-header h2 {\n\tmargin: 0;\n\tfont-size: 1.1rem;\n}\n\n.modal-body {\n\tpadding: 16px;\n\tcolor: #d7dadc;\n}\n\n.modal-body p,\n.modal-body li {\n\tline-height: 1.45;\n}\n\n.example-grid {\n\tdisplay: grid;\n\tgrid-template-columns: repeat(5, 42px);\n\tgap: 4px;\n\tmargin: 10px 0;\n}\n\n.example-tile {\n\twidth: 42px;\n\theight: 42px;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\tborder: 2px solid var(--border);\n\tfont-weight: 700;\n\tcolor: var(--text);\n}\n\n.example-tile.correct {\n\tbackground: var(--correct);\n\tborder-color: var(--correct);\n}\n\n.example-tile.present {\n\tbackground: var(--present);\n\tborder-color: var(--present);\n}\n\n.example-tile.absent {\n\tbackground: var(--absent);\n\tborder-color: var(--absent);\n}\n\n.result-summary {\n\tfont-size: 1rem;\n\tline-height: 1.5;\n\twhite-space: pre-wrap;\n}\n\n.modal-actions {\n\tmargin-top: 16px;\n}\n\n.primary-btn {\n\twidth: 100%;\n\theight: 46px;\n\tborder: 0;\n\tborder-radius: 12px;\n\tbackground: #ffffff;\n\tcolor: #121213;\n\tfont-weight: 800;\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\tgap: 8px;\n\tcursor: pointer;\n}\n\n@keyframes pop {\n\t0% {\n\t\ttransform: scale(1);\n\t}\n\n\t50% {\n\t\ttransform: scale(1.08);\n\t}\n\n\t100% {\n\t\ttransform: scale(1);\n\t}\n}\n\n@keyframes flip {\n\t0% {\n\t\ttransform: rotateX(0deg);\n\t}\n\n\t45% {\n\t\ttransform: rotateX(90deg);\n\t}\n\n\t55% {\n\t\ttransform: rotateX(90deg);\n\t}\n\n\t100% {\n\t\ttransform: rotateX(0deg);\n\t}\n}\n\n@media (max-width: 420px) {\n\t:root {\n\t\t--board-size: min(92vw, 320px);\n\t\t--gap: 5px;\n\t}\n\n\t.app-shell {\n\t\tpadding-left: 8px;\n\t\tpadding-right: 8px;\n\t}\n\n\t.key {\n\t\theight: 52px;\n\t\tfont-size: 0.92rem;\n\t}\n\n\t.key.wide {\n\t\tfont-size: 0.72rem;\n\t}\n}\n\n@media (min-width: 768px) {\n\t:root {\n\t\t--board-size: 360px;\n\t}\n\n\t.app-shell {\n\t\tmax-width: 620px;\n\t}\n}"}],"folders":[]},"variants":null,"createdAt":"2026-03-07T02:15:05.392Z","updatedAt":"2026-03-07T02:15:16.111Z"}}