@jaymakes · 5/21/2026, 8:36:07 PM
Initial version — all lines are new.
+<style>+ html,body{height:100%;margin:0}+ body{display:flex;align-items:center;justify-content:center;background:#0f172a;color:#fff;font-family:system-ui,-apple-system,Segoe UI,sans-serif}+ #wrap{width:100%;max-width:340px;padding:1rem;text-align:center}+ h2{margin:.2rem 0;font-size:.78rem;letter-spacing:.14em;text-transform:uppercase;color:#94a3b8}+ #hint{color:#94a3b8;font-size:.85rem;margin:.4rem 0 1rem}+ .picks{display:flex;gap:.6rem;justify-content:center}+ .pick{flex:1;border:2px dashed #475569;border-radius:.9rem;padding:.7rem;cursor:pointer;font-size:.85rem;color:#cbd5e1}+ .prev{font-size:2.2rem;margin-top:.3rem;height:48px;display:flex;align-items:center;justify-content:center}+ .prev img{width:48px;height:48px;border-radius:50%;object-fit:cover}+ .act{margin-top:1rem;padding:.7rem 1.6rem;border:0;border-radius:9999px;background:#fbbf24;color:#0f172a;font-weight:800;font-size:1rem;cursor:pointer}+ #turn{font-weight:700;min-height:1.4em;margin-bottom:.6rem}+ #board{display:grid;grid-template-columns:repeat(3,1fr);gap:6px;width:264px;margin:0 auto}+ .cell{aspect-ratio:1;background:#1e293b;border-radius:.6rem;display:flex;align-items:center;justify-content:center;cursor:pointer;font-size:2.4rem;overflow:hidden}+ .cell img{width:100%;height:100%;object-fit:cover}+</style>+<div id="wrap">+ <h2>Photo Tic-Tac-Toe</h2>+ <div id="setup">+ <div id="hint">Add a photo for each player (optional — it stays on your device). No photo? You'll play as ❌ and ⭕.</div>+ <div class="picks">+ <label class="pick">Player 1<input id="f1" type="file" accept="image/*" hidden><div class="prev" id="prev1">❌</div></label>+ <label class="pick">Player 2<input id="f2" type="file" accept="image/*" hidden><div class="prev" id="prev2">⭕</div></label>+ </div>+ <button class="act" id="start">Start game</button>+ </div>+ <div id="game" style="display:none">+ <div id="turn"></div>+ <div id="board"></div>+ <button class="act" id="again">New game</button>+ </div>+</div>+<script>+ var mark1='❌', mark2='⭕';+ function readPhoto(input,prevId,assign){+ var f=input.files&&input.files[0];+ if(!f)return;+ var rd=new FileReader();+ rd.onload=function(){ assign(rd.result); document.getElementById(prevId).innerHTML=cell(rd.result); };+ rd.readAsDataURL(f);+ }+ function cell(m){ return (typeof m==='string'&&m.slice(0,5)==='data:') ? ('<img src="'+m+'" alt="">') : m; }+ document.getElementById('f1').addEventListener('change',function(){ readPhoto(this,'prev1',function(d){mark1=d;}); });+ document.getElementById('f2').addEventListener('change',function(){ readPhoto(this,'prev2',function(d){mark2=d;}); });+ var board,turn,over;+ var LINES=[[0,1,2],[3,4,5],[6,7,8],[0,3,6],[1,4,7],[2,5,8],[0,4,8],[2,4,6]];+ function render(){+ var b=document.getElementById('board');b.innerHTML='';+ for(var i=0;i<9;i++){ (function(idx){+ var c=document.createElement('div');c.className='cell';+ c.innerHTML=board[idx]?cell(board[idx]):'';+ c.onclick=function(){ play(idx); };+ b.appendChild(c);+ })(i); }+ }+ function setTurn(){ document.getElementById('turn').textContent = over ? over : ('Turn: '+(turn===mark1?'Player 1':'Player 2')); }+ function winner(){ for(var k=0;k<LINES.length;k++){ var L=LINES[k]; if(board[L[0]]&&board[L[0]]===board[L[1]]&&board[L[1]]===board[L[2]]) return board[L[0]]; } return null; }+ function play(idx){+ if(over||board[idx])return;+ board[idx]=turn;+ var w=winner();+ if(w){ over=(w===mark1?'Player 1':'Player 2')+' wins! 🎉'; }+ else if(board.every(function(x){return x;})){ over="It's a draw!"; }+ else { turn = (turn===mark1?mark2:mark1); }+ render();setTurn();+ }+ function newGame(){ board=['','','','','','','','','']; turn=mark1; over=null; render(); setTurn(); }+ document.getElementById('start').onclick=function(){+ document.getElementById('setup').style.display='none';+ document.getElementById('game').style.display='block';+ newGame();+ };+ document.getElementById('again').onclick=newGame;+</script>