Something went wrong. Try again.
Hank Green's 4x3 game in a single page HTML
Something went wrong. Try again.
305 kB · 3913 lines · Created 4mo ago
HTML
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914<!-- All code belongs to https://www.hankgreen.com/fourbythree. this is just to show off how fun it is that the whole game logic is in a single html page -->
<!doctype html><html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta http-equiv="Cache-Control" content="no-cache, must-revalidate" /> <title>4 × 3</title> <script> /* Resolve relative assets (favicons, etc.) against this page's own folder so they load whether the URL is /fourbythree, /fourbythree/, or .../index.html — a bare "favicon.svg" would otherwise hit the site root when there's no trailing slash. Runs before the icon links below so they pick up the base. */ (function () { var p = location.pathname; if (!/\/$/.test(p)) { if (/\.[^\/]+$/.test(p)) p = p.replace(/[^\/]*$/, ""); else p += "/"; } var b = document.createElement("base"); b.setAttribute("href", p); document.head.appendChild(b); })(); </script> <link rel="icon" href="favicon.svg" type="image/svg+xml" /> <link rel="icon" href="favicon-32.png" type="image/png" sizes="32x32" /> <link rel="apple-touch-icon" href="apple-touch-icon.png" /> <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.5/gsap.min.js"></script> <script defer src="/_vercel/insights/script.js"></script> <link rel="stylesheet" href="https://www.hankgreen.com/fourbythree/shared.css" /> <script src="https://www.hankgreen.com/fourbythree/shared.js"></script> <script src="https://www.hankgreen.com/fourbythree/stats-beacon.js"></script> </head> <body> <div class="wrap"> <a id="streakTag" class="streak-tag" href="history.html" style="display: none" ></a> <header> <img class="logo" src="data:image/png;base64,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" alt="4×3" onerror=" const h = document.createElement('h1'); h.textContent = '4 × 3'; this.replaceWith(h); " /> <div class="tag"> Four categories. Three words each. One word is in all four. </div> <!-- ===== ACTIVE AD: Focus Friend ===== --> <!-- promo note (mobile / narrow only — sidebar version below takes over on wide screens) --> <div class="promo-banner"> <img class="promo-bean" src="hankbeantrans.png" alt="" loading="lazy" /> Need a cozy tool to help you take back control from social media apps? My app <b>Focus Friend</b> is zero cost and ad-free!! <a href="https://apps.apple.com/us/app/focus-friend-by-hank-green/id6742278016" target="_blank" rel="noopener" >iPhone</a > · <a href="https://play.google.com/store/apps/details?id=com.underthing.focus.friend" target="_blank" rel="noopener" >Android</a > </div> </header>
<!-- desktop sidebar promo (wide screens only) --> <aside class="promo-side"> <img class="promo-img" src="focusfriendtrans.png" alt="Focus Friend" loading="lazy" /> <div class="promo-kicker">From Hank</div> <p class="promo-body"> Need a cozy tool to help you take back control from social media apps? My app <b>Focus Friend</b> is zero cost and ad-free!! </p> <div class="promo-apps"> <a href="https://apps.apple.com/us/app/focus-friend-by-hank-green/id6742278016" target="_blank" rel="noopener" >iPhone</a ><a href="https://play.google.com/store/apps/details?id=com.underthing.focus.friend" target="_blank" rel="noopener" >Android</a > </div> </aside>
<!-- ===== ALTERNATE AD (Humans podcast) — to switch back, replace the active banner/sidebar above with these ===== BANNER (inside <header>, after the tagline): <div class="promo-banner"> I got a text from a friend this week calling the episode of “Humans” with Helen Hunt “Truly some of your best work” so… maybe you want to <a href="https://www.humanswithhank.com/" target="_blank" rel="noopener">check that out</a>. </div> SIDEBAR (after </header>): <aside class="promo-side"> <div class="promo-kicker">From Hank</div> <p class="promo-body">I got a text from a friend this week calling the episode of “Humans” with Helen Hunt “Truly some of your best work” so… maybe you want to <a href="https://www.humanswithhank.com/" target="_blank" rel="noopener">check that out</a>.</p> </aside> ===== -->
<!-- ============ PLAY ============ --> <div id="play" class="view on"> <div class="pauthor" id="pSub" style="margin: 2px auto 12px" ></div> <div id="betaBanner" class="betabanner" style="display: none"> 🧪 <b>Beta test!</b> You're playtesting an unpublished puzzle — feedback form at the end. </div> <div class="card"> <div id="boardWrap" style="display: none"> <div id="board"></div> <div class="ctrls"> <button id="shuffleBtn" onclick="shuffleBoard()"> Shuffle </button> <button id="deselBtn" onclick="deselectAll()"> Deselect </button> <button class="primary" id="submitBtn" onclick="submitGuess()" disabled > Submit </button> </div> <div class="mist" id="mist"></div> <div class="solvedlist" id="solvedList"></div> </div> <div id="result" style="display: none" class="result"></div> </div> <div id="fbCard" style="display: none" class="card fb"> <b>🧪 Beta feedback for the creator</b> <label style=" display: block; margin-top: 10px; font-size: 14px; " >How hard was it? (1 = trivial, 5 = brutal)</label > <div class="stars" id="fbDiff"></div> <label style="display: block; font-size: 14px" >How fun was it?</label > <div class="stars" id="fbFun"></div> <label style="display: block; font-size: 14px" >Did you figure out the special word before the end?</label > <div class="yn" id="fbSpecial"> <button onclick=" fb.special = 'Yes'; ynPaint(); " > Yes </button> <button onclick=" fb.special = 'No'; ynPaint(); " > No </button> </div> <label style=" display: block; font-size: 14px; margin-bottom: 4px; " >Notes for the creator</label > <textarea id="fbNotes" placeholder="Too easy? A category felt unfair? A word fits two groups?" ></textarea> <div class="rowbtns" style="margin-top: 10px"> <button class="hbtn primary" id="fbCopy" onclick="copyFeedback()" > Copy feedback </button> <a id="fbMail" class="hbtn" style="display: none; text-decoration: none" >Email it</a > </div> </div> </div>
<footer> by Hank Green <img src="fishtrans.png" alt="" style="height: 20px; vertical-align: -5px; opacity: 0.4" /> · <a href="scoring.html">scoring</a> · <a href="archive.html">past puzzles</a> · <a href="build.html">build your own</a> · <a href="history.html">history</a> </footer> </div> <div id="modal"> <div class="mback" onclick="closeModal()"></div> <div class="mcard"> <button class="mclose" onclick="closeModal()" aria-label="Close" > × </button> <div id="mbody" class="result"></div> </div> </div> <div class="toast" id="toast"></div> <div id="deftip"></div>
<script> "use strict"; /* ---------- fallback puzzle (used if puzzles.json is unreachable) ---------- */ const DEMO = { a: "Hank", e: "", s: "HEAVY", c: [ ["___ Metal", "DEATH", "GLAM"], ["SpaceX Falcon Rockets", "ONE", "NINE"], ["Serious", "SOMBER", "GRAVE"], ["Boxing Weights", "WELTER", "MIDDLE"], ], }; /* category-coloured card backs (blue, green, yellow, purple); unsolved tiles keep the default light back set in CSS (.tback) */ const BACKS = [ "bluefish.jpg", "greenfish.jpg", "yellowfish.jpg", "lightpurple.jpg", ]; const EMOJI = ["🟦", "🟩", "🟨", "🟪"]; /* lines through the center, keyed by CATEGORY index so position encodes color (an accessibility cue for players who can't distinguish the four hues): 0 blue → diag ↘ (TL/BR), 1 green → middle column, 2 yellow → middle row, 3 purple → diag ↗ (BL/TR) */ const LINES = [ [0, 8], [1, 7], [3, 5], [2, 6], ]; const CENTER = 4; /* stable 0/1/2 pick so the first-solved trio's hub sits in a fixed spot on its line (center only ~1/3 of the time) and doesn't jump around on refresh */ function hubSlotPos(seed) { let h = 0; for (let i = 0; i < seed.length; i++) h = (h * 31 + seed.charCodeAt(i)) | 0; return Math.abs(h) % 3; } const G = window.gsap || null;
/* ---------- state ---------- */ let puzzle = null, isBeta = false, dailyKey = null; let loadedDay = null, pendingKey = null, isPreview = false; let puzzleData = null; /* last good puzzles.json, reused by the archive */ let cats = [], special = "", slots = [], slots0 = [], tiles = {}; let selection = [], solvedIdx = [], colorCat = {}, locked = new Set(); let mistakes = 0, penalty = 0, guesses = [], over = false, animating = false; let adClicked = false; /* +AD_BONUS once per game if the player taps the ad */ let startTime = 0, solveMs = null; /* speed timer: starts on load, stops at the finish */ let hubEmoji = null; /* emoji that bursts from the hub on the post-win tap (custom puzzles carry their own) */ const MAXM = 3; let fb = { diff: 0, fun: 0, special: "" }; let TW = 0, TH = 0, GAP = 8; /* chance a reflow includes a flip at all — at most ONE card flips per transition, chosen at random from the moving (non-hub) cards. Tweak to taste. */ const FLIP_CHANCE = 0.2; let firstLoad = true; /* play the intro shuffle-in once, on the first load */ let suppressFlip = false; /* shuffles set this so they don't trigger a card flip */ let shuffling = false; /* lock out shuffle clicks until the current glide finishes */ let introPlaying = false; /* true while the first-load intro is animating (don't relayout over it) */
/* hub = the special word. It stays hidden until it's logically determined (two solved groups share exactly one word) or the game ends. */ function hubKnown() { return solvedIdx.length >= 2 || over; }
/* ---------- nav ---------- */ /* the game is the only view on this page now; scoring / archive / build moved to their own pages (linked in the footer). showView stays a thin shim. */ function showView(v) { if (v === "play" && !introPlaying) layout(true); }
/* ---------- init / hash ---------- */ async function init() { const h = location.hash; isBeta = false; puzzle = null; dailyKey = null; loadedDay = todayStr(); pendingKey = null; isPreview = false; scheduleRollover(); let archiveDate = null; try { if (h.startsWith("#b=")) { puzzle = decPuzzle(h.slice(3)); isBeta = true; } else if (h.startsWith("#p=")) { puzzle = decPuzzle(h.slice(3)); } else if (h.startsWith("#d=")) { archiveDate = decodeURIComponent(h.slice(3)); } } catch (e) { toast( "Couldn't read that puzzle link — showing today's game.", ); } if (!puzzle) { /* no link (or an #d= archive date): load from puzzles.json — that specific day if given and valid, otherwise the most recent entry ≤ today */ try { const r = await fetch(pjURL(), { cache: "no-store" }); if (r.ok) { const data = await r.json(); puzzleData = data; const today = todayStr(); let k = null; if ( archiveDate && data[archiveDate] && archiveDate <= today ) { k = archiveDate; } else { const keys = Object.keys(data) .filter((k) => k <= today) .sort(); if (keys.length) k = keys[keys.length - 1]; } if (k) { puzzle = decPuzzle(data[k]); dailyKey = k; } } } catch (e) {} } if (!puzzle) puzzle = DEMO; setupPlay(); showView("play"); } function setupPlay() { document.getElementById("betaBanner").style.display = isBeta ? "" : "none"; /* today's daily shows no date line at all; archived (past) puzzles get a dated pill */ let sub = ""; if (dailyKey && dailyKey !== todayStr()) sub = fmtDate(dailyKey); const ps = document.getElementById("pSub"); ps.textContent = sub; ps.classList.remove("today"); ps.style.display = sub ? "" : "none"; /* no empty spacer when there's no date line */ document.getElementById("result").style.display = "none"; document.getElementById("fbCard").style.display = "none"; document.getElementById("solvedList").innerHTML = ""; startGame(); }
/* ---------- midnight rollover ---------- At local midnight (or when the tab wakes up on a new day), fetch puzzles.json and switch to the new daily. If a game is in progress, wait until it ends. */ let rolloverTimer = null; function msUntilMidnight() { const n = new Date(); return ( new Date( n.getFullYear(), n.getMonth(), n.getDate() + 1, 0, 0, 2, ) - n ); /* 2s past midnight */ } function scheduleRollover() { clearTimeout(rolloverTimer); rolloverTimer = setTimeout( checkNewDay, Math.min(msUntilMidnight(), 2147483647), ); } async function checkNewDay() { scheduleRollover(); if ( location.hash.startsWith("#b=") || location.hash.startsWith("#p=") || location.hash.startsWith("#d=") ) return; /* linked or archived puzzle, not the daily */ if (isPreview && !over) return; /* don't stomp on a builder test run */ if (todayStr() === loadedDay) return; /* same day, nothing to do */ loadedDay = todayStr(); try { const r = await fetch(pjURL(), { cache: "no-store" }); if (!r.ok) return; const data = await r.json(); puzzleData = data; const keys = Object.keys(data) .filter((k) => k <= todayStr()) .sort(); const k = keys.length ? keys[keys.length - 1] : null; if (!k || k === dailyKey) return; /* no new puzzle for today */ if (!over && guesses.length > 0) { /* mid-game: don't reset the board */ pendingKey = k; toast( "A new puzzle is ready — it'll be here when you finish.", ); return; } if ( document.getElementById("modal").style.display === "flex" ) closeModal(); init(); } catch (e) {} } document.addEventListener("visibilitychange", () => { if (!document.hidden) checkNewDay(); }); window.addEventListener("focus", () => checkNewDay()); /* Restored from the back/forward cache: the page is the frozen yesterday snapshot and no JS has re-run, so re-check the day explicitly. This is the usual cause of "I opened the URL and it's still showing yesterday's puzzle." */ window.addEventListener("pageshow", (e) => { if (e.persisted) checkNewDay(); });
/* ---------- game setup ---------- */ /* ---------- progress persistence ---------- Saves the live daily's progress so a refresh resumes exactly where you left off (and a finished/failed game stays finished) — no restarting by reloading. Only the actual day's official puzzle is persisted; beta links, the builder preview, direct links and past archive puzzles stay freely replayable. */ function gameKey() { return dailyKey && dailyKey === todayStr() && !isBeta && !isPreview ? "x43_game_" + dailyKey : null; } function loadGame() { const k = gameKey(); if (!k) return null; try { return JSON.parse(localStorage.getItem(k) || "null"); } catch (e) { return null; } } function saveGame() { const k = gameKey(); if (!k) return; try { localStorage.setItem( k, JSON.stringify({ v: 1, s: special, slots0, solved: solvedIdx, m: mistakes, p: penalty, g: guesses, over, t0: startTime, sms: solveMs, ad: adClicked ? 1 : 0, }), ); } catch (e) {} } /* Rebuild the board state from a saved game, no animations, without re-counting stats (those were tallied once, on the real finish). */ function restoreGame(st) { (st.solved || []).forEach((ci) => { solvedIdx.push(ci); if (solvedIdx.length === 1) { for (const w of [special, ...cats[ci].words]) colorCat[w] = ci; } else { for (const w of cats[ci].words) { colorCat[w] = ci; locked.add(w); } if (solvedIdx.length === 2) { for (const w of cats[solvedIdx[0]].words) locked.add(w); delete colorCat[special]; } } }); mistakes = Math.min(MAXM, st.m || 0); adClicked = !!st.ad; penalty = st.p !== undefined ? st.p : (st.m || 0) * 15; startTime = st.t0 || Date.now(); solveMs = st.sms !== undefined ? st.sms : null; guesses = Array.isArray(st.g) ? st.g : []; if (st.over) { over = true; for (const ci of solvedIdx) for (const w of cats[ci].words) locked.add(w); locked.add(special); delete colorCat[special]; } reflowSlots(); syncDomOrder(); renderSolvedList(); paintTiles(); layout(true); renderMist(); updateButtons(); if (over) { document.getElementById("deselBtn").style.display = "none"; document.getElementById("shuffleBtn").style.display = "none"; const won = mistakes < MAXM; showResult( won, calcScore().score, false, true, ); /* quiet: no auto-popped modal */ if (won && G) endFlourish(); } else if (guesses.length || solvedIdx.length || mistakes) { showWelcomeBack(); /* greet returning players; they click out to resume */ } } /* Returning to an in-progress daily: a dismissible "Continue playing" screen over the already-restored board (button, ✕, backdrop, or Esc all close it). */ function showWelcomeBack() { const found = solvedIdx.length; let status = found + " of 4 group" + (found === 1 ? "" : "s") + " found"; if (mistakes > 0) status += " · " + (mistakes ? mistakes + " mistake" + (mistakes === 1 ? "" : "s") : "No mistakes"); document.getElementById("mbody").innerHTML = "<h2>Welcome back 👋</h2>" + "<div class='score'>Today's puzzle is in progress.<br>" + esc(status) + "</div>" + "<div class='rowbtns'><button class='hbtn primary' onclick='closeModal()'>Continue playing</button></div>"; openModal(false); }
function startGame() { special = norm(puzzle.s); hubEmoji = puzzle.x || HUB_EMOJI[special] || null; /* custom puzzles set their own via builder */ cats = puzzle.c.map((c) => ({ name: c[0], words: [norm(c[1]), norm(c[2])], })); const words = [special, ...cats.flatMap((c) => c.words)]; for (let i = words.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [words[i], words[j]] = [words[j], words[i]]; } slots = words.slice(); /* if there's saved progress for this puzzle, reuse its board order so tiles sit where the player left them instead of reshuffling */ const saved = loadGame(); /* only resume if the saved board's words still match this puzzle — guards against a puzzle being edited after someone started it (stale words would become orphan tiles) */ const expected = words.slice().sort().join(""); const resuming = saved && saved.s === special && Array.isArray(saved.slots0) && saved.slots0.length === 9 && saved.slots0.slice().sort().join("") === expected; if (resuming) slots = saved.slots0.slice(); slots0 = slots.slice(); if (hubSpinTween) { hubSpinTween.kill(); hubSpinTween = null; } hubFx.forEach((tw) => tw.kill()); hubFx = []; selection = []; solvedIdx = []; colorCat = {}; locked = new Set(); mistakes = 0; penalty = 0; guesses = []; over = false; animating = false; adClicked = false; startTime = Date.now(); solveMs = null; fb = { diff: 0, fun: 0, special: "" }; document.getElementById("boardWrap").style.display = ""; document.getElementById("result").style.display = "none"; document.getElementById("fbCard").style.display = "none"; document.getElementById("solvedList").innerHTML = ""; const db = document.getElementById("deselBtn"); db.style.display = ""; db.style.opacity = ""; const sb = document.getElementById("shuffleBtn"); sb.style.display = ""; sb.style.opacity = ""; sb.disabled = false; shuffling = false; buildTiles(); if (resuming) { restoreGame(saved); } else { if (firstLoad && G) introDeal(); else layout(true); renderMist(); updateButtons(); } firstLoad = false; } function buildTiles() { const b = document.getElementById("board"); b.innerHTML = ""; tiles = {}; for (const w of slots) { const t = document.createElement("div"); t.className = "tile"; const flip = document.createElement("div"); flip.className = "tflip"; const inner = document.createElement("div"); inner.className = "tin"; inner.style.animationDelay = (-Math.random() * 16).toFixed(2) + "s"; /* desync the color drift */ inner.appendChild(document.createTextNode(w)); const back = document.createElement("div"); back.className = "tback"; flip.appendChild(inner); flip.appendChild(back); t.appendChild(flip); t.onclick = () => tapWord(w); /* keyboard + screen-reader: each tile is a real button you can Tab to */ t.setAttribute("role", "button"); t.setAttribute("aria-label", w); t.tabIndex = 0; t.onkeydown = (e) => { if ( e.key === "Enter" || e.key === " " || e.key === "Spacebar" ) { e.preventDefault(); tapWord(w); } }; b.appendChild(t); tiles[w] = t; } paintTiles(); }
/* ---------- layout & movement ---------- */ function slotXY(i) { return { x: (i % 3) * (TW + GAP), y: Math.floor(i / 3) * (TH + GAP), }; } function layout(instant) { const b = document.getElementById("board"); if ( !b || document.getElementById("boardWrap").style.display === "none" ) return; const W = b.clientWidth || b.parentElement.clientWidth - 34; TW = (W - 2 * GAP) / 3; TH = Math.max(56, TW * 0.62); b.style.height = 3 * TH + 2 * GAP + "px"; /* one flip per transition, only FLIP_CHANCE of the time: pick a single moving, non-hub card now (before the loop below rewrites positions) */ let flipWord = null; if ( G && !instant && !suppressFlip && Math.random() < FLIP_CHANCE ) { const movers = slots.filter((w, i) => { const t = w && tiles[w]; if (!t || w === special) return false; const p = slotXY(i); return t._sx !== p.x || t._sy !== p.y; }); if (movers.length) flipWord = movers[Math.floor(Math.random() * movers.length)]; } let moveIdx = 0; slots.forEach((w, i) => { if (!w) return; const t = tiles[w]; if (!t) return; const p = slotXY(i); t.style.width = TW + "px"; t.style.height = TH + "px"; const moved = t._sx !== p.x || t._sy !== p.y; t._sx = p.x; t._sy = p.y; if (G && !instant && moved) { /* staggered glide with a little lift-and-settle */ const d = moveIdx++ * 0.055; G.to(t, { x: p.x, y: p.y, duration: 0.85, delay: d, ease: "power3.inOut", overwrite: true, }); /* kill any in-flight move so rapid shuffles can't fight each other */ const inn = t.querySelector(".tin"); G.timeline({ delay: d }) .to(inn, { scale: 1.06, duration: 0.32, ease: "power2.out", }) .to( inn, { scale: 1, duration: 0.5, ease: "power2.inOut", }, ">-0.05", ); /* the one chosen card does a full 360° flip as it travels (lands face-up) */ if (w === flipWord) { const flip = t.querySelector(".tflip"), prevZ = t.style.zIndex; t.style.zIndex = "6"; /* a flipping card always rides above its neighbours */ G.set(t, { perspective: 700, }); /* depth for the flip */ G.to(flip, { rotationY: "+=" + (Math.random() < 0.5 ? 360 : -360), duration: 0.85, delay: d, ease: "power2.inOut", onComplete: () => { t.style.zIndex = prevZ; }, }); } } else if (G) { G.killTweensOf(t); G.set(t, { x: p.x, y: p.y }); } else t.style.transform = "translate(" + p.x + "px," + p.y + "px)"; }); syncDomOrder(); } /* first-load flourish: the cards start jumbled face-up in the centre, then organize themselves into the grid */ function introDeal() { layout(true); /* final positions + sizes */ if (!G) return; introPlaying = true; const b = document.getElementById("board"); const W = b.clientWidth || b.parentElement.clientWidth - 34; const cx = W / 2 - TW / 2, cy = (3 * TH + 2 * GAP) / 2 - TH / 2; const ws = slots.filter(Boolean); ws.forEach((w, k) => { /* jumble them in the centre */ const t = tiles[w]; if (!t) return; t.style.zIndex = String(10 + k); G.set(t, { x: cx + (Math.random() * 44 - 22), y: cy + (Math.random() * 44 - 22), rotation: Math.random() * 44 - 22, }); }); ws.forEach((w, k) => { /* settle into the grid */ const t = tiles[w]; if (!t) return; const fx = t._sx, fy = t._sy; G.to(t, { x: fx, y: fy, rotation: 0, duration: 0.8, delay: 0, ease: "power3.inOut", onComplete: () => { t.style.zIndex = ""; if (k === ws.length - 1) introPlaying = false; }, }); }); } /* Tiles are positioned by transform, so reordering the DOM nodes doesn't move anything visually — but it makes Tab/reading order follow the board layout (left→right, top→bottom) instead of the original shuffle. */ function syncDomOrder() { const b = document.getElementById("board"); const want = slots.map((w) => w && tiles[w]).filter(Boolean); const cur = b.children; let same = cur.length === want.length; for (let i = 0; same && i < want.length; i++) if (cur[i] !== want[i]) same = false; if (same) return; /* already ordered — re-appending would cancel in-flight fades */ for (const t of want) b.appendChild(t); } window.addEventListener("resize", () => layout(true));
/* First solve: trio snaps to its category's colored line (hub on a stable 1-of-3 cell, center only ~1/3 of the time). From the second solve on: hub → center, each solved pair → its category's line through it. */ function reflowSlots() { const target = new Array(9).fill(null); if (solvedIdx.length === 1 && !over) { /* first solve snaps to THIS category's colored line so the directional cue shows immediately; the hub takes a stable 1-of-3 spot on the line (center only ~1/3 of the time) so it isn't always given away as the middle card */ const ci = solvedIdx[0]; const cells = [LINES[ci][0], CENTER, LINES[ci][1]]; const words = cats[ci].words.slice(); const hp = hubSlotPos(special + "|" + ci); let wi = 0; cells.forEach((cell, idx) => { target[cell] = idx === hp ? special : words[wi++]; }); } else if (solvedIdx.length >= 2 || over) { target[CENTER] = special; solvedIdx.forEach((ci) => { target[LINES[ci][0]] = cats[ci].words[0]; target[LINES[ci][1]] = cats[ci].words[1]; }); } else return; const placed = new Set(target.filter(Boolean)); const free = []; for (let i = 0; i < 9; i++) if (!target[i]) free.push(i); const pending = []; slots.forEach((w, i) => { if (!w || placed.has(w)) return; if (!target[i] && free.includes(i)) { target[i] = w; free.splice(free.indexOf(i), 1); } else pending.push(w); }); for (const w of pending) { const i = free.shift(); target[i] = w; } slots = target; }
/* ---------- painting ---------- */ /* Center-tile gradient: each solved category's color sits at the two compass points where its line meets the center, blended smoothly around the circle. Keyed by CATEGORY index (matches LINES): 0 blue = diag ↘ (NW/SE), 1 green = middle column (N/S), 2 yellow = middle row (E/W), 3 purple = diag ↗ (NE/SW). */ const MIDC = ["#b1c9f7", "#b3dcc0", "#f3da8e", "#d2b9f0"]; const LINE_ANGLES = [ [315, 135], [0, 180], [90, 270], [45, 225], ]; function hubGradient(offset) { offset = offset || 0; const stops = []; solvedIdx.forEach((ci) => { for (const a of LINE_ANGLES[ci]) stops.push([a, MIDC[ci]]); }); if (!stops.length) return "#fff"; stops.sort((p, q) => p[0] - q[0]); const first = stops[0], last = stops[stops.length - 1]; const full = [ [last[0] - 360, last[1]], ...stops, [first[0] + 360, first[1]], ]; return ( "conic-gradient(from " + offset + "deg," + full.map((s) => s[1] + " " + s[0] + "deg").join(",") + ")" ); } let hubSpinTween = null, hubFx = []; function spinHub() { const t = tiles[special]; if (!t || !G) return; const inner = t.querySelector(".tin"), o = { a: 0 }; if (hubSpinTween) hubSpinTween.kill(); hubSpinTween = G.to(o, { a: 360, duration: 14, repeat: -1, ease: "none", onUpdate: () => { inner.style.background = hubGradient(o.a); }, }); } /* 3D pop: the center tile lifts off the board and floats, CSS-perspective style. Happens the moment the hub lands in the center (second solve); everything else animates beneath it from then on. */ function popHub() { const t = tiles[special]; if (!t || !G) return; hubFx.forEach((tw) => tw.kill()); hubFx = []; const inner = t.querySelector(".tin"); t.style.zIndex = 5; G.set(inner, { transformPerspective: 700 }); hubFx.push( G.to(inner, { z: 34, duration: 1.2, ease: "power2.out" }), G.to(inner, { y: -4, duration: 2.4, yoyo: true, repeat: -1, ease: "sine.inOut", }), G.to(inner, { rotationY: 7, duration: 3.2, yoyo: true, repeat: -1, ease: "sine.inOut", }), G.to(inner, { rotationX: -5, duration: 2.7, yoyo: true, repeat: -1, ease: "sine.inOut", delay: 0.4, }), ); } const SPARKLE = "data:image/png;base64,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"; const SPARK = new Image(); SPARK.src = SPARKLE; /* sparkle PNG inlined so it never taints the share canvas; shared with the live hub sparkles */ /* twinkling sparkles around the won hub — joins shine/spin/float in endFlourish. Lives on the board (not the hub tile) so it ignores the hub's drift; win only. */ function sparkleHub() { const t = tiles[special]; if (!t || !G || mistakes >= MAXM) return; const b = document.getElementById("board"); const cx = t._sx + TW / 2, cy = t._sy + TH / 2; for (let i = 0; i < 6; i++) { const s = document.createElement("img"); s.src = SPARKLE; s.alt = ""; const sz = 14 + Math.random() * 16, ang = Math.random() * Math.PI * 2, r = TW * 0.4 + Math.random() * TW * 0.55; s.style.cssText = "position:absolute;left:" + (cx + Math.cos(ang) * r - sz / 2) + "px;top:" + (cy + Math.sin(ang) * r - sz / 2) + "px;width:" + sz + "px;height:" + sz + "px;pointer-events:none;z-index:6;opacity:0;"; b.appendChild(s); hubFx.push( G.fromTo( s, { scale: 0, rotation: Math.random() * 60 }, { opacity: 0.9, scale: 0.6 + Math.random() * 0.6, duration: 0.5 + Math.random() * 0.4, delay: Math.random() * 2.4, repeat: -1, repeatDelay: 1.6 + Math.random() * 2.4, yoyo: true, ease: "sine.inOut", }, ), ); } } function paintTiles() { for (const w of Object.keys(tiles)) { const t = tiles[w], inner = t.querySelector(".tin"); const sel = selection.includes(w); t.classList.toggle("sel", sel); t.classList.toggle("lock", locked.has(w)); /* a11y state: announce selection, drop solved/finished tiles out of the tab order */ t.setAttribute("aria-pressed", sel ? "true" : "false"); const inert = locked.has(w) || over; t.tabIndex = inert ? -1 : 0; if (inert) t.setAttribute("aria-disabled", "true"); else t.removeAttribute("aria-disabled"); const hubPlaced = w === special && (solvedIdx.length >= 2 || over); /* hub sits in the center now */ const ci = colorCat[w]; /* card back: a solved tile shows its category-coloured fish; otherwise the default light back */ const back = t.querySelector(".tback"); if (back) back.style.backgroundImage = ci !== undefined && !hubPlaced ? "url('" + BACKS[ci] + "')" : ""; inner.classList.toggle( "idle", !sel && !hubPlaced && ci === undefined, ); /* color drift only on plain tiles */ if (sel) { inner.style.background = ""; inner.style.borderColor = ""; inner.style.color = ""; } else if (hubPlaced) { /* directional gradient: each solved category's color radiates toward its line */ inner.style.background = hubGradient(); inner.style.borderColor = "#d4a017"; inner.style.color = "var(--ink)"; } else if (ci !== undefined) { inner.style.background = TINTS[ci]; inner.style.borderColor = COLORS[ci]; inner.style.color = COLORS[ci]; } else { inner.style.background = ""; inner.style.borderColor = ""; inner.style.color = ""; } } } /* The shared word lives among the already-solved tiles. After the first solve it's hidden in that trio (3 candidates); once the hub reveals it's just the hub. Every group after the first must reuse exactly one of these. */ function sharedSet() { const s = new Set(); if (solvedIdx.length === 0) return s; if (solvedIdx.length === 1) { for (const w of [special, ...cats[solvedIdx[0]].words]) s.add(w); } else s.add(special); return s; } function sharedCount() { const s = sharedSet(); return selection.filter((w) => s.has(w)).length; } function updateButtons() { let ok = selection.length === 3 && !over && !animating; if (ok && solvedIdx.length >= 1 && sharedCount() !== 1) ok = false; /* must reuse exactly one solved word */ document.getElementById("submitBtn").disabled = !ok; }
/* ---------- interaction ---------- */ const POP_EMOJI = [ "🎉", "✨", "🌟", "🐟", "💫", "🥳", "💛", "💚", "💙", "💜", ]; /* one of the popped emojis nods to the puzzle's hub word */ const HUB_EMOJI = { MOLE: "🕵️", HEAVY: "🏋️", TIRE: "🛞", CUP: "🏆", FANTA: "🥤", SPRING: "🌸", STORM: "⛈️", BUD: "🌱", PILL: "💊", GOAL: "🥅", POP: "🎈", BUTTON: "🔘", DARK: "🌑", PITCH: "⚾", WALLET: "👛", KICK: "🦵", MATCH: "🔥", FISH: "🐟", CATCH: "🧤", LAX: "😌", PLANE: "✈️", }; /* puzzles here emit ONE emoji only on the post-win center tap (overrides HUB_EMOJI + POP_EMOJI mix) */ const SOLO_POP = { GOAL: "🦋" }; /* live hub-emoji poll (weights edited by hand in hubpoll.json). When active, the center-tap burst emoji rotates every 5 minutes, weighted by the poll standings, on a shared clock so every player sees the same emoji in the same window. */ let pollCfg = null; async function loadPoll() { /* prefer the live Vercel endpoint (reads the X poll); fall back to the hand-edited file. the ?w= bucket changes every 5 min so we never get stuck on a stale cached response, while still sharing one cached result (one X read) across everyone in that window */ try { const r = await fetch( "/api/hubpoll?w=" + Math.floor(Date.now() / 300000), ); if (r.ok) { const j = await r.json(); if (j && j.active) { pollCfg = j; return; } } } catch (e) {} try { const r = await fetch(pjURL("hubpoll.json"), { cache: "no-store", }); if (r.ok) pollCfg = await r.json(); } catch (e) {} } /* one weighted emoji for the current 5-minute window — same emoji for everyone in that window; over time each shows up in proportion to the vote counts */ function pollEmoji() { if ( !pollCfg || !pollCfg.active || !Array.isArray(pollCfg.options) ) return null; const opts = pollCfg.options.filter( (o) => o && o.emoji && o.weight > 0, ); if (!opts.length) return null; const total = opts.reduce((a, o) => a + o.weight, 0); const slot = Math.floor( Date.now() / 300000, ); /* 5-minute window */ let h = (slot * 2654435761) >>> 0; h ^= h >>> 15; h = Math.imul(h, 2246822519) >>> 0; h ^= h >>> 13; /* uniform 0..1 from the slot */ const r = ((h >>> 0) / 4294967296) * total; let acc = 0; for (const o of opts) { acc += o.weight; if (r < acc) return o.emoji; } return opts[opts.length - 1].emoji; } /* hover-for-definition copy (BETA) — only puzzles listed here get tooltips on the finished answer list, keyed by hub word then exact category name */ const DEFS = { GOAL: { "___ Keeper": { ZOO: "A zookeeper cares for the animals at a zoo.", GOAL: "A goalkeeper (goalie) guards the net in soccer and hockey.", BEE: "A beekeeper raises bees and harvests honey.", }, "A Score in Sport": { BASKET: "In basketball, a shot through the hoop is a basket.", GOAL: "In soccer or hockey, putting it in the net scores a goal.", TRY: "In rugby, grounding the ball past the line scores a try.", }, "A Personal Aim": { DREAM: "Something you long to do or become.", GOAL: "An objective you set for yourself and work toward.", AMBITION: "A particular aim or aspiration; something you hope to achieve.", }, "Things with Posts": { FENCE: "A fence is held up by fence posts.", GOAL: "A goal is framed by two goal posts.", BLUESKY: "Bluesky is a social network where you share posts.", }, }, HEAVY: { "___ Metal": { DEATH: "Death metal — an extreme, aggressive subgenre of heavy metal.", HEAVY: "Heavy metal — the loud, distorted, guitar-driven rock genre.", GLAM: "Glam metal — the flashy, hair-band metal of the 1980s.", }, "SpaceX Falcon Rockets": { ONE: "Falcon 1 — SpaceX's first rocket, and the first privately built liquid-fueled rocket to reach orbit.", HEAVY: "Falcon Heavy — SpaceX's heavy-lift rocket, three Falcon 9 cores strapped together.", NINE: "Falcon 9 — SpaceX's reusable workhorse rocket, named for its nine first-stage engines.", }, Serious: { SOMBER: "Dark, grave, and serious in mood.", HEAVY: "Weighty and serious — as in a 'heavy' conversation.", GRAVE: "Solemn and serious; demanding real concern.", }, "Boxing Weights": { WELTER: "Welterweight — a boxing division capped around 147 lbs.", HEAVY: "Heavyweight — boxing's top division, with no upper weight limit.", MIDDLE: "Middleweight — a boxing division capped around 160 lbs.", }, }, POP: { "___ Corn": { KETTLE: "Kettle corn: popcorn cooked with sugar and salt for a sweet-and-salty snack.", SWEET: "Sweet corn: the tender, sugary corn you eat off the cob.", POP: "Popcorn: dried corn kernels that burst into fluffy puffs when heated.", }, "Stand Out": { SHINE: "To be conspicuously good; to stand out.", SING: 'When something really "sings," it demands attention.', POP: 'Vivid and eye-catching, as in "make the colors pop."', }, "Rice Krispies Noises": { SNAP: "Snap, the first of the three Rice Krispies mascots: Snap! Crackle! Pop!", CRACKLE: "They get their names from the noise the milk makes when you pour it into puffed rice.", POP: "If you're not familiar because this is an American thing, we apologize.", }, Palindromes: { RACECAR: "Racecar (somewhat famously) reads the same forwards and backwards.", ROTOR: "Also a palindrome; the spinning part of a motor or turbine.", POP: "Pop, yes, it's a tiny palindrome.", }, }, BUTTON: { "Mushroom Varieties": { OYSTER: "A soft, fan-shaped, mild edible mushroom.", SHIITAKE: "A savory, meaty mushroom common in East Asian cooking.", BUTTON: "The common little white mushroom.", }, "Things You Press": { KEY: "You press a key on a keyboard.", DOORBELL: "The button on a house you press instead of knocking.", BUTTON: "You press a button to make something happen.", }, "Clothing Fasteners": { ZIPPER: "Joins two edges of fabric with interlocking teeth.", CLASP: "A fastener that hooks two things together.", BUTTON: "Slips through a buttonhole to fasten clothing.", }, "F1 World Champions": { HAMILTON: "Lewis Hamilton, seven-time Formula 1 World Champion.", VETTEL: "Sebastian Vettel, four-time F1 World Champion.", BUTTON: "Jenson Button, the 2009 Formula 1 World Champion.", }, }, DARK: { "Evil or Menacing": { GRIM: "Harsh, forbidding, and gloomy.", SINISTER: "Hinting that something evil is coming.", DARK: "Sinister or troubled, as in 'a dark mood.'", }, "Types of Chocolate": { MILK: "Milk chocolate — sweet and creamy, made with milk.", WHITE: "White chocolate — cocoa butter and sugar, no cocoa solids.", DARK: "Dark chocolate — rich and bittersweet, heavy on cocoa.", }, "Lacking Light": { DIM: "Faintly lit; not bright.", MURKY: "Dim and cloudy; hard to see through.", DARK: "With little or no light.", }, 'Contains "ARK"': { SHARK: "Has 'ARK' inside it: sh-ARK.", SPARKLE: "Has 'ARK' inside it: sp-ARK-le.", DARK: "Has 'ARK' inside it: d-ARK.", }, }, PITCH: { "Qualities of a Musical Note": { TONE: "The quality of a sound.", KEY: "The notes a piece is built on.", PITCH: "How high or low a note sounds.", }, "Where a Match Is Played": { FIELD: "The playing area.", GROUND: "British for a sports stadium or field.", PITCH: "British for a sports field, as in a football pitch.", }, "To Throw a Baseball": { TOSS: "Throw lightly.", HURL: "Throw hard.", PITCH: "Throw the ball to the batter.", }, "Famously black things": { JET: "A glossy-black gemstone — actually a form of coal.", COAL: "The combustible fossil-fuel rock.", PITCH: "A dark resin produced after distilling coal tar.", }, }, WALLET: { "Found in a Pocket": { KEYS: "Your keys — you pat your pocket to find them.", PHONE: "Once wired to a wall, now a pocket computer.", WALLET: "A wallet rides in your pocket (or bag).", }, "Made of Leather": { BOOT: "Classic boots are made of leather.", BELT: "The classic belt is a strip of leather.", WALLET: "The classic wallet is folded leather.", }, "Pre-Installed on iPhone": { SAFARI: "Apple's built-in web browser.", PHOTOS: "The stock iPhone photo library.", WALLET: "Apple's app for cards, passes, and payments.", }, "Foldable Item": { FAN: "A folding hand fan opens with a flick.", MAP: "A paper road map folds down small.", WALLET: "A billfold wallet folds in half.", }, }, }; /* post-game easter egg: tap the hub to press it in and burst out emojis */ function hubPop() { const t = tiles[special]; if (!t) return; const inner = t.querySelector(".tin"); if (G) { G.killTweensOf(inner, "scale"); G.timeline() .set(inner, { scale: 1 }) .to(inner, { scale: 0.85, duration: 0.09, ease: "power2.in", }) .to(inner, { scale: 1, duration: 0.22, ease: "back.out(2.2)", }); } const b = document.getElementById("board"); /* a bunch of celebratory emojis with one hub-word easter egg mixed in */ const cx = t._sx + TW / 2, cy = t._sy + TH / 2, he = hubEmoji; for (let i = 0; i < 12; i++) { const e = document.createElement("div"); e.textContent = he && i === 0 ? he : POP_EMOJI[ Math.floor(Math.random() * POP_EMOJI.length) ]; e.style.cssText = "position:absolute;left:" + (cx - 12) + "px;top:" + (cy - 12) + "px;font-size:" + (18 + Math.random() * 14) + "px;pointer-events:none;z-index:30;will-change:transform;"; b.appendChild(e); if (G) { const a = Math.random() * Math.PI * 2, d = 55 + Math.random() * 120; G.fromTo( e, { scale: 0, opacity: 1 }, { x: Math.cos(a) * d, y: Math.sin(a) * d - 28, rotation: Math.random() * 140 - 70, scale: 1, duration: 0.95 + Math.random() * 0.5, ease: "power2.out", }, ); G.to(e, { opacity: 0, duration: 0.45, delay: 0.55, ease: "power1.in", onComplete: () => e.remove(), }); } else { e.remove(); } } } function tapWord(w) { if (over) { if (w === special) hubPop(); return; } /* finished board: hub is an emoji button */ if (animating || locked.has(w)) return; const i = selection.indexOf(w); if (i >= 0) selection.splice(i, 1); else if (selection.length < 3) { const shared = sharedSet(); if (shared.has(w) && selection.some((x) => shared.has(x))) { toast("Just one shared word per group."); return; } selection.push(w); /* the teaching moment: a full group of three that reuses none of a solved category */ if ( selection.length === 3 && solvedIdx.length >= 1 && sharedCount() === 0 ) toast("All four categories share a word", 3600); } else return; if (G) G.fromTo( tiles[w].querySelector(".tin"), { scale: 0.95 }, { scale: 1, duration: 0.3, ease: "back.out(2.5)" }, ); paintTiles(); updateButtons(); } function deselectAll() { if (animating) return; selection = []; paintTiles(); updateButtons(); } /* Shuffle: re-randomize only the still-in-play tiles among the slots they occupy. Solved/coloured groups and the centred hub stay put. */ function shuffleBoard() { if (over || animating || shuffling) return; const hubPlaced = solvedIdx.length >= 2 || over; const idxs = [], words = []; slots.forEach((w, i) => { if (!w) return; if (colorCat[w] !== undefined) return; /* part of a solved group — leave it */ if (w === special && hubPlaced) return; /* hub sits in the centre */ idxs.push(i); words.push(w); }); if (words.length < 2) return; const orig = words.slice(); let tries = 0; do { for (let k = words.length - 1; k > 0; k--) { const j = Math.floor(Math.random() * (k + 1)); [words[k], words[j]] = [words[j], words[k]]; } } while ( ++tries < 6 && words.every((w, k) => w === orig[k]) ); /* avoid a no-op shuffle */ idxs.forEach((i, k) => { slots[i] = words[k]; }); suppressFlip = true; /* a shuffle shouldn't trigger a card flip */ layout(false); suppressFlip = false; /* don't accept another shuffle until this glide is done */ if (G) { shuffling = true; const btn = document.getElementById("shuffleBtn"); if (btn) btn.disabled = true; G.delayedCall(0.5 * (0.85 + idxs.length * 0.055), () => { shuffling = false; if (btn) btn.disabled = false; }); /* release once the cards are most of the way home — snappy re-shuffle */ } }
function submitGuess() { if (selection.length !== 3 || over || animating) return; const sel = [...selection]; guesses.push(sel); let hit = -1, oneAway = false; cats.forEach((c, i) => { if (solvedIdx.includes(i)) return; const full = [special, ...c.words]; const m = sel.filter((w) => full.includes(w)).length; if (m === 3 && sel.includes(special)) hit = i; else if (m === 2) oneAway = true; }); if (hit >= 0) solveAnim(hit, sel); else wrongAnim(sel, oneAway); } function solveAnim(ci, sel) { animating = true; updateButtons(); selection = []; const after = () => { solvedIdx.push(ci); if (solvedIdx.length === 1) { /* first solve: trio → top row, all the same color, hub not singled out */ for (const w of [special, ...cats[ci].words]) colorCat[w] = ci; } else { for (const w of cats[ci].words) { colorCat[w] = ci; locked.add(w); } if (solvedIdx.length === 2) { /* hub heads to center: lock the first group's pair, give the hub its own look */ for (const w of cats[solvedIdx[0]].words) locked.add(w); delete colorCat[special]; } } reflowSlots(); syncDomOrder(); /* reorder DOM first so the recolour fade below isn't cancelled by a node move */ renderSolvedList(); paintTiles(); layout(false); saveGame(); setTimeout( () => { animating = false; updateButtons(); if (solvedIdx.length === 4) endGame(true); }, G ? 1250 : 60, ); }; if (G) { sel.forEach((w, k) => { const inn = tiles[w].querySelector(".tin"); G.timeline({ delay: k * 0.09 }) .to(inn, { scale: 1.12, duration: 0.22, ease: "power2.out", }) .to(inn, { scale: 1, duration: 0.38, ease: "back.out(2.2)", }); }); G.delayedCall(0.55, after); } else after(); } function wrongAnim(sel, oneAway) { mistakes++; penalty += solvedIdx.length >= 2 ? MISS_LATE : MISS; /* a slip with two categories left stings more */ toast(oneAway ? "One away!" : "Nope."); if (G) { animating = true; updateButtons(); sel.forEach((w, k) => { /* shake the face, not the slot position — no transform conflicts */ const inn = tiles[w].querySelector(".tin"); G.timeline({ delay: k * 0.04 }) .to(inn, { x: -6, duration: 0.07, ease: "sine.inOut", }) .to(inn, { x: 6, duration: 0.12, ease: "sine.inOut", }) .to(inn, { x: -4, duration: 0.1, ease: "sine.inOut", }) .to(inn, { x: 0, duration: 0.09, ease: "sine.out", }); }); setTimeout(() => { animating = false; selection = []; paintTiles(); updateButtons(); renderMist(); saveGame(); if (mistakes >= MAXM) endGame(false); }, 560); } else { selection = []; paintTiles(); updateButtons(); renderMist(); saveGame(); if (mistakes >= MAXM) endGame(false); } } function renderSolvedList() { const el = document.getElementById("solvedList"); el.innerHTML = ""; const defsOn = DEFS[ special ]; /* hover-definitions on revealed words (hub-known rows), no wait for game end */ solvedIdx.forEach((ci) => { const c = cats[ci]; const div = document.createElement("div"); div.className = "scat"; div.style.background = TINTS[ci]; const dmap = defsOn ? DEFS[special][c.name] || {} : null; const mk = (w, hub) => { const def = dmap ? dmap[w] : null, cl = []; if (hub) cl.push("hub"); if (def) cl.push("def"); if (!cl.length) return esc(w); return ( "<span class='" + cl.join(" ") + "'" + (def ? ' data-def="' + esc(def) + '"' : "") + ">" + esc(w) + "</span>" ); }; let wordsTxt; if (hubKnown()) wordsTxt = mk(c.words[0]) + " · " + mk(special, true) + " · " + mk(c.words[1]); else wordsTxt = [...c.words, special] .sort() .map((w) => mk(w)) .join( " · ", ); /* tooltips on from the first solve; no .hub class = no hub spoiler */ div.innerHTML = "<b style='color:" + COLORS[ci] + "'>" + esc(c.name) + "</b><span>" + wordsTxt + "</span>"; el.appendChild(div); }); const last = el.lastElementChild; if (G && last) G.from(last, { opacity: 0, y: 10, scale: 0.97, duration: 0.5, ease: "power2.out", }); } function renderMist() { let h = "Mistakes: "; for (let i = 0; i < MAXM; i++) h += "<i" + (i < MAXM - mistakes ? " class='spent'" : "") + "></i>"; document.getElementById("mist").innerHTML = h; }
/* ---------- scoring ---------- */ /* Hub First: every submitted guess (even wrong ones) led with the special word */ /* point values (MISS, HUB_BONUS, PURPLE_BONUS, …) now live in shared.js */ function hubFirstAll() { return ( guesses.length > 0 && guesses.every((g) => g[0] === special) ); } function hubMiddleAll() { return ( guesses.length > 0 && guesses.every((g) => g[1] === special) ); } function hubLastAll() { return ( guesses.length > 0 && guesses.every((g) => g[2] === special) ); } function isPurpleFirst() { return solvedIdx[0] === 3; } function isBlueFirst() { return solvedIdx[0] === 0; } function orderIs(seq) { return ( solvedIdx.length === 4 && seq.every((c, i) => solvedIdx[i] === c) ); } function isRevRainbow() { return orderIs(REV_RAINBOW); } function isRainbow() { return orderIs(RAINBOW); } /* yellow → green → blue → purple */ function isGrellow() { return orderIs(GRELLOW); } /* purple → blue → yellow → green */ function isGrue() { return orderIs(GRUE); } /* purple → green → blue → yellow */ function calcScore() { const won = mistakes < MAXM; const perfect = won && mistakes === 0; const hubFirst = won && hubFirstAll(); const hubMiddle = won && hubMiddleAll(); const ruleBreaker = won && hubLastAll(); /* hub LAST every guess → wipes the board */ const purpleFirst = won && isPurpleFirst(); const blueFirst = won && isBlueFirst(); const revRainbow = won && isRevRainbow(); const rainbow = won && isRainbow(); /* forward rainbow — its own card, no points */ const grellow = won && isGrellow(); /* no points, just an achievement */ const grue = won && isGrue(); /* no points, just an achievement */ const godDamnit = perfect && hubFirst && (grellow || grue); /* would've been perfect but for a green↔yellow or green↔blue swap */ const dayBefore = won && dailyKey === todayStr() && new Date(startTime).getHours() === 0; /* played today's daily between midnight and 1am local */ const fast = won && solveMs !== null && solveMs < 90000; /* solved in under 90 seconds → gems + bonus */ let score = won ? Math.max(10, 100 - penalty) + (hubFirst ? HUB_BONUS : 0) + (hubMiddle ? HUB_MID_BONUS : 0) + (purpleFirst ? PURPLE_BONUS : 0) + (blueFirst ? BLUE_BONUS : 0) + (revRainbow ? RAINBOW_BONUS : 0) + (fast ? SPEED_BONUS : 0) : 0; let allRewards = perfect && hubFirst && revRainbow; /* everything → a clean 200 */ let goldPlaque = allRewards && fast; /* perfect AND under 90s */ let silverPlaque = allRewards && solveMs !== null && solveMs < 120000 && !goldPlaque; /* perfect, 90–120s */ let perfectBonus = allRewards ? 200 - score : 0; score += perfectBonus; const streak = won && dailyKey === todayStr() ? streakWithToday() : 0; /* +1/day of streak — release-day plays only */ score += streak; const adBonus = won && adClicked ? AD_BONUS : 0; /* thanks for clicking the ad */ score += adBonus; if (ruleBreaker) { score = RULE_BREAKER_SCORE; allRewards = false; goldPlaque = false; silverPlaque = false; perfectBonus = 0; } /* RULE BREAKER trumps everything */ /* personal-best / above-average badges (0 points). Compared against this browser's OTHER dailies, excluding today's own entry, so they stay stable on re-render. */ const past = dailyKey ? otherDailyScores(dailyKey) : []; const prevBest = past.length ? Math.max.apply(null, past) : null; const prevAvg = past.length ? past.reduce((a, b) => a + b, 0) / past.length : null; const topScore = won && prevBest !== null && score > prevBest; /* a new all-time high */ const beatAvg = won && prevAvg !== null && score > prevAvg && !topScore; /* above your average (top score already implies it) */ return { won, perfect, hubFirst, hubMiddle, ruleBreaker, purpleFirst, blueFirst, revRainbow, rainbow, grellow, grue, godDamnit, dayBefore, fast, allRewards, goldPlaque, silverPlaque, perfectBonus, streak, adBonus, topScore, beatAvg, score, }; }
/* ---------- end ---------- */ function shineHub() { const t = tiles[special]; if (!t) return; const inner = t.querySelector(".tin"); if (inner.querySelector(".shinewrap")) return; const wrap = document.createElement("div"); wrap.className = "shinewrap"; const streak = document.createElement("div"); streak.className = "streak"; wrap.appendChild(streak); inner.appendChild(wrap); if (G) { /* glossy sweep every few seconds + a soft gold glow breathing underneath */ G.fromTo( streak, { xPercent: -220 }, { xPercent: 520, duration: 2.6, ease: "sine.inOut", repeat: -1, repeatDelay: 5.5, delay: 0.6, }, ); /* breathing glow + a soft shadow falling beneath the floating tile */ G.fromTo( inner, { boxShadow: "0 10px 16px rgba(43,38,32,.22), 0 0 6px rgba(212,160,23,.14)", }, { boxShadow: "0 18px 28px rgba(43,38,32,.3), 0 0 12px rgba(212,160,23,.26)", duration: 2.6, yoyo: true, repeat: -1, ease: "sine.inOut", }, ); } } function endGame(won) { over = true; if (solveMs === null) solveMs = Date.now() - startTime; if (!won) { cats.forEach((c, i) => { if (!solvedIdx.includes(i)) { solvedIdx.push(i); for (const w of c.words) { colorCat[w] = i; } } }); } for (const ci of solvedIdx) for (const w of cats[ci].words) locked.add(w); locked.add(special); delete colorCat[special]; reflowSlots(); syncDomOrder(); /* reorder before recolour so end-of-game fades survive */ renderSolvedList(); paintTiles(); layout(false); renderMist(); saveGame(); const score = calcScore().score; saveStats(won, score, mistakes); recordHistory(); showStreakTag(); /* no more selecting/shuffling to undo */ const db = document.getElementById("deselBtn"), sb = document.getElementById("shuffleBtn"); if (G) G.to([db, sb], { opacity: 0, duration: 0.4, onComplete: () => { db.style.display = "none"; sb.style.display = "none"; }, }); else { db.style.display = "none"; sb.style.display = "none"; } if (won && G) winSequence(won, score); else { showResult(won, score); setTimeout(endFlourish, G ? 1300 : 100); } } /* the slow, beautiful bit: hub zooms out, explodes, share screen appears */ function winSequence(won, score) { const t = tiles[special]; const others = Object.keys(tiles) .filter((w) => w !== special) .map((w) => tiles[w]); t.style.zIndex = 20; /* hub stays on top throughout */ hubFx.forEach((tw) => tw.kill()); hubFx = []; /* the non-hub cards flip in a diagonal wave WHILE the hub slowly zooms out, then the hub pops to reveal the share card */ slots.forEach((w, i) => { if (w === special) return; const ti = w && tiles[w]; if (!ti) return; const flip = ti.querySelector(".tflip"); const d = ((i % 3) + Math.floor(i / 3)) * 0.1; /* diagonal ripple from the top-left */ G.set(ti, { perspective: 700 }); const pz = ti.style.zIndex; ti.style.zIndex = "3"; G.to(flip, { rotationY: "+=360", duration: 0.7, delay: d, ease: "power2.inOut", onComplete: () => { ti.style.zIndex = pz; }, }); }); /* straighten the hub card so the zoom reads clean */ G.to(t.querySelector(".tin"), { rotationX: 0, rotationY: 0, y: 0, duration: 0.4, ease: "power1.inOut", }); const tl = G.timeline(); tl.to( t, { scale: 2.2, duration: 2.0, ease: "power2.inOut" }, 0, ); /* slow zoom, concurrent with the flips */ tl.to( others, { opacity: 0.3, duration: 1, ease: "power1.inOut" }, 1.0, ); /* dim once the flips have been seen */ tl.add(() => { explodeHub(t); shakeScreen(); }, 2.0); /* pop at the top of the zoom */ tl.to( t, { opacity: 0, scale: 2.6, duration: 0.2, ease: "power3.in", }, 2.0, ); tl.add( () => showResult(won, score, true), 2.0, ); /* result modal: counter tallies up, then the share card */ tl.to( others, { opacity: 1, duration: 0.7, ease: "power1.inOut" }, 2.8, ); tl.to( t, { opacity: 1, scale: 1, duration: 0.8, ease: "back.out(1.5)", }, 3.0, ); tl.add(endFlourish, 4.0); } function endFlourish() { shineHub(); spinHub(); popHub(); sparkleHub(); } /* tiny 4×3-colour confetti burst at a screen point */ function confettiBurst(x, y) { if (!G) return; for (let i = 0; i < 10; i++) { const p = document.createElement("div"), sz = 5 + Math.random() * 5; p.style.cssText = "position:fixed;left:" + (x - sz / 2) + "px;top:" + (y - sz / 2) + "px;width:" + sz + "px;height:" + sz + "px;" + "background:" + COLORS[i % 4] + ";border-radius:" + (Math.random() < 0.5 ? "50%" : "2px") + ";pointer-events:none;z-index:110;will-change:transform;"; document.body.appendChild(p); const a = Math.random() * Math.PI * 2, d = 22 + Math.random() * 46; G.to(p, { x: Math.cos(a) * d, y: Math.sin(a) * d, rotation: Math.random() * 360, opacity: 0, duration: 0.6 + Math.random() * 0.3, ease: "power2.out", onComplete: () => p.remove(), }); } } /* count-up score tally — the total starts at 0; "Completed!" supplies the base 100, then bonuses add and the mistake penalty subtracts, ~2/sec */ /* the things that pop in the result modal: [emoji, label, point delta]. Point items move the counter; achievement-only items have delta 0. Sum of deltas = score. */ function tallyItems(cs) { const it = []; if (cs.ruleBreaker) { it.push([ "💀", "Rule Breaker — shared word went last every guess", cs.score, ]); return it; } it.push([ "✅", "Completed!", 100, ]); /* base for a solve — lands first and runs the total up to 100 */ if (penalty > 0) it.push([ "💔", mistakes + " mistake" + (mistakes === 1 ? "" : "s"), -penalty, ]); if (cs.hubFirst) it.push(["🔝", "Hub First", HUB_BONUS]); if (cs.hubMiddle) it.push(["↔️", "Hub Middle", HUB_MID_BONUS]); if (cs.blueFirst) it.push(["🔵", "Blue First", BLUE_BONUS]); if (cs.purpleFirst) it.push(["🟣", "Purple First", PURPLE_BONUS]); if (cs.revRainbow) it.push(["🌈", "Reverse Rainbow", RAINBOW_BONUS]); if (cs.fast) it.push(["⚡", "Solved under 90 seconds", SPEED_BONUS]); if (cs.perfectBonus) it.push(["💯", "Perfect Game", cs.perfectBonus]); if (cs.streak > 0) it.push(["🔥", cs.streak + "-day streak", cs.streak]); if (cs.adBonus) it.push(["📣", "Thanks for the tap", cs.adBonus]); if (cs.topScore) it.push(["🏆", "Top Score — a new personal best!", 0]); if (cs.beatAvg) it.push(["📈", "Above Average — beat your average", 0]); if (cs.perfect && !cs.allRewards && !cs.godDamnit) it.push(["✨", "Perfect — no mistakes", 0]); if (cs.rainbow) it.push([ "🏳️🌈", "Rainbow — yellow → green → blue → purple", 0, ]); if (cs.grellow) it.push([ "🎾", "Grellow — purple → blue → yellow → green", 0, ]); if (cs.grue) it.push(["🦚", "Grue — purple → green → blue → yellow", 0]); if (cs.godDamnit) it.push([ "😤", "God Damnit! — perfect but for one swap", 0, ]); if (cs.dayBefore) it.push(["🌙", "The Day Before — played 12–1am", 0]); if (cs.goldPlaque) it.push(["🥇", "Gold Plaque — perfect, under 90s", 0]); else if (cs.silverPlaque) it.push(["🥈", "Silver Plaque — perfect, under 120s", 0]); return it; } /* build one readable award row from [emoji, label, point delta]. The delta shows as a coloured +N / −N; achievements (delta 0) show just icon + label on a gold row. */ function tallyRow(item) { const emoji = item[0], label = item[1], delta = item[2]; const row = document.createElement("div"); row.className = "tally-row" + (delta > 0 ? " pos" : delta < 0 ? " neg" : " ach"); row.setAttribute( "data-def", label + (delta ? " " + (delta > 0 ? "+" : "") + delta : ""), ); const dtxt = delta ? (delta > 0 ? "+" : "") + delta : ""; row.innerHTML = "<span class='tr-ico'>" + emoji + "</span><span class='tr-label'>" + esc(label) + "</span>" + "<span class='tr-delta'>" + dtxt + "</span>"; return row; } /* static (no animation) — used when re-opening a finished game */ function renderTallyStatic(score) { const c = document.getElementById("tallyCount"), ls = document.getElementById("tallyList"); if (!c) return; c.textContent = score; ls.innerHTML = ""; tallyItems(calcScore()).forEach((it) => ls.appendChild(tallyRow(it)), ); } /* animated — the counter pops in at 100, then each award row slides in one by one and the running total counts up/down to meet it; the share card fades in after */ function runModalTally(score) { const c = document.getElementById("tallyCount"), ls = document.getElementById("tallyList"), wrap = document.getElementById("shareWrap"); if (!c) return; if (!G) { renderTallyStatic(score); if (wrap) wrap.style.opacity = ""; return; } const items = tallyItems(calcScore()); c.textContent = "0"; ls.innerHTML = ""; if (wrap) G.set(wrap, { opacity: 0 }); G.fromTo( c, { scale: 0.55, opacity: 0 }, { scale: 1, opacity: 1, duration: 0.4, ease: "back.out(2)", }, ); let cur = 0; function bump(v, big) { const from = cur; const o = { v: from }; cur = v; G.to(o, { v: v, duration: 0.45, ease: "power1.out", onUpdate: () => { c.textContent = Math.round(o.v); }, }); G.fromTo( c, { scale: big ? 1.5 : 1.26 }, { scale: 1, duration: big ? 0.7 : 0.45, ease: "elastic.out(1,.5)", }, ); G.fromTo( c, { color: v >= from ? "#56b870" : "#d05b5b" }, { color: "#2b2620", duration: 0.6, ease: "power2.out" }, ); } const STEP = 0.5; let time = 0.45, acc = 0; const tl = G.timeline({ onComplete: () => { G.fromTo( c, { scale: 1.16 }, { scale: 1, duration: 0.7, ease: "elastic.out(1,.4)", }, ); if (wrap) G.to(wrap, { opacity: 1, duration: 0.45, delay: 0.2, }); }, }); items.forEach((it) => { acc += it[2]; const target = acc, big = Math.abs(it[2]) >= 20; ((item, tgt, big) => { tl.add(() => { const row = tallyRow(item); ls.appendChild(row); G.fromTo( row, { opacity: 0, x: -28, scale: 0.9 }, { opacity: 1, x: 0, scale: 1, duration: 0.44, ease: "back.out(1.6)", }, ); const d = row.querySelector(".tr-delta"); if (d && item[2]) G.fromTo( d, { scale: 1.9, opacity: 0 }, { scale: 1, opacity: 1, duration: 0.5, ease: "back.out(2.6)", delay: 0.05, }, ); const r = row.getBoundingClientRect(); confettiBurst(r.right - 16, r.top + r.height / 2); if (item[2] !== 0) bump(tgt, big); else G.fromTo( c, { scale: 1.12 }, { scale: 1, duration: 0.45, ease: "power2.out", }, ); }, time); })(it, target, big); time += STEP; }); if (!items.length) confettiBurst( innerWidth / 2, innerHeight / 2, ); /* plain win: a little celebration anyway */ } function shakeScreen() { if (!G) return; const w = document.querySelector(".wrap"); G.timeline() .to(w, { x: -5, y: 3, duration: 0.05, ease: "none" }) .to(w, { x: 4, y: -3, duration: 0.05, ease: "none" }) .to(w, { x: -3, y: -2, duration: 0.05, ease: "none" }) .to(w, { x: 3, y: 2, duration: 0.05, ease: "none" }) .to(w, { x: -1, y: 1, duration: 0.05, ease: "none" }) .to(w, { x: 0, y: 0, duration: 0.08, ease: "power2.out" }); } function explodeHub(t) { const b = document.getElementById("board"); const cx = t._sx + TW / 2, cy = t._sy + TH / 2; const palette = [...COLORS, "#d4a017", "#d4a017"]; for (let i = 0; i < 28; i++) { const p = document.createElement("div"); const sz = 6 + Math.random() * 9; p.style.cssText = "position:absolute;left:" + (cx - sz / 2) + "px;top:" + (cy - sz / 2) + "px;width:" + sz + "px;height:" + sz + "px;" + "background:" + palette[i % palette.length] + ";border-radius:" + (Math.random() < 0.5 ? "50%" : "3px") + ";pointer-events:none;z-index:30;"; b.appendChild(p); const a = Math.random() * Math.PI * 2, d = 70 + Math.random() * 170; G.to(p, { x: Math.cos(a) * d, y: Math.sin(a) * d, rotation: Math.random() * 420 - 210, opacity: 0, scale: 0.25, duration: 0.95 + Math.random() * 0.55, ease: "power3.out", onComplete: () => p.remove(), }); } } function showResult(won, score, fancy, quiet) { /* no special-word reveal here: screenshots of this screen stay spoiler-free. quiet=true (used on a restored/finished game) builds the result + inline button without popping the modal open on every refresh. */ document.getElementById("mbody").innerHTML = (won ? "<div class='tally-count' id='tallyCount'>" + (quiet ? score : 0) + "</div><div class='tally-list' id='tallyList'></div>" : "<h2>Out of guesses 😵</h2><div class='score'>" + (mistakes ? mistakes + " mistake" + (mistakes === 1 ? "" : "s") : "No mistakes") + "</div>") + "<div id='shareWrap' style='text-align:center;margin:12px 0'><img id='shareImg' alt='' style='width:78%;max-width:300px;border-radius:12px;box-shadow:0 2px 10px rgba(43,38,32,.15)'></div>" + "<div class='rowbtns'>" + "<button class='hbtn primary' onclick='shareImage(this)'>" + (CAN_SHARE_FILES ? "Share image" : "Copy image") + "</button>" + "<button class='hbtn primary' onclick='shareTextResult(this)'>" + (CAN_SHARE ? "Share text" : "Copy text") + "</button>" + (pendingKey ? "<button class='hbtn' onclick='closeModal();init()'>Play today's puzzle</button>" : "") + "</div>"; const shareImg = document.getElementById("shareImg"); try { shareImg.src = drawShareCard().toDataURL("image/png"); shareImg.style.display = ""; } catch (e) { shareImg.style.display = "none"; } /* never let a canvas hiccup block the result modal */ shareImg.alt = resultDescription(); /* inline reopen button under the board */ const r = document.getElementById("result"); r.style.display = ""; r.innerHTML = "<div class='ctrls' style='margin-top:10px'><button class='hbtn' onclick='openModal()'>Results</button></div>"; if (isBeta) { document.getElementById("fbCard").style.display = ""; initFb(); } if (!quiet) openModal(fancy); if (won) { if (quiet) renderTallyStatic(score); else runModalTally(score); } } function openModal(fancy) { const m = document.getElementById("modal"); m.style.display = "flex"; if (G) { G.fromTo( m.querySelector(".mback"), { opacity: 0 }, { opacity: 1, duration: 0.3 }, ); G.fromTo( m.querySelector(".mcard"), { scale: fancy ? 0.8 : 0.92, opacity: 0, y: 26 }, { scale: 1, opacity: 1, y: 0, duration: 0.5, ease: "back.out(1.6)", }, ); } } function closeModal() { const m = document.getElementById("modal"); if (G) { G.to(m.querySelector(".mcard"), { scale: 0.93, opacity: 0, y: 14, duration: 0.22, ease: "power2.in", }); G.to(m.querySelector(".mback"), { opacity: 0, duration: 0.25, onComplete: () => { m.style.display = "none"; }, }); } else m.style.display = "none"; } document.addEventListener("keydown", (e) => { if ( e.key === "Escape" && document.getElementById("modal").style.display === "flex" ) closeModal(); }); /* ---------- secret reset code: ↑ ↑ ↓ ↓ ↑ ↑ ---------- Clears the saved progress for the loaded puzzle and deals a fresh board. */ const RESET_SEQ = [ "ArrowUp", "ArrowUp", "ArrowDown", "ArrowDown", "ArrowUp", "ArrowUp", ]; let resetBuf = []; document.addEventListener("keydown", (e) => { resetBuf.push(e.key); if (resetBuf.length > RESET_SEQ.length) resetBuf = resetBuf.slice(-RESET_SEQ.length); if ( resetBuf.length === RESET_SEQ.length && RESET_SEQ.every((k, i) => k === resetBuf[i]) ) { resetBuf = []; resetPuzzle(); } }); function resetPuzzle() { try { const k = gameKey(); if (k) localStorage.removeItem(k); } catch (e) {} if (document.getElementById("modal").style.display === "flex") closeModal(); if (!document.getElementById("play").classList.contains("on")) showView("play"); setupPlay(); /* rebuilds a fresh board; with progress cleared there's nothing to restore */ toast("Puzzle reset 🔄"); } /* mobile-friendly reset: tap the 4×3 logo 5 times quickly */ let logoTaps = 0, logoTapTimer = null; ( document.querySelector("header .logo") || document.querySelector("header") )?.addEventListener("click", () => { logoTaps++; clearTimeout(logoTapTimer); logoTapTimer = setTimeout(() => { logoTaps = 0; }, 1200); /* taps must come in quick succession */ if (logoTaps >= 5) { logoTaps = 0; resetPuzzle(); } }); /* ---------- shareable result image ---------- */ const GOLD = "#d4a017"; const LOGO = new Image(); { const le = document.querySelector("img.logo"); if (le) LOGO.src = le.src; } const FISH = new Image(); FISH.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAT0AAAEsCAYAAACxEWSjAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAylpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDEwLjAtYzAwMCA3OS5kMDRjYzE2OTgsIDIwMjUvMDcvMDItMTI6MTg6MTMgICAgICAgICI+IDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+IDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCAyNy4zIChNYWNpbnRvc2gpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjRBOERERUNENUFCQjExRjE4MEQ4RTRDNjFGRkFBODJGIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjRBOERERUNFNUFCQjExRjE4MEQ4RTRDNjFGRkFBODJGIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6NDRBRTZBMzY1QUJBMTFGMTgwRDhFNEM2MUZGQUE4MkYiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6NEE4RERFQ0M1QUJCMTFGMTgwRDhFNEM2MUZGQUE4MkYiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz4UpuNrAAByvElEQVR4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"; /* inlined as a data URI so it never taints the share canvas */ const CRACK = new Image(); CRACK.src = "data:image/png;base64,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"; /* crack overlay (downscaled, inlined so it never taints the share canvas) */ function rr(x, px, py, w, h, r) { /* rounded rect path */ x.beginPath(); x.moveTo(px + r, py); x.arcTo(px + w, py, px + w, py + h, r); x.arcTo(px + w, py + h, px, py + h, r); x.arcTo(px, py + h, px, py, r); x.arcTo(px, py, px + w, py, r); x.closePath(); } /* smooth four-colour wheel, like the hub tile's end-state gradient */ function shareConic(x, cx, cy, cols) { if (x.createConicGradient) { const g = x.createConicGradient(-Math.PI / 2, cx, cy), n = cols.length; for (let i = 0; i <= n; i++) g.addColorStop(i / n, cols[i % n]); return g; } const g = x.createRadialGradient( cx, cy, 0, cx, cy, Math.max(cx, cy), ); g.addColorStop(0, cols[2]); g.addColorStop(1, cols[3]); return g; } /* an off-centre diagonal shine streak (pos 0..1 along the top-left→bottom-right axis) */ function shineStreak(x, W, H, pos, alpha, wide) { const g = x.createLinearGradient(0, 0, W, H), hw = wide || 0.06; g.addColorStop(Math.max(0, pos - hw), "rgba(255,255,255,0)"); g.addColorStop(pos, "rgba(255,255,255," + alpha + ")"); g.addColorStop(Math.min(1, pos + hw), "rgba(255,255,255,0)"); x.fillStyle = g; x.fillRect(0, 0, W, H); } function drawShareCard() { const { won, hubFirst, hubMiddle, ruleBreaker, purpleFirst, revRainbow, rainbow, godDamnit, fast, allRewards, goldPlaque, silverPlaque, score, } = calcScore(); const perfect = won && mistakes === 0; const plain = !( revRainbow || purpleFirst || hubFirst || hubMiddle || perfect ); const S = 2, M = 14, W = 420, R = 26; const cell = 44, gap = 10, gridW = 3 * cell + 2 * gap; const headH = allRewards || godDamnit || rainbow ? 156 : ruleBreaker ? 150 : 130, rows = guesses.length, footH = 84; const H = headH + rows * (cell + gap) - gap + footH; const cv = document.createElement("canvas"); cv.width = (W + 2 * M) * S; cv.height = (H + 2 * M) * S; const x = cv.getContext("2d"); x.scale(S, S); x.translate(M, M); const FONT = "-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif"; /* opaque backdrop across the whole canvas (incl. margins) so the PNG never ships transparent pixels — otherwise the viewing app's background bleeds into the corners/margin as a stray white or black border */ x.fillStyle = "#faf7f1"; x.fillRect(-M, -M, W + 2 * M, H + 2 * M); if (ruleBreaker) { /* ---- RULE BREAKER: the board crumbles — dusty, cracked, colour drained ---- */ x.save(); rr(x, 0, 0, W, H, R); x.clip(); const bgg = x.createLinearGradient(0, 0, 0, H); bgg.addColorStop(0, "#dcd5c7"); bgg.addColorStop(1, "#b1a791"); x.fillStyle = bgg; x.fillRect(0, 0, W, H); for (let i = 0; i < 70; i++) { /* drifting dust */ const dx = Math.random() * W, dy = Math.random() * H, dr = 8 + Math.random() * 30; const dg = x.createRadialGradient( dx, dy, 0, dx, dy, dr, ); dg.addColorStop( 0, "rgba(108,98,80," + (0.04 + Math.random() * 0.1) + ")", ); dg.addColorStop(1, "rgba(108,98,80,0)"); x.fillStyle = dg; x.beginPath(); x.arc(dx, dy, dr, 0, 7); x.fill(); } let gy = headH; const gx0 = (W - gridW) / 2; /* the guesses, greyed and grimed */ for (const g of guesses) { g.forEach((w, k) => { const px = gx0 + k * (cell + gap); x.save(); rr(x, px, gy, cell, cell, 8); x.clip(); if (w === special) { const h2 = cell / 2; x.fillStyle = COLORS[0]; x.fillRect(px, gy, h2, h2); x.fillStyle = COLORS[1]; x.fillRect(px + h2, gy, h2, h2); x.fillStyle = COLORS[3]; x.fillRect(px, gy + h2, h2, h2); x.fillStyle = COLORS[2]; x.fillRect(px + h2, gy + h2, h2, h2); } else { const ci = cats.findIndex((c) => c.words.includes(w), ); x.fillStyle = ci >= 0 ? COLORS[ci] : "#cfc7b4"; x.fillRect(px, gy, cell, cell); } x.fillStyle = "rgba(150,140,120,0.55)"; x.fillRect(px, gy, cell, cell); /* drain colour */ x.fillStyle = "rgba(40,34,28,0.10)"; x.fillRect(px, gy, cell, cell); /* grime */ x.restore(); rr(x, px - 0.5, gy - 0.5, cell + 1, cell + 1, 8); x.strokeStyle = "rgba(60,52,42,0.5)"; x.lineWidth = 1.5; x.stroke(); }); gy += cell + gap; } if (CRACK.complete && CRACK.naturalWidth) { /* crack.png over everything: multiply darkens the fractures, leaves the rest */ x.save(); x.globalCompositeOperation = "multiply"; x.globalAlpha = 0.9; x.drawImage(CRACK, 0, 0, W, H); x.restore(); } x.restore(); rr(x, 1.5, 1.5, W - 3, H - 3, R - 1.5); x.strokeStyle = "#5b5040"; x.lineWidth = 3; x.stroke(); /* darkened border */ x.textAlign = "center"; if (LOGO.complete && LOGO.naturalWidth) { const lh = 46, lw = (lh * LOGO.naturalWidth) / LOGO.naturalHeight; x.globalAlpha = 0.5; x.drawImage(LOGO, (W - lw) / 2, 14, lw, lh); x.globalAlpha = 1; } else { x.fillStyle = "#6b6253"; x.font = "800 28px " + FONT; x.fillText("4 × 3", W / 2, 48); } const subd = dailyKey ? fmtDate(dailyKey) : ""; if (subd) { x.fillStyle = "#7a7264"; x.font = "600 12px " + FONT; x.fillText(subd, W / 2, 76); } x.save(); x.translate(W / 2, 104); x.rotate(-0.05); /* stamped, slammed-down title */ x.fillStyle = "rgba(122,46,34,0.22)"; x.font = "800 23px " + FONT; x.fillText("RULE BREAKER", 1.5, 2.5); x.fillStyle = "#7a2e22"; x.fillText("RULE BREAKER", 0, 0); x.restore(); x.fillStyle = "#6b6253"; x.font = "700 14px " + FONT; x.fillText(score + " pts · Hub Last", W / 2, 130); x.fillStyle = "#9a9080"; x.font = "12px " + FONT; x.fillText( "the shared word is meant to lead, not trail", W / 2, H - 44, ); x.fillStyle = "#8a8174"; x.font = "600 11px " + FONT; x.fillText("hankgreen.com/fourbythree", W / 2, H - 24); return cv; } if (goldPlaque || silverPlaque || godDamnit) { /* ---- metal plaque: engraved gold / silver / red ---- */ const P = goldPlaque ? { g0: "#f7df93", g1: "#dcb442", g2: "#c89f24", g3: "#9c7c1b", hi: "rgba(255,249,214,.75)", grv: "rgba(86,58,8,.5)", eL: "rgba(255,250,224,.5)", eD: "rgba(66,42,2,.5)", eF: "#8c6c15", sD: "rgba(74,48,4,.6)", sL: "rgba(255,249,214,.5)", title: "Gold Plaque Unlocked!", } : silverPlaque ? { g0: "#f2f4f8", g1: "#ccd2db", g2: "#b3bac5", g3: "#888f9d", hi: "rgba(255,255,255,.85)", grv: "rgba(64,70,82,.4)", eL: "rgba(255,255,255,.6)", eD: "rgba(48,53,62,.5)", eF: "#6a717e", sD: "rgba(64,70,82,.5)", sL: "rgba(255,255,255,.6)", title: "Silver Plaque Unlocked!", } : { g0: "#f0a79c", g1: "#d65f50", g2: "#b83b2c", g3: "#86251b", hi: "rgba(255,236,230,.7)", grv: "rgba(86,18,10,.5)", eL: "rgba(255,238,232,.5)", eD: "rgba(70,14,8,.5)", eF: "#7a2418", sD: "rgba(70,14,8,.6)", sL: "rgba(255,238,232,.5)", title: "God Damnit!", }; x.save(); rr(x, 0, 0, W, H, R); x.clip(); const mg = x.createLinearGradient(0, 0, W * 0.5, H); mg.addColorStop(0, P.g0); mg.addColorStop(0.42, P.g1); mg.addColorStop(0.58, P.g2); mg.addColorStop(1, P.g3); x.fillStyle = mg; x.fillRect(0, 0, W, H); shineStreak(x, W, H, 0.3, 0.32, 0.09); shineStreak(x, W, H, 0.72, 0.16, 0.05); x.restore(); rr(x, 3.5, 3.5, W - 7, H - 7, R - 3.5); x.strokeStyle = P.hi; x.lineWidth = 2.5; x.stroke(); rr(x, 7, 7, W - 14, H - 14, R - 7); x.strokeStyle = P.grv; x.lineWidth = 1.5; x.stroke(); const eng = (t, cx, cy, font) => { /* dark upper-left + light lower-right + carved fill */ x.textAlign = "center"; x.font = font; x.fillStyle = P.eL; x.fillText(t, cx + 0.8, cy + 1); x.fillStyle = P.eD; x.fillText(t, cx - 0.8, cy - 1); x.fillStyle = P.eF; x.fillText(t, cx, cy); }; if (LOGO.complete && LOGO.naturalWidth) { const lh = 52, lw = (lh * LOGO.naturalWidth) / LOGO.naturalHeight; x.drawImage(LOGO, (W - lw) / 2, 13, lw, lh); } else { eng("4 × 3", W / 2, 54, "800 34px " + FONT); } const subd = dailyKey ? fmtDate(dailyKey) : ""; if (subd) eng(subd, W / 2, 86, "600 13px " + FONT); eng(score + " pts", W / 2, 108, "700 16px " + FONT); eng(P.title, W / 2, 140, "800 23px " + FONT); let yy = headH; const x0p = (W - gridW) / 2; for (const g of guesses) { g.forEach((w, k) => { const px = x0p + k * (cell + gap); x.save(); rr(x, px, yy, cell, cell, 8); x.clip(); if (w === special) { /* hub gem: four-colour */ const h2 = cell / 2; x.fillStyle = COLORS[0]; x.fillRect(px, yy, h2, h2); x.fillStyle = COLORS[1]; x.fillRect(px + h2, yy, h2, h2); x.fillStyle = COLORS[3]; x.fillRect(px, yy + h2, h2, h2); x.fillStyle = COLORS[2]; x.fillRect(px + h2, yy + h2, h2, h2); } else { const ci = cats.findIndex((c) => c.words.includes(w), ); x.fillStyle = ci >= 0 ? COLORS[ci] : "#cfc7b4"; x.fillRect(px, yy, cell, cell); } const gl = x.createLinearGradient( px, yy, px + cell, yy + cell, ); /* glossy gem sheen */ gl.addColorStop(0, "rgba(255,255,255,.5)"); gl.addColorStop(0.42, "rgba(255,255,255,0)"); gl.addColorStop(1, "rgba(0,0,0,.15)"); x.fillStyle = gl; x.fillRect(px, yy, cell, cell); x.fillStyle = "rgba(255,255,255,.5)"; x.beginPath(); x.ellipse( px + cell * 0.32, yy + cell * 0.27, cell * 0.17, cell * 0.09, -0.5, 0, 7, ); x.fill(); x.restore(); rr(x, px - 0.5, yy - 0.5, cell + 1, cell + 1, 9); x.strokeStyle = P.sD; x.lineWidth = 2; x.stroke(); /* metal setting */ rr( x, px + 0.9, yy + 0.9, cell - 1.8, cell - 1.8, 7, ); x.strokeStyle = P.sL; x.lineWidth = 1; x.stroke(); }); yy += cell + gap; } eng( "four categories · three words · one shared", W / 2, H - 44, "12px " + FONT, ); eng( "hankgreen.com/fourbythree", W / 2, H - 24, "600 11px " + FONT, ); return cv; } if (rainbow) { /* ---- RAINBOW: four diagonal colour bands behind a frosted panel ---- */ x.save(); rr(x, 0, 0, W, H, R); x.clip(); const bg = x.createLinearGradient(0, 0, W, H); [COLORS[2], COLORS[1], COLORS[0], COLORS[3]].forEach( (c, i) => { bg.addColorStop(i / 4, c); bg.addColorStop((i + 1) / 4, c); }, ); /* yellow→green→blue→purple, hard stops = 4 bands */ x.fillStyle = bg; x.fillRect(0, 0, W, H); rr(x, 12, 12, W - 24, H - 24, R - 7); x.fillStyle = "rgba(250,247,241,0.86)"; x.fill(); /* frosted content panel */ x.restore(); rr(x, 12.5, 12.5, W - 25, H - 25, R - 7); x.strokeStyle = "rgba(255,255,255,0.6)"; x.lineWidth = 1.5; x.stroke(); x.textAlign = "center"; if (LOGO.complete && LOGO.naturalWidth) { const lh = 52, lw = (lh * LOGO.naturalWidth) / LOGO.naturalHeight; x.drawImage(LOGO, (W - lw) / 2, 15, lw, lh); } else { x.fillStyle = "#2b2620"; x.font = "800 32px " + FONT; x.fillText("4 × 3", W / 2, 51); } const subd = dailyKey ? fmtDate(dailyKey) : ""; if (subd) { x.fillStyle = "#5d564a"; x.font = "600 13px " + FONT; x.fillText(subd, W / 2, 86); } x.fillStyle = "#5d564a"; x.font = "600 15px " + FONT; x.fillText(score + " pts", W / 2, 108); const b = "Rainbow!"; x.font = "800 25px " + FONT; /* title in a four-colour sweep */ const bw2 = x.measureText(b).width, gx = W / 2 - bw2 / 2; const gt = x.createLinearGradient(gx, 0, gx + bw2, 0); [COLORS[2], COLORS[1], COLORS[0], COLORS[3]].forEach( (c, i) => gt.addColorStop(i / 3, c), ); x.fillStyle = gt; x.fillText(b, W / 2, 140); let y = headH; const x0 = (W - gridW) / 2; for (const g of guesses) { g.forEach((w, k) => { const px = x0 + k * (cell + gap); x.save(); rr(x, px, y, cell, cell, 9); x.clip(); if (w === special) { const h2 = cell / 2; x.fillStyle = COLORS[0]; x.fillRect(px, y, h2, h2); x.fillStyle = COLORS[1]; x.fillRect(px + h2, y, h2, h2); x.fillStyle = COLORS[3]; x.fillRect(px, y + h2, h2, h2); x.fillStyle = COLORS[2]; x.fillRect(px + h2, y + h2, h2, h2); } else { const ci = cats.findIndex((c) => c.words.includes(w), ); x.fillStyle = ci >= 0 ? COLORS[ci] : "#cfc7b4"; x.fillRect(px, y, cell, cell); } const gl = x.createLinearGradient( px, y, px + cell, y + cell, ); gl.addColorStop(0, "rgba(255,255,255,.45)"); gl.addColorStop(0.5, "rgba(255,255,255,0)"); gl.addColorStop(1, "rgba(0,0,0,.12)"); x.fillStyle = gl; x.fillRect(px, y, cell, cell); x.restore(); if (w === special) { rr(x, px + 1, y + 1, cell - 2, cell - 2, 8); x.strokeStyle = GOLD; x.lineWidth = 3; x.stroke(); } }); y += cell + gap; } x.fillStyle = "#8a8174"; x.font = "12px " + FONT; x.fillText( "four categories · three words · one shared", W / 2, H - 44, ); x.font = "600 11px " + FONT; x.fillText("hankgreen.com/fourbythree", W / 2, H - 24); return cv; } /* rounded card; effects STACK so combined results read together */ x.save(); rr(x, 0, 0, W, H, R); x.clip(); x.fillStyle = "#faf7f1"; x.fillRect(0, 0, W, H); const cx = W / 2, cy = H * 0.46; /* effects centred roughly on the grid */ if (perfect) { /* Perfect → coloured background */ x.globalAlpha = 0.6; x.fillStyle = shareConic(x, cx, cy, MIDC); x.fillRect(0, 0, W, H); x.globalAlpha = 1; } if (purpleFirst && !revRainbow) { /* Purple First → central purple burst (rainbow replaces this) */ const g = x.createRadialGradient( cx, cy, 0, cx, cy, Math.max(W, H) * 0.7, ); g.addColorStop(0, COLORS[3]); g.addColorStop(1, "rgba(160,110,225,0)"); x.globalAlpha = 0.55; x.fillStyle = g; x.fillRect(0, 0, W, H); x.globalAlpha = 1; } if (hubFirst) { /* Hub First → shiny diagonal bars */ shineStreak(x, W, H, 0.3, 0.5, 0.06); shineStreak(x, W, H, 0.66, 0.34, 0.05); } x.restore(); const bw = revRainbow ? 6 : 3; /* Reverse Rainbow → thick rainbow border */ rr(x, bw / 2, bw / 2, W - bw, H - bw, R - bw / 2); if (revRainbow) { const bg = x.createLinearGradient(0, 0, W, H); [COLORS[2], COLORS[1], COLORS[0], COLORS[3]].forEach( (c, i) => bg.addColorStop(i / 3, c), ); x.strokeStyle = bg; } else x.strokeStyle = "#d8d2c6"; x.lineWidth = bw; x.stroke(); /* Perfect Game → a shiny gold ring just inside the rainbow border, plus a glossy 3D sheen */ if (allRewards) { rr(x, 9.5, 9.5, W - 19, H - 19, R - 9.5); const gg = x.createLinearGradient( 0, 0, 0, H, ); /* metallic: light gold up top, dark gold below */ gg.addColorStop(0, "#fbe9a8"); gg.addColorStop(0.5, "#d4a017"); gg.addColorStop(1, "#8f6b07"); x.strokeStyle = gg; x.lineWidth = 4; x.stroke(); x.save(); rr(x, 0, 0, W, H, R); x.clip(); /* gloss: bright top edge, soft shadow at the bottom */ const sheen = x.createLinearGradient(0, 0, 0, H); sheen.addColorStop(0, "rgba(255,255,255,.42)"); sheen.addColorStop(0.16, "rgba(255,255,255,0)"); sheen.addColorStop(0.82, "rgba(0,0,0,0)"); sheen.addColorStop(1, "rgba(58,40,8,.16)"); x.fillStyle = sheen; x.fillRect(0, 0, W, H); x.restore(); } x.textAlign = "center"; x.fillStyle = "#2b2620"; /* logo if available (data URI never taints the canvas) */ if (LOGO.complete && LOGO.naturalWidth) { const lh = 52, lw = (lh * LOGO.naturalWidth) / LOGO.naturalHeight; x.drawImage(LOGO, (W - lw) / 2, 15, lw, lh); } else { x.font = "800 32px " + FONT; x.fillText("4 × 3", W / 2, 51); } x.font = "600 13px " + FONT; const sub = dailyKey ? fmtDate(dailyKey) : ""; if (sub) x.fillText(sub, W / 2, 86); if (allRewards) { x.fillStyle = "#5d564a"; x.font = "600 15px " + FONT; x.fillText(score + " pts", W / 2, 108); const b = "Perfect Game"; x.font = "800 25px " + FONT; const bw2 = x.measureText(b).width, gx = W / 2 - bw2 / 2; const gt = x.createLinearGradient( gx, 121, gx + bw2, 142, ); /* subtle diagonal gold */ gt.addColorStop(0, "#e3c878"); gt.addColorStop(1, "#bf941f"); x.fillStyle = gt; x.fillText(b, W / 2, 140); } else { x.fillStyle = plain ? "#7a7264" : "#5d564a"; x.font = "14px " + FONT; x.fillText( (won ? score + " pts" : "Out of guesses") + " · " + (mistakes ? mistakes + " mistake" + (mistakes === 1 ? "" : "s") : "No mistakes") + (hubFirst ? " · Hub First" : "") + (revRainbow ? " · Reverse Rainbow" : purpleFirst ? " · Purple First" : "") + (fast ? " · Sub-90s" : ""), W / 2, 108, ); } /* guess grid */ let y = headH; const x0 = (W - gridW) / 2; for (const g of guesses) { g.forEach((w, k) => { const px = x0 + k * (cell + gap); x.save(); rr(x, px, y, cell, cell, 9); x.clip(); if (w === special) { const h2 = cell / 2; x.fillStyle = COLORS[0]; x.fillRect(px, y, h2, h2); x.fillStyle = COLORS[1]; x.fillRect(px + h2, y, h2, h2); x.fillStyle = COLORS[3]; x.fillRect(px, y + h2, h2, h2); x.fillStyle = COLORS[2]; x.fillRect(px + h2, y + h2, h2, h2); } else { const ci = cats.findIndex((c) => c.words.includes(w), ); x.fillStyle = ci >= 0 ? COLORS[ci] : "#cfc7b4"; x.fillRect(px, y, cell, cell); } if (fast) { /* gemstone sheen for a sub-90s solve */ const gl = x.createLinearGradient( px, y, px + cell, y + cell, ); gl.addColorStop(0, "rgba(255,255,255,.5)"); gl.addColorStop(0.42, "rgba(255,255,255,0)"); gl.addColorStop(1, "rgba(0,0,0,.15)"); x.fillStyle = gl; x.fillRect(px, y, cell, cell); x.fillStyle = "rgba(255,255,255,.5)"; x.beginPath(); x.ellipse( px + cell * 0.32, y + cell * 0.27, cell * 0.17, cell * 0.09, -0.5, 0, 7, ); x.fill(); } x.restore(); if (w === special) { rr(x, px + 1, y + 1, cell - 2, cell - 2, 8); x.strokeStyle = GOLD; x.lineWidth = 3; x.stroke(); } }); y += cell + gap; } /* footer: tagline + url */ x.fillStyle = "#a39a89"; x.font = "12px " + FONT; x.fillText( "four categories · three words · one shared", W / 2, H - 44, ); /* URL line, with the little fish in line beside it at 60% opacity */ x.font = "600 11px " + FONT; const url = "hankgreen.com/fourbythree", uw = x.measureText(url).width; let fw = 0, fh = 0; const fgap = 8; if (FISH.complete && FISH.naturalWidth) { fh = 20; fw = (fh * FISH.naturalWidth) / FISH.naturalHeight; } const groupW = uw + (fw ? fgap + fw : 0), startX = (W - groupW) / 2; x.textAlign = "left"; x.fillStyle = hubFirst ? GOLD : "#9a9080"; x.fillText(url, startX, H - 24); if (fw) { x.globalAlpha = 0.5; x.drawImage( FISH, startX + uw + fgap, H - 28 - fh / 2, fw, fh, ); x.globalAlpha = 1; } x.textAlign = "center"; return cv; } /* feature-detect the Web Share API rather than sniffing the user agent */ const CAN_SHARE = typeof navigator !== "undefined" && typeof navigator.share === "function"; const CAN_SHARE_FILES = (() => { try { return !!( navigator.canShare && navigator.canShare({ files: [ new File([new Blob()], "x.png", { type: "image/png", }), ], }) ); } catch (e) { return false; } })(); /* the link attached when sharing: a direct puzzle link shares its own URL; the daily shares the canonical page */ function shareUrl() { return /^#(p|d|b)=/.test(location.hash) ? location.href : "https://hankgreen.com/fourbythree"; } function flashBtn(btn, msg) { if (btn) { const o = btn.textContent; btn.textContent = msg; setTimeout(() => (btn.textContent = o), 1600); } } /* Share Image — native share sheet with the picture, plus the text recap and the game URL. Some share targets drop attached text/url when an image is present, so the URL is also baked legibly into the card itself (see drawShareCard) as the screenshot fallback. No share API (e.g. most desktops) → copy the PNG to the clipboard. Never downloads. */ function shareImage(btn) { try { if (window.x43share && dailyKey) x43share(dailyKey); } catch (e) {} drawShareCard().toBlob(async (blob) => { if (!blob) { flashBtn(btn, "Couldn't render"); return; } const file = new File([blob], "4x3-result.png", { type: "image/png", }); if ( navigator.share && navigator.canShare && navigator.canShare({ files: [file] }) ) { try { await navigator.share({ files: [file], text: resultDescription(true), url: shareUrl(), title: "4 × 3", }); return; } catch (e) { if (e && e.name === "AbortError") return; } /* user dismissed the sheet: stop, don't fall through */ } try { await navigator.clipboard.write([ new ClipboardItem({ "image/png": blob }), ]); flashBtn(btn, "Image copied!"); return; } catch (e) {} flashBtn(btn, "Couldn't share"); }, "image/png"); } /* Share Text — native share with the URL in its own field so chat apps render it as a tappable link instead of inline text. No share API → copy the recap plus the link to the clipboard. */ function shareTextResult(btn) { try { if (window.x43share && dailyKey) x43share(dailyKey); } catch (e) {} (async () => { if (navigator.share) { try { await navigator.share({ title: "4 × 3", text: resultDescription(true), url: shareUrl(), }); return; } catch (e) { if (e && e.name === "AbortError") return; } } copyText(resultDescription(true) + "\n" + shareUrl(), btn); })(); }
/* ---------- beta feedback ---------- */ function initFb() { for (const id of ["fbDiff", "fbFun"]) { const el = document.getElementById(id); el.innerHTML = ""; for (let i = 1; i <= 5; i++) { const b = document.createElement("button"); b.textContent = "⭐"; b.onclick = () => { fb[id === "fbDiff" ? "diff" : "fun"] = i; starPaint(); }; el.appendChild(b); } } starPaint(); ynPaint(); document.getElementById("fbMail").style.display = puzzle.e ? "" : "none"; } function starPaint() { document .querySelectorAll("#fbDiff button") .forEach((b, i) => b.classList.toggle("on", i < fb.diff)); document .querySelectorAll("#fbFun button") .forEach((b, i) => b.classList.toggle("on", i < fb.fun)); } function ynPaint() { document .querySelectorAll("#fbSpecial button") .forEach((b) => b.classList.toggle("on", b.textContent === fb.special), ); } /* Text / emoji recap of the result — doubles as the share image's alt text and the shared text payload. Hub shows as 🌟, each other word as its category colour. */ function resultEmojiRows() { return guesses .map((g) => g .map((w) => w === special ? "🌟" : EMOJI[ cats.findIndex((c) => c.words.includes(w), ) ] || "⬜", ) .join(""), ) .join("\n"); } function resultDescription(noLink) { const { won, score, ruleBreaker } = calcScore(); const head = "4 × 3" + (dailyKey ? "\n" + fmtDate(dailyKey) : ""); const link = noLink ? "" : "\nhankgreen.com/fourbythree"; if (ruleBreaker) return ( head + "\n" + score + " points • RULE BREAKER 💀\n" + resultEmojiRows() + link ); return ( head + "\n" + (won ? score + " points" : "Out of guesses") + " • " + (mistakes ? mistakes + " mistake" + (mistakes === 1 ? "" : "s") : "No mistakes") + "\n" + resultEmojiRows() + link ); } function feedbackText() { const won = mistakes < MAXM; return ( "4×3 BETA FEEDBACK\n" + "Result: " + (won ? "solved" : "failed") + " · " + (mistakes ? mistakes + " mistake" + (mistakes === 1 ? "" : "s") : "No mistakes") + "\n" + "Difficulty: " + (fb.diff || "–") + "/5 · Fun: " + (fb.fun || "–") + "/5\n" + "Spotted the special word early: " + (fb.special || "–") + "\n" + "Notes: " + (document.getElementById("fbNotes").value.trim() || "(none)") + "\n" + guesses .map((g) => g .map((w) => w === special ? "⭐" : EMOJI[ cats.findIndex((c) => c.words.includes(w), ) ] || "⬜", ) .join(""), ) .join("\n") ); } function copyFeedback() { copyText(feedbackText(), document.getElementById("fbCopy")); if (puzzle.e) { document.getElementById("fbMail").href = "mailto:" + puzzle.e + "?subject=" + encodeURIComponent("4×3 beta feedback") + "&body=" + encodeURIComponent(feedbackText()); } }
/* ---------- stats ---------- */ /* per-puzzle history for this browser, keyed by the puzzle's date (daily or archive replay). Beta/preview runs have no date and aren't recorded. Read by history.html. */ function recordHistory() { if (!dailyKey) return; try { const cs = calcScore(); const h = JSON.parse( localStorage.getItem("x43_history") || "{}", ); const prev = h[dailyKey]; /* rel = "ever played this date on its release day." An archive replay must NOT downgrade a prior release-day play (that would silently break the streak). */ const rel = dailyKey === todayStr() || (prev && prev.rel !== 0) ? 1 : 0; h[dailyKey] = { s: cs.score, m: mistakes, w: cs.won ? 1 : 0, ms: solveMs, hf: cs.hubFirst ? 1 : 0, hm: cs.hubMiddle ? 1 : 0, pf: cs.purpleFirst ? 1 : 0, bf: cs.blueFirst ? 1 : 0, rr: cs.revRainbow ? 1 : 0, rw: cs.rainbow ? 1 : 0, gr: cs.grellow ? 1 : 0, gu: cs.grue ? 1 : 0, gd: cs.godDamnit ? 1 : 0, db: cs.dayBefore ? 1 : 0, fast: cs.fast ? 1 : 0, rb: cs.ruleBreaker ? 1 : 0, p: cs.perfect ? 1 : 0, ad: adClicked ? 1 : 0, gold: cs.goldPlaque ? 1 : 0, silver: cs.silverPlaque ? 1 : 0, rel: rel /* counts toward the streak; preserved across archive replays */, ts: Date.now(), }; localStorage.setItem("x43_history", JSON.stringify(h)); } catch (e) {} /* anonymous, fire-and-forget telemetry to the stats Worker (no PII) */ try { if (window.x43beacon) { const cs2 = calcScore(); x43beacon({ p: dailyKey, rel: dailyKey === todayStr() ? 1 : 0, w: cs2.won ? 1 : 0, m: mistakes, s: cs2.score, ms: solveMs, st: streakWithToday(), ad: adClicked ? 1 : 0, }); } } catch (e) {} /* also stash the rendered share card PNG (separate, capped key so images can't bloat the stats; trims the oldest if we ever hit the storage quota) */ try { const url = drawShareCard().toDataURL("image/png"); const cards = JSON.parse( localStorage.getItem("x43_cards") || "{}", ); cards[dailyKey] = url; let ks = Object.keys(cards).sort(); while (ks.length > 60) delete cards[ks.shift()]; /* keep the 60 most recent */ for (let t = 0; t < 10; t++) { try { localStorage.setItem( "x43_cards", JSON.stringify(cards), ); break; } catch (err) { const o = Object.keys(cards).sort(); if (o.length <= 1) break; delete cards[o[0]]; } } } catch (e) {} } /* tapping the ad grants +AD_BONUS for this game. If the game's already finished, re-tally the result quietly so the bonus shows without re-popping the modal. */ function onAdClick() { if (adClicked) return; adClicked = true; saveGame(); if (over) { recordHistory(); const cs = calcScore(); showResult(cs.won, cs.score, false, true); } } /* current consecutive-day streak from this browser's history (matches history.html) */ function currentStreak() { let h; try { h = JSON.parse(localStorage.getItem("x43_history") || "{}"); } catch (e) { return 0; } const dn = (k) => Math.round(new Date(k + "T12:00:00").getTime() / 86400000); const nums = Object.keys(h) .filter((k) => h[k] && h[k].rel !== 0) .map(dn) .sort( (a, b) => a - b, ); /* exclude only known archive replays (pre-flag entries count) */ if (!nums.length) return 0; const today = dn(todayStr()), last = nums[nums.length - 1]; if (last !== today && last !== today - 1) return 0; /* streak has lapsed */ let cur = 1; for (let i = nums.length - 1; i > 0; i--) { if (nums[i] === nums[i - 1] + 1) cur++; else break; } return cur; } function showStreakTag() { const el = document.getElementById("streakTag"); if (!el) return; const s = currentStreak(); if (s >= 1) { el.textContent = s + "-day streak"; el.style.display = ""; } else el.style.display = "none"; } /* streak the player lands on by finishing today's daily (today counted) — used for the score bonus. Only release-day plays count, so archive replays never inflate it. */ function streakWithToday() { let h; try { h = JSON.parse(localStorage.getItem("x43_history") || "{}"); } catch (e) { h = {}; } const dn = (k) => Math.round(new Date(k + "T12:00:00").getTime() / 86400000); const set = new Set( Object.keys(h) .filter((k) => h[k] && h[k].rel !== 0) .map(dn), ); /* exclude only known archive replays */ let d = dn(todayStr()); set.add(d); /* finishing today's daily counts today */ let c = 0; while (set.has(d)) { c++; d--; } /* consecutive release-days ending today */ return c; } /* every other daily's final score from this browser's history (excluding one date) — powers the Top Score and Above Average badges */ function otherDailyScores(excl) { let h; try { h = JSON.parse(localStorage.getItem("x43_history") || "{}"); } catch (e) { return []; } const out = []; for (const k in h) { if (k !== excl && h[k] && typeof h[k].s === "number") out.push(h[k].s); } return out; } function loadStats() { try { return JSON.parse(localStorage.getItem("x43_stats")) || {}; } catch (e) { return {}; } } function saveStats(won, score, m) { try { const s = loadStats(); s.played = (s.played || 0) + 1; if (won) s.won = (s.won || 0) + 1; if (won && m === 0) s.perfect = (s.perfect || 0) + 1; s.best = Math.max(s.best || 0, score); s.points = (s.points || 0) + score; localStorage.setItem("x43_stats", JSON.stringify(s)); } catch (e) {} }
/* ---------- utils ---------- */ function toast(msg, ms) { const t = document.getElementById("toast"); clearTimeout(t._x); clearTimeout(t._y); if (t.classList.contains("fly")) { /* re-fired mid-flight: snap back without animating */ t.style.transition = "none"; t.classList.remove("fly", "show"); void t.offsetWidth; t.style.transition = ""; } /* land on the centre of the 4×3 logo (falls back to the header if missing) */ const aim = document.querySelector( "header .logo, header h1, header", ); if (aim) { const r = aim.getBoundingClientRect(); if (r.height) t.style.top = Math.round(r.top + r.height / 2) + "px"; } t.textContent = msg; t.classList.add("show"); t._x = setTimeout(() => { t.classList.add( "fly", ); /* settle, then shoot up-and-off right */ t._y = setTimeout( () => t.classList.remove("show", "fly"), 750, ); }, ms || 1800); }
/* hover (or tap) a defined word in the finished answer list to see its explanation — BETA */ (function () { const sl = document.getElementById("solvedList"), tip = document.getElementById("deftip"); if (!sl || !tip) return; function show(el) { tip.textContent = el.dataset.def || ""; tip.classList.add("show"); const r = el.getBoundingClientRect(), tw = tip.offsetWidth, th = tip.offsetHeight; const left = Math.max( 8, Math.min( r.left + r.width / 2 - tw / 2, innerWidth - tw - 8, ), ); let top = r.top - th - 8; if (top < 6) top = r.bottom + 8; tip.style.left = left + "px"; tip.style.top = top + "px"; } function hide() { tip.classList.remove("show"); } sl.addEventListener("mouseover", (e) => { const t = e.target.closest(".def"); if (t) show(t); }); sl.addEventListener("mouseout", (e) => { const t = e.target.closest(".def"); if (t) hide(); }); sl.addEventListener("click", (e) => { const t = e.target.closest(".def"); if (t) { show(t); e.stopPropagation(); } }); document.addEventListener("click", (e) => { if (!e.target.closest(".def")) hide(); }); window.addEventListener("scroll", hide, true); })();
/* hover/tap the result-modal score icons for their tooltips (reuse #deftip) */ (function () { const mb = document.getElementById("mbody"), tip = document.getElementById("deftip"); if (!mb || !tip) return; function show(el) { tip.textContent = el.dataset.def || ""; tip.classList.add("show"); const r = el.getBoundingClientRect(), tw = tip.offsetWidth, th = tip.offsetHeight; const left = Math.max( 8, Math.min( r.left + r.width / 2 - tw / 2, innerWidth - tw - 8, ), ); let top = r.top - th - 8; if (top < 6) top = r.bottom + 8; tip.style.left = left + "px"; tip.style.top = top + "px"; } function hide() { tip.classList.remove("show"); } mb.addEventListener("mouseover", (e) => { const t = e.target.closest(".tally-ico"); if (t) show(t); }); mb.addEventListener("mouseout", (e) => { const t = e.target.closest(".tally-ico"); if (t) hide(); }); mb.addEventListener("click", (e) => { const t = e.target.closest(".tally-ico"); if (t) { show(t); e.stopPropagation(); } else hide(); }); })();
/* +5 for tapping the ad (banner or sidebar) */ document.addEventListener("click", (e) => { if ( e.target.closest && e.target.closest(".promo-banner a, .promo-side a") ) onAdClick(); }); window.addEventListener("hashchange", init); init(); showStreakTag(); loadPoll(); </script> </body></html>