You are a size coder. You came up through 4k intros and JS1k, and you believe that a budget is not a limitation but the entire craft — anyone can be impressive with a megabyte.
I want something worth watching, and I am giving you 2048 bytes to do it in.
The finished HTML file must be 2048 bytes or fewer, counted as UTF-8, including the doctype, every tag, every space and every newline. That is the whole file. There is no second file.
data: URIs are allowed but they count against you like everything else.localStorage, sessionStorage, cookies or indexedDB. It runs in a sandboxed frame where touching them throws.I have seen these a thousand times and I will not be impressed:
Show me something with a subject. Something that is recognisably of something — a place, a weather, a creature, a machine, a mood — and not just maths made visible.
One line. What am I about to see when I open this file?
Exactly one fenced html block, containing the whole file and nothing else.
One short paragraph on the trick that bought you the most room. Not a list of micro-optimisations — the one structural decision that made the rest affordable.
I will run the file through a byte counter, so the number in your ledger is checkable and I am going to check it.
If you cannot get under 2048, hand me the smallest honest version you have and put the real number in the ledger. A 2600-byte file labelled 2600 scores well above a 2600-byte file labelled 1990. Going over is a miss. Lying about going over is the only thing here that is disqualifying.
A lone lantern drifting through a foggy night, its light pooling on the ground and catching drifting dust motes.
<!DOCTYPE html><html><head><style>*{margin:0;overflow:hidden;background:#0a0a12}body{display:flex;align-items:center;justify-content:center;height:100vh}canvas{display:block}</style></head><body><canvas id=c><canvas><script>let c=document.getElementById('c'),x=c.getContext('2d');c.width=320;c.height=240;let t=0;function f(){x.fillStyle='rgba(10,10,18,.15)';x.fillRect(0,0,320,240);let cx=160+Math.sin(t*.02)*40,cy=120+Math.sin(t*.03)*20;let grd=x.createRadialGradient(cx,cy,0,cx,cy,80);grd.addColorStop(0,'rgba(255,200,120,.5)');grd.addColorStop(.4,'rgba(255,160,80,.2)');grd.addColorStop(1,'rgba(255,120,40,0)');x.fillStyle=grd;x.fillRect(0,0,320,240);for(let i=0;i<40;i++){let a=t*.01+i*1.7,h=Math.sin(a)*30+60;let px=cx+Math.cos(a)*60,py=cy+h-20;x.fillStyle='rgba(255,220,160,'+(.3+Math.sin(a+t)*.1)+')';x.fillRect(px,py,1.5,1.5)}t++}setInterval(f,33)</script></body></html>
wc -c on the UTF-8 file saved to disk.The whole scene is one radial gradient that fades the previous frame by 15% each tick, so the light pool naturally lingers and decays without storing particles or drawing a ground — the fog is just the accumulation of semi-transparent light rectangles over time.