08 Lumen

A daily logic puzzle: everyone gets the same board. Each tap flips a tile and a secret pattern around it that changes every day. Darken the grid within par.

Controls Tap a tile, or move with the arrows and play with Space / Enter. Once solved, tap or press Space for a random extra puzzle

980 / 1024 bytes · 44 to spare

The 980 bytes that ship
for(_='(iF-2d,et,26++)0,,1610),r=.fill=(":"0)/28,t>>S&1][S])%5)},=>{>>>0<c),Text(+28*for(	&&down=f"#e9e7df",f.offsRect(Style="#ffd23f#2a2a36"	y=;y<3;y	d=;d<3;dS=d*d+y*y,l f,l,e,t,o,i,r,n,y,S,R=Date.now()/864e5|s=2,k=2,w=A)=>l=16807*l%2147483647,Tf,l)(!S||)f+d5l+y5(e[f+d+5*(l+y)]^=1g=d	f=l=7919*d+1,t=[32,278,310][d%3],e=Array(25)(o=i=6,n=A()%25;r--;nn+1+A()%4)%25)T(n%5,n/5|0ml,t)ifF)rurn g(w);T(s=l,k=t),o++,F=!e.some(f=>f))f==R(localStorage.lumen1k=R++o)};onkeyS=f.keyCode-37,S4!i?(ss+[4,1,0,kk+[4,1):-5==S|4==Sm(s,konpointerf.targ==a(S=320/a.clientWidth,dX*S-9yY*SF||d>=0d<5y>=0y<5)m(0|0|y)g(R),sInterval(()	w++,"#0b0b10",32180;r<25;rd=r%5,y=r/5|e[r]||i?(w+4*r&31)<4?"#fff3a0":,9020y);S??:24+8*80+8*y,6,6);i||90s,43k,3F?"SOLVED IN ")+o+" / PAR 6"2"LUMEN #"+(f0762)+F?" / TAP")7516)';G=/[-F]/.exec(_);)with(_.split(G))_=join(shift());eval(_)
Readable source
// LUMEN: daily seeded lights-out variant. Darken every tile; the flip pattern changes per day.
let day = Date.now() / 864e5 | 0, seed, s, g, T, moves, done, cx = 2, cy = 2, t = 0, i, j, X, Y, k;
let r = () => s = s * 16807 % 2147483647;
// toggle tile (x,y) plus every cell whose squared distance k has bit k set in mask T.
// The 3 daily masks (knight 32, star 278, square 310) are the only full-rank ones on 5x5,
// so every puzzle has exactly one solution: the 6 distinct generating taps. Par 6 is exact.
let tap = (x, y) => {
  for (Y = -2; Y < 3; Y++) for (X = -2; X < 3; X++) {
    k = X * X + Y * Y;
    if ((!k || T >> k & 1) && (x + X) >>> 0 < 5 && (y + Y) >>> 0 < 5) g[x + X + (y + Y) * 5] ^= 1;
  }
};
let init = q => {
  seed = q; s = q * 7919 + 1; T = [32, 278, 310][q % 3]; g = Array(25).fill(moves = done = 0);
  // 6 distinct random taps from the dark board: steps of 1-4 cells sum to < 25, so no repeats
  // (j, not k: tap() uses X, Y, k as scratch)
  for (i = 6, j = r() % 25; i--; j = (j + 1 + r() % 4) % 25) tap(j % 5, j / 5 | 0);
};
// move cursor to (x,y) and play it
let go = (x, y) => {
  if (done) return init(t); // extra puzzle, seeded by the frame counter
  tap(cx = x, cy = y); moves++;
  if (done = !g.some(v => v) ) if (seed == day) localStorage.lumen1k = day + ':' + moves;
};
onkeydown = e => {
  k = e.keyCode - 37; // arrows 0-3; space / enter toggle
  if (k >>> 0 < 4 && !done) cx = (cx + [4, 0, 1, 0][k]) % 5, cy = (cy + [0, 4, 0, 1][k]) % 5;
  else if (k == -5 | k == -24) go(cx, cy);
};
onpointerdown = e => {
  if (e.target != a) return;
  k = 320 / a.clientWidth; X = (e.offsetX * k - 90) / 28; Y = (e.offsetY * k - 20) / 28;
  if (done || X >= 0 && X < 5 && Y >= 0 && Y < 5) go(X | 0, Y | 0);
};
init(day);
setInterval(() => {
  t++;
  c.fillStyle = '#0b0b10';
  c.fillRect(0, 0, 320, 180);
  for (i = 0; i < 25; i++) {
    X = i % 5; Y = i / 5 | 0;
    c.fillStyle = g[i] || done ? (t + i * 4 & 31) < 4 ? '#fff3a0' : '#ffd23f' : '#2a2a36';
    c.fillRect(90 + X * 28, 20 + Y * 28, 26, 26);
  }
  // legend: the day's flip pattern around a center tile
  for (Y = -2; Y < 3; Y++) for (X = -2; X < 3; X++) {
    k = X * X + Y * Y;
    c.fillStyle = !k ? '#e9e7df' : T >> k & 1 ? '#ffd23f' : '#2a2a36';
    c.fillRect(24 + X * 8, 80 + Y * 8, 6, 6);
  }
  // cursor: a bar under the selected tile
  c.fillStyle = '#e9e7df';
  if (!done) c.fillRect(90 + cx * 28, 43 + cy * 28, 26, 3);
  c.fillText((done ? 'SOLVED IN ' : '') + moves + ' / PAR 6', 160, 12);
  c.fillText('LUMEN #' + (seed - 20762) + (done ? ' / TAP' : ''), 160, 175);
}, 16);