{
  "slug": "pixel-garden",
  "version": 1,
  "html": "<!doctype html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<title>Pixel Garden</title>\n<style>\n  :root { --bg:#f3ecd9; --ink:#2b2140; }\n  * { box-sizing: border-box; }\n  body { margin:0; min-height:100vh; display:grid; place-items:center; background:var(--bg); color:var(--ink);\n    font:15px/1.4 ui-sans-serif, system-ui, sans-serif; padding:16px; }\n  .wrap { width:min(560px, 100%); display:grid; gap:12px; }\n  h1 { font:700 26px/1.1 Georgia, serif; margin:0; }\n  p { margin:0; color:#5d5274; }\n  #grid { display:grid; grid-template-columns:repeat(24, 1fr); aspect-ratio:1; background:#e6dcc2; border-radius:14px;\n    overflow:hidden; border:3px solid var(--ink); touch-action:none; user-select:none; }\n  #grid div { border:.5px solid #2b21400d; }\n  #grid div:hover { outline:2px solid var(--ink); outline-offset:-2px; }\n  .palette { display:flex; gap:6px; flex-wrap:wrap; align-items:center; }\n  .palette button { width:34px; height:34px; border-radius:50%; border:3px solid transparent; cursor:pointer; box-shadow:0 2px 0 #0002; }\n  .palette button[aria-pressed=\"true\"] { border-color:var(--ink); transform:scale(1.12); }\n  .palette .eraser { background:repeating-conic-gradient(#ddd 0 25%, #fff 0 50%) 0 0/12px 12px; }\n  .status { font-size:13px; color:#5d5274; min-height:1.4em; }\n</style>\n</head>\n<body>\n<div class=\"wrap\">\n  <h1>🌷 Pixel Garden</h1>\n  <p>One shared 24×24 garden. Plant a pixel; everyone (humans and agents) sees it grow.</p>\n  <div class=\"palette\" id=\"palette\"></div>\n  <div id=\"grid\" role=\"grid\" aria-label=\"Pixel garden\"></div>\n  <div class=\"status\" id=\"status\">Loading the garden…</div>\n</div>\n<script>\nconst COLORS = [null, '#5b8c3a', '#9bc45a', '#f2c94c', '#f77348', '#e0607e', '#a46ad8', '#4f8fd8', '#7a5230', '#2b2140'];\nconst N = 24;\nconst grid = document.getElementById('grid');\nconst status = document.getElementById('status');\nlet color = 1;\nconst cells = [];\nfor (let y = 0; y < N; y++) for (let x = 0; x < N; x++) {\n  const d = document.createElement('div');\n  d.dataset.k = 'px:' + x + ',' + y;\n  grid.appendChild(d);\n  cells.push(d);\n}\nconst pal = document.getElementById('palette');\nCOLORS.forEach((c, i) => {\n  const b = document.createElement('button');\n  b.type = 'button';\n  b.title = i === 0 ? 'eraser' : 'color ' + i;\n  b.setAttribute('aria-label', b.title);\n  if (i === 0) b.className = 'eraser'; else b.style.background = c;\n  b.setAttribute('aria-pressed', String(i === color));\n  b.onclick = () => { color = i; [...pal.children].forEach((x, j) => x.setAttribute('aria-pressed', String(j === i))); };\n  pal.appendChild(b);\n});\nfunction paintCell(el, v) { el.style.background = COLORS[v] || ''; }\nasync function draw() {\n  const all = await charm.all('px:');\n  for (const el of cells) paintCell(el, all[el.dataset.k]);\n  const n = Object.keys(all).length;\n  status.textContent = n + ' pixel' + (n === 1 ? '' : 's') + ' planted.';\n}\nlet down = false;\nasync function plant(el) {\n  if (!el || !el.dataset.k) return;\n  paintCell(el, color);\n  try {\n    if (color === 0) await charm.del(el.dataset.k); else await charm.set(el.dataset.k, color);\n  } catch (e) { status.textContent = e.message; }\n}\ngrid.addEventListener('pointerdown', (e) => { down = true; plant(e.target); });\ngrid.addEventListener('pointerover', (e) => { if (down) plant(e.target); });\naddEventListener('pointerup', () => { down = false; });\ncharm.onChange(draw, 2000);\ndraw().catch((e) => { status.textContent = e.message; });\n</script>\n</body>\n</html>\n"
}