{"$schema":"https://ui.shadcn.com/schema/registry-item.json","name":"wedding-countdown","type":"registry:component","title":"Wedding Countdown","description":"Countdown to the wedding date with task progress.","author":"Notion Arena","categories":["time"],"tags":["widget","free","wedding","countdown","tasks","planning"],"meta":{"kind":"widget","tier":"free","version":"1.0.0","updatedAt":"2026-10-12","notionPlan":"Free","emoji":"⏰","delivery":["embed","html-block","download"],"capabilities":{"interactive":true,"offlineSafe":true,"persistsLocally":true,"writesToNotion":false,"needsNetwork":false},"embedUrl":"https://notionarena.vercel.app/embed/wedding-countdown","fileUrl":"https://notionarena.vercel.app/widgets/wedding-countdown.html","downloadUrl":"https://notionarena.vercel.app/api/widget/wedding-countdown","height":480,"minHeight":350,"maxHeight":660,"params":[{"key":"label","label":"Widget title","type":"text","default":"Wedding Countdown"},{"key":"accent","label":"Accent","type":"color","default":"#b06aa0"},{"key":"theme","label":"Theme","type":"select","default":"auto","options":[{"value":"auto","label":"Match Notion"},{"value":"light","label":"Light"},{"value":"dark","label":"Dark"}]}]},"files":[{"path":"widgets/wedding-countdown.html","type":"registry:file","target":"notion/widgets/wedding-countdown.html","content":"<!doctype html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf8\">\n<meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n<meta name=\"color-scheme\" content=\"light dark\">\n<title>Wedding Countdown</title>\n<style>\n*{box-sizing:border-box}html,body{width:100%;height:100%;min-height:100%;margin:0;overflow:hidden}body{background:var(--bg);color:var(--fg);font:12px/1.4 ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,\"Segoe UI\",sans-serif;-webkit-font-smoothing:antialiased}\n:root{color-scheme:light;--bg:#f7f7f5;--fg:#24231f;--card:#fff;--muted:#65635c;--faint:#6f6d65;--border:#e5e2da;--surface:#fbfaf8;--danger:#a33228;--danger-soft:#fff0ed;--accent:#477d6f;--accent-text:#28594d;--accent-ink:#fff;--soft:#e9f0ed}\n:root[data-theme=\"dark\"]{color-scheme:dark;--bg:#191919;--fg:#f2f0e9;--card:#222220;--muted:#c0beb6;--faint:#aaa79f;--border:#41403c;--surface:#1e1e1c;--danger:#ffb5a9;--danger-soft:#3c2421;--soft:#29332f}\n@media(prefers-color-scheme:dark){:root[data-theme=\"auto\"]{color-scheme:dark;--bg:#191919;--fg:#f2f0e9;--card:#222220;--muted:#c0beb6;--faint:#aaa79f;--border:#41403c;--surface:#1e1e1c;--danger:#ffb5a9;--danger-soft:#3c2421;--soft:#29332f}}\n.wrap{height:100%;max-height:100%;min-height:100%;display:flex;flex-direction:column;gap:8px;padding:11px}.head{display:flex;align-items:center;justify-content:space-between;gap:12px;min-height:34px}.brand{display:flex;align-items:center;gap:9px;min-width:0}.mark{display:grid;place-items:center;flex:0 0 32px;width:32px;height:32px;border:1px solid var(--border);border-radius:9px;background:var(--soft);color:var(--accent-text)}.mark svg{width:19px;height:19px;fill:none;stroke:currentColor;stroke-width:1.55;stroke-linecap:round;stroke-linejoin:round}.kicker{color:var(--muted);font-size:9px;font-weight:700;letter-spacing:.105em;line-height:1.1}.title{margin-top:3px;font-size:13px;font-weight:700;line-height:1.2;letter-spacing:-.015em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.metrics{display:flex;gap:5px;flex:0 0 auto}.metric{display:flex;flex-direction:column;align-items:flex-end;min-width:48px;padding:4px 7px;border:1px solid var(--border);border-radius:8px;background:var(--card);font-variant-numeric:tabular-nums}.metric-value{color:var(--fg);font-size:11px;font-weight:700;line-height:1.2}.metric-label{color:var(--muted);font-size:8px;line-height:1.25;white-space:nowrap}\n.form{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));gap:6px;padding:8px;border:1px solid var(--border);border-radius:9px;background:var(--surface)}.field{display:flex;flex-direction:column;gap:3px;min-width:0}.field.wide{grid-column:span 12}.field.half{grid-column:span 6}.field.third{grid-column:span 4}.field label{color:var(--muted);font-size:9px;font-weight:650;line-height:1.2}.input{width:100%;min-width:0;min-height:28px;padding:5px 7px;border:1px solid var(--border);border-radius:6px;background:var(--card);color:var(--fg);font:inherit;font-size:11px;outline:none}.input::placeholder{color:var(--faint);opacity:.85}.input:focus-visible,.status:focus-visible,.btn:focus-visible,.remove:focus-visible,.check:focus-visible{outline:2px solid var(--accent);outline-offset:2px}.input[type=date]{min-height:28px}.input[type=number]{font-variant-numeric:tabular-nums}.input select{color:var(--fg)}textarea.input{min-height:40px;resize:vertical}.btn{min-height:28px;padding:5px 9px;border:1px solid var(--border);border-radius:6px;background:var(--card);color:var(--fg);font:inherit;font-size:10px;font-weight:650;cursor:pointer}.btn.primary{border-color:var(--accent);background:var(--accent);color:var(--accent-ink)}.submit{grid-column:span 4;align-self:end}\n.toolbar{display:flex;align-items:center;gap:6px;min-height:27px}.search{flex:1;min-width:0;min-height:27px;padding:5px 8px;border:1px solid var(--border);border-radius:7px;background:var(--card);color:var(--fg);font:inherit;font-size:10px;outline:none}.search::placeholder{color:var(--faint)}.search:focus-visible{outline:2px solid var(--accent);outline-offset:1px}.count{color:var(--muted);font-size:9px;white-space:nowrap}.clear{border:0;padding:3px 5px;background:transparent;color:var(--accent-text);font:inherit;font-size:9px;cursor:pointer}\n.list{display:grid;align-content:start;gap:6px;flex:1;min-height:0;overflow:auto;padding:1px 2px 2px 0;scrollbar-color:var(--border) transparent;scrollbar-width:thin}.entry{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:7px 9px;align-items:start;padding:7px 8px;border:1px solid var(--border);border-radius:8px;background:var(--card)}.entry-main{min-width:0}.entry-title{overflow:hidden;color:var(--fg);font-size:11px;font-weight:680;line-height:1.35;text-overflow:ellipsis}.chips{display:flex;flex-wrap:wrap;gap:4px;margin-top:4px}.chip{display:inline-flex;align-items:center;max-width:100%;padding:2px 5px;border-radius:99px;background:var(--soft);color:var(--accent-text);font-size:8.5px;line-height:1.25;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.chip.priority{background:var(--danger-soft);color:var(--danger)}.detail{margin:4px 0 0;color:var(--muted);font-size:9px;line-height:1.35;overflow-wrap:anywhere}.actions{display:flex;align-items:flex-start;gap:4px}.status{max-width:110px;min-height:24px;padding:3px 5px;border:1px solid var(--border);border-radius:6px;background:var(--surface);color:var(--fg);font:inherit;font-size:9px}.remove{min-height:24px;padding:3px 6px;border:1px solid var(--border);border-radius:6px;background:transparent;color:var(--muted);font:inherit;font-size:9px;cursor:pointer}.remove:hover{border-color:var(--danger);color:var(--danger)}.empty{padding:18px 8px;border:1px dashed var(--border);border-radius:8px;color:var(--muted);font-size:10px;text-align:center}.footer{display:flex;align-items:center;justify-content:space-between;gap:8px;padding-top:4px;border-top:1px solid var(--border);color:var(--muted);font-size:8px;line-height:1.3}.footer-note{min-width:0}.live{flex:0 0 auto;text-align:right}.checklist{grid-column:1/-1;display:grid;gap:4px;padding-top:4px;border-top:1px solid var(--border)}.check-row{display:flex;align-items:flex-start;gap:6px;color:var(--muted);font-size:9px;line-height:1.3}.check{flex:0 0 auto;margin:1px 0 0;accent-color:var(--accent)}.progress-row{display:flex;align-items:center;gap:7px;margin-top:2px}.small{color:var(--muted);font-size:8.5px;white-space:nowrap}.bar{height:4px;flex:1;overflow:hidden;border-radius:99px;background:var(--border)}.bar span{display:block;height:100%;border-radius:inherit;background:var(--accent)}\n@media(max-width:420px){.wrap{gap:7px;padding:9px}.metrics{gap:3px}.metric{min-width:40px;padding:3px 5px}.metric-label{font-size:7.5px}.form{gap:5px;padding:7px}.field.third{grid-column:span 6}.submit{grid-column:span 6}.status{max-width:92px}.footer{font-size:7.5px}}\n@media(max-width:300px){.head{align-items:flex-start;flex-direction:column;gap:5px}.metrics{width:100%;justify-content:flex-end}.field.half,.field.third,.submit{grid-column:span 12}.entry{grid-template-columns:minmax(0,1fr)}.actions{justify-content:flex-end}.footer{align-items:flex-start;flex-direction:column}.live{text-align:left}}\n@media(prefers-reduced-motion:reduce){*,*::before,*::after{animation-duration:.01ms!important;transition-duration:.01ms!important;scroll-behavior:auto!important}}\n</style>\n</head>\n<body><main class=\"wrap\">\n<header class=\"head\"><div class=\"brand\"><span class=\"mark\"><svg viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path d=\"M3 4h18v2H3zM3 10h18v2H3zM3 16h12v2H3z\"/></svg></span><div><div class=\"kicker\">COUNTDOWN</div><div class=\"title\" id=\"title\">Wedding Countdown</div></div></div><div class=\"metrics\" id=\"metrics\"></div></header>\n<form class=\"form\" id=\"form\"></form>\n<div class=\"toolbar\"><input class=\"search\" id=\"search\" type=\"search\" placeholder=\"Filter tasks or categories\" aria-label=\"Filter tasks or categories\"><span class=\"count\" id=\"count\"></span><button type=\"button\" class=\"clear\" id=\"clear\" aria-label=\"Clear filter\">Clear filter</button></div>\n<section class=\"list\" id=\"list\" aria-label=\"Wedding Countdown entries\"></section>\n<footer class=\"footer\"><span class=\"footer-note\">Manual log only. Not an event planning platform, countdown service, or wedding management tool.</span><span class=\"live\" id=\"status\" role=\"status\" aria-live=\"polite\">Saved only in this browser.</span></footer>\n</main>\n<script id=\"bk-config\" type=\"application/json\">{\"label\":\"Wedding Countdown\",\"accent\":\"#b06aa0\",\"theme\":\"auto\"}</script>\nvar SPEC={\"slug\":\"wedding-countdown\",\"title\":\"Wedding Countdown\",\"kicker\":\"COUNTDOWN\",\"accent\":\"#b06aa0\",\"tagline\":\"Countdown to the wedding date with task progress.\",\"description\":\"A browser-local wedding countdown that stores the wedding date and task aliases only. It holds no guest lists, vendor contracts, or event details and is not an event planning platform, countdown service, or wedding management tool.\",\"category\":\"time\",\"color\":\"pink\",\"height\":480,\"fields\":[{\"key\":\"title\",\"label\":\"Task alias\",\"type\":\"text\",\"required\":true,\"max\":60,\"placeholder\":\"Send invitations\",\"span\":\"half\"},{\"key\":\"category\",\"label\":\"Category\",\"type\":\"select\",\"options\":[\"Venue\",\"Guests\",\"Attire\",\"Photography\",\"Catering\",\"Other\"],\"default\":\"Other\",\"span\":\"half\"},{\"key\":\"dueDate\",\"label\":\"Due date\",\"type\":\"date\",\"required\":true,\"span\":\"third\"},{\"key\":\"priority\",\"label\":\"Priority\",\"type\":\"select\",\"options\":[\"Low\",\"Medium\",\"High\"],\"default\":\"Medium\",\"span\":\"third\"},{\"key\":\"done\",\"label\":\"Done\",\"type\":\"checkbox\",\"span\":\"third\"},{\"key\":\"note\",\"label\":\"Notes\",\"type\":\"text\",\"max\":100,\"placeholder\":\"Task notes, no guest lists or contracts\",\"span\":\"wide\"}],\"titleField\":\"title\",\"cardFields\":[{\"key\":\"category\",\"label\":\"Category\"},{\"key\":\"dueDate\",\"label\":\"Due\",\"kind\":\"date\"},{\"key\":\"priority\",\"label\":\"Priority\",\"kind\":\"priority\"},{\"key\":\"done\",\"label\":\"Done\",\"kind\":\"detail\"}],\"status\":{\"field\":\"status\",\"values\":[\"To do\",\"In progress\",\"Done\",\"Cancelled\"],\"default\":\"To do\",\"colors\":{\"To do\":\"info\",\"In progress\":\"warning\",\"Done\":\"success\",\"Cancelled\":\"neutral\"}},\"sortPriority\":{\"field\":\"priority\",\"order\":[\"High\",\"Medium\",\"Low\"]},\"dateField\":{\"key\":\"dueDate\",\"label\":\"Due date\",\"future\":\"in\",\"past\":\"ago\"},\"metrics\":[{\"kind\":\"total\"},{\"kind\":\"statusCount\",\"status\":\"Done\",\"label\":\"Done\"},{\"kind\":\"statusCount\",\"status\":\"To do\",\"label\":\"To do\"},{\"kind\":\"rate\",\"numerator\":\"Done\",\"denominator\":\"total\",\"format\":\"percent\",\"label\":\"Progress\"}],\"checks\":[],\"search\":true,\"empty\":\"No tasks yet. Add a task above to start your wedding countdown.\",\"footnote\":\"Manual log only. Not an event planning platform, countdown service, or wedding management tool.\",\"submit\":\"Add task\",\"searchPlaceholder\":\"Filter tasks or categories\"};\n(function(){\nvar cfgEl=document.getElementById('bk-config'),base={};try{base=cfgEl?JSON.parse(cfgEl.textContent||'{}'):{};}catch(e){}\nvar q=new URLSearchParams(location.search),c={};for(var k in base)c[k]=base[k];q.forEach(function(v,k){c[k]=v;});\nfunction safeColor(v,d){return /^#[0-9a-f]{6}$/i.test(String(v||''))?String(v):d;}\nvar theme=['auto','light','dark'].indexOf(String(c.theme||'auto'))>=0?String(c.theme||'auto'):'auto',ACCENT=safeColor(c.accent,SPEC.accent),LABEL=String(c.label||SPEC.title).slice(0,48),KEY=\"notion-arena.wedding-countdown.v1\",LIMIT=120;\ndocument.documentElement.setAttribute('data-theme',theme);document.documentElement.style.setProperty('--accent',ACCENT);document.getElementById('title').textContent=LABEL;document.title=LABEL;\nfunction rgb(h){var s=h.slice(1);return[0,2,4].map(function(i){return parseInt(s.slice(i,i+2),16);});}function lum(a){return a.map(function(v){v/=255;return v<=.04045?v/12.92:Math.pow((v+.055)/1.055,2.4);}).reduce(function(sum,v,i){return sum+v*[.2126,.7152,.0722][i];},0);}function ratio(a,b){var x=lum(a),y=lum(b);return(Math.max(x,y)+.05)/(Math.min(x,y)+.05);}function hex(a){return'#'+a.map(function(v){return Math.max(0,Math.min(255,v)).toString(16).padStart(2,'0');}).join('');}function mix(a,b,t){return a.map(function(v,i){return Math.round(v+(b[i]-v)*t);});}function setAccent(){var dark=theme==='dark'||(theme==='auto'&&window.matchMedia&&window.matchMedia('(prefers-color-scheme: dark)').matches),bg=rgb(dark?'#222220':'#ffffff'),a=rgb(ACCENT),soft=mix(bg,a,.12),target=dark?[255,255,255]:[0,0,0],text=a;for(var t=.02;t<=1;t+=.02){if(ratio(text,soft)>=4.5)break;text=mix(a,target,t);}var black=[0,0,0],white=[255,255,255],ink=ratio(a,black)>=ratio(a,white)?black:white;document.documentElement.style.setProperty('--accent-text',hex(text));document.documentElement.style.setProperty('--accent-ink',hex(ink));document.documentElement.style.setProperty('--soft',hex(soft));document.documentElement.style.colorScheme=dark?'dark':'light';}setAccent();if(theme==='auto'&&window.matchMedia){var mq=window.matchMedia('(prefers-color-scheme: dark)');if(mq.addEventListener)mq.addEventListener('change',setAccent);else if(mq.addListener)mq.addListener(setAccent);}\nvar items=[];try{var raw=JSON.parse(localStorage.getItem(KEY)||'[]');if(Array.isArray(raw))items=raw.filter(function(x){return x&&typeof x.id==='string';}).slice(0,LIMIT);}catch(e){}\nfunction el(tag,cls,text){var n=document.createElement(tag);if(cls)n.className=cls;if(text!==undefined&&text!==null)n.textContent=String(text);return n;}function clean(s,max){return String(s||'').trim().slice(0,max);}function uid(){return Date.now().toString(36)+Math.random().toString(36).slice(2,8);}function localToday(){var d=new Date();return d.getFullYear()+'-'+String(d.getMonth()+1).padStart(2,'0')+'-'+String(d.getDate()).padStart(2,'0');}function dateDiff(s){if(!/^\\d{4}-\\d{2}-\\d{2}$/.test(String(s||'')))return null;var a=new Date(s+'T00:00:00'),b=new Date(localToday()+'T00:00:00');if(Number.isNaN(a.getTime()))return null;return Math.round((a-b)/86400000);}function prettyDate(s){if(!/^\\d{4}-\\d{2}-\\d{2}$/.test(String(s||'')))return String(s||'');var d=new Date(s+'T12:00:00');return Number.isNaN(d.getTime())?s:d.toLocaleDateString(undefined,{month:'short',day:'numeric'});}function announce(s){document.getElementById('status').textContent=s;}function save(s){try{localStorage.setItem(KEY,JSON.stringify(items));announce(s||'Saved only in this browser.');}catch(e){announce('Browser storage is unavailable. Changes may not persist.');}}\nfunction buildForm(){var form=document.getElementById('form');SPEC.fields.forEach(function(f){var box=el('div','field '+(f.span||'half'));var id='f-'+f.key,lab=el('label','',f.label);lab.htmlFor=id;box.appendChild(lab);var input;if(f.type==='select'){input=el('select','input');(f.options||[]).forEach(function(v){var o=el('option','',v);o.value=v;input.appendChild(o);});}else if(f.type==='textarea'){input=el('textarea','input');input.rows=2;}else{input=el('input','input');input.type=f.type||'text';if(f.min!==undefined)input.min=String(f.min);if(f.max!==undefined){if(f.type==='number')input.max=String(f.max);else input.maxLength=f.max;}if(f.step!==undefined)input.step=String(f.step);}input.id=id;if(f.required)input.required=true;if(f.placeholder)input.placeholder=f.placeholder;if(f.type==='number')input.inputMode='decimal';box.appendChild(input);form.appendChild(box);});var btn=el('button','btn primary submit',SPEC.submit||'Add item');btn.type='submit';form.appendChild(btn);}\nbuildForm();\nfunction statusOptions(){return SPEC.status?SPEC.status.options:[];}function isDone(item){return !!(SPEC.status&&SPEC.status.done.indexOf(item.status)>=0);}function wanted(m){return m.values?m.values:(m.value!==undefined?[m.value]:[]);}function inWanted(m,v){var w=wanted(m);return !w.length||w.indexOf(v)>=0;}function num(v){return Number(v)||0;}function sumOf(rows,key){return rows.reduce(function(a,x){return a+num(x[key]);},0);}\nfunction countKind(m){if(m.kind==='total')return items.length;\nif(m.kind==='open')return items.filter(function(x){return!isDone(x);}).length;\nif(m.kind==='countStatus')return items.filter(function(x){return inWanted(m,x.status);}).length;\nif(m.kind==='countField')return items.filter(function(x){return(!m.excludeDone||!isDone(x))&&inWanted(m,x[m.key]);}).length;\nif(m.kind==='dueSoon'){var w=m.days===undefined?7:m.days;return items.filter(function(x){var n=dateDiff(x[m.key]);return!isDone(x)&&n!==null&&n>=0&&n<=w;}).length;}\nif(m.kind==='overdue')return items.filter(function(x){var n=dateDiff(x[m.key]);return!isDone(x)&&n!==null&&n<0;}).length;\nif(m.kind==='recent'){var r=m.days===undefined?7:m.days;return items.filter(function(x){var n=dateDiff(x[m.key]);return n!==null&&n<=0&&n>=-r;}).length;}\nif(m.kind==='sum')return sumOf(items,m.key);\nif(m.kind==='sumStatus')return sumOf(items.filter(function(x){return inWanted(m,x.status);}),m.key);\nif(m.kind==='sumField')return sumOf(items.filter(function(x){return(!m.excludeDone||!isDone(x))&&inWanted(m,x[m.by]);}),m.key);\nif(m.kind==='checkRate'){var all=0,done=0;items.forEach(function(x){(x.checks||[]).forEach(function(ch){all++;if(ch.done)done++;});});return all?Math.round(done/all*100):0;}\nif(m.kind==='rate'){var rows=items.filter(function(x){return!m.excludeDone||!isDone(x);});if(!rows.length)return 0;var hit=rows.filter(function(x){return inWanted(m,m.by?x[m.by]:x.status);}).length;return Math.round(hit/rows.length*100);}\nif(m.kind==='ratio'){var parts=m.parts||[m.key],top=0,total=0;items.forEach(function(x){parts.forEach(function(k,i){var v=num(x[k]);total+=v;if(!i)top+=v;});});return total?Math.round(top/total*100):0;}\nreturn 0;}\nfunction metricText(m){var n=countKind(m);if(m.format==='money')return'$'+Math.round(n).toLocaleString('en-US');if(m.format==='hours'||m.format==='days')return Number(n).toFixed(1);if(m.format==='percent')return String(n)+'%';if(m.format==='duration'){var s=Math.max(0,Math.round(n));return Math.floor(s/60)+':'+String(s%60).padStart(2,'0');}if(m.kind==='sum'&&m.key==='estimate')return'$'+Math.round(n).toLocaleString('en-US');return String(n);}\nfunction drawMetrics(){var root=document.getElementById('metrics');root.textContent='';SPEC.metrics.forEach(function(m){var box=el('div','metric');box.appendChild(el('span','metric-value',metricText(m)));box.appendChild(el('span','metric-label',m.label));root.appendChild(box);});}\nfunction makeChip(text,kind){return el('span','chip'+(kind?' '+kind:''),text);}function formatCardField(f,item){var raw=item[f.key];if(raw===undefined||raw===null||raw==='')return null;if(f.kind==='detail')return el('p','detail',String(raw));var value=String(raw);if(f.kind==='date')value=prettyDate(value);if(f.kind==='money')value='$'+num(raw).toLocaleString('en-US',{maximumFractionDigits:0})+' USD est.';if(f.kind==='number')value=f.label+': '+raw;else if(f.label&&f.kind!=='priority')value=f.label+': '+value;return makeChip(value,f.kind==='priority'?'priority':'');}\nfunction sortRows(rows){var a=rows.slice();if(SPEC.sortPriority){var p=SPEC.sortPriority.values; a.sort(function(x,y){var ax=p.indexOf(x[SPEC.sortPriority.key]),ay=p.indexOf(y[SPEC.sortPriority.key]);if(ax<0)ax=99;if(ay<0)ay=99;return ax-ay;});}if(SPEC.dateField){a.sort(function(x,y){var ax=x[SPEC.dateField]||'9999-99-99',ay=y[SPEC.dateField]||'9999-99-99';if(SPEC.sortPriority){var p=SPEC.sortPriority.values,px=p.indexOf(x[SPEC.sortPriority.key]),py=p.indexOf(y[SPEC.sortPriority.key]);if(px<0)px=99;if(py<0)py=99;if(px!==py)return px-py;}return ax.localeCompare(ay);});}return a;}\nfunction render(){drawMetrics();var root=document.getElementById('list');root.textContent='';var term=document.getElementById('search').value.trim().toLowerCase(),rows=items.filter(function(x){var hay=Object.keys(x).map(function(k){return typeof x[k]==='string'?x[k]:'';}).join(' ').toLowerCase();return!term||hay.indexOf(term)>=0;});rows=sortRows(rows);document.getElementById('count').textContent=rows.length+' shown';if(!rows.length){root.appendChild(el('div','empty',items.length?'No entries match the filter.':SPEC.empty));return;}rows.forEach(function(item){var row=el('article','entry'),main=el('div','entry-main');main.appendChild(el('div','entry-title',item[SPEC.titleField]||'Untitled'));var meta=el('div','chips');(SPEC.cardFields||[]).forEach(function(f){var n=formatCardField(f,item);if(n){if(f.kind==='detail')main.appendChild(n);else meta.appendChild(n);}});if(meta.childNodes.length)main.appendChild(meta);row.appendChild(main);var actions=el('div','actions');if(SPEC.status){var select=el('select','status');statusOptions().forEach(function(v){var o=el('option','',v);o.value=v;select.appendChild(o);});select.value=item.status||SPEC.status.default;select.setAttribute('data-status',item.id);select.setAttribute('aria-label',SPEC.status.label+' for '+(item[SPEC.titleField]||'entry'));actions.appendChild(select);}var del=el('button','remove','Remove');del.type='button';del.setAttribute('data-remove',item.id);del.setAttribute('aria-label','Remove '+(item[SPEC.titleField]||'entry'));actions.appendChild(del);row.appendChild(actions);if(SPEC.checks){var checks=el('div','checklist');(item.checks||[]).forEach(function(ch,i){var lab=el('label','check-row');var input=el('input','check');input.type='checkbox';input.checked=!!ch.done;input.setAttribute('data-check',item.id);input.setAttribute('data-index',String(i));input.id='check-'+item.id+'-'+i;lab.htmlFor=input.id;lab.appendChild(input);lab.appendChild(el('span','',ch.label));checks.appendChild(lab);});var progress=el('div','progress-row');var done=(item.checks||[]).filter(function(ch){return ch.done;}).length;progress.appendChild(el('span','small',done+' of '+(item.checks||[]).length+' checks'));var bar=el('div','bar'),fill=el('span');fill.style.width=(item.checks&&item.checks.length?Math.round(done/item.checks.length*100):0)+'%';bar.appendChild(fill);progress.appendChild(bar);checks.appendChild(progress);row.appendChild(checks);}root.appendChild(row);});}\ndocument.getElementById('form').addEventListener('submit',function(e){e.preventDefault();if(items.length>=LIMIT){announce('This local list is full. Remove an entry to add another.');return;}var item={id:uid(),status:SPEC.defaultStatus||statusOptions()[0]||''};SPEC.fields.forEach(function(f){var input=document.getElementById('f-'+f.key),v=input.value;if(f.type==='number'&&v!==''){var n=Number(v);v=Number.isFinite(n)?String(Math.min(f.max===undefined?1e9:f.max,Math.max(f.min||0,n))):'';}item[f.key]=f.type==='date'?String(v||''):clean(v,f.max||160);});if(SPEC.checks)item.checks=SPEC.checks.map(function(label){return{label:label,done:false};});items.unshift(item);try{localStorage.setItem(KEY,JSON.stringify(items));announce('Saved only in this browser.');}catch(err){announce('Browser storage is unavailable. Changes may not persist.');}this.reset();render();document.getElementById('f-'+SPEC.titleField).focus();});\ndocument.getElementById('search').addEventListener('input',render);document.getElementById('list').addEventListener('click',function(e){var n=e.target;while(n&&n!==this){var id=n.getAttribute&&n.getAttribute('data-remove');if(id){items=items.filter(function(x){return x.id!==id;});save('Entry removed.');render();return;}n=n.parentNode;}});document.getElementById('list').addEventListener('change',function(e){var id=e.target.getAttribute('data-status');if(id){var item=items.find(function(x){return x.id===id;});if(item){item.status=e.target.value;save('State updated.');render();}return;}var checkId=e.target.getAttribute('data-check');if(checkId){var row=items.find(function(x){return x.id===checkId;});var index=Number(e.target.getAttribute('data-index'));if(row&&row.checks&&row.checks[index]){row.checks[index].done=e.target.checked;save('Checklist updated.');render();}}});document.getElementById('clear').addEventListener('click',function(){document.getElementById('search').value='';render();});render();\n})();</script>\n</body></html>\n\n</body>\n</html>"}]}