{"$schema":"https://ui.shadcn.com/schema/registry-item.json","name":"manuscript-progress","type":"registry:component","title":"Manuscript Progress Tracker","description":"Compare a manually entered word count with a writing goal.","author":"Notion Arena","categories":["trackers"],"tags":["widget","free","manuscript","writing progress","word count","author","goal"],"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/manuscript-progress","fileUrl":"https://notionarena.vercel.app/widgets/manuscript-progress.html","downloadUrl":"https://notionarena.vercel.app/api/widget/manuscript-progress","height":290,"minHeight":230,"maxHeight":390,"params":[{"key":"label","label":"Widget title","type":"text","default":"Manuscript progress"},{"key":"accent","label":"Accent","type":"color","default":"#6940a5"},{"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/manuscript-progress.html","type":"registry:file","target":"notion/widgets/manuscript-progress.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>Manuscript Progress</title>\n<style>\n:root{--bg:#fff;--fg:#37352f;--muted:#6b6a68;--surface:#f7f7f5;--border:#e9e9e7;--accent:#6940a5;--accent-ink:#fff;--accent-text:var(--accent);--danger:#c24136}\nhtml[data-theme=\"dark\"]{--bg:#191919;--fg:#e6e6e4;--muted:#9b9a97;--surface:#252525;--border:#343434;--danger:#ff7369}@media(prefers-color-scheme:dark){html[data-theme=\"auto\"]{--bg:#191919;--fg:#e6e6e4;--muted:#9b9a97;--surface:#252525;--border:#343434;--danger:#ff7369}}\n*{box-sizing:border-box}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}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}.wrap{height:100%;min-height:250px;display:flex;flex-direction:column;gap:10px;padding:14px;overflow:auto}.head{display:flex;align-items:center;justify-content:space-between;gap:8px}.kicker{font-size:9px;text-transform:uppercase;letter-spacing:.1em;color:var(--muted);font-weight:650}.title{margin-top:2px;font-size:14px;font-weight:650}.percent{text-align:right;color:var(--accent-text);font-size:16px;font-weight:700;font-variant-numeric:tabular-nums}.form{display:grid;grid-template-columns:minmax(0,1fr) 100px 100px auto;gap:5px}.form input{min-width:0;height:31px;border:1px solid var(--border);border-radius:7px;background:var(--surface);color:var(--fg);padding:4px 6px;font:inherit;font-size:9px}.form input:focus-visible{outline:2px solid var(--accent);outline-offset:1px}.form button{height:31px;border:1px solid var(--accent);border-radius:7px;background:var(--accent);color:var(--accent-ink);font:inherit;font-size:9px;padding:4px 8px;cursor:pointer}.meter{height:12px;overflow:hidden;border:1px solid var(--border);border-radius:7px;background:var(--surface)}.fill{height:100%;width:0;border-radius:6px;background:var(--accent);transition:width .2s ease}.stats{display:flex;align-items:center;justify-content:space-between;gap:10px;color:var(--muted);font-size:9px}.stats strong{color:var(--fg);font-size:10px;font-variant-numeric:tabular-nums}.status,.note{color:var(--muted);font-size:9px;line-height:1.35}.status{min-height:14px}@media(max-width:370px){.wrap{padding:11px}.form{grid-template-columns:minmax(0,1fr) 88px 88px}.form input:first-of-type{grid-column:1/4}.form button{grid-column:3}}@media(prefers-reduced-motion:reduce){*,*::before,*::after{animation-duration:.01ms!important;transition-duration:.01ms!important;scroll-behavior:auto!important}}\n</style></head>\n<body><main class=\"wrap\"><header class=\"head\"><div><div class=\"kicker\">Words entered by you</div><div class=\"title\" id=\"title\">Manuscript progress</div></div><div class=\"percent\" id=\"percent\">0%</div></header>\n<form class=\"form\" id=\"form\"><label class=\"sr-only\" for=\"manuscript\">Manuscript title</label><input id=\"manuscript\" maxlength=\"56\" placeholder=\"Manuscript title\" required /><label class=\"sr-only\" for=\"words\">Current word count</label><input id=\"words\" type=\"number\" min=\"0\" max=\"5000000\" step=\"1\" placeholder=\"Current words\" required /><label class=\"sr-only\" for=\"target\">Word goal</label><input id=\"target\" type=\"number\" min=\"1\" max=\"5000000\" step=\"1\" value=\"50000\" required /><button type=\"submit\">Update</button></form>\n<div class=\"meter\" role=\"progressbar\" id=\"meter\" aria-label=\"Manuscript word goal\" aria-valuemin=\"0\" aria-valuemax=\"100\" aria-valuenow=\"0\"><div class=\"fill\" id=\"fill\"></div></div><div class=\"stats\"><span><strong id=\"current\">0</strong> words</span><span>Goal <strong id=\"goal\">50,000</strong></span><span id=\"remaining\">50,000 to go</span></div><div class=\"status\" id=\"status\" aria-live=\"polite\">Counts are manual and stay in this browser.</div><div class=\"note\">Tracks numbers only, not manuscript text, quality, or publication readiness.</div></main>\n<script>\n(function(){var cfgEl=document.getElementById('bk-config'),base={};try{base=cfgEl?JSON.parse(cfgEl.textContent||'{}'):{};}catch(e){}var q=new URLSearchParams(location.search),c={};for(var k in base)c[k]=base[k];q.forEach(function(v,k){c[k]=v;});function safeColor(v,d){return /^#[0-9a-f]{6}$/i.test(String(v||''))?String(v):d;}function 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(s,v,i){return s+v*[.2126,.7152,.0722][i];},0);}function contrast(a,b){var x=lum(a),y=lum(b);return(Math.max(x,y)+.05)/(Math.min(x,y)+.05);}function ink(h){var a=rgb(h);return contrast(a,[255,255,255])>=contrast(a,[0,0,0])?'#fff':'#000';}function textColor(h){var dark=theme==='dark'||(theme==='auto'&&window.matchMedia&&window.matchMedia('(prefers-color-scheme: dark)').matches),bg=rgb(dark?'#252525':'#f7f7f5'),a=rgb(h),to=dark?[255,255,255]:[0,0,0];if(contrast(a,bg)>=4.5)return h;for(var t=.02;t<=1;t+=.02){var m=a.map(function(v,i){return Math.round(v+(to[i]-v)*t);});if(contrast(m,bg)>=4.5)return'#'+m.map(function(v){return v.toString(16).padStart(2,'0');}).join('');}return dark?'#fff':'#191919';}var theme=['auto','light','dark'].indexOf(String(c.theme||'auto'))>=0?String(c.theme||'auto'):'auto',ACCENT=safeColor(c.accent,'#6940a5'),LABEL=String(c.label||'Manuscript progress').slice(0,48),KEY='notion-arena.manuscript-progress.v1',state={title:'',words:0,target:50000};function setText(){document.documentElement.style.setProperty('--accent-text',textColor(ACCENT));}document.documentElement.setAttribute('data-theme',theme);document.documentElement.style.setProperty('--accent',ACCENT);document.documentElement.style.setProperty('--accent-ink',ink(ACCENT));setText();if(theme==='auto'&&window.matchMedia){var mq=window.matchMedia('(prefers-color-scheme: dark)');if(mq.addEventListener)mq.addEventListener('change',setText);else if(mq.addListener)mq.addListener(setText);}document.getElementById('title').textContent=LABEL;document.title=LABEL;try{var a=JSON.parse(localStorage.getItem(KEY)||'null');if(a){state.title=typeof a.title==='string'?a.title.slice(0,56):'';state.words=Math.max(0,Math.min(5000000,Number(a.words)||0));state.target=Math.max(1,Math.min(5000000,Number(a.target)||50000));}}catch(e){}var title=document.getElementById('manuscript'),words=document.getElementById('words'),target=document.getElementById('target'),status=document.getElementById('status');title.value=state.title;words.value=state.words;target.value=state.target;function format(v){return new Intl.NumberFormat().format(v);}function save(){state.title=title.value.trim().slice(0,56);state.words=Math.max(0,Math.min(5000000,Math.floor(Number(words.value)||0)));state.target=Math.max(1,Math.min(5000000,Math.floor(Number(target.value)||50000)));try{localStorage.setItem(KEY,JSON.stringify(state));status.textContent='Progress saved only in this browser.';}catch(e){status.textContent='Storage is unavailable in this browser session.';}render();}function render(){var pct=Math.max(0,Math.min(100,Math.round(state.words/state.target*100))),remaining=Math.max(0,state.target-state.words);document.getElementById('current').textContent=format(state.words);document.getElementById('goal').textContent=format(state.target);document.getElementById('remaining').textContent=remaining?format(remaining)+' to go':'Goal reached';document.getElementById('percent').textContent=pct+'%';document.getElementById('fill').style.width=pct+'%';var meter=document.getElementById('meter');meter.setAttribute('aria-valuenow',String(pct));meter.setAttribute('aria-valuetext',pct+' percent of word goal');}document.getElementById('form').addEventListener('submit',function(e){e.preventDefault();var n=Number(words.value),g=Number(target.value);if(!title.value.trim()||!isFinite(n)||!isFinite(g)||n<0||g<1||n>5000000||g>5000000){status.textContent='Enter a title, a non-negative word count, and a goal from 1 to 5,000,000.';return;}save();});render();})();\n</script></body></html>\n"}]}