{"$schema":"https://ui.shadcn.com/schema/registry-item.json","name":"seo-content-planner","type":"registry:component","title":"SEO Content Planner","description":"Plan topics, keywords, intent, and draft stages without live SEO data.","author":"Notion Arena","categories":["docs"],"tags":["widget","free","SEO","content planning","keywords","editorial","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/seo-content-planner","fileUrl":"https://notionarena.vercel.app/widgets/seo-content-planner.html","downloadUrl":"https://notionarena.vercel.app/api/widget/seo-content-planner","height":440,"minHeight":340,"maxHeight":650,"params":[{"key":"label","label":"Widget title","type":"text","default":"SEO content planner"},{"key":"accent","label":"Accent","type":"color","default":"#355db4"},{"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/seo-content-planner.html","type":"registry:file","target":"notion/widgets/seo-content-planner.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>SEO Content Planner</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=\"M5 4h9l5 5v11H5z\"/><path d=\"M14 4v5h5M8 13h8M8 16h5\"/><circle cx=\"17.5\" cy=\"17.5\" r=\"3\"/><path d=\"m20 20 2 2\"/></svg></span><div><div class=\"kicker\">CONTENT PLANNING</div><div class=\"title\" id=\"title\">SEO Content Planner</div></div></div><div class=\"metric\" id=\"metric\">0 topics</div></header>\n<form class=\"form-grid\" id=\"form\"><div class=\"field wide\"><label for=\"topic\">Topic or working title</label><input id=\"topic\" maxlength=\"90\" placeholder=\"A useful article or page idea\" required /></div><div class=\"field wide\"><label for=\"keyword\">Primary keyword</label><input id=\"keyword\" maxlength=\"80\" placeholder=\"Entered manually, no search data\" /></div><div class=\"field third\"><label for=\"intent\">Search intent</label><select id=\"intent\"><option>Informational</option><option>Commercial</option><option>Transactional</option><option>Navigational</option></select></div><div class=\"field third\"><label for=\"format\">Format</label><select id=\"format\"><option>Article</option><option>Landing page</option><option>Guide</option><option>Case study</option><option>Other</option></select></div><div class=\"field third\"><label for=\"due\">Target date</label><input id=\"due\" type=\"date\" /></div><div class=\"field full\"><label for=\"brief\">Brief or angle</label><input id=\"brief\" maxlength=\"150\" placeholder=\"Audience, point of view, or outline note\" /></div><button class=\"btn primary field full\" type=\"submit\">Add content idea</button></form>\n<div class=\"statline\"><span>Plan topics and drafts</span><span class=\"notice\">No rankings or search-volume data</span></div><section class=\"list\" id=\"list\" aria-label=\"SEO content ideas\"></section><footer class=\"footer\"><span class=\"notice\">Local notes are not encrypted. No search tool, crawler, rankings, or analytics connection.</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,'#355db4'),LABEL=String(c.label||'SEO content planner').slice(0,48),KEY='notion-arena.seo-content-planner.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 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 stages=['Idea','Briefing','Drafting','Review','Ready','Published'];function render(){var root=document.getElementById('list');root.textContent='';document.getElementById('metric').textContent=items.length+' topics';if(!items.length){root.appendChild(el('div','empty','Add a topic and optional keyword to make a private editorial list.'));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.topic));var meta=el('div','row');if(item.keyword)addChip(meta,'Keyword: '+item.keyword);addChip(meta,item.intent);addChip(meta,item.format);if(item.due)meta.appendChild(el('span','sub',prettyDate(item.due)));main.appendChild(meta);if(item.brief)main.appendChild(el('div','details',item.brief));row.appendChild(main);var actions=el('div','actions'),sel=el('select','select-mini');stages.forEach(function(v){var o=el('option','',v);o.value=v;sel.appendChild(o);});sel.value=item.stage;sel.setAttribute('aria-label','Content stage for '+item.topic);sel.setAttribute('data-stage',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 topic '+item.topic);actions.appendChild(del);row.appendChild(actions);root.appendChild(row);});}document.getElementById('form').addEventListener('submit',function(e){e.preventDefault();var topic=clean(document.getElementById('topic').value,90);if(!topic||items.length>=LIMIT)return;items.push({id:uid(),topic:topic,keyword:clean(document.getElementById('keyword').value,80),intent:document.getElementById('intent').value,format:document.getElementById('format').value,due:document.getElementById('due').value,brief:clean(document.getElementById('brief').value,150),stage:'Idea'});this.reset();save();render();document.getElementById('topic').focus();});document.getElementById('list').addEventListener('change',function(e){var id=e.target.getAttribute('data-stage');if(!id)return;var item=items.find(function(x){return x.id===id;});if(item){item.stage=e.target.value;save();render();}});bindDelete('list',render);render();\n})();</script>\n</body></html>\n"}]}