[object Object]

← back to Studio Zero

studio-zero: export — download full channel plan as standalone HTML + copy-as-markdown, inline rename; builder toolbar

edefa92338870b0fd72cab40c6a11399f38d4cc6 · 2026-07-25 00:16:18 -0700 · Steve

Files touched

Diff

commit edefa92338870b0fd72cab40c6a11399f38d4cc6
Author: Steve <steve@designerwallcoverings.com>
Date:   Sat Jul 25 00:16:18 2026 -0700

    studio-zero: export — download full channel plan as standalone HTML + copy-as-markdown, inline rename; builder toolbar
---
 public/index.html | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 60 insertions(+), 4 deletions(-)

diff --git a/public/index.html b/public/index.html
index 5de516c..8650501 100644
--- a/public/index.html
+++ b/public/index.html
@@ -53,7 +53,13 @@
   .pcard .del{float:right;color:var(--faint);font-size:12px}
   .pcard .del:hover{color:var(--red)}
 
-  .stepper{display:flex;align-items:center;gap:0;margin:26px 0 26px;overflow-x:auto;padding-bottom:6px}
+  .builderbar{display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin:22px 0 2px}
+  .builderbar .pname{font-weight:700;font-size:17px;background:none;border:0;border-bottom:1px solid transparent;color:var(--ink);padding:2px 0;min-width:120px;max-width:340px}
+  .builderbar .pname:hover{border-bottom-color:var(--line)} .builderbar .pname:focus{outline:0;border-bottom-color:var(--orange)}
+  .builderbar .prog2{font-size:12px;color:var(--faint)}
+  .builderbar .sp{flex:1}
+  .builderbar .done0{opacity:.45;pointer-events:none}
+  .stepper{display:flex;align-items:center;gap:0;margin:16px 0 26px;overflow-x:auto;padding-bottom:6px}
   .snode{display:flex;align-items:center;flex:0 0 auto}
   .sdot{width:30px;height:30px;border-radius:50%;border:2px solid var(--line);display:grid;place-items:center;font-size:13px;font-weight:700;color:var(--mut);background:var(--panel);cursor:pointer;transition:.15s}
   .sdot.done{background:var(--grad);border-color:transparent;color:#fff}
@@ -142,6 +148,7 @@
   </section>
 
   <section id="builder" class="hidden">
+    <div class="builderbar" id="builderbar"></div>
     <div class="stepper" id="stepper"></div>
     <div class="panel" id="panel"></div>
     <div class="footnote">Deliverables autosave to this browser · nothing is published. Studio Zero — accelerator prototype.</div>
@@ -197,6 +204,55 @@ function persist(){
 }
 function newProject(){return {id:uid(),name:'Untitled channel',createdAt:new Date().toISOString(),niche:'',outputs:{},costs:{}};}
 
+// ---- builder toolbar: rename + export ----
+function stepByKey(k){return PROMPTS.find(s=>s.key===k);}
+function planMarkdown(){
+  const lines=[];
+  lines.push('# '+(STATE.name||'Untitled channel'));
+  lines.push('');
+  lines.push('*0 → monetized AI YouTube channel in 90 days — built with Studio Zero.*');
+  if(STATE.niche)lines.push('','**Niche:** '+STATE.niche);
+  lines.push('','_Generated '+new Date().toLocaleString()+'_','');
+  PROMPTS.forEach(s=>{
+    const o=STATE.outputs[s.key];if(!o)return;
+    lines.push('','---','','## Step '+s.id+' · '+s.title,'');
+    lines.push(o.text.trim(),'');
+  });
+  const done=Object.keys(STATE.outputs||{}).length;
+  if(!done)lines.push('','_(No steps generated yet.)_');
+  return lines.join('\n');
+}
+function planHTML(){
+  const body=md(planMarkdown());
+  return '<!doctype html><html><head><meta charset="utf-8"><title>'+escAttr(STATE.name||'Channel plan')+' — Studio Zero</title>'
+    +'<style>body{max-width:760px;margin:40px auto;padding:0 20px;font:16px/1.6 -apple-system,BlinkMacSystemFont,Segoe UI,Inter,system-ui,sans-serif;color:#1a1a1f}'
+    +'h1{font-size:30px;letter-spacing:-.02em}h2{font-size:21px;margin-top:32px;border-top:1px solid #eee;padding-top:20px}h3{font-size:17px}h4{font-size:15px;color:#c0501a}'
+    +'table{border-collapse:collapse;width:100%;margin:14px 0;font-size:14px}th,td{border:1px solid #ddd;padding:7px 10px;text-align:left}th{background:#faf6f2}'
+    +'code{background:#f4f4f6;border-radius:4px;padding:1px 5px;font-size:13px}hr{display:none}a{color:#c0501a}'
+    +'@media print{body{margin:0}}</style></head><body>'+body
+    +'<p style="margin-top:40px;color:#999;font-size:12px">Studio Zero — prompts seeded by @David263146.</p></body></html>';
+}
+function escAttr(s){return String(s).replace(/"/g,'&quot;').replace(/</g,'&lt;');}
+function slugify(s){return String(s||'channel').toLowerCase().replace(/[^a-z0-9]+/g,'-').replace(/^-|-$/g,'').slice(0,40)||'channel';}
+function downloadFile(name,content,mime){
+  const b=new Blob([content],{type:mime});const u=URL.createObjectURL(b);
+  const a=document.createElement('a');a.href=u;a.download=name;document.body.appendChild(a);a.click();a.remove();
+  setTimeout(()=>URL.revokeObjectURL(u),2000);
+}
+function renderBar(){
+  const done=Object.keys(STATE.outputs||{}).length;
+  const bar=$('#builderbar');
+  bar.innerHTML=`
+    <input class="pname" id="pname" value="${escAttr(STATE.name||'Untitled channel')}" title="Rename this channel">
+    <span class="prog2">${done}/7 steps</span>
+    <span class="sp"></span>
+    <button class="btn ghost sm ${done?'':'done0'}" id="dlBtn">⤓ Download plan</button>
+    <button class="btn ghost sm ${done?'':'done0'}" id="mdBtn">⧉ Copy markdown</button>`;
+  $('#pname').onchange=()=>{STATE.name=$('#pname').value.trim()||'Untitled channel';persist();};
+  $('#dlBtn').onclick=()=>{ if(!done)return; downloadFile('studio-zero-'+slugify(STATE.name)+'.html',planHTML(),'text/html'); toast('Downloaded your channel plan'); };
+  $('#mdBtn').onclick=()=>{ if(!done)return; navigator.clipboard.writeText(planMarkdown()); toast('Copied full plan as Markdown'); };
+}
+
 function renderStepper(){
   const el=$('#stepper');el.innerHTML='';
   PROMPTS.forEach((s,idx)=>{
@@ -311,7 +367,7 @@ async function doGenerate(){
     if(j.warning)toast('Live call failed — showing demo');
     persist();
     renderOutput(step,j.text,j.demo,j.cost,j.maxPlan,j.equiv);
-    renderStepper();
+    renderStepper();renderBar();
   }catch(e){
     $('#mdOut').innerHTML='<p style="color:var(--red2)">Error: '+esc(e.message)+'</p>';
   }finally{
@@ -401,8 +457,8 @@ function renderSaved(){
     grid.appendChild(c);
   });
 }
-function openProject(p){STATE=p;cur=0;show('builder');renderStepper();renderStep();}
-function startNew(){STATE=newProject();persist();cur=0;show('builder');renderStepper();renderStep();}
+function openProject(p){STATE=p;cur=0;show('builder');renderBar();renderStepper();renderStep();}
+function startNew(){STATE=newProject();persist();cur=0;show('builder');renderBar();renderStepper();renderStep();}
 
 function show(which){
   $('#home').classList.toggle('hidden',which!=='home');

← 1518094 studio-zero: robust calendar title parser (whole-line bold t  ·  back to Studio Zero  ·  studio-zero: one-click auto-build all 7 steps (chains niche→ cceb51d →