{
  "kind": "html",
  "title": "Bedtime story for Zosia: you choose!",
  "html": "<style>\n*{box-sizing:border-box}\nbody{margin:0;background:linear-gradient(170deg,#2b1b5a 0%,#45288a 55%,#6a3fb5 100%);color:#fff;font:17px/1.4 system-ui,-apple-system,\"Segoe UI\",Roboto,sans-serif;min-height:100vh}\n.wrap{position:relative;max-width:520px;margin:0 auto;padding:20px 18px 28px;overflow:hidden}\n.sky{position:absolute;left:0;right:0;top:0;height:96px;pointer-events:none}\n.sky i{position:absolute;width:3px;height:3px;border-radius:50%;background:#fff;opacity:.8;animation:tw 3s ease-in-out infinite}\n@keyframes tw{50%{opacity:.25}}\n.moon{position:absolute;top:14px;right:18px;width:56px;height:56px}\n.top{position:relative;padding-right:70px;margin-bottom:18px}\n.eyebrow{font-size:13px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:#ffd23f;margin:0 0 4px}\nh1{font-size:25px;line-height:1.2;margin:0;letter-spacing:-.01em}\nh2{position:relative;font-size:17px;margin:0 0 10px;display:flex;align-items:center;gap:8px}\nh2 span{font-size:13px;font-weight:600;color:#d9ccf5}\n.grid{position:relative;display:grid;grid-template-columns:repeat(4,1fr);gap:8px;margin-bottom:20px}\n.tile{font:inherit;color:#fff;border:2px solid rgba(255,255,255,.14);background:rgba(255,255,255,.09);border-radius:20px;min-height:96px;padding:10px 4px 8px;cursor:pointer;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:4px;transition:transform .18s,box-shadow .18s,background .18s,border-color .18s}\n.tile b{font-size:38px;line-height:1;font-weight:400}\n.tile small{font-size:12.5px;font-weight:600;line-height:1.15;text-align:center;color:#ece4ff}\n.tile:active{transform:scale(.96)}\n.tile.on{background:rgba(255,210,63,.18);border-color:#ffd23f;transform:scale(1.06);box-shadow:0 0 0 4px rgba(255,210,63,.25),0 0 24px rgba(255,210,63,.55)}\n.len{position:relative;display:grid;grid-template-columns:repeat(3,1fr);gap:4px;background:rgba(0,0,0,.22);border-radius:16px;padding:4px;margin-bottom:20px}\n.len button{font:inherit;font-size:15px;font-weight:700;border:0;border-radius:12px;min-height:52px;background:transparent;color:#ece4ff;cursor:pointer;transition:background .18s,color .18s}\n.len button small{display:block;font-size:12px;font-weight:600;opacity:.85}\n.len button.on{background:#fff;color:#2b1b5a}\n.preview{position:relative;background:rgba(255,255,255,.1);border:1px dashed rgba(255,255,255,.35);border-radius:18px;padding:14px 16px;margin-bottom:18px;font-size:17px;line-height:1.45;min-height:76px}\n.preview em{font-style:normal;color:#ffd23f;font-weight:700}\n.preview .ph{color:#d9ccf5}\n.main{position:relative;width:100%;font:inherit;font-size:19px;font-weight:800;border:0;border-radius:18px;min-height:60px;background:#ffd23f;color:#2b1b5a;cursor:pointer;box-shadow:0 6px 0 #c99a00;transition:transform .1s,box-shadow .1s,background .18s}\n.main:active{transform:translateY(3px) scale(.98);box-shadow:0 3px 0 #c99a00}\n.main:disabled{background:#8c7bb8;color:#2b1b5a;box-shadow:none;cursor:default}\n.alt{position:relative;width:100%;font:inherit;font-weight:600;border:0;background:none;color:#d9ccf5;min-height:48px;margin-top:8px;cursor:pointer}\n.status{position:relative;text-align:center;color:#ece4ff;font-size:14px;min-height:20px;margin-top:6px}\n</style>\n<div class=\"wrap\">\n  <div class=\"sky\" id=\"sky\"></div>\n  <svg class=\"moon\" viewBox=\"0 0 56 56\" aria-hidden=\"true\"><path d=\"M38.3 9.8A22 22 0 1 0 47.9 37.9A20 20 0 0 1 38.3 9.8Z\" fill=\"#ffe89a\"/><circle cx=\"18\" cy=\"36\" r=\"2.5\" fill=\"#f2d36b\"/><circle cx=\"14\" cy=\"24\" r=\"1.8\" fill=\"#f2d36b\"/></svg>\n  <div class=\"top\"><p class=\"eyebrow\" id=\"eyebrow\"></p><h1 id=\"title\"></h1></div>\n  <div id=\"rows\"></div>\n  <h2 id=\"lenTitle\"></h2>\n  <div class=\"len\" id=\"len\"></div>\n  <div class=\"preview\" id=\"preview\"></div>\n  <button class=\"main\" id=\"go\" disabled></button>\n  <button class=\"alt\" id=\"surprise\"></button>\n  <div class=\"status\" id=\"status\"></div>\n</div>\n<script>\n// answer.data: {hero:\"fox\", place:\"volcano\", twist:\"key\", minutes:6, surprise:false}\n// The card's content. Change only this object.\nvar CARD = {\n  eyebrow: 'Bedtime',\n  title: 'Zosia, build your story!',\n  rows: [\n    {key:'hero', title:\"Who's the hero?\", options:[\n      {id:'fox', emoji:'🦊', label:'Fox', phrase:'A brave fox'},\n      {id:'dragon', emoji:'🐉', label:'Dragon', phrase:'A little dragon'},\n      {id:'robot', emoji:'🤖', label:'Robot', phrase:'A clever robot'},\n      {id:'mermaid', emoji:'🧜', label:'Mermaid', phrase:'A kind mermaid'}]},\n    {key:'place', title:'Where?', options:[\n      {id:'castle', emoji:'🏰', label:'Castle', phrase:'in a sparkly castle'},\n      {id:'volcano', emoji:'🌋', label:'Volcano island', phrase:'on a volcano island'},\n      {id:'space', emoji:'🚀', label:'Space', phrase:'far out in space'},\n      {id:'forest', emoji:'🌲', label:'Forest', phrase:'in a whispering forest'}]},\n    {key:'twist', title:'What happens?', options:[\n      {id:'party', emoji:'🎂', label:'Surprise party', phrase:'plans a surprise party'},\n      {id:'key', emoji:'🗝️', label:'Lost key', phrase:'finds a lost key'},\n      {id:'rainbow', emoji:'🌈', label:'Rainbow bridge', phrase:'crosses a rainbow bridge'},\n      {id:'friend', emoji:'🐣', label:'New friend', phrase:'meets a new friend'}]}\n  ],\n  lenTitle: 'How long?',\n  lengths: [{label:'Short', minutes:3}, {label:'Medium', minutes:6}, {label:'Long', minutes:10}],\n  defaultMinutes: 6,\n  placeholder: 'Pick a hero, a place and what happens…',\n  go: 'Tell my story ✨',\n  goNotReady: 'Pick all three first',\n  surprise: 'Surprise me!',\n  sending: 'Sending…',\n  doneText: 'Story time! Get cosy 🌙',\n  preview: 'Preview only: open this card in Bridgit to answer.'\n};\nvar $ = function(id){return document.getElementById(id)};\nvar pick = {}, minutes = CARD.defaultMinutes, sent = false, surprised = false;\n$('eyebrow').textContent = CARD.eyebrow; $('title').textContent = CARD.title;\n$('lenTitle').textContent = CARD.lenTitle; $('surprise').textContent = CARD.surprise;\nfor (var s = 0; s < 16; s++) {\n  var st = document.createElement('i');\n  st.style.left = (Math.random()*100) + '%'; st.style.top = (Math.random()*100) + '%';\n  st.style.animationDelay = (Math.random()*3) + 's';\n  if (s % 5 === 0) { st.style.width = st.style.height = '4px'; }\n  $('sky').appendChild(st);\n}\nCARD.rows.forEach(function(row){\n  var h = document.createElement('h2'); h.textContent = row.title; $('rows').appendChild(h);\n  var g = document.createElement('div'); g.className = 'grid'; $('rows').appendChild(g);\n  row.options.forEach(function(o){\n    var b = document.createElement('button'); b.className = 'tile';\n    var e = document.createElement('b'); e.textContent = o.emoji;\n    var l = document.createElement('small'); l.textContent = o.label;\n    b.appendChild(e); b.appendChild(l); g.appendChild(b);\n    o.el = b;\n    b.onclick = function(){ if (sent) return; pick[row.key] = o; draw(); };\n  });\n});\nCARD.lengths.forEach(function(L){\n  var b = document.createElement('button'); b.textContent = L.label;\n  var m = document.createElement('small'); m.textContent = L.minutes + ' min'; b.appendChild(m);\n  L.el = b; b.onclick = function(){ if (sent) return; minutes = L.minutes; draw(); };\n  $('len').appendChild(b);\n});\nfunction draw(){\n  CARD.rows.forEach(function(row){ row.options.forEach(function(o){ o.el.classList.toggle('on', pick[row.key] === o) }) });\n  CARD.lengths.forEach(function(L){ L.el.classList.toggle('on', L.minutes === minutes) });\n  var p = $('preview'); p.textContent = '';\n  var ready = pick.hero && pick.place && pick.twist;\n  if (!pick.hero && !pick.place && !pick.twist) {\n    var ph = document.createElement('span'); ph.className = 'ph'; ph.textContent = CARD.placeholder; p.appendChild(ph);\n  } else {\n    var parts = [[pick.hero, 'Someone'], [pick.twist, 'does something'], [pick.place, 'somewhere']];\n    parts.forEach(function(pt, i){\n      if (i) p.appendChild(document.createTextNode(' '));\n      var em = document.createElement(pt[0] ? 'em' : 'span');\n      if (!pt[0]) em.className = 'ph';\n      em.textContent = pt[0] ? pt[0].phrase : pt[1];\n      p.appendChild(em);\n    });\n    p.appendChild(document.createTextNode('…'));\n  }\n  $('go').disabled = !ready;\n  $('go').textContent = ready ? CARD.go : CARD.goNotReady;\n}\ndraw();\nfunction answer(){\n  if (sent) return;\n  var b = window.Bridgit || window.Bridget;\n  if (!b) { $('status').textContent = CARD.preview; return; }\n  sent = true;\n  document.querySelectorAll('button').forEach(function(x){ x.disabled = true });\n  $('status').textContent = CARD.sending;\n  b.respond(JSON.stringify({hero:pick.hero.id, place:pick.place.id, twist:pick.twist.id, minutes:minutes, surprise:surprised}));\n}\n$('go').onclick = answer;\n$('surprise').onclick = function(){\n  if (sent) return;\n  CARD.rows.forEach(function(row){ pick[row.key] = row.options[Math.floor(Math.random()*row.options.length)] });\n  surprised = true; draw();\n};\ndocument.addEventListener('bridgit:answered', function(e){\n  e.preventDefault();\n  $('title').textContent = '✓ ' + CARD.doneText;\n  $('status').textContent = '';\n  setTimeout(function(){ $('title').scrollIntoView({block:'center'}) }, 400);\n});\n</script>\n",
  "expires_in_seconds": 7200
}
