…
## From a search to tasks {#workflow}
-**From a search to pipeline tasks, in one place.** Search, tick what belongs together, add it to a Focus, write your notes, and send it: it comes back as tasks.
+**Gather it, think it through, send it as tasks.** Search and tick what belongs together; it goes *poof* into a Focus and the map spins up. Add your thoughts one by one, and each lights what it names. Ask one question with **Thread now** and the answer comes back into that thought. Ask for a mockup and your designer shows it on the spot; the one you like joins. **Send focus**, split by feature, and it lands in the pipeline as tasks.
```embedhtml
-<div id="bff">
+<div id="bfc">
<style>
-#bff{font:14px/1.4 system-ui,-apple-system,Segoe UI,sans-serif;color:#ecebe6;background:#141413;border:1px solid #33322f;border-radius:14px;padding:14px;max-width:640px;margin:auto;position:relative;overflow:hidden}
-#bff *{box-sizing:border-box}
-#bff .cap{min-height:20px;font-size:13px;color:#9c9a93;margin:0 0 10px;transition:opacity .3s}
-#bff .cap b{color:#ecebe6}
-#bff .stage{position:relative;height:380px}
-#bff .sc{position:absolute;inset:0;opacity:0;pointer-events:none;transition:opacity .45s}
-#bff .sc.on{opacity:1}
-#bff .bar{display:flex;align-items:center;gap:8px;border:1px solid #4a4945;border-radius:9px;background:#1d1d1b;padding:7px 10px}
-#bff .bar i{color:#9c9a93;font-style:normal}
-#bff .cur{display:inline-block;width:2px;height:14px;background:#6aa3ff;vertical-align:-2px;animation:bffb 1s steps(1) infinite}
-@keyframes bffb{50%{opacity:0}}
-#bff .res{margin-top:10px;display:grid;gap:6px}
-#bff .row{display:flex;align-items:center;gap:9px;border:1px solid #33322f;border-radius:9px;background:#1d1d1b;padding:7px 10px;opacity:0;transform:translateY(6px);transition:opacity .3s,transform .3s,border-color .2s,background .2s}
-#bff .row.in{opacity:1;transform:none}
-#bff .row.pick{border-color:#3b82f6;background:#17233a}
-#bff .ck{flex:0 0 15px;height:15px;border-radius:4px;border:1.5px solid #6b6a66;position:relative}
-#bff .row.pick .ck{background:#3b82f6;border-color:#3b82f6}
-#bff .row.pick .ck:after{content:"";position:absolute;left:4px;top:1px;width:4px;height:8px;border:solid #fff;border-width:0 2px 2px 0;transform:rotate(45deg)}
-#bff .kind{font-size:10px;letter-spacing:.06em;color:#9c9a93;width:52px}
-#bff .kind.t{color:#e0a050}
-#bff .tools{display:flex;gap:8px;align-items:center;margin-top:10px}
-#bff .btn{display:inline-block;border:1px solid #4a4945;border-radius:7px;padding:4px 11px;font-size:12px;background:#22211f;color:#ecebe6;transition:transform .15s}
-#bff .btn.p{background:#3b82f6;border-color:#3b82f6;color:#fff}
-#bff .btn.press{transform:scale(.9)}
-#bff .menu{border:1px solid #4a4945;border-radius:9px;background:#1d1d1b;padding:6px 10px;font-size:12px;opacity:0;transform:translateY(-4px);transition:opacity .25s,transform .25s}
-#bff .menu.on{opacity:1;transform:none}
-#bff .fly{position:absolute;border:1px solid #3b82f6;border-radius:9px;background:#17233a;padding:7px 10px;font-size:13px;white-space:nowrap;overflow:hidden;transition:all .7s cubic-bezier(.6,-.2,.7,1);z-index:3}
-#bff .fly.go{left:calc(50% - 22px)!important;top:150px!important;width:44px!important;height:44px!important;border-radius:50%;opacity:0;color:transparent;background:#6aa3ff}
-#bff .orb{position:absolute;left:calc(50% - 38px);top:128px;width:76px;height:76px;border-radius:50%;background:#6aa3ff;color:#0d1b33;font-weight:700;display:flex;align-items:center;justify-content:center;text-align:center;font-size:13px;line-height:1.1;transform:scale(0);transition:transform .45s cubic-bezier(.3,1.6,.5,1);z-index:2}
-#bff .orb.on{transform:scale(1)}
-#bff .puff{position:absolute;width:10px;height:10px;border-radius:50%;background:#9fc2ff;left:calc(50% - 5px);top:161px;opacity:.9;transition:transform .6s ease-out,opacity .6s;z-index:1}
-#bff svg{display:block;width:100%;height:230px}
-#bff .lobe{fill:#1d1d1b;stroke:#33322f}
-#bff .spk{stroke:#4a4945;stroke-width:1.4}
-#bff .lnk{stroke:#6b6a66;stroke-width:1.2;stroke-dasharray:4 4;fill:none}
-#bff .nd{opacity:0;transition:opacity .4s}
-#bff .nd.on{opacity:1}
-#bff .nd text{fill:#9c9a93;font-size:11px;text-anchor:middle}
-#bff .nd.hot text{fill:#ecebe6;font-weight:700}
+#bfc{font:14px/1.4 system-ui,-apple-system,Segoe UI,sans-serif;color:#ecebe6;background:#141413;border:1px solid #33322f;border-radius:14px;padding:14px;max-width:660px;margin:auto;position:relative;overflow:hidden}
+#bfc *{box-sizing:border-box}
+#bfc .cap{min-height:20px;font-size:13px;color:#9c9a93;margin:0 0 10px}
+#bfc .cap b{color:#ecebe6}
+#bfc .stage{position:relative;height:440px}
+#bfc .sc{position:absolute;inset:0;opacity:0;pointer-events:none;transition:opacity .45s}
+#bfc .sc.on{opacity:1}
+#bfc .bar{display:flex;align-items:center;gap:8px;border:1px solid #4a4945;border-radius:9px;background:#1d1d1b;padding:7px 10px}
+#bfc .bar i{color:#9c9a93;font-style:normal}
+#bfc .cur{display:inline-block;width:2px;height:14px;background:#6aa3ff;vertical-align:-2px;animation:bfcb 1s steps(1) infinite}
+@keyframes bfcb{50%{opacity:0}}
+#bfc .res{margin-top:10px;display:grid;gap:6px}
+#bfc .row{display:flex;align-items:center;gap:9px;border:1px solid #33322f;border-radius:9px;background:#1d1d1b;padding:7px 10px;opacity:0;transform:translateY(6px);transition:opacity .3s,transform .3s,border-color .2s,background .2s}
+#bfc .row.in{opacity:1;transform:none}
+#bfc .row.pick{border-color:#3b82f6;background:#17233a}
+#bfc .ck{flex:0 0 15px;height:15px;border-radius:4px;border:1.5px solid #6b6a66;position:relative}
+#bfc .row.pick .ck{background:#3b82f6;border-color:#3b82f6}
+#bfc .row.pick .ck:after{content:"";position:absolute;left:4px;top:1px;width:4px;height:8px;border:solid #fff;border-width:0 2px 2px 0;transform:rotate(45deg)}
+#bfc .kind{font-size:10px;letter-spacing:.06em;color:#9c9a93;width:52px}
+#bfc .kind.t{color:#e0a050}
+#bfc .tools{display:flex;gap:8px;align-items:center;margin-top:10px}
+#bfc .btn{display:inline-block;border:1px solid #4a4945;border-radius:7px;padding:3px 10px;font-size:12px;background:#22211f;color:#ecebe6;transition:transform .15s}
-#bff .nd.hot circle{stroke-width:3.5}
-#bff .spin{transform-origin:360px 115px;transition:transform 1.6s cubic-bezier(.2,.8,.2,1)}
-#bff .spark{fill:#9fc2ff}
+#bfc .btn.p{background:#3b82f6;border-color:#3b82f6;color:#fff}
+#bfc .btn.press{transform:scale(.9)}
+#bfc .menu{border:1px solid #4a4945;border-radius:9px;background:#1d1d1b;padding:6px 10px;font-size:12px;opacity:0;transition:opacity .25s}
-#bff .notes{border:1px solid #3b82f6;border-radius:9px;background:#1d1d1b;padding:8px 10px;min-height:58px;font-size:13px;margin-top:6px}
-#bff .nhead{font:600 10px ui-monospace,Menlo,monospace;letter-spacing:.08em;color:#6aa3ff;margin-bottom:4px;display:flex;justify-content:space-between;align-items:center}
-#bff .ask{position:absolute;left:50%;top:120px;transform:translate(-50%,8px);width:310px;border:1px solid #4a4945;border-radius:12px;background:#22211f;padding:12px 14px;box-shadow:0 10px 30px rgba(0,0,0,.5);opacity:0;transition:opacity .3s,transform .3s;z-index:4}
-#bff .ask.on{opacity:1;transform:translate(-50%,0)}
-#bff .sw{display:inline-flex;border:1px solid #4a4945;border-radius:999px;overflow:hidden;font-size:11px;margin:8px 0}
-#bff .sw span{padding:3px 9px;transition:background .25s,color .25s}
-#bff .sw .on{background:#2e2419;color:#f0a35e;font-weight:700}
-#bff .pipe{position:absolute;right:0;top:20px;width:200px;bottom:10px;border-left:1px dashed #33322f;padding-left:12px}
-#bff .ph{font-size:10px;letter-spacing:.08em;color:#9c9a93;margin-bottom:8px}
-#bff .task{border:1px solid #3b6d41;background:#1f3d22;color:#8fd19a;border-radius:8px;padding:7px 9px;font-size:12px;margin-bottom:8px;opacity:0;transform:translateX(-180px) scale(.6);transition:all .7s cubic-bezier(.2,.8,.2,1)}
-#bff .task.on{opacity:1;transform:none}
-#bff .task b{color:#6aa3ff;font-weight:600;margin-right:4px}
-#bff .sent{position:absolute;left:30px;top:120px;font-size:15px;color:#8fd19a;opacity:0;transition:opacity .5s}#bff .sent.on{opacity:1}#bff .sent small{display:block;color:#9c9a93;font-size:12px;margin-top:4px}
-#bff .shrink{transition:transform .7s,opacity .7s}
-#bff .shrink.go{transform:scale(.2);opacity:0}
+#bfc .menu.on{opacity:1}
+#bfc .fly{position:absolute;border:1px solid #3b82f6;border-radius:9px;background:#17233a;padding:7px 10px;font-size:13px;white-space:nowrap;overflow:hidden;transition:all .7s cubic-bezier(.6,-.2,.7,1);z-index:3}
+#bfc .fly.go{left:calc(50% - 22px)!important;top:110px!important;width:44px!important;height:44px!important;border-radius:50%;opacity:0;color:transparent;background:#6aa3ff}
+#bfc .orb{position:absolute;left:calc(50% - 38px);top:94px;width:76px;height:76px;border-radius:50%;background:#6aa3ff;color:#0d1b33;font-weight:700;display:flex;align-items:center;justify-content:center;text-align:center;font-size:13px;line-height:1.1;transform:scale(0);transition:transform .45s cubic-bezier(.3,1.6,.5,1);z-index:2}
+#bfc .orb.on{transform:scale(1)}
+#bfc .puff{position:absolute;width:10px;height:10px;border-radius:50%;background:#9fc2ff;left:calc(50% - 5px);top:127px;opacity:.9;transition:transform .6s ease-out,opacity .6s;z-index:1}
+#bfc svg{display:block;width:100%;height:200px}
+#bfc .lobe{fill:#1d1d1b;stroke:#33322f}
+#bfc .spk{stroke:#4a4945;stroke-width:1.4;transition:opacity .4s}
+#bfc .lnk{stroke:#6b6a66;stroke-width:1.2;stroke-dasharray:4 4;fill:none;transition:opacity .4s}
+#bfc .nd{opacity:0;transition:opacity .4s}
+#bfc .nd.on{opacity:1}
+#bfc .nd text{fill:#9c9a93;font-size:11px;text-anchor:middle}
+#bfc .nd.hot text{fill:#ecebe6;font-weight:700}
+#bfc .nd.hot circle,#bfc .nd.hot rect{stroke-width:3.5}
+#bfc .spin{transform-origin:360px 100px;transition:transform 1.6s cubic-bezier(.2,.8,.2,1)}
+#bfc .spark{fill:#9fc2ff}
+#bfc .lo{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-top:4px}
+#bfc .notes{border:1px solid #3b82f6;border-radius:9px;background:#1d1d1b;padding:7px 9px;font-size:12.5px;min-height:96px}
+#bfc .nhead{font:600 10px ui-monospace,Menlo,monospace;letter-spacing:.08em;color:#6aa3ff;margin-bottom:4px;display:flex;justify-content:space-between;align-items:center;gap:6px}
+#bfc .newt{border:1px dashed #4a4945;border-radius:7px;padding:5px 7px;margin-top:6px;min-height:28px;font-size:12.5px}
+#bfc .cards{display:flex;flex-direction:column;gap:5px}
+#bfc .card{border:1px solid #33322f;border-radius:10px;background:#1d1d1b;padding:6px 9px;font-size:12px;opacity:0;transform:translateY(8px);transition:opacity .4s,transform .4s,border-color .4s,background .4s,box-shadow .4s}
+#bfc .card.in{opacity:1;transform:none}
+#bfc .card b{font-weight:600}
+#bfc .card .m{display:flex;gap:5px;align-items:center;margin-top:3px;font-size:10.5px;color:#9c9a93}
+#bfc .st{border:1px solid currentColor;border-radius:999px;padding:0 6px;white-space:nowrap}
+#bfc .st.sent{color:#9c9a93;border-style:dashed}#bfc .st.ask{color:#f08a92}#bfc .st.done{color:#6cc08a}#bfc .st.mock{color:#e0a050}
+#bfc .card.amber{border-color:#d99a00;box-shadow:inset 3px 0 0 #d99a00;background:#2a2416}
+#bfc .ans{max-height:0;opacity:0;overflow:hidden;transition:max-height .5s,opacity .5s;margin-top:3px;padding-left:7px;border-left:2px solid #33322f;font-size:11.5px}
+#bfc .ans.on{max-height:40px;opacity:1}
+#bfc .esp{position:absolute;left:50%;top:6px;transform:translate(-50%,-10px);border:1px solid #c5a0f5;border-radius:999px;background:#2a2038;color:#ecebe6;font-size:12px;padding:5px 12px;opacity:0;transition:opacity .3s,transform .3s;z-index:5;white-space:nowrap}
+#bfc .esp.on{opacity:1;transform:translate(-50%,0)}
+#bfc .mock{position:absolute;left:18%;right:18%;top:40px;height:150px;border:2px solid #c5a0f5;border-radius:12px;background:#1d1d1b;padding:10px;opacity:0;transform:scale(.9);transition:all .5s;z-index:4}
+#bfc .mock.on{opacity:1;transform:none}
+#bfc .mock.away{opacity:0;transform:translate(160px,-40px) scale(.2)}
+#bfc .mk1{height:18px;border-radius:5px;background:#33322f;margin-bottom:8px;width:60%}
+#bfc .mk2{height:52px;border-radius:8px;background:#2e2419;border:1px solid #e0a050;margin-bottom:8px;display:flex;align-items:center;justify-content:center;color:#e0a050;font-size:12px}
+#bfc .mk3{height:12px;border-radius:5px;background:#33322f;width:80%}
+#bfc .ask{position:absolute;left:50%;top:110px;transform:translate(-50%,8px);width:320px;border:1px solid #4a4945;border-radius:12px;background:#22211f;padding:12px 14px;box-shadow:0 10px 30px rgba(0,0,0,.5);opacity:0;transition:opacity .3s,transform .3s;z-index:6}
+#bfc .ask.on{opacity:1;transform:translate(-50%,0)}
+#bfc .sw{display:inline-flex;border:1px solid #4a4945;border-radius:999px;overflow:hidden;font-size:11px;margin:8px 0}
+#bfc .sw span{padding:3px 9px;transition:background .25s,color .25s}
+#bfc .sw .on{background:#2e2419;color:#f0a35e;font-weight:700}
+#bfc .shrink{transition:transform .7s,opacity .7s}
+#bfc .shrink.go{transform:scale(.2);opacity:0}
+#bfc .sentmsg{position:absolute;left:24px;top:150px;font-size:15px;color:#8fd19a;opacity:0;transition:opacity .5s}
+#bfc .sentmsg.on{opacity:1}
+#bfc .sentmsg small{display:block;color:#9c9a93;font-size:12px;margin-top:4px}
+#bfc .pipe{position:absolute;right:0;top:20px;width:230px;bottom:10px;border-left:1px dashed #33322f;padding-left:12px;opacity:0;transition:opacity .4s}
+#bfc .ph{font-size:10px;letter-spacing:.08em;color:#9c9a93;margin-bottom:8px}
+#bfc .task{border:1px solid #3b6d41;background:#1f3d22;color:#8fd19a;border-radius:8px;padding:7px 9px;font-size:12px;margin-bottom:8px;opacity:0;transform:translateX(-180px) scale(.6);transition:all .7s cubic-bezier(.2,.8,.2,1)}
+#bfc .task.on{opacity:1;transform:none}
+#bfc .task b{color:#6aa3ff;font-weight:600;margin-right:4px}
</style>
+<p class="cap" id="bfc-cap"></p>
+<div class="stage" id="bfc-stage">
+ <div class="sc" id="bfc-s1">
+ <div class="bar"><i>⌕</i><span id="bfc-q"></span><span class="cur"></span></div>
+ <div class="res" id="bfc-res"></div>
+ <div class="tools"><span class="btn" id="bfc-addf">Add to a Focus ▾</span><span class="menu" id="bfc-menu">+ New Focus: <b id="bfc-fname"></b></span></div>
-<p class="cap" id="bff-cap"></p>
-<div class="stage">
- <div class="sc" id="bff-s1">
- <div class="bar"><i>⌕</i><span id="bff-q"></span><span class="cur"></span></div>
- <div class="res" id="bff-res"></div>
- <div class="tools"><span class="btn" id="bff-addf">Add to a Focus ▾</span><span class="menu" id="bff-menu">+ New Focus: <b id="bff-fname"></b></span></div>
</div>
+ <div class="orb" id="bfc-orb">invite<br>flow</div>
+ <div class="sc" id="bfc-s3"><div class="shrink" id="bfc-mapw">
+ <svg viewBox="0 0 720 200"><g class="spin" id="bfc-spin">
+ <ellipse class="lobe" cx="215" cy="100" rx="160" ry="92"/><ellipse class="lobe" cx="505" cy="100" rx="160" ry="92"/>
+ <g id="bfc-edges"></g><g id="bfc-nodes"></g>
+ <circle cx="360" cy="100" r="34" fill="#6aa3ff"/><text x="360" y="96" text-anchor="middle" font-size="12" font-weight="700" fill="#0d1b33">invite</text><text x="360" y="110" text-anchor="middle" font-size="12" font-weight="700" fill="#0d1b33">flow</text>
+ <circle class="spark" id="bfc-spark" r="3" cx="360" cy="100" opacity="0"/>
- <div class="orb" id="bff-orb">invite<br>flow</div>
- <div class="sc" id="bff-s3"><div class="shrink" id="bff-mapw">
- <svg viewBox="0 0 720 230" id="bff-svg"><g class="spin" id="bff-spin">
- <ellipse class="lobe" cx="215" cy="115" rx="160" ry="104"/><ellipse class="lobe" cx="505" cy="115" rx="160" ry="104"/>
- <g id="bff-edges"></g><g id="bff-nodes"></g>
- <circle cx="360" cy="115" r="36" fill="#6aa3ff"/><text x="360" y="111" text-anchor="middle" font-size="12" font-weight="700" fill="#0d1b33">invite</text><text x="360" y="125" text-anchor="middle" font-size="12" font-weight="700" fill="#0d1b33">flow</text>
- <circle class="spark" id="bff-spark" r="3" cx="360" cy="115" opacity="0"/>
</g></svg>
- <div class="notes"><div class="nhead"><span>FOCUS · YOUR NOTES</span><span class="btn p" id="bff-send">Send focus</span></div><span id="bff-nt"></span><span class="cur"></span></div>
- </div>
+ <div class="lo">
- <div class="ask" id="bff-ask">Send this Focus to your designer: 2 thoughts, 1 topic and your notes?<br><span class="sw"><span id="bff-one" class="on">one task</span><span id="bff-split">split by feature</span></span><div style="text-align:right"><span class="btn p" id="bff-go">Send</span></div></div>
- <div class="sent" id="bff-sent">✓ <b>invite flow</b> sent<small>split by feature: one task each</small></div>
- <div class="pipe" id="bff-pipe" style="opacity:0;transition:opacity .4s"><div class="ph">PIPELINE</div><div class="task" id="bff-t1"><b>P-1201</b>invites: say what to do when one expires</div><div class="task" id="bff-t2"><b>P-1202</b>onboarding: a welcome card on joining</div></div>
+ <div class="notes"><div class="nhead"><span>FOCUS · NEW THOUGHT</span><span><span class="btn" id="bfc-add">Add</span> <span class="btn p" id="bfc-send">Send focus</span></span></div><div class="newt"><span id="bfc-nt"></span><span class="cur"></span></div></div>
+ <div class="cards" id="bfc-cards"></div>
+ </div>
</div>
+ <div class="esp" id="bfc-esp">ESP · your designer is showing you: <b>Mockup · welcome card v1</b></div>
+ <div class="mock" id="bfc-mock"><div class="mk1"></div><div class="mk2">Welcome to Acme! Here's who to ask.</div><div class="mk3"></div></div>
+ <div class="ask" id="bfc-ask">Send this Focus to your designer: 5 thoughts, 3 topics and your notes?<br><span class="sw"><span id="bfc-one" class="on">one task</span><span id="bfc-split">split by feature</span></span><div style="text-align:right"><span class="btn p" id="bfc-go">Send</span></div></div>
+ <div class="sentmsg" id="bfc-sent">✓ <b>invite flow</b> sent<small>split by feature: one task each</small></div>
+ <div class="pipe" id="bfc-pipe"><div class="ph">PIPELINE</div><div class="task" id="bfc-t1"><b>P-1201</b>invites: what to do when one expires</div><div class="task" id="bfc-t2"><b>P-1202</b>onboarding: the welcome card, as in the mockup</div><div class="task" id="bfc-t3"><b>P-1203</b>email: invites pass Gmail's checks</div></div>
+</div>
</div>
<script>
-(()=>{const $=i=>document.getElementById("bff-"+i),sl=ms=>new Promise(r=>setTimeout(r,ms)),NS="http://www.w3.org/2000/svg";
+(()=>{const $=i=>document.getElementById("bfc-"+i),sl=ms=>new Promise(r=>setTimeout(r,ms)),NS="http://www.w3.org/2000/svg";
const cap=h=>{$("cap").innerHTML=h};
-async function type(el,s,ms){el.textContent="";for(const c of s){el.textContent+=c;await sl(ms||45)}}
+async function type(el,s,ms){el.textContent="";for(const c of s){el.textContent+=c;await sl(ms||42)}}
async function press(b){b.classList.add("press");await sl(220);b.classList.remove("press")}
const R=[["THOUGHT","expired invite shows a raw error",1],["TOPIC","Invites",1],["THOUGHT","invite emails land in spam",0],["THOUGHT","welcome card after joining",1],["TOPIC","Invite settings",0]];
-// the map: topics right, the model left (violet classes, a teal feature)
+// the map: topics right; the model left (violet classes, teal features); [kind,label,x,y,shown from the start]
+const N=[["t","Invites",500,38,1],["t","Onboarding",610,135,1],["c","Invite",170,40,1],["c","Member",108,112,1],["f","Joining a project",290,48,1],["c","Project",210,172,0],["f","Email",470,170,0],["t","Mockup v1",640,60,0]];
-const N=[["t","Invites",500,48],["t","Onboarding",610,150],["c","Invite",170,52],["c","Member",110,128],["c","Project",215,190],["f","Joining a project",290,58]];
const col={t:"#e0a050",c:"#a98ae8",f:"#4fb8a8"};
function draw(){const e=$("edges"),n=$("nodes");e.innerHTML="";n.innerHTML="";
+N.forEach((x,i)=>{const l=document.createElementNS(NS,"line");l.setAttribute("class","spk");l.setAttribute("x1",360);l.setAttribute("y1",100);l.setAttribute("x2",x[2]);l.setAttribute("y2",x[3]);l.style.opacity=0;l.id="bfc-l"+i;e.appendChild(l);
+const g=document.createElementNS(NS,"g");g.setAttribute("class","nd");g.id="bfc-n"+i;
+g.innerHTML=(x[0]==="t"?`<rect x="${x[2]-12}" y="${x[3]-12}" width="24" height="24" rx="6" fill="#1d1d1b" stroke="${col.t}" stroke-width="2"/>`:`<circle cx="${x[2]}" cy="${x[3]}" r="9" fill="#1d1d1b" stroke="${col[x[0]]}" stroke-width="2"/>`)+`<text x="${x[2]}" y="${x[3]+(x[3]<100?-16:24)}">${x[1]}</text>`;n.appendChild(g)})}
+const show=i=>{$("l"+i).style.opacity=1;$("n"+i).classList.add("on")};
+async function spark(i){const s=$("spark"),x=N[i];s.setAttribute("opacity",1);for(let k=0;k<=10;k++){s.setAttribute("cx",360+(x[2]-360)*k/10);s.setAttribute("cy",100+(x[3]-100)*k/10);await sl(26)}s.setAttribute("opacity",0)}
-N.forEach((x,i)=>{const l=document.createElementNS(NS,"line");l.setAttribute("class","spk");l.setAttribute("x1",360);l.setAttribute("y1",115);l.setAttribute("x2",x[2]);l.setAttribute("y2",x[3]);l.style.opacity=0;l.id="bff-l"+i;e.appendChild(l);
-const g=document.createElementNS(NS,"g");g.setAttribute("class","nd");g.id="bff-n"+i;
-g.innerHTML=(x[0]==="t"?`<rect x="${x[2]-13}" y="${x[3]-13}" width="26" height="26" rx="6" fill="#1d1d1b" stroke="${col.t}" stroke-width="2"/>`:`<circle cx="${x[2]}" cy="${x[3]}" r="10" fill="#1d1d1b" stroke="${col[x[0]]}" stroke-width="2"/>`)+`<text x="${x[2]}" y="${x[3]+(x[3]<115?-18:26)}">${x[1]}</text>`;n.appendChild(g)});
-const p=document.createElementNS(NS,"path");p.setAttribute("class","lnk");p.setAttribute("d","M500 48 Q585 80 610 150");p.style.opacity=0;p.id="bff-lk";e.appendChild(p)}
-async function sparkle(){const s=$("spark");s.setAttribute("opacity",1);for(const i of [0,2,5,1]){const x=N[i];for(let k=0;k<=10;k++){s.setAttribute("cx",360+(x[2]-360)*k/10);s.setAttribute("cy",115+(x[3]-115)*k/10);await sl(28)}}s.setAttribute("opacity",0)}
function hot(names){N.forEach((x,i)=>$("n"+i).classList.toggle("hot",names.includes(x[1])))}
+function card(t,st,sc){const c=document.createElement("div");c.className="card";c.innerHTML=`<b>${t}</b><div class="ans"></div><div class="m"><span class="st ${sc||"sent"}">${st}</span></div>`;$("cards").prepend(c);setTimeout(()=>c.classList.add("in"),30);while($("cards").children.length>4)$("cards").lastChild.remove();return c}
async function run(){for(;;){
+["s1","s3"].forEach(s=>$(s).classList.remove("on"));$("orb").classList.remove("on");["ask","esp","mock","sent"].forEach(k=>$(k).classList.remove("on"));$("mock").classList.remove("away");$("pipe").style.opacity=0;["t1","t2","t3"].forEach(t=>$(t).classList.remove("on"));
+$("mapw").classList.remove("go");$("res").innerHTML="";$("menu").classList.remove("on");$("fname").textContent="";$("nt").textContent="";$("q").textContent="";$("cards").innerHTML="";$("one").className="on";$("split").className="";
-// reset
-["s1","s3"].forEach(s=>$(s).classList.remove("on"));$("orb").classList.remove("on");$("ask").classList.remove("on");$("pipe").style.opacity=0;$("sent").classList.remove("on");["t1","t2"].forEach(t=>$(t).classList.remove("on"));
-$("mapw").classList.remove("go");$("res").innerHTML="";$("menu").classList.remove("on");$("fname").textContent="";$("nt").textContent="";$("q").textContent="";$("one").className="on";$("split").className="";
draw();$("spin").style.transition="none";$("spin").style.transform="rotate(-140deg) scale(.4)";
+// 1 search, tick, add to a new Focus
+$("s1").classList.add("on");cap("<b>1 · Search</b> for what's on your mind");await sl(500);await type($("q"),"invite",100);await sl(300);
-// 1 search and pick
-$("s1").classList.add("on");cap("<b>1 · Search</b> for what's on your mind");await sl(500);await type($("q"),"invite",110);await sl(300);
const rows=R.map(r=>{const d=document.createElement("div");d.className="row";d.innerHTML=`<span class="ck"></span><span class="kind${r[0]==="TOPIC"?" t":""}">${r[0]}</span><span>${r[1]}</span>`;$("res").appendChild(d);return d});
-for(const d of rows){d.classList.add("in");await sl(140)}await sl(500);
-cap("<b>2 · Tick</b> the thoughts and topics that belong together");
-for(let i=0;i<R.length;i++)if(R[i][2]){rows[i].classList.add("pick");await sl(550)}
-await sl(300);cap("<b>3 · Add to a Focus</b>, a new one");await press($("addf"));$("menu").classList.add("on");await sl(400);await type($("fname"),"invite flow",70);await sl(600);
-// 2 poof into the focus
-const st=$("s1").parentNode,box=st.getBoundingClientRect(),fl=[];
+for(const d of rows){d.classList.add("in");await sl(130)}await sl(400);
+cap("<b>2 · Tick</b> what belongs together");for(let i=0;i<R.length;i++)if(R[i][2]){rows[i].classList.add("pick");await sl(480)}
+await sl(250);cap("<b>3 · Add to a Focus</b>, a new one");await press($("addf"));$("menu").classList.add("on");await sl(350);await type($("fname"),"invite flow",65);await sl(500);
+// poof
+const st=$("stage"),box=st.getBoundingClientRect(),fl=[];
rows.forEach((d,i)=>{if(!R[i][2])return;const r=d.getBoundingClientRect(),f=document.createElement("div");f.className="fly";f.textContent=d.textContent.replace(/^(THOUGHT|TOPIC)/,"");f.style.left=(r.left-box.left)+"px";f.style.top=(r.top-box.top)+"px";f.style.width=r.width+"px";f.style.height=r.height+"px";st.appendChild(f);fl.push(f)});
+$("s1").classList.remove("on");await sl(60);fl.forEach((f,i)=>setTimeout(()=>f.classList.add("go"),i*110));await sl(780);
-$("s1").classList.remove("on");await sl(60);fl.forEach((f,i)=>setTimeout(()=>f.classList.add("go"),i*120));await sl(800);
$("orb").classList.add("on");const pf=[];for(let k=0;k<10;k++){const p=document.createElement("div");p.className="puff";st.appendChild(p);pf.push(p)}
await sl(30);pf.forEach((p,k)=>{const a=k/10*6.283;p.style.transform=`translate(${Math.cos(a)*70}px,${Math.sin(a)*70}px) scale(.3)`;p.style.opacity=0});
+cap("<b>Poof:</b> they're one Focus now");await sl(850);fl.concat(pf).forEach(x=>x.remove());
+// the map spins in
-cap("<b>Poof:</b> they're one Focus now");await sl(900);fl.concat(pf).forEach(x=>x.remove());
-// 3 the map spins in
$("orb").classList.remove("on");$("s3").classList.add("on");await sl(50);$("spin").style.transition="";$("spin").style.transform="rotate(0) scale(1)";
+card("welcome card after joining","in focus");card("expired invite shows a raw error","in focus");
cap("<b>4 · The map</b>: its topics on the right, the model they name on the left");await sl(700);
+for(let i=0;i<N.length;i++)if(N[i][4]){show(i);await sl(200)}await spark(0);await spark(2);await sl(300);
+// three new thoughts, each joins and lights the map
+const T=[["a new Member should see who to ask",["Member"],[]],["the Project's welcome card names its admin",["Project"],[5]],["invite email: say when the link expires",["Email","Invite"],[6]]];
+let k=0;for(const [t,h,add] of T){k++;cap(`<b>5 · Think it through:</b> thought ${k} of 3 joins the Focus, and lights what it names`);
+await type($("nt"),t,34);await sl(250);await press($("add"));$("nt").textContent="";card(t,"in focus");for(const i of add){show(i);spark(i)}hot(h);await sl(1100)}hot([]);
+// thread now on one; the answer comes back into it
+cap("<b>6 · One question?</b> Thread now on that thought: the answer comes back into it");
+const c=$("cards").children[0];c.querySelector(".st").textContent="with designer";await sl(1400);
+const a=c.querySelector(".ans");a.innerHTML="<b>designer:</b> say it in the email and on the page?";a.classList.add("on");c.classList.add("amber");c.querySelector(".st").className="st ask";c.querySelector(".st").textContent="ai-question";await sl(1800);
+// a mockup, shown with ESP, joins
-for(let i=0;i<N.length;i++){$("l"+i).style.transition="opacity .4s";$("l"+i).style.opacity=1;$("n"+i).classList.add("on");await sl(230)}$("lk").style.transition="opacity .4s";$("lk").style.opacity=1;
+cap("<b>7 · Ask for a mockup:</b> your designer shows it to you on the spot");$("esp").classList.add("on");await sl(500);$("mock").classList.add("on");await sl(2000);
-await sparkle();await sl(400);
+cap("<b>Like it?</b> It joins the Focus");$("esp").classList.remove("on");$("mock").classList.add("away");await sl(500);show(7);spark(7);hot(["Mockup v1"]);card("Mockup · welcome card v1","topic","mock");await sl(1300);hot([]);
+// send it, split by feature
+cap("<b>8 · Send focus</b>: as one task, or split by feature");await press($("send"));$("ask").classList.add("on");await sl(1100);
-// 4 notes
-cap("<b>5 · Your notes</b>: the map follows the words you type");
-const said=[["A new Member",["Member"]],[" should land in the Project",["Project"]],[" with a welcome; an expired Invite",["Invite","Invites"]],[" should say what to do next.",[]]];
-for(const [s,h] of said){const el=$("nt"),t0=el.textContent;for(const c of s){el.textContent+=c;await sl(38)}if(h.length)hot(h);await sl(250)}hot([]);await sl(700);
-// 5 send, split by feature
-cap("<b>6 · Send focus</b>: as one task, or split by feature");await press($("send"));$("ask").classList.add("on");await sl(1100);
$("one").className="";$("split").className="on";await sl(900);await press($("go"));$("ask").classList.remove("on");
+$("mapw").classList.add("go");$("pipe").style.opacity=1;$("sent").classList.add("on");await sl(500);cap("<b>9 · Pipeline</b>: one task per feature, picked up by your agents");
-// 6 pipeline
-$("mapw").classList.add("go");$("pipe").style.opacity=1;$("sent").classList.add("on");await sl(500);cap("<b>7 · Pipeline</b>: one task per feature, picked up by your agents");
-$("t1").classList.add("on");await sl(600);$("t2").classList.add("on");await sl(3600)}}
+for(const t of ["t1","t2","t3"]){$(t).classList.add("on");await sl(550)}await sl(3600)}}
run()})();
-</script>
-</div>
-```
-
-**Think on one subject. End with one task.**
-
-```embedhtml
-<div id="fa">
-<style>
-#fa{--ink:var(--ink,#1d1d1b);font:14px/1.4 system-ui,-apple-system,Segoe UI,sans-serif;color:#ecebe6;background:#141413;border:1px solid #33322f;border-radius:14px;padding:14px;max-width:760px;margin:auto;position:relative;overflow:hidden}
-#fa .cap{font-weight:700;font-size:15px;min-height:22px;margin-bottom:8px;transition:opacity .4s}
-#fa svg{width:100%;height:auto;display:block}
-#fa .lobe{fill:#1d1d1b;stroke:#33322f}
-#fa .lc{font:700 11px system-ui;fill:#9c9a93;letter-spacing:.08em}
-#fa .core{fill:#3b82f6}#fa .coret{fill:#fff;font:700 11px system-ui}
-#fa .sp{stroke:#3b5b8f;stroke-width:1.5;transition:opacity .6s}
-#fa .n{transition:opacity .6s,transform .6s;transform-box:fill-box;transform-origin:center}
-#fa .n.off{opacity:0;transform:scale(.3)}
-#fa .c{fill:#a58bf0}#fa .f{fill:#5cc0b8}#fa .b{fill:#e5b454}#fa .t{fill:#1d1d1b;stroke:#6aa3ff;stroke-width:2}
-#fa .nl{font:600 11px system-ui;fill:#d8d6cf}
-#fa .lit{animation:falit 1.2s ease 2}
-@keyframes falit{50%{filter:drop-shadow(0 0 6px #f0b000)}}
-#fa .bar{display:flex;align-items:center;gap:8px;border:1px solid #33322f;border-radius:8px 8px 0 0;padding:6px 10px;background:#1d1d1b;margin-top:6px}
-#fa .bar b{font-size:12px;color:#6aa3ff;letter-spacing:.06em}#fa .sp1{flex:1}
-#fa .btn{border:1px solid #4a4945;border-radius:7px;padding:3px 10px;font-size:12px;background:#22211f;color:#ecebe6;transition:transform .15s,box-shadow .15s}
-#fa .btn.p{background:#3b82f6;color:#fff;border-color:#3b82f6}
-#fa .btn.press{transform:scale(.92);box-shadow:0 0 0 4px #f0b00066}
-#fa .ed{border:1px solid #33322f;border-top:0;border-radius:0 0 8px 8px;background:#1d1d1b;padding:8px 10px;min-height:38px;font-family:ui-monospace,Menlo,monospace;font-size:13px}
-#fa .cur{display:inline-block;width:2px;height:14px;background:#6aa3ff;vertical-align:-2px;animation:fablink 1s steps(1) infinite}
-@keyframes fablink{50%{opacity:0}}
-#fa .cards{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin-top:10px;min-height:72px}
-#fa .card{background:#1d1d1b;border:1px solid #33322f;border-radius:9px;padding:7px 9px;font-size:12px;transition:all .5s}
-#fa .card .ti{font-weight:600}#fa .card .ch{display:inline-block;margin-top:4px;background:#1c2b45;color:#8fb8ff;border-radius:9px;padding:0 7px;font-size:11px}
-#fa .card.new{animation:faflash 1.4s ease}
-@keyframes faflash{0%{transform:translateY(-14px);opacity:0;background:#3a3015}40%{opacity:1;background:#3a3015}100%{transform:none;background:#1d1d1b}}
-#fa .card .st{float:right;font-size:11px;color:#9c9a93}
-#fa .task{position:absolute;right:18px;bottom:18px;background:#1b2a20;color:#ecebe6;border:2px solid #6cc08a;border-radius:10px;padding:8px 12px;font-size:12px;opacity:0;transform:translateY(20px);transition:all .6s}
-#fa .task.on{opacity:1;transform:none}
-#fa .fly{transition:all .9s ease-in;}#fa .fly.go{transform:translate(260px,60px) scale(.2);opacity:0}
-#fa .m{fill:#2a2418;stroke:#e5b454;stroke-width:2;stroke-dasharray:4 3}
-#fa .mock{position:absolute;left:50%;top:44%;width:300px;margin-left:-150px;background:#1d1d1b;border:1px solid #4a4945;border-radius:10px;box-shadow:0 10px 30px #000a;opacity:0;transform:scale(.6);transition:all .6s;z-index:3}
-#fa .mock.on{opacity:1;transform:none}#fa .mock.away{opacity:0;transform:translate(110px,-150px) scale(.1)}
-#fa .mock .mh{font-size:11px;color:#e5b454;padding:6px 10px;border-bottom:1px solid #33322f}
-#fa .mock .mb{padding:10px;display:grid;grid-template-columns:1fr 1fr;gap:6px}#fa .mock .mb i{height:26px;border-radius:6px;background:#22211f;border:1px solid #33322f}#fa .mock .mb i.b{background:#1c2b45}
-#fa .leg{font-size:11px;color:#9c9a93;margin-top:6px}#fa .leg i{display:inline-block;width:9px;height:9px;border-radius:50%;margin:0 4px 0 10px;vertical-align:-1px}
-</style>
-<div class="cap" id="fa-cap">A Focus: everything on one subject, in one place</div>
-<svg viewBox="0 0 720 230" aria-label="Focus map">
-<ellipse class="lobe" cx="200" cy="115" rx="170" ry="100"/><ellipse class="lobe" cx="520" cy="115" rx="170" ry="100"/>
-<text class="lc" x="200" y="28" text-anchor="middle">MODEL</text><text class="lc" x="520" y="28" text-anchor="middle">TOPICS</text>
-<g id="fa-sp"></g>
-<g id="fa-nodes"></g>
-<circle class="core" cx="360" cy="115" r="30"/><text class="coret" x="360" y="112" text-anchor="middle">skills</text><text class="coret" x="360" y="125" text-anchor="middle">reorg</text>
-</svg>
-<div class="leg"><i style="background:#a58bf0"></i>concept<i style="background:#5cc0b8"></i>feature<i style="background:#e5b454"></i>behaviour<i style="background:#1d1d1b;border:2px solid #6aa3ff"></i>topic<i style="background:#2a2418;border:2px dashed #e5b454"></i>mockup</div>
-<div class="fly" id="fa-body">
-<div class="bar"><b>FOCUS · NEW THOUGHT</b><span class="sp1"></span><span class="btn" id="fa-send1">Send</span><span class="btn" id="fa-add">Add</span><span class="btn p" id="fa-sendf">Send focus</span></div>
-<div class="ed" id="fa-ed"><span id="fa-tx"></span><span class="cur"></span></div>
-<div class="cards" id="fa-cards"></div>
-</div>
-<div class="mock" id="fa-mock"><div class="mh">ESP · your designer is showing you: Mockup · Focus cards v1</div><div class="mb"><i class="b"></i><i class="b"></i><i></i><i></i><i></i><i class="b"></i></div></div>
-<div class="task" id="fa-task">✓ Sent · became <b>P-1082</b> for your designer<br><span style="color:#9c9a93">4 thoughts · 4 topic links · 1 mockup · your notes</span></div>
-<script>
-(()=>{const $=i=>document.getElementById(i),NS="http://www.w3.org/2000/svg";
-const N=[["t","DesignSkills",470,60],["t","SkillAreas",600,95],["t","SkillOrganization",560,170],["t","Help:Thoughts",455,165],
-["c","Skill",150,60,1],["f","thoughts",230,75,2],["b","^thoughts-ui-31",120,145,2],["c","Feature",265,160,3],["b","^agents-29",190,190,3],["f","sprint",95,100,3],["m","Mockup v1",640,190,4]];
-const sleep=ms=>new Promise(r=>setTimeout(r,ms));
-function draw(){$("fa-nodes").innerHTML="";$("fa-sp").innerHTML="";N.forEach((n,i)=>{const g=document.createElementNS(NS,"g");g.setAttribute("class","n"+(n[4]?" off":""));g.id="fa-n"+i;
-const l=document.createElementNS(NS,"line");l.setAttribute("x1",360);l.setAttribute("y1",115);l.setAttribute("x2",n[2]);l.setAttribute("y2",n[3]);l.setAttribute("class","sp");l.id="fa-l"+i;if(n[4])l.style.opacity=0;$("fa-sp").appendChild(l);
-let s;if(n[0]=="t"||n[0]=="m"){s=document.createElementNS(NS,"rect");s.setAttribute("x",n[2]-10);s.setAttribute("y",n[3]-10);s.setAttribute("width",20);s.setAttribute("height",20);s.setAttribute("rx",5)}else{s=document.createElementNS(NS,"circle");s.setAttribute("cx",n[2]);s.setAttribute("cy",n[3]);s.setAttribute("r",9)}
-s.setAttribute("class",n[0]);g.appendChild(s);const t=document.createElementNS(NS,"text");t.setAttribute("x",n[2]);t.setAttribute("y",n[3]-14);t.setAttribute("text-anchor","middle");t.setAttribute("class","nl");t.textContent=n[1];g.appendChild(t);$("fa-nodes").appendChild(g)})}
-function show(step){N.forEach((n,i)=>{if(n[4]==step){$("fa-n"+i).classList.remove("off");$("fa-n"+i).classList.add("lit");$("fa-l"+i).style.opacity=1}})}
-async function type(s){$("fa-tx").textContent="";for(const ch of s){$("fa-tx").textContent+=ch;await sleep(38)}}
-async function press(id){$(id).classList.add("press");await sleep(220);$(id).classList.remove("press")}
-function card(t,st){const d=document.createElement("div");d.className="card new";d.innerHTML='<span class="st">'+(st||"")+'</span><div class="ti">'+t+'</div><span class="ch">skills reorg</span>';$("fa-cards").prepend(d);while($("fa-cards").children.length>3)$("fa-cards").lastChild.remove();return d}
-function cap(s){$("fa-cap").textContent=s}
-async function run(){{draw();$("fa-cards").innerHTML="";$("fa-task").classList.remove("on");$("fa-body").classList.remove("go");$("fa-mock").className="mock";$("fa-tx").textContent="";
-cap("A Focus: your thoughts and the docs on one subject, in one place");await sleep(1800);
-cap("Think out loud: type, or say it");await type("one skill per feature, the Skill concept carries the rules");await sleep(500);
-await press("fa-add");card("one skill per feature, the Skill concept carries the rules");$("fa-tx").textContent="";cap("Add: it joins the Focus, and the model lights up what it touches");show(1);await sleep(2200);
-await type("thoughts skill: say how a sprint is batched");await sleep(400);await press("fa-add");card("thoughts skill: say how a sprint is batched");show(2);$("fa-tx").textContent="";await sleep(2000);
-cap("Need your designer's eye on one? Send just that thought");await type("Feature vs agent role: which owns the status steps?");await sleep(300);await press("fa-send1");const c=card("Feature vs agent role: which owns the status steps?","→ designer");$("fa-tx").textContent="";await sleep(1600);
-c.querySelector(".st").textContent="answered ✓";c.classList.remove("new");void c.offsetWidth;c.classList.add("new");show(3);cap("The answer lands in the thought, and the model grows");await sleep(2400);
-cap("Ask to see it: your designer makes a mockup");await type("show me a mockup of the cards");await sleep(300);await press("fa-send1");const m=card("show me a mockup of the cards","→ designer");$("fa-tx").textContent="";await sleep(1500);
-cap("…and shows it to you, right there (ESP)");$("fa-mock").classList.remove("away");$("fa-mock").classList.add("on");await sleep(2600);
-cap("Like it? It joins the Focus; keep thinking");$("fa-mock").classList.add("away");$("fa-mock").classList.remove("on");await sleep(600);show(4);m.querySelector(".st").textContent="mockup ✓";await sleep(2200);
-cap("Done thinking? Send focus: one task with everything");await press("fa-sendf");$("fa-body").classList.add("go");await sleep(900);$("fa-task").classList.add("on");await sleep(3200)}}
-const pb=document.createElement("button");pb.type="button";pb.textContent="▶ Watch";pb.style.cssText="display:block;margin:10px auto 0;padding:5px 14px;border:1px solid #4a4945;border-radius:999px;background:#22211f;color:#ecebe6;font:600 12px system-ui,sans-serif;cursor:pointer";
-document.getElementById("fa").appendChild(pb);pb.onclick=async()=>{pb.disabled=true;pb.textContent="Playing…";try{await run()}finally{pb.disabled=false;pb.textContent="↻ Watch again"}}})();
</script>
</div>
-
```
…