{
  "kind": "html",
  "title": "Team dinner: which evening works?",
  "html": "<style>\n*{box-sizing:border-box}\nbody{margin:0;background:linear-gradient(180deg,#f6f5ff 0%,#ffffff 60%);color:#1e1b3a;font:16px/1.45 system-ui,-apple-system,\"Segoe UI\",Roboto,sans-serif;min-height:100vh}\n.wrap{max-width:520px;margin:0 auto;padding:20px 18px 28px}\n.eyebrow{display:inline-flex;align-items:center;gap:6px;font-size:13px;font-weight:700;color:#4646b8;background:#ebebfd;border-radius:999px;padding:5px 10px}\nh1{font-size:24px;line-height:1.2;margin:10px 0 4px;letter-spacing:-.01em}\n.sub{color:#5d5a7a;font-size:15px;margin:0 0 16px}\n.cal{background:#fff;border-radius:20px;padding:14px 12px 12px;box-shadow:0 4px 18px rgba(60,55,140,.09)}\n.mon{display:flex;justify-content:space-between;align-items:baseline;margin:0 4px 10px}\n.mon b{font-size:17px}\n.mon span{font-size:12px;color:#5d5a7a}\n.grid{display:grid;grid-template-columns:repeat(7,1fr);gap:5px}\n.dow{text-align:center;font-size:12px;font-weight:700;color:#7a77a0;padding-bottom:2px}\n.day{font:inherit;border:0;border-radius:12px;min-height:50px;padding:4px 0;background:transparent;color:#bdbbd0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:1px;font-variant-numeric:tabular-nums;transition:transform .15s,box-shadow .18s}\n.day b{font-size:15px;font-weight:600;line-height:1.1}\n.day small{font-size:11px;font-weight:700;line-height:1}\n.day.c{cursor:pointer}\n.day.on{box-shadow:0 0 0 2.5px #fff,0 0 0 5px #2f2d8c;transform:scale(1.04)}\n.day.c:active{transform:scale(.96)}\n.key{display:flex;align-items:center;gap:8px;justify-content:flex-end;font-size:12px;color:#5d5a7a;margin:10px 4px 0}\n.key i{display:block;width:90px;height:8px;border-radius:4px;background:linear-gradient(90deg,#efeefd,#403ec4)}\n.lbl{font-size:13px;font-weight:700;color:#5d5a7a;margin:18px 0 8px}\n.times{display:grid;grid-template-columns:repeat(4,1fr);gap:8px}\n.tm{font:inherit;min-height:56px;border-radius:14px;border:1.5px solid #dcdaf5;background:#fff;color:#1e1b3a;cursor:pointer;font-variant-numeric:tabular-nums;transition:all .18s}\n.tm b{display:block;font-size:16px}\n.tm small{font-size:12px;color:#5d5a7a}\n.tm.on{background:#5b5bd6;border-color:#5b5bd6;color:#fff;box-shadow:0 6px 14px rgba(91,91,214,.3)}\n.tm.on small{color:#e4e4ff}\n.who{background:#fff;border-radius:16px;padding:12px 14px;margin-top:12px;box-shadow:0 2px 10px rgba(60,55,140,.06);min-height:58px}\n.who p{margin:0 0 8px;font-size:14px;color:#5d5a7a}\n.ppl{display:flex;flex-wrap:wrap;gap:8px}\n.pp{display:flex;align-items:center;gap:6px;background:#f4f3ff;border-radius:999px;padding:4px 10px 4px 4px;font-size:14px;font-weight:600}\n.pp i{width:24px;height:24px;border-radius:50%;background:#c9c8f3;color:#2f2d8c;display:grid;place-content:center;font-style:normal;font-size:12px;font-weight:800}\n.all{font-weight:700;color:#2f8a5a}\n.foot{margin-top:20px}\nbutton.main{width:100%;font:inherit;font-weight:700;font-size:17px;border:0;border-radius:16px;padding:16px;min-height:56px;background:#5b5bd6;color:#fff;cursor:pointer;box-shadow:0 8px 18px rgba(91,91,214,.32);transition:transform .15s,opacity .2s}\nbutton.alt{width:100%;font:inherit;font-weight:600;border:0;border-radius:14px;padding:14px;min-height:48px;background:transparent;color:#4646b8;cursor:pointer;margin-top:6px}\nbutton:active{transform:scale(.98)}\nbutton:disabled{opacity:.5;cursor:default;transform:none}\n.status{text-align:center;color:#5d5a7a;font-size:14px;min-height:20px;margin-top:6px}\n.done{color:#4646b8}\n</style>\n<div class=\"wrap\">\n  <span class=\"eyebrow\" id=\"eyebrow\"></span>\n  <h1 id=\"title\"></h1>\n  <p class=\"sub\" id=\"sub\"></p>\n  <div class=\"cal\">\n    <div class=\"mon\"><b id=\"month\"></b><span id=\"hint\"></span></div>\n    <div class=\"grid\" id=\"grid\"></div>\n    <div class=\"key\"><span id=\"kLo\"></span><i></i><span id=\"kHi\"></span></div>\n  </div>\n  <p class=\"lbl\" id=\"timeLbl\"></p>\n  <div class=\"times\" id=\"times\"></div>\n  <div class=\"who\"><p id=\"whoLbl\"></p><div class=\"ppl\" id=\"ppl\"></div></div>\n  <div class=\"foot\"><button class=\"main\" id=\"go\"></button><button class=\"alt\" id=\"alt\"></button><div class=\"status\" id=\"status\"></div></div>\n</div>\n<script>\n// The card's content. Change only this object.\n// answer.data: {date:\"2026-12-10\", time:\"19:30\", free:7, missing:[\"Ola\"]} or {action:\"none_work\"}\nvar CARD = {\n  eyebrow: \"👥 Design team · 8 people\",\n  title: \"Team dinner: which evening works?\",\n  sub: \"I checked everyone's calendars. Darker evenings have more people free.\",\n  year: 2026, month: 12, monthName: \"December 2026\",\n  hint: \"Tap an evening\",\n  weekdays: [\"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\", \"Sun\"],\n  dayNames: [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"],\n  shortMonth: \"Dec\",\n  keyLow: \"fewer\", keyHigh: \"more free\",\n  people: [\n    { name: \"Ania\" }, { name: \"Bartek\", earliest: \"19:00\" }, { name: \"Kasia\" }, { name: \"Marek\" },\n    { name: \"Ola\" }, { name: \"Piotr\" }, { name: \"Zosia\", earliest: \"19:30\" }, { name: \"Tomek\", latest: \"19:30\" }\n  ],\n  // candidate evenings: day of month -> who is busy all evening\n  days: {\n    1: [\"Ania\", \"Piotr\", \"Tomek\"], 2: [\"Marek\", \"Kasia\"], 3: [\"Ola\", \"Ania\", \"Piotr\", \"Kasia\"],\n    4: [\"Tomek\", \"Marek\"], 8: [\"Kasia\", \"Zosia\", \"Ola\", \"Bartek\", \"Piotr\"], 9: [\"Piotr\", \"Ania\"],\n    10: [\"Ola\"], 11: [\"Marek\", \"Tomek\", \"Ania\"], 15: [\"Bartek\", \"Kasia\"],\n    16: [\"Ania\", \"Marek\", \"Ola\", \"Tomek\", \"Kasia\", \"Piotr\"], 17: [\"Zosia\", \"Ola\"]\n  },\n  times: [\"18:30\", \"19:00\", \"19:30\", \"20:00\"],\n  pick: { day: 10, time: \"19:30\" },\n  timeLabel: \"Start time\",\n  whoLabel: \"Can't make it\",\n  everyone: \"Everyone's in 🎉\",\n  primary: \"Propose {day}, {time}\",\n  secondary: \"None of these work\",\n  sending: \"Sending…\",\n  doneTitle: \"Proposed to the team\",\n  doneSub: \"I'll send the invite and book a table for {n}.\",\n  preview: \"Preview only: open this card in Bridgit to answer.\"\n};\n\nvar sent = false, day = CARD.pick.day, time = CARD.pick.time, cells = {}, chips = [];\nfunction $(id){ return document.getElementById(id); }\nfunction el(tag, cls, text){ var e = document.createElement(tag); if (cls) e.className = cls; if (text != null) e.textContent = text; return e; }\nfunction m(t){ var p = t.split(\":\"); return +p[0] * 60 + +p[1]; }\nfunction missing(d, t){\n  var busy = CARD.days[d] || [];\n  return CARD.people.filter(function(p){\n    return busy.indexOf(p.name) >= 0 || (p.earliest && m(t) < m(p.earliest)) || (p.latest && m(t) > m(p.latest));\n  }).map(function(p){ return p.name; });\n}\nfunction best(d){ return Math.max.apply(null, CARD.times.map(function(t){ return CARD.people.length - missing(d, t).length; })); }\nfunction tint(n){\n  var a = [239, 238, 253], b = [64, 62, 196], k = Math.max(0, (n - 1) / (CARD.people.length - 1));\n  return a.map(function(v, i){ return Math.round(v + (b[i] - v) * k); });\n}\nfunction label(d){ var w = new Date(CARD.year, CARD.month - 1, d).getDay(); return CARD.dayNames[w] + \" \" + d + \" \" + CARD.shortMonth; }\n\n[\"eyebrow\", \"title\", \"sub\"].forEach(function(k){ $(k).textContent = CARD[k]; });\n$(\"month\").textContent = CARD.monthName; $(\"hint\").textContent = CARD.hint;\n$(\"kLo\").textContent = CARD.keyLow; $(\"kHi\").textContent = CARD.keyHigh;\n$(\"timeLbl\").textContent = CARD.timeLabel; $(\"whoLbl\").textContent = CARD.whoLabel; $(\"alt\").textContent = CARD.secondary;\n\nCARD.weekdays.forEach(function(w){ $(\"grid\").appendChild(el(\"div\", \"dow\", w)); });\nvar lead = (new Date(CARD.year, CARD.month - 1, 1).getDay() + 6) % 7, total = new Date(CARD.year, CARD.month, 0).getDate();\nfor (var i = 0; i < lead; i++) $(\"grid\").appendChild(el(\"div\"));\nfor (var d = 1; d <= total; d++) (function(d){\n  var cand = !!CARD.days[d], c = el(cand ? \"button\" : \"div\", \"day\" + (cand ? \" c\" : \"\"));\n  c.appendChild(el(\"b\", null, String(d)));\n  if (cand) {\n    var n = best(d);\n    c.appendChild(el(\"small\", null, n + \"/\" + CARD.people.length));\n    var rgb = tint(n), L = rgb.map(function(v){ v /= 255; return v <= .03928 ? v / 12.92 : Math.pow((v + .055) / 1.055, 2.4); });\n    L = .2126 * L[0] + .7152 * L[1] + .0722 * L[2];\n    c.style.background = \"rgb(\" + rgb.join(\",\") + \")\"; c.style.color = 1.05 / (L + .05) > (L + .05) / .0644 ? \"#fff\" : \"#1c1a4a\";\n    c.setAttribute(\"aria-label\", label(d) + \": \" + n + \" free\");\n    c.onclick = function(){ if (sent) return; day = d; render(); };\n    cells[d] = c;\n  }\n  $(\"grid\").appendChild(c);\n})(d);\n\nCARD.times.forEach(function(t){\n  var b = el(\"button\", \"tm\"); b.appendChild(el(\"b\", null, t)); b.appendChild(el(\"small\"));\n  b.onclick = function(){ if (sent) return; time = t; render(); };\n  chips.push({ t: t, b: b }); $(\"times\").appendChild(b);\n});\n\nfunction render(){\n  Object.keys(cells).forEach(function(k){ cells[k].classList.toggle(\"on\", +k === day); });\n  chips.forEach(function(c){\n    c.b.classList.toggle(\"on\", c.t === time);\n    c.b.lastChild.textContent = (CARD.people.length - missing(day, c.t).length) + \" free\";\n  });\n  var miss = missing(day, time), box = $(\"ppl\");\n  box.textContent = \"\";\n  if (!miss.length) box.appendChild(el(\"span\", \"all\", CARD.everyone));\n  miss.forEach(function(n){ var p = el(\"span\", \"pp\"); p.appendChild(el(\"i\", null, n.charAt(0))); p.appendChild(document.createTextNode(n)); box.appendChild(p); });\n  $(\"go\").textContent = CARD.primary.replace(\"{day}\", label(day)).replace(\"{time}\", time);\n  return miss;\n}\n\nfunction send(answer){\n  if (sent) return;\n  var B = window.Bridgit || window.Bridget;\n  if (!B || !B.respond) { $(\"status\").textContent = CARD.preview; return; }\n  sent = true;\n  document.querySelectorAll(\"button\").forEach(function(b){ b.disabled = true; });\n  $(\"status\").textContent = CARD.sending;\n  B.respond(JSON.stringify(answer));\n}\n$(\"go\").onclick = function(){\n  var miss = render(), mm = CARD.month < 10 ? \"0\" + CARD.month : CARD.month, dd = day < 10 ? \"0\" + day : day;\n  send({ date: CARD.year + \"-\" + mm + \"-\" + dd, time: time, free: CARD.people.length - miss.length, missing: miss });\n};\n$(\"alt\").onclick = function(){ send({ action: \"none_work\" }); };\ndocument.addEventListener(\"bridgit:answered\", function(e){\n  e.preventDefault();\n  $(\"title\").textContent = \"✓ \" + CARD.doneTitle; $(\"title\").className = \"done\";\n  $(\"sub\").textContent = CARD.doneSub.replace(\"{n}\", CARD.people.length - missing(day, time).length);\n  $(\"status\").textContent = \"\";\n  setTimeout(function(){ $(\"title\").scrollIntoView({ block: \"center\" }); }, 400);\n});\nrender();\n</script>\n",
  "expires_in_seconds": 172800
}
