{"$schema":"https://ui.shadcn.com/schema/registry-item.json","name":"construction-punch-list","type":"registry:component","title":"Construction Punch List","description":"Track manual finish items by area, trade, date, and status.","author":"Notion Arena","categories":["planning"],"tags":["widget","free","construction","punch list","field work","project","offline"],"meta":{"kind":"widget","tier":"free","version":"1.0.0","updatedAt":"2026-10-11","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/construction-punch-list","fileUrl":"https://notionarena.vercel.app/widgets/construction-punch-list.html","downloadUrl":"https://notionarena.vercel.app/api/widget/construction-punch-list","height":440,"minHeight":340,"maxHeight":640,"params":[{"key":"label","label":"Widget title","type":"text","default":"Construction punch list"},{"key":"accent","label":"Accent","type":"color","default":"#b56a18"},{"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/construction-punch-list.html","type":"registry:file","target":"notion/widgets/construction-punch-list.html","content":"<!doctype html>\n<html lang=\"en\" data-theme=\"auto\">\n<head><meta charset=\"utf-8\" /><meta name=\"viewport\" content=\"width=device-width,initial-scale=1\" /><title>Construction Punch List</title>\n<style>\n:root{color-scheme:light;--bg:#fff;--fg:#37352f;--muted:#777672;--surface:#f7f7f5;--border:#e9e9e7;--accent:#2383e2;--accent-text:#1765a8;--accent-ink:#fff;--danger:#c24136;--soft:color-mix(in srgb,var(--accent) 10%,var(--bg))}\nhtml[data-theme=\"dark\"]{color-scheme:dark;--bg:#191919;--fg:#e6e6e4;--muted:#aaa9a5;--surface:#222;--border:#363636;--danger:#ff8177}\n@media(prefers-color-scheme:dark){html[data-theme=\"auto\"]{color-scheme:dark;--bg:#191919;--fg:#e6e6e4;--muted:#aaa9a5;--surface:#222;--border:#363636;--danger:#ff8177}}\n*{box-sizing:border-box}html,body{margin:0;height:100%}body{overflow:hidden;background:var(--bg);color:var(--fg);font-family:ui-sans-serif,-apple-system,BlinkMacSystemFont,\"Segoe UI\",Helvetica,Arial,sans-serif;-webkit-font-smoothing:antialiased;font-size:12px}\nbutton,input,select,textarea{font:inherit;color:inherit}button{cursor:pointer}.sr{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n.wrap{height:100%;min-height:275px;display:flex;flex-direction:column;gap:8px;padding:12px;overflow:auto}.head{display:flex;align-items:center;justify-content:space-between;gap:8px;min-width:0}.brand{display:flex;align-items:center;gap:8px;min-width:0}.mark{width:30px;height:30px;display:grid;place-items:center;flex:none;border-radius:8px;background:var(--soft);color:var(--accent-text)}.mark svg{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:1.65;stroke-linecap:round;stroke-linejoin:round}.kicker{font-size:9px;text-transform:uppercase;letter-spacing:.08em;color:var(--muted);font-weight:650}.title{margin-top:2px;font-size:14px;line-height:1.25;font-weight:650;overflow-wrap:anywhere}.metric{flex:none;min-width:52px;padding:5px 7px;border-radius:7px;background:var(--soft);color:var(--accent-text);text-align:center;font-size:10px;font-weight:650;font-variant-numeric:tabular-nums}\n.toolbar{display:flex;align-items:center;gap:6px;min-width:0}.toolbar>*{min-width:0}.form-grid{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));gap:6px;align-items:end}.field{grid-column:span 4;min-width:0;display:flex;flex-direction:column;gap:3px}.field.wide{grid-column:span 6}.field.full{grid-column:1/-1}.field.third{grid-column:span 3}.field.half{grid-column:span 6}.field label{font-size:9px;color:var(--muted);font-weight:600}.field input,.field select,.field textarea,.search{width:100%;min-width:0;border:1px solid var(--border);border-radius:7px;background:var(--surface);color:var(--fg);padding:6px 7px;font-size:10px;outline:none}.field input,.field select,.search{height:31px}.field textarea{min-height:46px;line-height:1.4;resize:vertical}.field input:focus-visible,.field select:focus-visible,.field textarea:focus-visible,.search:focus-visible{outline:2px solid var(--accent-text);outline-offset:1px}.btn{min-height:30px;border:1px solid var(--border);border-radius:7px;background:var(--surface);color:var(--fg);padding:5px 9px;font-size:10px;font-weight:600}.btn:hover,.icon-btn:hover{border-color:var(--accent-text)}.btn.primary{border-color:var(--accent);background:var(--accent);color:var(--accent-ink)}.btn.primary:hover{filter:brightness(.96)}.btn.small{min-height:25px;padding:3px 7px;font-size:9px}.icon-btn{min-width:28px;min-height:27px;border:1px solid var(--border);border-radius:6px;background:var(--bg);color:var(--muted);padding:3px 6px;font-size:9px}.icon-btn:hover{color:var(--danger);border-color:var(--danger)}\n.list{display:flex;flex:1;min-height:52px;flex-direction:column;gap:5px;overflow:auto}.entry{display:flex;align-items:flex-start;justify-content:space-between;gap:8px;min-width:0;padding:8px;border:1px solid var(--border);border-radius:8px;background:var(--surface)}.entry-main{flex:1;min-width:0}.entry-title{font-size:11px;font-weight:650;overflow-wrap:anywhere;line-height:1.35}.sub{margin-top:3px;color:var(--muted);font-size:9px;line-height:1.4;overflow-wrap:anywhere}.details{margin-top:5px;color:var(--fg);font-size:10px;line-height:1.45;overflow-wrap:anywhere;white-space:pre-wrap}.row{display:flex;align-items:center;gap:5px;flex-wrap:wrap}.actions{display:flex;align-items:center;gap:4px;flex:none}.select-mini{max-width:132px;height:26px;border:1px solid var(--border);border-radius:6px;background:var(--bg);color:var(--fg);padding:3px 5px;font-size:9px}.chip{display:inline-flex;align-items:center;min-height:19px;padding:2px 6px;border-radius:999px;background:var(--soft);color:var(--accent-text);font-size:8px;font-weight:650;white-space:nowrap}.empty{padding:12px 8px;border:1px dashed var(--border);border-radius:8px;color:var(--muted);text-align:center;font-size:10px;line-height:1.45}.notice{color:var(--muted);font-size:9px;line-height:1.4}.footer{display:flex;align-items:flex-start;justify-content:space-between;gap:8px;border-top:1px solid var(--border);padding-top:6px}.message{color:var(--muted);font-size:9px;line-height:1.35;text-align:right}.search{flex:1}.check{accent-color:var(--accent);margin:2px 0 0}.task{display:flex;align-items:flex-start;gap:7px;min-width:0}.task.done .entry-title{text-decoration:line-through;color:var(--muted)}.bar{height:4px;flex:1;overflow:hidden;border-radius:99px;background:var(--border)}.bar span{display:block;height:100%;background:var(--accent);border-radius:inherit}.progress{display:flex;align-items:center;gap:8px;color:var(--muted);font-size:9px}.statline{display:flex;align-items:center;justify-content:space-between;gap:8px;color:var(--muted);font-size:9px}.pill{display:inline-flex;align-items:center;padding:2px 6px;border-radius:999px;background:var(--soft);color:var(--accent-text);font-size:8px;font-weight:650}.totals{display:grid;grid-template-columns:1fr auto;gap:3px 10px;align-items:center;padding:8px;border:1px solid var(--border);border-radius:8px;background:var(--surface);font-variant-numeric:tabular-nums}.total-label{color:var(--muted);font-size:9px}.total-value{font-size:10px;text-align:right}.total-strong{padding-top:5px;border-top:1px solid var(--border);font-weight:700;color:var(--fg)}\n@media(max-width:410px){.wrap{padding:10px;gap:7px}.field,.field.third{grid-column:span 6}.field.full{grid-column:1/-1}.entry{gap:5px;padding:7px}.select-mini{max-width:110px}.footer{flex-direction:column}.message{text-align:left}}\n@media(max-width:290px){.metric{min-width:42px;padding:4px;font-size:9px}.title{font-size:12px}.field,.field.third{grid-column:1/-1}.actions{gap:2px}.btn{padding:4px 6px}}\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\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\"><path d=\"M4 20h16M7 17l7-7M12 6l3-3 3 3-3 3M6 12l6 6M4 4l4 4M3 8l5-5\"/><path d=\"M15 15h5v5h-5z\"/></svg></span><div><div class=\"kicker\">FIELD CHECKLIST</div><div class=\"title\" id=\"title\">Construction Punch List</div></div></div><div class=\"metric\" id=\"metric\">0 open</div></header>\n<form class=\"form-grid\" id=\"form\"><div class=\"field wide\"><label for=\"item\">Punch item</label><input id=\"item\" maxlength=\"90\" placeholder=\"Describe a finish or repair\" required /></div><div class=\"field wide\"><label for=\"location\">Area label</label><input id=\"location\" maxlength=\"60\" placeholder=\"Room, level, or zone\" /></div><div class=\"field third\"><label for=\"trade\">Trade</label><select id=\"trade\"><option>General</option><option>Electrical</option><option>Plumbing</option><option>Finish</option><option>Exterior</option><option>Other</option></select></div><div class=\"field third\"><label for=\"priority\">Priority</label><select id=\"priority\"><option>Normal</option><option>High</option><option>Low</option></select></div><div class=\"field third\"><label for=\"due\">Target date</label><input id=\"due\" type=\"date\" /></div><button class=\"btn primary field full\" type=\"submit\">Add punch item</button></form>\n<div class=\"statline\"><span>Manual field list</span><span class=\"notice\">Not a safety inspection or code review</span></div><section class=\"list\" id=\"list\" aria-label=\"Construction punch items\"></section><footer class=\"footer\"><span class=\"notice\">No compliance checks, sign-off, or project sync. Storage is not encrypted.</span><span class=\"message\" id=\"status\" role=\"status\" aria-live=\"polite\">Saved only in this browser.</span></footer>\n</main>\n<script>(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';\nvar ACCENT=safeColor(c.accent,'#b56a18'),LABEL=String(c.label||'Construction punch list').slice(0,48),KEY='notion-arena.construction-punch-list.v1',LIMIT=150;\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 setAccentText(){var dark=theme==='dark'||(theme==='auto'&&window.matchMedia&&window.matchMedia('(prefers-color-scheme: dark)').matches),bg=rgb(dark?'#191919':'#f7f7f5'),a=rgb(ACCENT),soft=mix(bg,a,.1),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));}setAccentText();if(theme==='auto'&&window.matchMedia){var mq=window.matchMedia('(prefers-color-scheme: dark)');if(mq.addEventListener)mq.addEventListener('change',setAccentText);else if(mq.addListener)mq.addListener(setAccentText);}\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 announce(text){var n=document.getElementById('status');if(n)n.textContent=text;}\nfunction save(text){try{localStorage.setItem(KEY,JSON.stringify(items));announce(text||'Saved only in this browser.');}catch(e){announce('Browser storage is unavailable. Changes may not persist.');}}\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;}\nfunction clean(s,max){return String(s||'').trim().slice(0,max);}\nfunction uid(){return Date.now().toString(36)+Math.random().toString(36).slice(2,8);}\nfunction number(id,max){var n=Number(document.getElementById(id).value);if(!Number.isFinite(n))return 0;return Math.min(max,Math.max(0,n));}\nfunction 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',year:'numeric'});}\nfunction usd(n){try{return new Intl.NumberFormat('en-US',{style:'currency',currency:'USD',maximumFractionDigits:2}).format(Number(n)||0);}catch(e){return '$'+(Number(n)||0).toFixed(2);}}\nfunction bindDelete(rootId,renderFn){var root=document.getElementById(rootId);root.addEventListener('click',function(e){var node=e.target;while(node&&node!==root){var key=node.getAttribute&&node.getAttribute('data-remove');if(key){items=items.filter(function(x){return x.id!==key;});save('Entry removed.');renderFn();return;}node=node.parentNode;}});}\nfunction addChip(parent,text){parent.appendChild(el('span','chip',text));}\n\nvar states=['Open','In progress','Ready for review','Closed'];function render(){var root=document.getElementById('list');root.textContent='';var open=items.filter(function(x){return x.state!=='Closed';}).length;document.getElementById('metric').textContent=open+' open';if(!items.length){root.appendChild(el('div','empty','Add a manual punch item for a project area.'));return;}items.slice().sort(function(a,b){return String(a.due||'9999').localeCompare(String(b.due||'9999'));}).forEach(function(item){var row=el('article','entry'),main=el('div','entry-main');main.appendChild(el('div','entry-title',item.title));var meta=el('div','row');if(item.location)addChip(meta,item.location);addChip(meta,item.trade);addChip(meta,item.priority+' priority');if(item.due)meta.appendChild(el('span','sub',prettyDate(item.due)));main.appendChild(meta);row.appendChild(main);var actions=el('div','actions'),sel=el('select','select-mini');states.forEach(function(v){var o=el('option','',v);o.value=v;sel.appendChild(o);});sel.value=item.state;sel.setAttribute('aria-label','Punch item state for '+item.title);sel.setAttribute('data-state',item.id);actions.appendChild(sel);var del=el('button','icon-btn','Remove');del.type='button';del.setAttribute('data-remove',item.id);del.setAttribute('aria-label','Remove punch item '+item.title);actions.appendChild(del);row.appendChild(actions);root.appendChild(row);});}document.getElementById('form').addEventListener('submit',function(e){e.preventDefault();var title=clean(document.getElementById('item').value,90);if(!title||items.length>=LIMIT)return;items.push({id:uid(),title:title,location:clean(document.getElementById('location').value,60),trade:document.getElementById('trade').value,priority:document.getElementById('priority').value,due:document.getElementById('due').value,state:'Open'});this.reset();save();render();document.getElementById('item').focus();});document.getElementById('list').addEventListener('change',function(e){var id=e.target.getAttribute('data-state');if(!id)return;var item=items.find(function(x){return x.id===id;});if(item){item.state=e.target.value;save();render();}});bindDelete('list',render);render();\n})();</script>\n</body></html>\n"}]}