loop-canvas 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -4,6 +4,6 @@ A canvas of live screens for your coding agent. Point at anything, draw on it, c
4
4
 
5
5
  Ask your agent:
6
6
 
7
- > Run `npx skills add amalenezi/loop-skill -g -y`, then use the Loop canvas skill to put this project's screens on a canvas.
7
+ > Run `npx skills add amalenezi/loop-skill -g -y`, then use the Loop canvas skill to put this project on a canvas.
8
8
 
9
9
  Or by hand: `npm install -g loop-canvas`, then `loop scan` in your project.
package/cli.mjs CHANGED
@@ -1,14 +1,14 @@
1
1
  #!/usr/bin/env node
2
- import f from"node:fs";import c from"node:path";import G from"node:os";import{spawn as Z,execFileSync as J}from"node:child_process";import{fileURLToPath as ee}from"node:url";import w from"node:fs";import p from"node:path";import{spawn as X,execFileSync as I}from"node:child_process";var q=new Set(["node_modules",".git",".loop",".next",".nuxt",".svelte-kit",".output",".vercel","dist","build","out","coverage",".turbo",".cache"]);function S(e,t=6,o=[]){if(t<0||!w.existsSync(e))return o;for(let r of w.readdirSync(e,{withFileTypes:!0})){if(q.has(r.name)||r.name.startsWith("."))continue;let n=p.join(e,r.name);r.isDirectory()?S(n,t-1,o):o.push(n)}return o}var k=(e,...t)=>t.map(o=>p.join(e,o)).find(o=>w.existsSync(o)&&w.statSync(o).isDirectory()),z=e=>/^\[|^\$|^:|\*/.test(e);function T(e){let t=[];for(let o of e)if(!(!o||o==="index"||o==="_index")&&!(/^\(.*\)$/.test(o)||o.startsWith("@")||o.startsWith("_"))&&!/^\[\[\.\.\..+\]\]$/.test(o)){if(z(o))return null;t.push(o)}return"/"+t.join("/")}var F={"next-app":e=>{let t=k(e,"app","src/app");return t?S(t).filter(o=>/[\\/]page\.(t|j)sx?$|[\\/]page\.mdx$/.test(o)).map(o=>T(p.relative(t,p.dirname(o)).split(p.sep))):null},"next-pages":e=>{let t=k(e,"pages","src/pages");return t?S(t).filter(o=>/\.(t|j)sx?$|\.mdx$/.test(o)).map(o=>p.relative(t,o).replace(/\.(t|j)sx?$|\.mdx$/,"")).filter(o=>!o.startsWith("api")&&!/^_(app|document|error)$/.test(o)&&!/^(404|500)$/.test(o)).map(o=>T(o.split(p.sep))):null},sveltekit:e=>{let t=k(e,"src/routes");return t?S(t).filter(o=>/\+page\.svelte$/.test(o)).map(o=>T(p.relative(t,p.dirname(o)).split(p.sep))):null},nuxt:e=>{let t=k(e,"pages","app/pages");return t?S(t).filter(o=>o.endsWith(".vue")).map(o=>T(p.relative(t,o).replace(/\.vue$/,"").split(p.sep))):null},astro:e=>{let t=k(e,"src/pages");return t?S(t).filter(o=>/\.(astro|md|mdx|html)$/.test(o)).map(o=>T(p.relative(t,o).replace(/\.(astro|md|mdx|html)$/,"").split(p.sep))):null},remix:e=>{let t=k(e,"app/routes");return t?S(t,1).filter(o=>/\.(t|j)sx?$/.test(o)).map(o=>p.relative(t,o).replace(/\/route\.(t|j)sx?$|\.(t|j)sx?$/,"")).filter(o=>!/^(api|resources)\b/.test(o)&&!o.includes("[.")).map(o=>T(o.split("."))):null},spa:e=>{let t=k(e,"src","app")||e,o=new Set(["/"]),r=[/\bpath\s*:\s*["'`]([^"'`]*)["'`]/g,/<Route\b[^>]*\bpath=["']([^"']*)["']/g,/createRoute\([^)]*path\s*:\s*["']([^"']*)["']/g];for(let n of S(t).filter(s=>/\.(t|j)sx?$|\.vue$/.test(s)&&!/\.(test|spec|stories)\./.test(s)).slice(0,2e3)){let s;try{s=w.readFileSync(n,"utf8")}catch{continue}if(!(s.length>4e5))for(let l of r)for(let m of s.matchAll(l)){let g=m[1].trim();g===""||g.includes(":")||g.includes("*")||g.includes("$")||/\s/.test(g)||g.length>80||!g.startsWith("/")&&/\.\w{2,4}$/.test(g)||o.add("/"+g.replace(/^\/+/,""))}}return[...o]}};function W(e){let t=null;try{t=JSON.parse(w.readFileSync(p.join(e,"package.json"),"utf8"))}catch{}let o={...t?.dependencies||{},...t?.devDependencies||{}},r=i=>i in o,n=null,s=null,l=null;r("next")?(n="Next.js",s=k(e,"app","src/app")?"next-app":"next-pages",l=3e3):r("@sveltejs/kit")?(n="SvelteKit",s="sveltekit",l=5173):r("nuxt")?(n="Nuxt",s="nuxt",l=3e3):r("astro")?(n="Astro",s="astro",l=4321):r("@remix-run/react")||r("@remix-run/dev")?(n="Remix",s="remix",l=5173):r("@angular/core")?(n="Angular",s="spa",l=4200):r("react-router")||r("react-router-dom")||r("@tanstack/react-router")||r("vue-router")?(n="SPA",s="spa",l=r("vite")?5173:3e3):r("vite")?(n="Vite",s="spa",l=5173):r("react-scripts")?(n="Create React App",s="spa",l=3e3):(r("expo")||r("react-native"))&&(n="React Native");let m=[],g=0;if(s){let i=[...F[s](e)||[]];s==="next-app"&&k(e,"pages","src/pages")&&i.push(...F["next-pages"](e)||[]),g=i.filter(h=>h==null).length,m=i.filter(h=>h!=null)}m=[...new Set(m)].sort((i,h)=>i==="/"?-1:h==="/"?1:i.split("/").length-h.split("/").length||i.localeCompare(h));let j=!s&&n!=="React Native"?S(e,4).filter(i=>i.endsWith(".html")).slice(0,60):[],v=t?.scripts||{},b=["dev","start","serve"].find(i=>v[i]),_=w.existsSync(p.join(e,"pnpm-lock.yaml"))?"pnpm":w.existsSync(p.join(e,"yarn.lock"))?"yarn":w.existsSync(p.join(e,"bun.lockb"))||w.existsSync(p.join(e,"bun.lock"))?"bun":"npm";return{framework:n,router:s,routes:m,dynamic:g,html:j,port:l,script:b,pm:_,hasPackage:!!t}}function N(e){return e==="/"?"Home":e.split("/").filter(Boolean).map(t=>t.replace(/[-_]+/g," ").replace(/^\w/,o=>o.toUpperCase())).join(" / ")}async function V(e){try{return(await fetch(`http://localhost:${e}/__loop/api/ping`,{signal:AbortSignal.timeout(800)})).ok}catch{return!1}}async function D(e){try{return(await fetch(e,{signal:AbortSignal.timeout(1200),redirect:"manual"})).status<500}catch{return!1}}async function M(e,t,{url:o,log:r=console.error}={}){try{e=w.realpathSync(e)}catch{}if(o)return{url:o.replace(/\/$/,""),started:!1};for(let v of Y())if(v.cwd&&(v.cwd===e||v.cwd.startsWith(e+p.sep))&&!await V(v.port)&&await D(`http://localhost:${v.port}`))return{url:`http://localhost:${v.port}`,started:!1,reused:!0};if(!t.script)return null;let n=p.join(e,".loop");w.mkdirSync(n,{recursive:!0});let s=p.join(n,"dev.log");w.writeFileSync(s,"");let l=w.openSync(s,"a"),m=t.pm==="pnpm"&&!Q("pnpm")?["corepack",["pnpm","run",t.script]]:[t.pm,["run",t.script]];r(`starting the dev server: ${m[0]} ${m[1].join(" ")} (log: .loop/dev.log)`);let g=X(m[0],m[1],{cwd:e,detached:!0,stdio:["ignore",l,l],env:{...process.env,BROWSER:"none",FORCE_COLOR:"0"}});g.unref(),w.writeFileSync(p.join(n,"dev.json"),JSON.stringify({pid:g.pid,cmd:m.flat().join(" ")}));let j=Date.now()+12e4;for(;Date.now()<j;){await new Promise(_=>setTimeout(_,700));let v=w.readFileSync(s,"utf8").replace(/\x1b\[[0-9;]*m/g,""),b=v.match(/https?:\/\/(?:localhost|127\.0\.0\.1|\[::1\]|0\.0\.0\.0):(\d+)/);if(b&&await D(`http://localhost:${b[1]}`))return{url:`http://localhost:${b[1]}`,started:!0,pid:g.pid};try{process.kill(g.pid,0)}catch{throw new Error(`the dev server exited \u2014 see .loop/dev.log:
3
- ${v.split(`
2
+ import u from"node:fs";import i from"node:path";import A from"node:os";import{spawn as te,execFileSync as B}from"node:child_process";import{fileURLToPath as oe}from"node:url";import g from"node:fs";import m from"node:path";import{spawn as q,execFileSync as M}from"node:child_process";var V=new Set(["node_modules",".git",".loop",".next",".nuxt",".svelte-kit",".output",".vercel","dist","build","out","coverage",".turbo",".cache"]);function j(e,t=6,o=[]){if(t<0||!g.existsSync(e))return o;for(let r of g.readdirSync(e,{withFileTypes:!0})){if(V.has(r.name)||r.name.startsWith("."))continue;let n=m.join(e,r.name);r.isDirectory()?j(n,t-1,o):o.push(n)}return o}var b=(e,...t)=>t.map(o=>m.join(e,o)).find(o=>g.existsSync(o)&&g.statSync(o).isDirectory()),Y=e=>/^\[|^\$|^:|\*/.test(e);function O(e){let t=[];for(let o of e)if(!(!o||o==="index"||o==="_index")&&!(/^\(.*\)$/.test(o)||o.startsWith("@")||o.startsWith("_"))&&!/^\[\[\.\.\..+\]\]$/.test(o)){if(Y(o))return null;t.push(o)}return"/"+t.join("/")}var W={"next-app":e=>{let t=b(e,"app","src/app");return t?j(t).filter(o=>/[\\/]page\.(t|j)sx?$|[\\/]page\.mdx$/.test(o)).map(o=>O(m.relative(t,m.dirname(o)).split(m.sep))):null},"next-pages":e=>{let t=b(e,"pages","src/pages");return t?j(t).filter(o=>/\.(t|j)sx?$|\.mdx$/.test(o)).map(o=>m.relative(t,o).replace(/\.(t|j)sx?$|\.mdx$/,"")).filter(o=>!o.startsWith("api")&&!/^_(app|document|error)$/.test(o)&&!/^(404|500)$/.test(o)).map(o=>O(o.split(m.sep))):null},sveltekit:e=>{let t=b(e,"src/routes");return t?j(t).filter(o=>/\+page\.svelte$/.test(o)).map(o=>O(m.relative(t,m.dirname(o)).split(m.sep))):null},nuxt:e=>{let t=b(e,"pages","app/pages");return t?j(t).filter(o=>o.endsWith(".vue")).map(o=>O(m.relative(t,o).replace(/\.vue$/,"").split(m.sep))):null},astro:e=>{let t=b(e,"src/pages");return t?j(t).filter(o=>/\.(astro|md|mdx|html)$/.test(o)).map(o=>O(m.relative(t,o).replace(/\.(astro|md|mdx|html)$/,"").split(m.sep))):null},remix:e=>{let t=b(e,"app/routes");return t?j(t,1).filter(o=>/\.(t|j)sx?$/.test(o)).map(o=>m.relative(t,o).replace(/\/route\.(t|j)sx?$|\.(t|j)sx?$/,"")).filter(o=>!/^(api|resources)\b/.test(o)&&!o.includes("[.")).map(o=>O(o.split("."))):null},spa:e=>{let t=b(e,"src","app")||e,o=new Set(["/"]),r=[/\bpath\s*:\s*["'`]([^"'`]*)["'`]/g,/<Route\b[^>]*\bpath=["']([^"']*)["']/g,/createRoute\([^)]*path\s*:\s*["']([^"']*)["']/g];for(let n of j(t).filter(a=>/\.(t|j)sx?$|\.vue$/.test(a)&&!/\.(test|spec|stories)\./.test(a)).slice(0,2e3)){let a;try{a=g.readFileSync(n,"utf8")}catch{continue}if(!(a.length>4e5))for(let c of r)for(let h of a.matchAll(c)){let f=h[1].trim();f===""||f.includes(":")||f.includes("*")||f.includes("$")||/\s/.test(f)||f.length>80||!f.startsWith("/")&&/\.\w{2,4}$/.test(f)||o.add("/"+f.replace(/^\/+/,""))}}return[...o]}};function U(e){let t=null;try{t=JSON.parse(g.readFileSync(m.join(e,"package.json"),"utf8"))}catch{}let o={...t?.dependencies||{},...t?.devDependencies||{}},r=l=>l in o,n=null,a=null,c=null;r("next")?(n="Next.js",a=b(e,"app","src/app")?"next-app":"next-pages",c=3e3):r("@sveltejs/kit")?(n="SvelteKit",a="sveltekit",c=5173):r("nuxt")?(n="Nuxt",a="nuxt",c=3e3):r("astro")?(n="Astro",a="astro",c=4321):r("@remix-run/react")||r("@remix-run/dev")?(n="Remix",a="remix",c=5173):r("@angular/core")?(n="Angular",a="spa",c=4200):r("react-router")||r("react-router-dom")||r("@tanstack/react-router")||r("vue-router")?(n="SPA",a="spa",c=r("vite")?5173:3e3):r("vite")?(n="Vite",a="spa",c=5173):r("react-scripts")?(n="Create React App",a="spa",c=3e3):(r("expo")||r("react-native"))&&(n="React Native");let h=[],f=0;if(a){let l=[...W[a](e)||[]];a==="next-app"&&b(e,"pages","src/pages")&&l.push(...W["next-pages"](e)||[]),f=l.filter($=>$==null).length,h=l.filter($=>$!=null)}h=[...new Set(h)].sort((l,$)=>l==="/"?-1:$==="/"?1:l.split("/").length-$.split("/").length||l.localeCompare($));let S=!a&&n!=="React Native"?j(e,4).filter(l=>l.endsWith(".html")).slice(0,60):[],w=t?.scripts||{},_=["dev","start","serve"].find(l=>w[l]),T=g.existsSync(m.join(e,"pnpm-lock.yaml"))?"pnpm":g.existsSync(m.join(e,"yarn.lock"))?"yarn":g.existsSync(m.join(e,"bun.lockb"))||g.existsSync(m.join(e,"bun.lock"))?"bun":"npm";return{framework:n,router:a,routes:h,dynamic:f,html:S,port:c,script:_,pm:T,hasPackage:!!t}}function R(e){return e==="/"?"Home":e.split("/").filter(Boolean).map(t=>t.replace(/[-_]+/g," ").replace(/^\w/,o=>o.toUpperCase())).join(" / ")}async function Q(e){try{return(await fetch(`http://localhost:${e}/__loop/api/ping`,{signal:AbortSignal.timeout(800)})).ok}catch{return!1}}async function G(e){try{return(await fetch(e,{signal:AbortSignal.timeout(1200),redirect:"manual"})).status<500}catch{return!1}}async function H(e,t,{url:o,log:r=console.error}={}){try{e=g.realpathSync(e)}catch{}if(o)return{url:o.replace(/\/$/,""),started:!1};for(let w of Z())if(w.cwd&&(w.cwd===e||w.cwd.startsWith(e+m.sep))&&!await Q(w.port)&&await G(`http://localhost:${w.port}`))return{url:`http://localhost:${w.port}`,started:!1,reused:!0};if(!t.script)return null;let n=m.join(e,".loop");g.mkdirSync(n,{recursive:!0});let a=m.join(n,"dev.log");g.writeFileSync(a,"");let c=g.openSync(a,"a"),h=t.pm==="pnpm"&&!ee("pnpm")?["corepack",["pnpm","run",t.script]]:[t.pm,["run",t.script]];r(`starting the dev server: ${h[0]} ${h[1].join(" ")} (log: .loop/dev.log)`);let f=q(h[0],h[1],{cwd:e,detached:!0,stdio:["ignore",c,c],env:{...process.env,BROWSER:"none",FORCE_COLOR:"0"}});f.unref(),g.writeFileSync(m.join(n,"dev.json"),JSON.stringify({pid:f.pid,cmd:h.flat().join(" ")}));let S=Date.now()+12e4;for(;Date.now()<S;){await new Promise(T=>setTimeout(T,700));let w=g.readFileSync(a,"utf8").replace(/\x1b\[[0-9;]*m/g,""),_=w.match(/https?:\/\/(?:localhost|127\.0\.0\.1|\[::1\]|0\.0\.0\.0):(\d+)/);if(_&&await G(`http://localhost:${_[1]}`))return{url:`http://localhost:${_[1]}`,started:!0,pid:f.pid};try{process.kill(f.pid,0)}catch{throw new Error(`the dev server exited \u2014 see .loop/dev.log:
3
+ ${w.split(`
4
4
  `).slice(-12).join(`
5
- `)}`)}}throw new Error("the dev server took more than 2 minutes to start \u2014 see .loop/dev.log")}function Y(){try{let e=I("lsof",["-nP","-iTCP","-sTCP:LISTEN","-Fpn"],{encoding:"utf8",stdio:["ignore","pipe","ignore"]}),t=new Map,o=null;for(let n of e.split(`
6
- `))if(n[0]==="p")o=n.slice(1);else if(n[0]==="n"&&o){let s=n.match(/:(\d+)$/);s&&(t.get(o)||t.set(o,new Set).get(o)).add(+s[1])}let r=[];for(let[n,s]of t){let l=null;try{l=I("lsof",["-a","-p",n,"-d","cwd","-Fn"],{encoding:"utf8",stdio:["ignore","pipe","ignore"]}).split(`
7
- `).find(m=>m[0]==="n")?.slice(1)||null}catch{}if(l)try{l=w.realpathSync(l)}catch{}for(let m of s)m>=1024&&m!==4848&&r.push({port:m,pid:+n,cwd:l})}return r}catch{return[]}}function Q(e){return(process.env.PATH||"").split(":").some(t=>{try{return w.accessSync(p.join(t,e),w.constants.X_OK),!0}catch{return!1}})}var O=c.dirname(f.realpathSync(ee(import.meta.url))),[te="help",...oe]=process.argv.slice(2),{flags:a,pos:d}=re(oe),ne=`loop \u2014 a canvas of live frames you can draw on, point at, and comment on.
5
+ `)}`)}}throw new Error("the dev server took more than 2 minutes to start \u2014 see .loop/dev.log")}function Z(){try{let e=M("lsof",["-nP","-iTCP","-sTCP:LISTEN","-Fpn"],{encoding:"utf8",stdio:["ignore","pipe","ignore"]}),t=new Map,o=null;for(let n of e.split(`
6
+ `))if(n[0]==="p")o=n.slice(1);else if(n[0]==="n"&&o){let a=n.match(/:(\d+)$/);a&&(t.get(o)||t.set(o,new Set).get(o)).add(+a[1])}let r=[];for(let[n,a]of t){let c=null;try{c=M("lsof",["-a","-p",n,"-d","cwd","-Fn"],{encoding:"utf8",stdio:["ignore","pipe","ignore"]}).split(`
7
+ `).find(h=>h[0]==="n")?.slice(1)||null}catch{}if(c)try{c=g.realpathSync(c)}catch{}for(let h of a)h>=1024&&h!==4848&&r.push({port:h,pid:+n,cwd:c})}return r}catch{return[]}}function ee(e){return(process.env.PATH||"").split(":").some(t=>{try{return g.accessSync(m.join(t,e),g.constants.X_OK),!0}catch{return!1}})}var P=i.dirname(u.realpathSync(oe(import.meta.url))),[ne="help",...re]=process.argv.slice(2),{flags:s,pos:p}=ae(re),se=`loop \u2014 a canvas of live frames you can draw on, point at, and comment on.
8
8
  Comments go to your agent; the frame shows it working and reloads when it's done.
9
9
 
10
10
  loop open start the canvas for this project and open it
11
- loop scan [--url --mobile --landscape --both --w W --h H --limit N]
11
+ loop scan [--url --mobile --landscape --both --w W --h H] [--all --limit N]
12
12
  find every screen in this project and put it on the canvas
13
13
  (starts the dev server if needed; pages render live, element-pickable)
14
14
  loop add-route </path> [--name] add one app route with real values, e.g. /posts/hello-world
@@ -17,6 +17,7 @@ Comments go to your agent; the frame shows it working and reloads when it's done
17
17
  place a folder, an HTML file, or a running page (http://localhost:3000/x)
18
18
  loop create "<brief>" [--name] have the agent build a brand-new frame from a prompt
19
19
  loop list frames, their folders and status
20
+ loop name "<your name>" the name shown on your cursor and comments (default: your computer account name)
20
21
  loop rm <frameId> remove a frame from the canvas (files stay)
21
22
  loop share [--public] print the share link (LAN; --public opens a cloudflared tunnel)
22
23
  loop agent headless|inbox headless: Loop runs the agent that launched it (Claude Code or Codex) on each comment
@@ -30,11 +31,11 @@ Comments go to your agent; the frame shows it working and reloads when it's done
30
31
  loop stop stop the canvas server
31
32
  loop install-skill install the Claude Code skill (~/.claude/skills/loop-canvas)
32
33
 
33
- Options: --dir <path> uses that .loop folder instead of ./.loop (searched upward).`;function re(e){let t={},o=[];for(let r=0;r<e.length;r++)if(e[r].startsWith("--")){let n=e[r].slice(2);t[n]=e[r+1]&&!e[r+1].startsWith("--")?e[++r]:!0}else o.push(e[r]);return{flags:t,pos:o}}function se(){if(a.dir)return c.resolve(a.dir);let e=process.cwd();for(;;){if(f.existsSync(c.join(e,".loop","canvas.json"))||f.existsSync(c.join(e,".loop","server.json")))return c.join(e,".loop");let t=c.dirname(e);if(t===e)return c.join(process.cwd(),".loop");e=t}}var x=se();async function R(e){try{return(await fetch(`http://127.0.0.1:${e}/__loop/api/ping`,{signal:AbortSignal.timeout(800)})).ok}catch{return!1}}function L(){try{return JSON.parse(f.readFileSync(c.join(x,"server.json"),"utf8"))}catch{return null}}function ae(){let e=String(a.agent||process.env.LOOP_AGENT||"").toLowerCase();if(e.includes("codex"))return"codex";if(e.includes("claude"))return"claude";let t=Object.keys(process.env);if(process.env.CLAUDECODE||process.env.CLAUDE_CODE_ENTRYPOINT)return"claude";if(t.some(o=>o.startsWith("CODEX_")))return"codex";try{let o=process.ppid;for(let r=0;r<14&&o>1;r++){let n=J("ps",["-o","ppid=,command=","-p",String(o)],{encoding:"utf8",stdio:["ignore","pipe","ignore"]}).trim(),s=/^(\d+)\s+(.*)$/.exec(n);if(!s)break;let l=s[2].toLowerCase();if(/(^|\/)codex(\s|$)|codex-cli|codex\.app/.test(l))return"codex";if(/(^|\/)claude(\s|$)|claude-code|claude\.app/.test(l))return"claude";o=+s[1]}}catch{}return null}var H=!1;async function P(){if(H)return;H=!0;let e=ae();if(e)try{await u("POST","/__loop/api/settings",{runner:e})}catch{}}function ie(){return(process.env.PATH||"").split(":").some(e=>{try{return f.realpathSync(c.join(e,"loop"))===f.realpathSync(c.join(O,"cli.mjs"))}catch{return!1}})}async function E(){let e=L();if(e&&await R(e.port))return e.port;f.mkdirSync(x,{recursive:!0}),ce();let t=f.openSync(c.join(x,"server.log"),"a"),o=Z(process.execPath,[c.join(O,"server.mjs"),"--dir",x,...a.port?["--port",String(a.port)]:[]],{detached:!0,stdio:["ignore",t,t]});o.unref();for(let r=0;r<50;r++){await new Promise(s=>setTimeout(s,100));let n=L();if(n&&n.pid===o.pid&&await R(n.port))return n.port}throw new Error(`Loop server didn't start \u2014 see ${c.join(x,"server.log")}`)}function ce(){let e=c.join(x,".gitignore");f.existsSync(e)||f.writeFileSync(e,`server.json
34
+ Options: --dir <path> uses that .loop folder instead of ./.loop (searched upward).`;function ae(e){let t={},o=[];for(let r=0;r<e.length;r++)if(e[r].startsWith("--")){let n=e[r].slice(2);t[n]=e[r+1]&&!e[r+1].startsWith("--")?e[++r]:!0}else o.push(e[r]);return{flags:t,pos:o}}function ie(){if(s.dir)return i.resolve(s.dir);let e=process.cwd();for(;;){if(u.existsSync(i.join(e,".loop","canvas.json"))||u.existsSync(i.join(e,".loop","server.json")))return i.join(e,".loop");let t=i.dirname(e);if(t===e)return i.join(process.cwd(),".loop");e=t}}var k=ie();async function D(e){try{return(await fetch(`http://127.0.0.1:${e}/__loop/api/ping`,{signal:AbortSignal.timeout(800)})).ok}catch{return!1}}function N(){try{return JSON.parse(u.readFileSync(i.join(k,"server.json"),"utf8"))}catch{return null}}function le(){let e=String(s.agent||process.env.LOOP_AGENT||"").toLowerCase();if(e.includes("codex"))return"codex";if(e.includes("claude"))return"claude";let t=Object.keys(process.env);if(process.env.CLAUDECODE||process.env.CLAUDE_CODE_ENTRYPOINT)return"claude";if(t.some(o=>o.startsWith("CODEX_")))return"codex";try{let o=process.ppid;for(let r=0;r<14&&o>1;r++){let n=B("ps",["-o","ppid=,command=","-p",String(o)],{encoding:"utf8",stdio:["ignore","pipe","ignore"]}).trim(),a=/^(\d+)\s+(.*)$/.exec(n);if(!a)break;let c=a[2].toLowerCase();if(/(^|\/)codex(\s|$)|codex-cli|codex\.app/.test(c))return"codex";if(/(^|\/)claude(\s|$)|claude-code|claude\.app/.test(c))return"claude";o=+a[1]}}catch{}return null}function ce(){let e={runner:"claude",effort:process.env.CLAUDE_EFFORT||void 0};try{let t=process.env.CLAUDE_CODE_SESSION_ID,o=i.join(A.homedir(),".claude","projects");if(!t||!/^[\w-]+$/.test(t))return e;for(let r of u.readdirSync(o)){let n=i.join(o,r,`${t}.jsonl`);if(!u.existsSync(n))continue;let a=u.statSync(n).size,c=Math.min(a,4e5),h=Buffer.alloc(c),f=u.openSync(n,"r");u.readSync(f,h,0,c,a-c),u.closeSync(f);let S=[...h.toString("utf8").matchAll(/"model":"(claude-[\w.-]+)"/g)];S.length&&(e.model=S[S.length-1][1]);break}}catch{}return e}var J=!1;async function L(){if(J)return;J=!0;let e=le();if(e)try{await d("POST","/__loop/api/settings",{runner:e,...e==="claude"&&process.env.CLAUDECODE?{mode:"inbox",chat:ce()}:{}})}catch{}}function pe(){return(process.env.PATH||"").split(":").some(e=>{try{return u.realpathSync(i.join(e,"loop"))===u.realpathSync(i.join(P,"cli.mjs"))}catch{return!1}})}async function E(){let e=N();if(e&&await D(e.port))return e.port;u.mkdirSync(k,{recursive:!0}),de();let t=u.openSync(i.join(k,"server.log"),"a"),o=te(process.execPath,[i.join(P,"server.mjs"),"--dir",k,...s.port?["--port",String(s.port)]:[]],{detached:!0,stdio:["ignore",t,t]});o.unref();for(let r=0;r<50;r++){await new Promise(a=>setTimeout(a,100));let n=N();if(n&&n.pid===o.pid&&await D(n.port))return n.port}throw new Error(`Loop server didn't start \u2014 see ${i.join(k,"server.log")}`)}function de(){let e=i.join(k,".gitignore");u.existsSync(e)||u.writeFileSync(e,`server.json
34
35
  server.log
35
36
  history/
36
37
  annotations/
37
38
  *.tmp
38
- `)}async function u(e,t,o){let r=await E(),n=await fetch(`http://127.0.0.1:${r}${t}`,{method:e,headers:{"content-type":"application/json"},body:o?JSON.stringify(o):void 0}),s=await n.json().catch(()=>({}));if(!n.ok)throw new Error(s.error||`HTTP ${n.status}`);return s}var y=e=>e==null||e===!0?void 0:+e;function U(e){try{J(process.platform==="darwin"?"open":"xdg-open",[e],{stdio:"ignore"})}catch{}}async function le(){switch(te){case"open":case"start":{let e=await E();await P();let t=`http://localhost:${e}/__loop/`;console.log(`Loop canvas \u25B8 ${t}`),a["no-open"]||U(t);break}case"new":{await E(),await P();let e=d.join(" ")||"Untitled",t=await u("POST","/__loop/api/frames",{new:!0,name:e,w:y(a.w),h:y(a.h),x:y(a.x),y:y(a.y),near:a.near});console.log(t.dir),console.error(`frame ${t.id} "${t.name}" \u2014 write ${c.join(t.dir,"index.html")}; the canvas reloads it live`);break}case"add":{if(!d[0])throw new Error("usage: loop add <path|url> [--name ...]");let e=/^https?:\/\//.test(d[0])?d[0]:c.resolve(d[0]),t=await u("POST","/__loop/api/frames",{src:e,name:a.name,w:y(a.w),h:y(a.h),x:y(a.x),y:y(a.y)});console.log(`added ${t.id} "${t.name}" (${t.kind}: ${t.src})`);break}case"create":{let e=d.join(" ");if(!e)throw new Error('usage: loop create "<brief>"');let t=await u("POST","/__loop/api/frames",{prompt:e,name:a.name,w:y(a.w),h:y(a.h)});console.log(`frame ${t.id} "${t.name}" \u2014 the agent is building it in ${t.dir}`);break}case"list":case"ls":{let e=await u("GET","/__loop/api/state");if(!e.frames.length)return console.log("No frames yet.");for(let t of e.frames){let o=e.live[t.id],r=e.comments.filter(n=>n.frameId===t.id&&["queued","waiting","working"].includes(n.status)).length;console.log(`${t.id} ${t.name.padEnd(28)} ${o?`\u27F3 ${o.step}`:r?`${r} open`:"\xB7"} ${t.src}`)}break}case"rm":await u("DELETE",`/__loop/api/frames/${d[0]}`),console.log("removed");break;case"share":{let e=(await u("GET","/__loop/api/state")).share;a.public&&(e=await u("POST","/__loop/api/share/public")),e.lan&&console.log(`Same network: ${e.lan}`),e.public?console.log(`Public: ${e.public}`):a.public||console.log(e.tunnelAvailable?"Public link: loop share --public":"Public link: brew install cloudflared, then loop share --public");break}case"agent":{if(!["headless","inbox"].includes(d[0]))throw new Error("usage: loop agent headless|inbox");await u("POST","/__loop/api/settings",{mode:d[0]}),console.log(`agent mode: ${d[0]}`);break}case"watch":{await E(),await P(),await u("POST","/__loop/api/settings",{mode:"inbox"});let e=c.join(x,"inbox");f.mkdirSync(e,{recursive:!0});let t=ie()?"loop":`node ${c.join(O,"cli.mjs")}`;for(console.log("Loop is sending this canvas's comments to this chat. Each comment arrives as a line starting with COMMENT.");;){let o;try{o=await u("GET","/__loop/api/inbox?wait=1")}catch{await new Promise(n=>setTimeout(n,2e3));continue}if(!o.comment)continue;let r=c.join(e,`${o.comment.id}.md`);f.writeFileSync(r,o.prompt),console.log(`COMMENT ${o.comment.id} on "${o.frame.name}": ${JSON.stringify(o.comment.text)} | full instructions: ${r} | when done: ${t} reply ${o.comment.id} "<one sentence on what you changed>" --model <your model id>`)}}case"note":{if(!d[0]||!d[1])throw new Error('usage: loop note <commentId> "<message>" [--model <id>] (adds your message to that comment thread on the canvas)');await u("POST",`/__loop/api/comments/${d[0]}/note`,{text:d.slice(1).join(" "),model:a.model}),console.log("noted on the canvas");break}case"thread":{let e=await u("GET","/__loop/api/state"),t=e.comments.find(r=>r.id===d[0]);if(!t)throw new Error("no such comment");let o=t.parentId||t.id;for(let r of e.comments.filter(n=>n.id===o||n.parentId===o).sort((n,s)=>n.createdAt-s.createdAt))console.log(`[${r.id}] ${r.author?.agent?"Agent":r.author?.name||"User"}: ${r.text}${r.reply?`
39
- \u21B3 ${r.reply}`:""}`);break}case"inbox":{let e=await u("GET",`/__loop/api/inbox${a.wait?"?wait=1":""}`);console.log(JSON.stringify(e,null,2));break}case"step":await u("POST",`/__loop/api/comments/${d[0]}/step`,{text:d.slice(1).join(" ")});break;case"reply":{await u("POST",`/__loop/api/comments/${d[0]}/reply`,{text:d.slice(1).join(" ")||"Done.",error:!!a.error,model:a.model}),console.log("replied");break}case"add-route":{if(!d[0])throw new Error("usage: loop add-route </path> [--name ...] (needs a dev server \u2014 run loop scan first)");if(!(await u("GET","/__loop/api/state")).proxy)throw new Error("no dev server is connected yet \u2014 run loop scan (or loop scan --url http://localhost:PORT) first");let t=await u("POST","/__loop/api/frames",{route:d[0],name:a.name||N(d[0]),w:y(a.w),h:y(a.h),near:a.near});console.log(`added ${t.id} "${t.name}" (route ${t.src})`);break}case"scan":{let e=c.dirname(x);await E(),await P();let t=W(e);if(t.framework==="React Native")throw new Error("this looks like a React Native app \u2014 it can't render in a browser canvas yet");console.log(`${t.framework||(t.html.length?"Static HTML":"No framework found")} \xB7 ${t.routes.length||t.html.length} screen${(t.routes.length||t.html.length)===1?"":"s"}${t.dynamic?` (+${t.dynamic} that need a URL parameter, skipped)`:""}`),await E();let o=await u("GET","/__loop/api/state"),n=(y(a.w)&&y(a.h)?[[y(a.w),y(a.h)]]:null)||(a.landscape?[[852,393]]:a.mobile?[[393,852]]:a.both?[[1440,1024],[393,852]]:[[1440,1024]]),s=Math.max(...n.map(i=>i[0]))+(n.length>1?n[1][0]+80:0),l=Math.max(...n.map(i=>i[1])),m=+a.cols||(n[0][0]<600?6:4),g=o.frames.length?Math.max(...o.frames.map(i=>i.y+i.h))+280:0,j=+a.limit||40,v=0,b=(i,h)=>({x:i%m*(s+160)+(h?n[0][0]+80:0),y:g+Math.floor(i/m)*(l+220)});if(t.routes.length){let i=await M(e,t,{url:a.url});if(!i)throw new Error("couldn't find or start a dev server. Start it yourself, then run: loop scan --url http://localhost:<port>");i.reused&&console.log(`using this project's dev server at ${i.url}`),await u("POST","/__loop/api/settings",{proxy:i.url});let h=new Set(o.frames.filter($=>$.kind==="route").map($=>`${$.src}@${$.w}`));t.routes.slice(0,j).forEach(($,K)=>n.forEach(([C,B],A)=>{h.has(`${$}@${C}`)||(v++,u("POST","/__loop/api/frames",{route:$,name:N($)+(n.length>1?A?" \xB7 mobile":" \xB7 desktop":""),w:C,h:B,...b(K,A)}))})),t.routes.length>j&&console.log(`showing the first ${j} \u2014 pass --limit ${t.routes.length} for all`)}else if(t.html.length){let i=new Set(o.frames.filter(h=>h.kind==="folder").map(h=>c.join(h.src,h.entry)));t.html.slice(0,j).forEach((h,$)=>{i.has(h)||(v++,u("POST","/__loop/api/frames",{src:h,name:c.relative(e,h),w:n[0][0],h:n[0][1],...b($,0)}))})}else console.log('Nothing to scan here. Ask your agent to create frames (loop new "<name>"), or pass --url for a running app.');await new Promise(i=>setTimeout(i,300));let _=L().port;console.log(`added ${v} frame${v===1?"":"s"} \u25B8 http://localhost:${_}/__loop/`),!a["no-open"]&&v&&U(`http://localhost:${_}/__loop/`);break}case"stop":{let e=L();e&&await R(e.port)?(await fetch(`http://127.0.0.1:${e.port}/__loop/api/shutdown`,{method:"POST"}).catch(()=>{}),console.log("stopped")):console.log("not running");try{let t=JSON.parse(f.readFileSync(c.join(x,"dev.json"),"utf8"));process.kill(-t.pid,"SIGTERM"),f.rmSync(c.join(x,"dev.json")),console.log("stopped the dev server Loop started")}catch{}break}case"install-skill":{let e=c.join(G.homedir(),".claude","skills","loop-canvas");f.mkdirSync(e,{recursive:!0}),f.copyFileSync(c.join(O,"skills","loop-canvas","SKILL.md"),c.join(e,"SKILL.md"));let t=c.join(G.homedir(),".local","bin","loop");try{f.mkdirSync(c.dirname(t),{recursive:!0});try{f.unlinkSync(t)}catch{}f.symlinkSync(c.join(O,"cli.mjs"),t),f.chmodSync(c.join(O,"cli.mjs"),493)}catch(o){console.error(`(couldn't link ${t}: ${o.message})`)}console.log(`Skill installed \u2192 ${e}/SKILL.md
40
- CLI linked \u2192 ${t}`);break}default:console.log(ne)}}le().catch(e=>{console.error(`margin: ${e.message}`),process.exit(1)});
39
+ `)}async function d(e,t,o){let r=await E(),n=await fetch(`http://127.0.0.1:${r}${t}`,{method:e,headers:{"content-type":"application/json"},body:o?JSON.stringify(o):void 0}),a=await n.json().catch(()=>({}));if(!n.ok)throw new Error(a.error||`HTTP ${n.status}`);return a}var y=e=>e==null||e===!0?void 0:+e;function K(e){try{B(process.platform==="darwin"?"open":"xdg-open",[e],{stdio:"ignore"})}catch{}}async function ue(){switch(ne){case"open":case"start":{let e=await E();await L();let t=`http://localhost:${e}/__loop/`;console.log(`Loop canvas \u25B8 ${t}`),s["no-open"]||K(t);break}case"new":{await E(),await L();let e=p.join(" ")||"Untitled",t=await d("POST","/__loop/api/frames",{new:!0,name:e,w:y(s.w),h:y(s.h),x:y(s.x),y:y(s.y),near:s.near});console.log(t.dir),console.error(`frame ${t.id} "${t.name}" \u2014 write ${i.join(t.dir,"index.html")}; the canvas reloads it live`);break}case"add":{if(!p[0])throw new Error("usage: loop add <path|url> [--name ...]");let e=/^https?:\/\//.test(p[0])?p[0]:i.resolve(p[0]),t=await d("POST","/__loop/api/frames",{src:e,name:s.name,w:y(s.w),h:y(s.h),x:y(s.x),y:y(s.y)});console.log(`added ${t.id} "${t.name}" (${t.kind}: ${t.src})`);break}case"create":{let e=p.join(" ");if(!e)throw new Error('usage: loop create "<brief>"');let t=await d("POST","/__loop/api/frames",{prompt:e,name:s.name,w:y(s.w),h:y(s.h)});console.log(`frame ${t.id} "${t.name}" \u2014 the agent is building it in ${t.dir}`);break}case"list":case"ls":{let e=await d("GET","/__loop/api/state");if(!e.frames.length)return console.log("No frames yet.");for(let t of e.frames){let o=e.live[t.id],r=e.comments.filter(n=>n.frameId===t.id&&["queued","waiting","working"].includes(n.status)).length;console.log(`${t.id} ${t.name.padEnd(28)} ${o?`\u27F3 ${o.step}`:r?`${r} open`:"\xB7"} ${t.src}`)}break}case"rm":await d("DELETE",`/__loop/api/frames/${p[0]}`),console.log("removed");break;case"share":{let e=(await d("GET","/__loop/api/state")).share;s.public&&(e=await d("POST","/__loop/api/share/public")),e.lan&&console.log(`Same network: ${e.lan}`),e.public?console.log(`Public: ${e.public}`):s.public||console.log(e.tunnelAvailable?"Public link: loop share --public":"Public link: brew install cloudflared, then loop share --public");break}case"agent":{if(!["headless","inbox"].includes(p[0]))throw new Error("usage: loop agent headless|inbox");await d("POST","/__loop/api/settings",{mode:p[0]}),console.log(`agent mode: ${p[0]}`);break}case"watch":{await E(),await L(),await d("POST","/__loop/api/settings",{mode:"inbox"});let e=i.join(k,"inbox");u.mkdirSync(e,{recursive:!0});let t=pe()?"loop":`node ${i.join(P,"cli.mjs")}`;for(console.log("Loop is sending this canvas's comments to this chat. Each comment arrives as a line starting with COMMENT.");;){let o;try{o=await d("GET","/__loop/api/inbox?wait=1")}catch{await new Promise(n=>setTimeout(n,2e3));continue}if(!o.comment)continue;let r=i.join(e,`${o.comment.id}.md`);u.writeFileSync(r,o.prompt),console.log(`COMMENT ${o.comment.id} on "${o.frame.name}": ${JSON.stringify(o.comment.text)} | details (where they pointed, marks, attachments, a screenshot of the frame as they saw it): ${r} | say what you're doing as you go: ${t} step ${o.comment.id} "<a few words>" | check design work: ${t} shot ${o.frame.id} | when done: ${t} reply ${o.comment.id} "<what you changed>" --model <your model id>`)}}case"note":{if(!p[0]||!p[1])throw new Error('usage: loop note <commentId> "<message>" [--model <id>] (adds your message to that comment thread on the canvas)');await d("POST",`/__loop/api/comments/${p[0]}/note`,{text:p.slice(1).join(" "),model:s.model}),console.log("noted on the canvas");break}case"thread":{let e=await d("GET","/__loop/api/state"),t=e.comments.find(r=>r.id===p[0]);if(!t)throw new Error("no such comment");let o=t.parentId||t.id;for(let r of e.comments.filter(n=>n.id===o||n.parentId===o).sort((n,a)=>n.createdAt-a.createdAt))console.log(`[${r.id}] ${r.author?.agent?"Agent":r.author?.name||"User"}: ${r.text}${r.reply?`
40
+ \u21B3 ${r.reply}`:""}`);break}case"inbox":{let e=await d("GET",`/__loop/api/inbox${s.wait?"?wait=1":""}`);console.log(JSON.stringify(e,null,2));break}case"step":await d("POST",`/__loop/api/comments/${p[0]}/step`,{text:p.slice(1).join(" ")});break;case"shot":{if(!p[0])throw new Error("usage: loop shot <frameId>");let e=await d("POST",`/__loop/api/frames/${p[0]}/shot`,s.option?{option:s.option}:{});console.log(e.path);break}case"option":{if(!p[0])throw new Error('usage: loop option <commentId> "<short name>"');let e=await d("POST",`/__loop/api/comments/${p[0]}/option`,{name:p.slice(1).join(" ")});console.log(e.frame?`option ${e.id}: ${e.dir} is a full copy of the frame, already on the canvas as its own frame. Make this option's changes there (edit its files in place).`:`option ${e.id}: write the changed files into ${e.dir} (paths relative to ${e.root})`);break}case"reply":{await d("POST",`/__loop/api/comments/${p[0]}/reply`,{text:p.slice(1).join(" ")||"Done.",error:!!s.error,model:s.model}),console.log("replied");break}case"add-route":{if(!p[0])throw new Error("usage: loop add-route </path> [--name ...] (needs a dev server \u2014 run loop scan first)");if(!(await d("GET","/__loop/api/state")).proxy)throw new Error("no dev server is connected yet \u2014 run loop scan (or loop scan --url http://localhost:PORT) first");let t=await d("POST","/__loop/api/frames",{route:p[0],name:s.name||R(p[0]),w:y(s.w),h:y(s.h),near:s.near});console.log(`added ${t.id} "${t.name}" (route ${t.src})`);break}case"scan":{let e=i.dirname(k);await E(),await L();let t=U(e);if(t.framework==="React Native")throw new Error("this looks like a React Native app \u2014 it can't render in a browser canvas yet");console.log(`${t.framework||(t.html.length?"Static HTML":"No framework found")} \xB7 ${t.routes.length||t.html.length} screen${(t.routes.length||t.html.length)===1?"":"s"}${t.dynamic?` (+${t.dynamic} that need a URL parameter, skipped)`:""}`),await E();let o=await d("GET","/__loop/api/state"),n=(y(s.w)&&y(s.h)?[[y(s.w),y(s.h)]]:null)||(s.landscape?[[852,393]]:s.mobile?[[393,852]]:s.both?[[1440,1024],[393,852]]:[[1440,1024]]),a=Math.max(...n.map(l=>l[0]))+(n.length>1?n[1][0]+80:0),c=Math.max(...n.map(l=>l[1])),h=+s.cols||(n[0][0]<600?6:4),f=o.frames.length?Math.max(...o.frames.map(l=>l.y+l.h))+280:0,S=+s.limit||40,w=0,_=(l,$)=>({x:l%h*(a+160)+($?n[0][0]+80:0),y:f+Math.floor(l/h)*(c+220)});if(t.routes.length){let l=await H(e,t,{url:s.url});if(!l)throw new Error("couldn't find or start a dev server. Start it yourself, then run: loop scan --url http://localhost:<port>");l.reused&&console.log(`using this project's dev server at ${l.url}`),await d("POST","/__loop/api/settings",{proxy:l.url});let $=new Set(o.frames.filter(x=>x.kind==="route").map(x=>`${x.src}@${x.w}`)),v=t.routes.includes("/")?"/":t.routes[0],C=s.all?t.routes.slice(0,S):[v];!s.all&&t.routes.length>1&&(console.log(`placed the app as one live frame (${v}). Click around inside it; duplicate it (\u2318D or \u2325-drag the title) to keep a screen side by side.`),console.log(`other screens: ${t.routes.filter(x=>x!==v).slice(0,12).join(" ")}${t.routes.length>13?" \u2026":""}`),console.log("add one directly: loop add-route /path \xB7 every screen at once: loop scan --all")),C.forEach((x,z)=>n.forEach(([I,X],F)=>{$.has(`${x}@${I}`)||(w++,d("POST","/__loop/api/frames",{route:x,name:R(x)+(n.length>1?F?" \xB7 mobile":" \xB7 desktop":""),w:I,h:X,..._(z,F)}))})),s.all&&t.routes.length>S&&console.log(`showing the first ${S} \u2014 pass --limit ${t.routes.length} for all`)}else if(t.html.length){let l=new Set(o.frames.filter(v=>v.kind==="folder").map(v=>i.join(v.src,v.entry))),$=t.html.find(v=>/(^|\/)index\.html?$/i.test(i.relative(e,v))&&!i.relative(e,v).includes("/"))||t.html[0];!s.all&&t.html.length>1&&console.log(`placed ${i.relative(e,$)} as one frame. Click through it, or add another page with: loop add <file> \xB7 every page: loop scan --all`),(s.all?t.html.slice(0,S):[$]).forEach((v,C)=>{l.has(v)||(w++,d("POST","/__loop/api/frames",{src:v,name:i.relative(e,v),w:n[0][0],h:n[0][1],..._(C,0)}))})}else console.log('Nothing to scan here. Ask your agent to create frames (loop new "<name>"), or pass --url for a running app.');await new Promise(l=>setTimeout(l,300));let T=N().port;console.log(`added ${w} frame${w===1?"":"s"} \u25B8 http://localhost:${T}/__loop/`),!s["no-open"]&&w&&K(`http://localhost:${T}/__loop/`);break}case"name":{await E(),p[0]&&await d("POST","/__loop/api/settings",{hostName:p.join(" ")});let e=await d("GET","/__loop/api/state");console.log(`you appear on the canvas as "${e.hostName}"`);break}case"stop":{let e=N();e&&await D(e.port)?(await fetch(`http://127.0.0.1:${e.port}/__loop/api/shutdown`,{method:"POST"}).catch(()=>{}),console.log("stopped")):console.log("not running");try{let t=JSON.parse(u.readFileSync(i.join(k,"dev.json"),"utf8"));process.kill(-t.pid,"SIGTERM"),u.rmSync(i.join(k,"dev.json")),console.log("stopped the dev server Loop started")}catch{}break}case"install-skill":{let e=i.join(A.homedir(),".claude","skills","loop-canvas");u.mkdirSync(e,{recursive:!0}),u.copyFileSync(i.join(P,"skills","loop-canvas","SKILL.md"),i.join(e,"SKILL.md"));let t=i.join(A.homedir(),".local","bin","loop");try{u.mkdirSync(i.dirname(t),{recursive:!0});try{u.unlinkSync(t)}catch{}u.symlinkSync(i.join(P,"cli.mjs"),t),u.chmodSync(i.join(P,"cli.mjs"),493)}catch(o){console.error(`(couldn't link ${t}: ${o.message})`)}console.log(`Skill installed \u2192 ${e}/SKILL.md
41
+ CLI linked \u2192 ${t}`);break}default:console.log(se)}}ue().catch(e=>{console.error(`margin: ${e.message}`),process.exit(1)});
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "loop-canvas",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "A canvas of live screens you can point at, draw on and comment on. Comments go straight to your coding agent (Claude Code or Codex), which updates the screen.",
5
5
  "type": "module",
6
6
  "bin": {
7
- "loop": "./cli.mjs"
7
+ "loop": "cli.mjs"
8
8
  },
9
9
  "files": [
10
10
  "cli.mjs",
package/public/app.css CHANGED
@@ -1 +1 @@
1
- :root{--paper: #F4F3EF;--grid: #D6D3CA;--surface: #FFFFFF;--surface-2: #FAF9F6;--line: #E4E1D9;--line-strong: #CFCBC1;--ink: #17171A;--ink-2: #4A4945;--muted: #8B8880;--accent: #2F5BFF;--accent-soft: rgba(47, 91, 255, .12);--mark: #E5484D;--ok: #1F9D55;--shadow: 0 1px 2px rgba(23,23,26,.06), 0 8px 24px rgba(23,23,26,.08);--shadow-lg: 0 2px 6px rgba(23,23,26,.08), 0 18px 48px rgba(23,23,26,.14);--font: Inter, ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;--mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;color-scheme:light}@media(prefers-color-scheme:dark){:root:not([data-theme=light]){--paper: #141416;--grid: #2C2C30;--surface: #1D1D20;--surface-2: #232327;--line: #2E2E33;--line-strong: #3C3C42;--ink: #EDEDEA;--ink-2: #C4C3BE;--muted: #85847F;--accent: #6E8BFF;--accent-soft: rgba(110,139,255,.16);--shadow: 0 1px 2px rgba(0,0,0,.3), 0 8px 24px rgba(0,0,0,.35);--shadow-lg: 0 2px 6px rgba(0,0,0,.35), 0 18px 48px rgba(0,0,0,.5);color-scheme:dark}}:root[data-theme=dark]{--paper: #141416;--grid: #2C2C30;--surface: #1D1D20;--surface-2: #232327;--line: #2E2E33;--line-strong: #3C3C42;--ink: #EDEDEA;--ink-2: #C4C3BE;--muted: #85847F;--accent: #6E8BFF;--accent-soft: rgba(110,139,255,.16);color-scheme:dark}*{box-sizing:border-box}html,body{overscroll-behavior:none;margin:0;height:100%;overflow:hidden;background:var(--paper);color:var(--ink);font:13px/1.45 var(--font);-webkit-font-smoothing:antialiased}button{font:inherit;color:inherit;background:none;border:0;padding:0;cursor:pointer}input,textarea{font:inherit;color:inherit}kbd{font:500 10.5px/1 var(--mono);padding:2px 4px;border-radius:4px;border:1px solid var(--line);background:var(--surface-2);color:var(--ink-2)}code{font:12px/1.5 var(--mono)}.muted{color:var(--muted)}[hidden]{display:none!important}#viewport{position:fixed;inset:0;overflow:hidden;touch-action:none;user-select:none;background-color:var(--paper);background-image:radial-gradient(var(--grid) calc(var(--dot, 1px)),transparent 0);background-size:var(--gs, 24px) var(--gs, 24px);background-position:var(--gx, 0) var(--gy, 0)}#viewport[data-tool=hand],#viewport.panning{cursor:grab}#viewport.panning:active,#viewport.dragging{cursor:grabbing}#viewport[data-tool=pen],#viewport[data-tool=pen] .shield{cursor:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='32' height='32' viewBox='0 0 32 32'%3E%3Cpath d='M4.5 27.5l2.2-7.4L20.6 6.2a3.2 3.2 0 014.5 0l.7.7a3.2 3.2 0 010 4.5L11.9 25.3z' fill='%2317171A' stroke='white' stroke-width='2.2' stroke-linejoin='round'/%3E%3Cpath d='M18.3 8.5l5.2 5.2' stroke='white' stroke-width='1.8'/%3E%3Cpath d='M4.5 27.5l2.2-7.4 5.2 5.2z' fill='%23E5484D' stroke='white' stroke-width='1.4' stroke-linejoin='round'/%3E%3C/svg%3E") 4 28,crosshair}#viewport[data-tool=deep],#viewport[data-tool=deep] .shield{cursor:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='28' height='28' viewBox='0 0 28 28'%3E%3Crect x='11' y='11' width='13' height='13' rx='2' fill='rgba(47,91,255,.15)' stroke='%232F5BFF' stroke-width='1.6' stroke-dasharray='2.6 2.2'/%3E%3Cpath d='M3 3l10.5 5.4-4.4 1.4-1.9 4.2z' fill='%2317171A' stroke='white' stroke-width='1.4' stroke-linejoin='round'/%3E%3C/svg%3E") 3 3,default}#viewport[data-tool=comment]{cursor:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='26' height='26' viewBox='0 0 26 26'%3E%3Cpath d='M3 23V8a5 5 0 015-5h10a5 5 0 015 5v6a5 5 0 01-5 5H8z' fill='%232F5BFF' stroke='white' stroke-width='2'/%3E%3C/svg%3E") 3 23,crosshair}#viewport[data-tool=erase],#viewport[data-tool=erase] .shield,#viewport[data-tool=erase] #ink path{cursor:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='26' height='26' viewBox='0 0 26 26'%3E%3Ccircle cx='13' cy='13' r='11' fill='rgba(255,255,255,.35)' stroke='%2317171A' stroke-width='1.5'/%3E%3Ccircle cx='13' cy='13' r='12' fill='none' stroke='white' stroke-width='1'/%3E%3C/svg%3E") 13 13,cell}#world{position:absolute;left:0;top:0;transform-origin:0 0;will-change:transform}.frame{position:absolute}.frame-label{position:absolute;left:0;bottom:100%;display:flex;align-items:center;gap:6px;height:28px;padding:0 2px 6px;transform-origin:0 100%;scale:calc(1 / var(--z, 1));white-space:nowrap;color:var(--muted);font-weight:500;font-size:12.5px;cursor:default;max-width:max(calc(var(--fw) * var(--z, 1)),240px)}#viewport[data-tool=select] .frame-label{cursor:move}.frame-label .name{overflow:hidden;text-overflow:ellipsis}.frame.selected .frame-label{color:var(--accent)}.frame-label .kind{font:500 10px/1 var(--mono);color:var(--muted);padding:3px 5px;border-radius:4px;background:var(--surface);border:1px solid var(--line);text-transform:uppercase;letter-spacing:.04em}.frame-label .count{font:500 11px/1 var(--mono);color:var(--accent)}.frame-label .rename{font:inherit;color:var(--ink);background:var(--surface);border:1px solid var(--accent);border-radius:5px;padding:2px 6px;outline:0;width:220px}.frame-label .spinner{display:none;width:12px;height:12px;border-radius:50%;border:1.6px solid var(--accent-soft);border-top-color:var(--accent);animation:spin .7s linear infinite;flex:none}.frame-label .step{display:none}.frame-label .stop{display:none;font-size:11px;color:var(--muted);padding:2px 7px;border-radius:99px;border:1px solid var(--line);background:var(--surface)}.frame-label .stop:hover{color:var(--mark);border-color:var(--mark)}.frame.working .frame-label{color:var(--ink)}.frame.working .frame-label .spinner,.frame.working .frame-label .stop{display:inline-block}.frame.working .frame-label .step{display:inline;overflow:hidden;text-overflow:ellipsis;background:linear-gradient(90deg,var(--muted) 0%,var(--muted) 35%,var(--ink) 50%,var(--muted) 65%,var(--muted) 100%);background-size:250% 100%;-webkit-background-clip:text;background-clip:text;color:transparent;animation:shimmer 1.8s linear infinite}.frame.working .frame-label .step:before{content:"\b7 "}.frame.working .frame-label .elapsed{display:inline;font:11px/1 var(--mono);color:var(--muted)}.frame-label .elapsed{display:none}.frame-label .updated{display:none;font-size:11px;font-weight:600;color:var(--ok)}.frame.updated .frame-label .updated{display:inline;animation:fadeout 2.8s ease forwards}.frame.failed .frame-label .updated{display:inline;color:var(--mark);animation:fadeout 4s ease forwards}.frame-body{position:relative;width:100%;height:100%;background:#fff;border-radius:2px;box-shadow:0 0 0 1px var(--line),var(--shadow);overflow:hidden}.frame.selected .frame-body{box-shadow:0 0 0 calc(1.5px / var(--z, 1)) var(--accent),var(--shadow)}.frame.working .frame-body{box-shadow:0 0 0 calc(1.5px / var(--z, 1)) var(--accent-soft),var(--shadow)}.frame iframe{position:absolute;inset:0;width:100%;height:100%;border:0;background:#fff;display:block}.frame .shield{position:absolute;inset:0}.frame.live .shield{display:none}.frame .progress{position:absolute;left:0;right:0;top:0;height:calc(3px / var(--z, 1));overflow:hidden;pointer-events:none;opacity:0;transition:opacity .2s}.frame.working .progress{opacity:1}.frame .progress:after{content:"";position:absolute;top:0;bottom:0;width:35%;background:linear-gradient(90deg,transparent,var(--accent),transparent);animation:sweep 1.4s ease-in-out infinite}.frame .resize{position:absolute;display:none;z-index:7;--t: calc(10px / var(--z, 1))}#viewport[data-tool=select] .frame.selected .resize{display:block}.frame .rz-n,.frame .rz-s{left:var(--t);right:var(--t);height:var(--t);cursor:ns-resize}.frame .rz-n{top:calc(var(--t) / -2)}.frame .rz-s{bottom:calc(var(--t) / -2)}.frame .rz-e,.frame .rz-w{top:var(--t);bottom:var(--t);width:var(--t);cursor:ew-resize}.frame .rz-e{right:calc(var(--t) / -2)}.frame .rz-w{left:calc(var(--t) / -2)}.frame .rz-ne,.frame .rz-nw,.frame .rz-se,.frame .rz-sw{width:calc(var(--t) * 1.4);height:calc(var(--t) * 1.4)}.frame .rz-nw{left:calc(var(--t) * -.7);top:calc(var(--t) * -.7);cursor:nwse-resize}.frame .rz-se{right:calc(var(--t) * -.7);bottom:calc(var(--t) * -.7);cursor:nwse-resize}.frame .rz-ne{right:calc(var(--t) * -.7);top:calc(var(--t) * -.7);cursor:nesw-resize}.frame .rz-sw{left:calc(var(--t) * -.7);bottom:calc(var(--t) * -.7);cursor:nesw-resize}.frame .rz-ne:after,.frame .rz-nw:after,.frame .rz-se:after,.frame .rz-sw:after{content:"";position:absolute;inset:30%;background:#fff;border:calc(1.5px / var(--z, 1)) solid var(--accent);border-radius:calc(1.5px / var(--z, 1))}.frame .pins{position:absolute;inset:0;pointer-events:none;overflow:visible;z-index:6}.frame .areas{position:absolute;inset:0;pointer-events:none;overflow:hidden}.pin{position:absolute;width:0;height:0;pointer-events:auto}.pin-dot{position:absolute;left:0;bottom:0;transform-origin:0 100%;scale:calc(1 / var(--z, 1));min-width:26px;height:26px;padding:0 7px;border-radius:13px 13px 13px 2px;display:grid;place-items:center;background:var(--accent);color:#fff;font:600 11.5px/1 var(--font);box-shadow:0 0 0 2px #fff,var(--shadow);cursor:pointer}.pin.done .pin-dot{background:#17171a}.pin.error .pin-dot{background:var(--mark)}.pin.waiting .pin-dot{background:#fff;color:#17171a;box-shadow:0 0 0 1.5px #cfcbc1,var(--shadow)}.pin.resolved .pin-dot{opacity:.45}.pin.working .pin-dot:after{content:"";position:absolute;inset:-5px;border-radius:inherit;border:2px solid var(--accent);animation:ring 1.4s ease-out infinite}.pin.active .pin-dot{box-shadow:0 0 0 2px #fff,0 0 0 4px var(--accent),var(--shadow)}.pin.draft .pin-dot{background:var(--accent)}#ink{position:absolute;left:0;top:0;overflow:visible;pointer-events:none}#ink path{fill:none;stroke-linecap:round;stroke-linejoin:round}#ink path.used{opacity:.28}#viewport[data-tool=erase] #ink path{pointer-events:stroke}#viewport[data-tool=erase] #ink path:hover{opacity:.4}#hover-box{position:fixed;pointer-events:none;border:1.5px solid var(--accent);background:var(--accent-soft);border-radius:3px;z-index:5;transition:all .06s ease-out}#hover-box:after{content:attr(data-tag);position:absolute;left:-1.5px;top:-20px;font:500 10.5px/1 var(--mono);color:#fff;background:var(--accent);padding:4px 5px;border-radius:3px 3px 3px 0;white-space:nowrap}.cursor{position:absolute;left:0;top:0;pointer-events:none;transition:transform .08s linear}.cursor-inner{transform-origin:0 0;scale:calc(1 / var(--z, 1))}.cursor svg{width:18px;height:18px;display:block;filter:drop-shadow(0 1px 1px rgba(0,0,0,.2))}.cursor span{display:inline-block;margin:2px 0 0 12px;padding:3px 7px;border-radius:99px;color:#fff;font:500 11px/1.2 var(--font);white-space:nowrap}#topbar{position:fixed;left:12px;right:12px;top:12px;display:flex;justify-content:space-between;align-items:center;pointer-events:none;z-index:20}#topbar>*{pointer-events:auto}.brand{display:flex;align-items:center;gap:8px;padding:6px 12px 6px 7px;background:var(--surface);border:1px solid var(--line);border-radius:10px;box-shadow:var(--shadow)}.logo svg{width:22px;height:22px;display:block}.logo rect{fill:var(--ink)}.logo circle{stroke:var(--paper);stroke-width:2.6;fill:none}.wordmark{font-weight:600;letter-spacing:-.01em}.sep{color:var(--line-strong)}.canvas-name{color:var(--ink-2);max-width:30vw;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.top-right{display:flex;align-items:center;gap:8px}.pill{display:flex;align-items:center;gap:7px;height:34px;padding:0 12px;background:var(--surface);border:1px solid var(--line);border-radius:10px;box-shadow:var(--shadow);color:var(--ink-2);font-weight:500}.pill:hover{border-color:var(--line-strong)}.agent-dot{width:7px;height:7px;border-radius:50%;background:var(--ok);box-shadow:0 0 0 3px #1f9d5524}.pill.busy .agent-dot{background:var(--accent);box-shadow:0 0 0 3px var(--accent-soft);animation:pulse 1.2s ease-in-out infinite}.pill.inbox .agent-dot{background:#d9a100;box-shadow:0 0 0 3px #d9a10029}.btn-primary{height:34px;padding:0 14px;border-radius:10px;background:var(--ink);color:var(--paper);font-weight:500;display:inline-flex;align-items:center;gap:8px;box-shadow:var(--shadow)}.btn-primary:hover{opacity:.9}.btn-primary kbd{background:transparent;border-color:#ffffff40;color:inherit}.btn-secondary{height:32px;padding:0 12px;border-radius:8px;border:1px solid var(--line);background:var(--surface);font-weight:500}.btn-secondary:hover{border-color:var(--line-strong)}.link-btn{color:var(--muted);font-size:12px;text-decoration:underline;text-underline-offset:2px}.icon-btn{width:26px;height:26px;border-radius:6px;color:var(--muted);font-size:18px;line-height:1}.icon-btn:hover{background:var(--surface-2);color:var(--ink)}.presence{display:flex}.avatar{width:28px;height:28px;border-radius:50%;color:#fff;display:grid;place-items:center;font:600 11px/1 var(--font);border:2px solid var(--paper);margin-left:-6px}.menu{position:fixed;z-index:30;width:320px;padding:8px;background:var(--surface);border:1px solid var(--line);border-radius:12px;box-shadow:var(--shadow-lg)}.menu-title{padding:6px 8px 8px;font-weight:600}.menu-copy,.menu-note{margin:0 8px 10px;color:var(--muted);font-size:12px}.menu-note:empty{display:none}.menu-item{display:flex;gap:10px;text-align:left;width:100%;padding:9px 8px;border-radius:8px}.menu-item:hover{background:var(--surface-2)}.menu-item b{display:block;font-weight:500}.menu-item small{display:block;color:var(--muted);font-size:12px;margin-top:2px}.menu-item code{font-size:11px}.radio{flex:none;width:14px;height:14px;margin-top:2px;border-radius:50%;border:1.5px solid var(--line-strong)}.menu-item.on .radio{border:4px solid var(--accent)}#share-menu{padding:12px}#share-menu .menu-title{padding:0 0 6px}#share-menu .menu-copy,#share-menu .menu-note{margin:0 0 12px}.field-label{display:block;font-size:11.5px;color:var(--muted);font-weight:500;margin:0 0 5px}.copy-row{display:flex;gap:6px;margin-bottom:12px}.copy-row input{flex:1;min-width:0;height:32px;padding:0 9px;border-radius:8px;border:1px solid var(--line);background:var(--surface-2);font:11.5px var(--mono);color:var(--ink-2);outline:0}.copy-row button{height:32px;padding:0 11px;border-radius:8px;border:1px solid var(--line);background:var(--surface);font-weight:500}#share-public-btn{width:100%;margin-bottom:8px}#toolbar{position:fixed;left:50%;bottom:16px;transform:translate(-50%);z-index:20;display:flex;align-items:center;gap:2px;padding:5px;background:var(--surface);border:1px solid var(--line);border-radius:14px;box-shadow:var(--shadow-lg)}#toolbar button{width:38px;height:38px;border-radius:10px;display:grid;place-items:center;color:var(--ink-2)}#toolbar button:hover{background:var(--surface-2);color:var(--ink)}#toolbar button.on{background:var(--ink);color:var(--paper)}#toolbar button[data-tool=comment].on{background:var(--accent);color:#fff}#toolbar svg{width:19px;height:19px;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round}#toolbar .tb-sep{width:1px;height:22px;background:var(--line);margin:0 4px}#toolbar .tb-new{width:auto;padding:0 12px 0 9px;display:flex;gap:5px;font-weight:500}#zoom{position:fixed;right:16px;bottom:16px;z-index:20;display:flex;background:var(--surface);border:1px solid var(--line);border-radius:10px;box-shadow:var(--shadow);overflow:hidden}#zoom button{height:32px;min-width:32px;padding:0 8px;color:var(--ink-2);font:500 12px var(--mono)}#zoom button:hover{background:var(--surface-2)}#zoom-level{min-width:56px;border-left:1px solid var(--line)!important;border-right:1px solid var(--line)!important}.pop{position:fixed;z-index:25;width:340px;background:var(--surface);border:1px solid var(--line);border-radius:12px;box-shadow:var(--shadow-lg)}#composer{padding:10px}.composer-target{display:flex;align-items:center;gap:6px;margin-bottom:8px;font:11px var(--mono);color:var(--muted);overflow:hidden;white-space:nowrap}.composer-target b{color:var(--accent);font-weight:500}.composer-target span{overflow:hidden;text-overflow:ellipsis}#composer textarea,.thread-reply textarea{width:100%;resize:none;border:0;outline:0;background:transparent;font-size:13.5px;line-height:1.45;max-height:180px;padding:2px 0}#composer textarea::placeholder,.thread-reply textarea::placeholder{color:var(--muted)}.composer-foot{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-top:8px;padding-top:8px;border-top:1px solid var(--line)}.hint{color:var(--muted);font-size:11px;display:flex;gap:4px;align-items:center;margin-left:auto}.chip{font-size:11px;font-weight:500;color:var(--mark);background:#e5484d1a;padding:3px 7px;border-radius:99px}#thread{max-height:min(70vh,560px);display:flex;flex-direction:column}.thread-head{display:flex;align-items:center;justify-content:space-between;padding:8px 8px 8px 12px;border-bottom:1px solid var(--line)}.thread-head .t-title{font-weight:600;font-size:12.5px}.thread-head .t-actions{display:flex;gap:2px}.thread-body{overflow:auto;padding:4px 0}.msg{padding:10px 12px}.msg+.msg{border-top:1px solid var(--line)}.msg-head{display:flex;align-items:center;gap:7px;margin-bottom:4px}.msg-head .av{width:18px;height:18px;border-radius:50%;color:#fff;display:grid;place-items:center;font:600 9px/1 var(--font)}.msg-head b{font-weight:600;font-size:12.5px}.msg-head time{color:var(--muted);font-size:11px}.msg-text{white-space:pre-wrap;word-wrap:break-word}.agent-line{display:flex;gap:8px;align-items:flex-start;margin-top:8px;padding:8px 10px;background:var(--surface-2);border-radius:8px;font-size:12.5px;color:var(--ink-2)}.agent-line .a-ic{flex:none;width:16px;height:16px;margin-top:1px;border-radius:4px;background:var(--ink);display:grid;place-items:center}.agent-line .a-ic svg{width:10px;height:10px;stroke:var(--paper);fill:none;stroke-width:2.4}.agent-line.working .a-ic{background:none;border:1.6px solid var(--accent-soft);border-top-color:var(--accent);border-radius:50%;animation:spin .7s linear infinite}.agent-line.working .a-ic svg{display:none}.agent-line.working .a-text{background:linear-gradient(90deg,var(--muted) 0%,var(--muted) 35%,var(--ink) 50%,var(--muted) 65%,var(--muted) 100%);background-size:250% 100%;-webkit-background-clip:text;background-clip:text;color:transparent;animation:shimmer 1.8s linear infinite}.agent-line.error{background:#e5484d14;color:var(--mark)}.agent-line.error .a-ic{background:var(--mark)}.agent-line.waiting .a-ic{background:var(--line-strong)}.agent-line .a-actions{display:flex;gap:10px;margin-top:6px}.agent-line .a-actions button{font-size:12px;font-weight:500;color:var(--accent)}.agent-line .a-actions button.quiet{color:var(--muted)}.thread-reply{display:flex;align-items:flex-end;gap:8px;padding:10px 12px;border-top:1px solid var(--line)}#ink-chip{position:fixed;z-index:22}#ink-chip button{height:30px;padding:0 11px;border-radius:99px;background:var(--ink);color:var(--paper);font-weight:500;font-size:12px;box-shadow:var(--shadow-lg)}.modal{position:fixed;inset:0;z-index:40;display:grid;place-items:start center;padding-top:18vh;background:#1414162e}.modal-card{width:min(560px,calc(100vw - 32px));background:var(--surface);border:1px solid var(--line);border-radius:14px;box-shadow:var(--shadow-lg);padding:14px}.modal-card.narrow{width:min(380px,calc(100vw - 32px))}.modal-head{display:flex;align-items:center;justify-content:space-between;font-weight:600;margin-bottom:10px}.modal-card textarea,.modal-card input{width:100%;border:1px solid var(--line);background:var(--surface-2);border-radius:10px;padding:10px 12px;outline:0;resize:none;font-size:14px}.modal-card textarea:focus,.modal-card input:focus{border-color:var(--accent)}.modal-foot{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-top:12px}.size-pick{display:flex;gap:2px;padding:3px;border-radius:9px;background:var(--surface-2);border:1px solid var(--line)}.size-pick button{height:26px;padding:0 10px;border-radius:6px;color:var(--muted);font-weight:500;font-size:12px}.size-pick button.on{background:var(--surface);color:var(--ink);box-shadow:0 1px 2px #00000014}#empty{position:absolute;inset:0;display:grid;place-items:center;pointer-events:none}.empty-card{max-width:420px;text-align:center;pointer-events:auto;padding:0 16px}.empty-mark{width:44px;height:44px;margin:0 auto 16px;border-radius:12px;border:1.5px dashed var(--line-strong)}.empty-card h1{font-size:18px;font-weight:600;margin:0 0 6px;letter-spacing:-.01em}.empty-card p{margin:0 0 10px;color:var(--ink-2)}.empty-card code{display:block;margin:0 0 14px;padding:10px 12px;border-radius:10px;background:var(--surface);border:1px solid var(--line);color:var(--ink);text-align:left;user-select:all}#toast{position:fixed;left:50%;bottom:76px;transform:translate(-50%);z-index:50;padding:8px 14px;border-radius:10px;background:var(--ink);color:var(--paper);font-weight:500;box-shadow:var(--shadow-lg)}#share-menu{width:360px;max-height:calc(100vh - 80px);overflow:auto}.btn-google{width:100%;height:38px;display:flex;align-items:center;justify-content:center;gap:10px;border-radius:10px;border:1px solid var(--line-strong);background:var(--surface);font-weight:500;margin-bottom:12px}.btn-google:hover{background:var(--surface-2)}.btn-google svg{width:18px;height:18px}.btn-dark{height:32px;padding:0 12px;border-radius:8px;background:var(--ink);color:var(--paper);font-weight:500}.btn-dark:disabled{opacity:.5}.members{margin:0 0 12px;display:flex;flex-direction:column;gap:2px}.member{display:flex;align-items:center;gap:9px;padding:6px 2px}.member .m-av{width:26px;height:26px;border-radius:50%;background:var(--surface-2);border:1px solid var(--line);display:grid;place-items:center;font:600 10px/1 var(--font);color:var(--ink-2);overflow:hidden;flex:none}.member .m-av img,.av-sm img{width:100%;height:100%;object-fit:cover}.member .m-text{flex:1;min-width:0}.member .m-name{font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.member .m-sub{font-size:11.5px;color:var(--muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.member .m-x{color:var(--muted);font-size:16px;width:22px;height:22px;border-radius:6px}.member .m-x:hover{background:var(--surface-2);color:var(--mark)}.signed-as{display:flex;align-items:center;gap:7px;font-size:12px;color:var(--muted);margin:2px 0 12px}.signed-as #me-email{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.av-sm{width:18px;height:18px;border-radius:50%;overflow:hidden;background:var(--surface-2);flex:none}.lan-share{border-top:1px solid var(--line);padding-top:10px}.lan-share.only{border-top:0;padding-top:0}.lan-share summary{cursor:pointer;color:var(--ink-2);font-weight:500;font-size:12.5px;margin-bottom:10px}.agent-line .a-meta{font:500 11px/1.4 var(--mono);color:var(--muted);margin-top:5px}.agent-line .a-model{font:500 10.5px/1 var(--mono);color:var(--muted);padding:2px 5px;border-radius:4px;border:1px solid var(--line);margin-right:4px}.msg-agent{background:var(--surface-2)}.av-agent{background:var(--ink)!important}.av-agent svg{width:10px;height:10px;stroke:var(--paper);fill:none;stroke-width:2.4}.sc-card{width:min(720px,calc(100vw - 32px))}.sc-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:18px 28px}.sc-group{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.06em;color:var(--muted);margin-bottom:6px}.sc-row{display:flex;justify-content:space-between;gap:12px;padding:5px 0;border-bottom:1px solid var(--line);font-size:12.5px}.sc-keys{display:flex;gap:4px;flex:none}@media(max-width:640px){.sc-grid{grid-template-columns:1fr}}#composer.soft{animation:softIn .22s ease-out}#composer.soft textarea::placeholder{color:var(--accent)}@keyframes softIn{0%{opacity:0;transform:translateY(4px) scale(.98)}to{opacity:1;transform:none}}.prompt-head,.prompt-ideas{display:none}#composer.prompt{width:400px;padding:14px}#composer.prompt .prompt-head{display:flex;align-items:center;gap:8px;font-weight:600;font-size:14px;margin-bottom:10px}#composer.prompt .prompt-head b{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.spark{width:24px;height:24px;border-radius:7px;display:grid;place-items:center;background:var(--accent);color:#fff;font-size:13px;flex:none;animation:spark 2.4s ease-in-out infinite}@keyframes spark{50%{transform:rotate(12deg) scale(1.06)}}#composer.prompt .prompt-ideas{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:10px}.prompt-ideas button{height:26px;padding:0 10px;border-radius:99px;border:1px solid var(--line);background:var(--surface-2);font-size:12px;font-weight:500;color:var(--ink-2)}.prompt-ideas button:hover{border-color:var(--accent);color:var(--accent);background:var(--accent-soft)}#composer.prompt textarea{min-height:44px;font-size:14px}.frame.empty .empty-hint b{color:var(--accent)}.frame.empty .shield{cursor:pointer}.canvas-name.editable{cursor:text;border-radius:6px;padding:2px 4px;margin:-2px -4px}.canvas-name.editable:hover{background:var(--surface-2)}.canvas-rename{font:inherit;color:var(--ink);background:var(--surface-2);border:1px solid var(--accent);border-radius:6px;padding:1px 5px;outline:0;width:220px}#fp-name{width:100%;font:600 13px var(--font);color:var(--ink);border:1px solid transparent;background:transparent;border-radius:6px;padding:3px 5px;margin-left:-5px;outline:0}#fp-name:hover{border-color:var(--line)}#fp-name:focus{border-color:var(--accent);background:var(--surface-2)}.deep-box{position:absolute;pointer-events:none;border:calc(2px / var(--z, 1)) solid var(--accent);background:#2f5bff14;border-radius:calc(2px / var(--z, 1))}.deep-box:before{content:attr(data-tag);position:absolute;left:calc(-2px / var(--z, 1));bottom:100%;transform-origin:0 100%;scale:calc(1 / var(--z, 1));font:500 10.5px/1 var(--mono);color:#fff;background:var(--accent);padding:4px 5px;border-radius:3px 3px 3px 0;margin-bottom:calc(2px / var(--z, 1));white-space:nowrap}.area{position:absolute;pointer-events:none;border:calc(2px / var(--z, 1)) solid var(--accent);background:#2f5bff1a;border-radius:calc(3px / var(--z, 1));opacity:0;transition:opacity .15s}.area.show,.area.hover{opacity:1}.area:before{content:"Area";position:absolute;left:calc(-2px / var(--z, 1));bottom:100%;transform-origin:0 100%;scale:calc(1 / var(--z, 1));font:600 10px/1 var(--font);letter-spacing:.02em;color:#fff;background:var(--accent);padding:4px 6px;border-radius:4px 4px 4px 0;margin-bottom:calc(2px / var(--z, 1));white-space:nowrap}.frame .area.draft,.frame .area.picking{box-shadow:0 0 0 100000px #0a0c1438}.area.picking{border-style:dashed}.chip-area{color:var(--accent);background:var(--accent-soft)}.scope-pick{display:flex;gap:2px;padding:3px;margin-bottom:8px;border-radius:8px;background:var(--surface-2);border:1px solid var(--line)}.scope-pick button{flex:1;height:24px;border-radius:6px;font-size:11.5px;font-weight:500;color:var(--muted)}.scope-pick button.on{background:var(--surface);color:var(--ink);box-shadow:0 1px 2px #00000014}.scope-pick button:disabled{opacity:.4;cursor:default}#canvas-pins{position:absolute;left:0;top:0;width:0;height:0}#canvas-pins .pin-dot{background:var(--surface);color:var(--ink);box-shadow:0 0 0 1.5px var(--ink),var(--shadow)}#canvas-pins .pin.working .pin-dot,#canvas-pins .pin.draft .pin-dot{background:var(--accent);color:#fff;box-shadow:0 0 0 2px #fff,var(--shadow)}#marquee{position:absolute;pointer-events:none;border:calc(1px / var(--z, 1)) solid var(--accent);background:#2f5bff14}#align-bar{position:fixed;z-index:22;display:flex;align-items:center;gap:2px;padding:4px;background:var(--surface);border:1px solid var(--line);border-radius:12px;box-shadow:var(--shadow-lg);animation:softIn .15s ease-out}#align-bar button{width:32px;height:32px;border-radius:8px;display:grid;place-items:center;color:var(--ink-2)}#align-bar button:hover{background:var(--surface-2);color:var(--ink)}#align-bar button:disabled{opacity:.35;cursor:default;background:none}#align-bar svg{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round}#align-bar .ab-count{font:500 12px var(--font);color:var(--ink-2);padding:0 8px 0 6px;white-space:nowrap}#align-bar .ab-sep{width:1px;height:20px;background:var(--line);margin:0 3px}#align-bar .ab-spacing{display:flex;align-items:center;gap:6px;padding-right:4px;animation:softIn .18s ease-out}#align-bar .ab-spacing[hidden]{display:none}#align-bar .ab-scrub{width:26px;height:28px;display:grid;place-items:center;color:var(--accent);cursor:ew-resize;border-radius:6px}#align-bar .ab-scrub:hover{background:var(--accent-soft)}#align-bar .ab-range{width:120px;accent-color:var(--accent);cursor:pointer}#align-bar .ab-num{display:flex;align-items:center;gap:2px;height:28px;padding:0 6px;border-radius:7px;border:1px solid var(--line);background:var(--surface-2)}#align-bar .ab-num:focus-within{border-color:var(--accent)}#align-bar .ab-val{width:38px;border:0;outline:0;background:transparent;font:12px var(--mono);color:var(--ink);text-align:right}#align-bar .ab-num small{font:11px var(--mono);color:var(--muted)}#guides{position:absolute;left:0;top:0;overflow:visible;pointer-events:none;z-index:8}#guides line{stroke:#ff2d55;stroke-width:calc(.6px / var(--z, 1));shape-rendering:crispEdges}#dup-ghost{position:absolute;pointer-events:none;border:calc(1.5px / var(--z, 1)) dashed var(--accent);background:var(--accent-soft);border-radius:2px}#dup-ghost span{position:absolute;left:0;bottom:100%;transform-origin:0 100%;scale:calc(1 / var(--z, 1));padding-bottom:6px;font:500 12.5px var(--font);color:var(--accent);white-space:nowrap}#viewport.alt[data-tool=select] .frame-label{cursor:copy}#viewport[data-tool=frame],#viewport[data-tool=frame] .shield{cursor:crosshair}#draw-box{position:absolute;border:calc(1.5px / var(--z, 1)) solid var(--accent);background:var(--accent-soft);pointer-events:none}#draw-box span{position:absolute;left:50%;top:100%;transform-origin:50% 0;translate:-50% 0;scale:calc(1 / var(--z, 1));margin-top:6px;font:500 11px/1 var(--mono);color:#fff;background:var(--accent);padding:4px 6px;border-radius:4px;white-space:nowrap}.frame-label .dims{flex:none;display:none;font:500 10.5px/1 var(--mono);color:var(--muted)}.frame.selected .frame-label .dims{display:inline}.frame .empty-hint{position:absolute;inset:0;display:none;flex-direction:column;align-items:center;justify-content:center;gap:6px;text-align:center;padding:24px;pointer-events:none;color:#9a978f;font:14px/1.4 var(--font)}.frame .empty-hint b{color:#6b6964;font-weight:600;font-size:15px}.frame.empty .empty-hint{display:flex}.frame.empty .frame-body{box-shadow:0 0 0 1px var(--line-strong),var(--shadow)}.panel{position:fixed;right:12px;top:60px;z-index:21;width:268px;max-height:calc(100vh - 140px);overflow:auto;background:var(--surface);border:1px solid var(--line);border-radius:12px;box-shadow:var(--shadow-lg);padding:10px}.panel-head{display:flex;align-items:center;justify-content:space-between;font-weight:600;padding:2px 2px 10px}.panel-head span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fp-quick{display:grid;grid-template-columns:repeat(3,1fr);gap:6px}.fp-q{display:flex;flex-direction:column;align-items:center;gap:3px;padding:10px 4px 8px;border-radius:10px;border:1px solid var(--line);background:var(--surface-2)}.fp-q:hover{border-color:var(--accent);background:var(--accent-soft)}.fp-q svg{width:22px;height:22px;fill:none;stroke:var(--ink-2);stroke-width:1.6;stroke-linecap:round;margin-bottom:2px}.fp-q b{font-weight:500;font-size:12.5px}.fp-q small,.fp-row small{font:10.5px/1 var(--mono);color:var(--muted)}.fp-hint{color:var(--muted);font-size:12px;margin:10px 2px}.fp-group{border-top:1px solid var(--line);padding:6px 0}.fp-group summary{cursor:pointer;font-weight:500;font-size:12.5px;color:var(--ink-2);padding:4px 2px}.fp-row{display:flex;justify-content:space-between;align-items:center;width:100%;padding:7px 6px;border-radius:7px;font-size:12.5px;text-align:left}.fp-row:hover{background:var(--surface-2)}.fp-custom,.fp-size{display:flex;gap:6px;align-items:center;border-top:1px solid var(--line);padding-top:10px;margin-top:4px}.fp-size{border-top:0;padding-top:0;margin:0 0 8px}.fp-custom label,.fp-size label{flex:1;display:flex;align-items:center;gap:6px;height:32px;padding:0 8px;border-radius:8px;border:1px solid var(--line);background:var(--surface-2);font:500 11px var(--mono);color:var(--muted)}.fp-custom input,.fp-size input{width:100%;min-width:0;border:0;outline:0;background:transparent;font:12.5px var(--mono);color:var(--ink)}.fp-custom label:focus-within,.fp-size label:focus-within{border-color:var(--accent)}.fp-chips{display:flex;gap:4px;margin-bottom:6px}.fp-chip{flex:1;height:28px;border-radius:7px;border:1px solid var(--line);font-size:12px;font-weight:500;color:var(--ink-2)}.fp-chip:hover{background:var(--surface-2)}.fp-chip.on{border-color:var(--ink);color:var(--ink)}#fp-describe{display:block;margin:12px 2px 2px;text-align:left}#viewport.dragging iframe,#viewport.panning iframe{pointer-events:none}#agent-pill.offline .agent-dot{background:var(--muted);box-shadow:none}@keyframes spin{to{transform:rotate(360deg)}}@keyframes shimmer{0%{background-position:125% 0}to{background-position:-125% 0}}@keyframes sweep{0%{left:-35%}to{left:100%}}@keyframes ring{0%{opacity:.9;transform:scale(.9)}to{opacity:0;transform:scale(1.35)}}@keyframes pulse{50%{opacity:.45}}@keyframes fadeout{0%,70%{opacity:1}to{opacity:0}}@media(max-width:640px){.canvas-name,.sep{display:none}#toolbar{bottom:12px}#zoom{display:none}.pop,.menu{width:calc(100vw - 32px)}}
1
+ :root{--paper: #F4F4F5;--grid: #D4D4D8;--surface: #FFFFFF;--surface-2: #FAFAFA;--line: #E4E4E7;--line-strong: #D1D1D6;--ink: #17171A;--ink-2: #48484D;--muted: #88888F;--accent: #2F5BFF;--accent-soft: rgba(47, 91, 255, .12);--mark: #E5484D;--ok: #1F9D55;--shadow: 0 1px 2px rgba(23,23,26,.06), 0 8px 24px rgba(23,23,26,.08);--frame-shadow: 0 0 #0000;--shadow-lg: 0 2px 6px rgba(23,23,26,.08), 0 18px 48px rgba(23,23,26,.14);--font: Inter, ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;--mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;color-scheme:light}@media(prefers-color-scheme:dark){:root:not([data-theme=light]){--paper: #141416;--grid: #2C2C30;--surface: #1D1D20;--surface-2: #232327;--line: #2E2E33;--line-strong: #3C3C42;--ink: #EDEDEF;--ink-2: #C3C3C8;--muted: #838389;--accent: #6E8BFF;--accent-soft: rgba(110,139,255,.16);--shadow: 0 1px 2px rgba(0,0,0,.3), 0 8px 24px rgba(0,0,0,.35);--shadow-lg: 0 2px 6px rgba(0,0,0,.35), 0 18px 48px rgba(0,0,0,.5);color-scheme:dark}}:root[data-theme=dark]{--paper: #141416;--grid: #2C2C30;--surface: #1D1D20;--surface-2: #232327;--line: #2E2E33;--line-strong: #3C3C42;--ink: #EDEDEF;--ink-2: #C3C3C8;--muted: #838389;--accent: #6E8BFF;--accent-soft: rgba(110,139,255,.16);color-scheme:dark}*{box-sizing:border-box}html,body{overscroll-behavior:none;margin:0;height:100%;overflow:hidden;background:var(--paper);color:var(--ink);font:13px/1.45 var(--font);-webkit-font-smoothing:antialiased}button{font:inherit;color:inherit;background:none;border:0;padding:0;cursor:pointer}input,textarea{font:inherit;color:inherit}kbd{font:500 10.5px/1 var(--mono);padding:2px 4px;border-radius:4px;border:1px solid var(--line);background:var(--surface-2);color:var(--ink-2)}code{font:12px/1.5 var(--mono)}.muted{color:var(--muted)}[hidden]{display:none!important}#viewport{position:fixed;inset:0;overflow:hidden;touch-action:none;user-select:none;background-color:var(--paper);background-image:radial-gradient(var(--grid) calc(var(--dot, 1px)),transparent 0);background-size:var(--gs, 24px) var(--gs, 24px);background-position:var(--gx, 0) var(--gy, 0)}#viewport[data-tool=hand],#viewport.panning{cursor:grab}#viewport.panning:active,#viewport.dragging{cursor:grabbing}#viewport[data-tool=pen],#viewport[data-tool=pen] .shield{cursor:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='32' height='32' viewBox='0 0 32 32'%3E%3Cpath d='M4.5 27.5l2.2-7.4L20.6 6.2a3.2 3.2 0 014.5 0l.7.7a3.2 3.2 0 010 4.5L11.9 25.3z' fill='%2317171A' stroke='white' stroke-width='2.2' stroke-linejoin='round'/%3E%3Cpath d='M18.3 8.5l5.2 5.2' stroke='white' stroke-width='1.8'/%3E%3Cpath d='M4.5 27.5l2.2-7.4 5.2 5.2z' fill='%23E5484D' stroke='white' stroke-width='1.4' stroke-linejoin='round'/%3E%3C/svg%3E") 4 28,crosshair}#viewport[data-tool=deep],#viewport[data-tool=deep] .shield{cursor:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='28' height='28' viewBox='0 0 28 28'%3E%3Crect x='11' y='11' width='13' height='13' rx='2' fill='rgba(47,91,255,.15)' stroke='%232F5BFF' stroke-width='1.6' stroke-dasharray='2.6 2.2'/%3E%3Cpath d='M3 3l10.5 5.4-4.4 1.4-1.9 4.2z' fill='%2317171A' stroke='white' stroke-width='1.4' stroke-linejoin='round'/%3E%3C/svg%3E") 3 3,default}#viewport[data-tool=comment]{cursor:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='26' height='26' viewBox='0 0 26 26'%3E%3Cpath d='M3 23V8a5 5 0 015-5h10a5 5 0 015 5v6a5 5 0 01-5 5H8z' fill='%232F5BFF' stroke='white' stroke-width='2'/%3E%3C/svg%3E") 3 23,crosshair}#viewport[data-tool=erase],#viewport[data-tool=erase] .shield,#viewport[data-tool=erase] #ink path{cursor:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='26' height='26' viewBox='0 0 26 26'%3E%3Ccircle cx='13' cy='13' r='11' fill='rgba(255,255,255,.35)' stroke='%2317171A' stroke-width='1.5'/%3E%3Ccircle cx='13' cy='13' r='12' fill='none' stroke='white' stroke-width='1'/%3E%3C/svg%3E") 13 13,cell}#world{position:absolute;left:0;top:0;transform-origin:0 0}.frame{position:absolute}.frame-label{position:absolute;left:0;bottom:100%;display:flex;align-items:center;gap:6px;height:28px;padding:0 2px 6px;transform-origin:0 100%;scale:calc(1 / var(--z, 1));white-space:nowrap;color:var(--muted);font-weight:500;font-size:12.5px;cursor:default;max-width:calc(var(--fw) * var(--z, 1));min-width:0;overflow:hidden}#viewport[data-tool=select] .frame-label{cursor:default}#viewport[data-tool=select] .frame-label:hover .name{color:var(--accent)}.frame-label .name{overflow:hidden;text-overflow:ellipsis;min-width:24px;flex:0 1 auto}.frame-label .ic{flex:none;display:inline-grid;place-items:center;width:11px;height:11px;color:var(--muted)}.frame-label .ic[data-k=live]:before{content:"";width:5px;height:5px;border-radius:50%;background:currentColor;opacity:.45}.frame-label .ic[data-k=frozen]{color:#4a9fe0}.frame-label .ic svg{width:11px;height:11px}.frame.working .frame-label .ic{display:none}.fp-acts{display:flex;flex-wrap:wrap;gap:6px;margin-top:10px}.fp-act{display:inline-flex;align-items:center;gap:6px;height:30px;padding:0 10px;border-radius:8px;border:1px solid var(--line);background:transparent;color:var(--ink);font:500 12.5px/1 var(--font);cursor:pointer}.fp-act:hover{background:var(--surface)}.fp-act svg{width:12px;height:12px;color:#4a9fe0}.fp-act kbd{font:500 10.5px/1 var(--mono);color:var(--muted)}.fp-act.on{border-color:var(--accent);color:var(--accent)}.frame .kb{display:none}.frame.kb-on .kb{position:absolute;left:0;right:0;bottom:0;height:336px;display:flex;flex-direction:column;gap:11px;padding:0 3px 40px;background:#d1d4da;font:400 22px/1 -apple-system,SF Pro Text,system-ui,sans-serif;color:#000;pointer-events:none;z-index:1}.frame.kb-on iframe{height:calc(100% - 336px)}.frame.kb-on:has(.kb.land) iframe{height:calc(100% - 209px)}.kb.land{height:209px!important;gap:6px!important;padding:0 60px 6px!important}.kb-bar{display:flex;justify-content:space-around;align-items:center;height:44px;font-size:16px;color:#333}.kb.land .kb-bar{height:34px}.kb-row{display:flex;gap:6px;justify-content:center}.kb-row.r2{padding:0 18px}.kb .k{flex:1;height:42px;display:grid;place-items:center;background:#fff;border-radius:5px;box-shadow:0 1px #898a8d}.kb.land .k{height:32px;font-size:18px}.kb .k.fn{flex:1.35;background:#abb0bc;font-size:15px}.kb .k.sp{flex:5;font-size:15px}.kb .k.ret{flex:2}.frame-label .dims{flex:none;border-radius:4px;padding:2px 4px;margin:0 -4px}.frame.selected .frame-label .dims{cursor:pointer}.frame.selected .frame-label .dims:hover{background:var(--surface);color:var(--ink)}.frame.narrow .frame-label .dims,.frame.narrow .frame-label .kind{display:none}.frame .parked-hint{position:absolute;inset:0;display:none;align-items:center;justify-content:center;padding:16px;text-align:center;color:var(--muted);font:500 13px/1.4 var(--font);background:var(--surface);pointer-events:none}.frame.parked .parked-hint{display:flex}.frame.parked iframe{visibility:hidden}.frame-label .kind{font:500 10px/1 var(--mono);color:var(--muted);padding:3px 5px;border-radius:4px;background:var(--surface);border:1px solid var(--line);text-transform:uppercase;letter-spacing:.04em;flex:0 2 auto;min-width:0;max-width:45%;overflow:hidden;text-overflow:ellipsis}.frame-label .count{font:500 11px/1 var(--mono);color:var(--accent)}.frame-label .rename{font:inherit;color:var(--ink);background:var(--surface);border:1px solid var(--accent);border-radius:5px;padding:2px 6px;outline:0;width:220px}.frame-label .spinner{display:none;width:12px;height:12px;border-radius:50%;border:1.6px solid var(--accent-soft);border-top-color:var(--accent);animation:spin .7s linear infinite;flex:none}.frame-label .step{display:none}.frame-label .stop{display:none;font-size:11px;color:var(--muted);padding:2px 7px;border-radius:99px;border:1px solid var(--line);background:var(--surface)}.frame-label .stop:hover{color:var(--mark);border-color:var(--mark)}.frame.working .frame-label .spinner,.frame.working .frame-label .stop{display:inline-block}.frame.working .frame-label .step{display:inline;overflow:hidden;text-overflow:ellipsis;background:linear-gradient(90deg,var(--muted) 0%,var(--muted) 35%,var(--ink) 50%,var(--muted) 65%,var(--muted) 100%);background-size:250% 100%;-webkit-background-clip:text;background-clip:text;color:transparent;animation:shimmer 1.8s linear infinite}.frame.working .frame-label .step:before{content:"\b7 "}.frame.working .frame-label .elapsed{display:inline;font:11px/1 var(--mono);color:var(--muted)}.frame-label .elapsed{display:none}.frame-label .updated{display:none;font-size:11px;font-weight:600;color:var(--ok)}.frame.updated .frame-label .updated{display:inline;animation:fadeout 2.8s ease forwards}.frame.failed .frame-label .updated{display:inline;color:var(--mark);animation:fadeout 4s ease forwards}.frame-body{position:relative;width:100%;height:100%;background:#fff;border-radius:2px;box-shadow:0 0 0 1px var(--line),var(--frame-shadow);overflow:hidden}.frame.selected .frame-body{box-shadow:0 0 0 calc(1.5px / var(--z, 1)) var(--accent),var(--frame-shadow)}.frame.working .frame-body{box-shadow:0 0 0 calc(1.5px / var(--z, 1)) var(--accent-soft),var(--frame-shadow)}.frame iframe{position:absolute;inset:0;width:100%;height:100%;border:0;background:#fff;display:block}.frame .shield{position:absolute;inset:0}.frame.live .shield{display:none}.frame .progress{position:absolute;left:0;right:0;top:0;height:calc(3px / var(--z, 1));overflow:hidden;pointer-events:none;opacity:0;transition:opacity .2s}.frame.working .progress{opacity:1}.frame .progress:after{content:"";position:absolute;top:0;bottom:0;width:35%;background:linear-gradient(90deg,transparent,var(--accent),transparent);animation:sweep 1.4s ease-in-out infinite}.frame .resize{position:absolute;display:none;z-index:7;--t: calc(10px / var(--z, 1))}#viewport[data-tool=select] .frame.selected .resize{display:block}.frame .rz-n,.frame .rz-s{left:var(--t);right:var(--t);height:var(--t);cursor:ns-resize}.frame .rz-n{top:calc(var(--t) / -2)}.frame .rz-s{bottom:calc(var(--t) / -2)}.frame .rz-e,.frame .rz-w{top:var(--t);bottom:var(--t);width:var(--t);cursor:ew-resize}.frame .rz-e{right:calc(var(--t) / -2)}.frame .rz-w{left:calc(var(--t) / -2)}.frame .rz-ne,.frame .rz-nw,.frame .rz-se,.frame .rz-sw{width:calc(var(--t) * 1.4);height:calc(var(--t) * 1.4)}.frame .rz-nw{left:calc(var(--t) * -.7);top:calc(var(--t) * -.7);cursor:nwse-resize}.frame .rz-se{right:calc(var(--t) * -.7);bottom:calc(var(--t) * -.7);cursor:nwse-resize}.frame .rz-ne{right:calc(var(--t) * -.7);top:calc(var(--t) * -.7);cursor:nesw-resize}.frame .rz-sw{left:calc(var(--t) * -.7);bottom:calc(var(--t) * -.7);cursor:nesw-resize}.frame .rz-ne:after,.frame .rz-nw:after,.frame .rz-se:after,.frame .rz-sw:after{content:"";position:absolute;inset:30%;background:#fff;border:calc(1.5px / var(--z, 1)) solid var(--accent);border-radius:calc(1.5px / var(--z, 1))}.frame .pins{position:absolute;inset:0;pointer-events:none;overflow:visible;z-index:6}.frame .areas{position:absolute;inset:0;pointer-events:none;overflow:hidden}.pin{position:absolute;width:0;height:0;pointer-events:auto}#ink{position:absolute;left:0;top:0;overflow:visible;pointer-events:none}#ink path{fill:none;stroke-linecap:round;stroke-linejoin:round}#ink path.used{opacity:.9}#viewport[data-tool=erase] #ink path{pointer-events:stroke}#viewport[data-tool=erase] #ink path:hover{opacity:.4}#hover-box{position:fixed;pointer-events:none;border:1.5px solid var(--accent);background:var(--accent-soft);border-radius:3px;z-index:5;transition:all .06s ease-out}#hover-box:after{content:attr(data-tag);position:absolute;left:-1.5px;top:-20px;font:500 10.5px/1 var(--mono);color:#fff;background:var(--accent);padding:4px 5px;border-radius:3px 3px 3px 0;white-space:nowrap}.cursor{position:absolute;left:0;top:0;pointer-events:none;transition:transform .08s linear}.cursor-inner{transform-origin:0 0;scale:calc(1 / var(--z, 1))}.cursor svg{width:18px;height:18px;display:block;filter:drop-shadow(0 1px 1px rgba(0,0,0,.2))}.cursor span{display:inline-block;margin:2px 0 0 12px;padding:3px 7px;border-radius:99px;color:#fff;font:500 11px/1.2 var(--font);white-space:nowrap}#topbar{position:fixed;left:12px;right:12px;top:12px;display:flex;justify-content:space-between;align-items:center;pointer-events:none;z-index:20}#topbar>*{pointer-events:auto}.brand{display:flex;align-items:center;gap:8px;padding:6px 12px 6px 7px;background:var(--surface);border:1px solid var(--line);border-radius:10px;box-shadow:var(--shadow)}.logo svg{width:22px;height:22px;display:block}.logo rect{fill:var(--ink)}.logo circle{stroke:var(--paper);stroke-width:2.6;fill:none}.wordmark{font-weight:600;letter-spacing:-.01em}.sep{color:var(--line-strong)}.canvas-name{color:var(--ink-2);max-width:30vw;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.top-right{display:flex;align-items:center;gap:8px}.pill{display:flex;align-items:center;gap:7px;height:34px;padding:0 12px;background:var(--surface);border:1px solid var(--line);border-radius:10px;box-shadow:var(--shadow);color:var(--ink-2);font-weight:500}.pill:hover{border-color:var(--line-strong)}.agent-dot{width:7px;height:7px;border-radius:50%;background:var(--ok);box-shadow:0 0 0 3px #1f9d5524}.pill.busy .agent-dot{background:var(--accent);box-shadow:0 0 0 3px var(--accent-soft);animation:pulse 1.2s ease-in-out infinite}.pill.inbox .agent-dot{background:#d9a100;box-shadow:0 0 0 3px #d9a10029}.btn-primary{height:34px;padding:0 14px;border-radius:10px;background:var(--ink);color:var(--paper);font-weight:500;display:inline-flex;align-items:center;gap:8px;box-shadow:var(--shadow)}.btn-primary:hover{opacity:.9}.btn-primary kbd{background:transparent;border-color:#ffffff40;color:inherit}.btn-secondary{height:32px;padding:0 12px;border-radius:8px;border:1px solid var(--line);background:var(--surface);font-weight:500}.btn-secondary:hover{border-color:var(--line-strong)}.link-btn{color:var(--muted);font-size:12px;text-decoration:underline;text-underline-offset:2px}.icon-btn{width:26px;height:26px;border-radius:6px;color:var(--muted);font-size:18px;line-height:1}.icon-btn:hover{background:var(--surface-2);color:var(--ink)}.presence{display:flex}.avatar{width:28px;height:28px;border-radius:50%;color:#fff;display:grid;place-items:center;font:600 11px/1 var(--font);border:2px solid var(--paper);margin-left:-6px}.menu{position:fixed;z-index:30;width:320px;padding:8px;background:var(--surface);border:1px solid var(--line);border-radius:12px;box-shadow:var(--shadow-lg)}.menu-title{padding:6px 8px 8px;font-weight:600}.menu-copy,.menu-note{margin:0 8px 10px;color:var(--muted);font-size:12px}.menu-note:empty{display:none}.menu-item{display:flex;gap:10px;text-align:left;width:100%;padding:9px 8px;border-radius:8px}.menu-item:hover{background:var(--surface-2)}.menu-item b{display:block;font-weight:500}.menu-item small{display:block;color:var(--muted);font-size:12px;margin-top:2px}.menu-item code{font-size:11px}.radio{flex:none;width:14px;height:14px;margin-top:2px;border-radius:50%;border:1.5px solid var(--line-strong)}.menu-item.on .radio{border:4px solid var(--accent)}#share-menu{padding:12px}#share-menu .menu-title{padding:0 0 6px}#share-menu .menu-copy,#share-menu .menu-note{margin:0 0 12px}.field-label{display:block;font-size:11.5px;color:var(--muted);font-weight:500;margin:0 0 5px}.copy-row{display:flex;gap:6px;margin-bottom:12px}.copy-row input{flex:1;min-width:0;height:32px;padding:0 9px;border-radius:8px;border:1px solid var(--line);background:var(--surface-2);font:11.5px var(--mono);color:var(--ink-2);outline:0}.copy-row button{height:32px;padding:0 11px;border-radius:8px;border:1px solid var(--line);background:var(--surface);font-weight:500}#share-public-btn{width:100%;margin-bottom:8px}#toolbar{position:fixed;left:50%;bottom:16px;transform:translate(-50%);z-index:20;display:flex;align-items:center;gap:2px;padding:5px;background:var(--surface);border:1px solid var(--line);border-radius:14px;box-shadow:var(--shadow-lg)}#toolbar button{width:38px;height:38px;border-radius:10px;display:grid;place-items:center;color:var(--ink-2)}#toolbar button:hover{background:var(--surface-2);color:var(--ink)}#toolbar button.on{background:var(--ink);color:var(--paper)}#toolbar button[data-tool=comment].on{background:var(--accent);color:#fff}#toolbar svg{width:19px;height:19px;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round}#toolbar .tb-sep{width:1px;height:22px;background:var(--line);margin:0 4px}#toolbar .tb-new{width:auto;padding:0 12px 0 9px;display:flex;gap:5px;font-weight:500}#zoom{position:fixed;right:16px;bottom:16px;z-index:20;display:flex;background:var(--surface);border:1px solid var(--line);border-radius:10px;box-shadow:var(--shadow);overflow:hidden}#zoom button{height:32px;min-width:32px;padding:0 8px;color:var(--ink-2);font:500 12px var(--mono)}#zoom button:hover{background:var(--surface-2)}#zoom-level{min-width:56px;border-left:1px solid var(--line)!important;border-right:1px solid var(--line)!important}.pop{position:fixed;z-index:25;width:340px;background:var(--surface);border:1px solid var(--line);border-radius:12px;box-shadow:var(--shadow-lg)}#composer{padding:10px}.composer-target{display:flex;align-items:center;gap:6px;margin-bottom:8px;font:11px var(--mono);color:var(--muted);overflow:hidden;white-space:nowrap}.composer-target b{color:var(--accent);font-weight:500}.composer-target span{overflow:hidden;text-overflow:ellipsis}#composer textarea,.thread-reply textarea{width:100%;resize:none;border:0;outline:0;background:transparent;font-size:13.5px;line-height:1.45;max-height:180px;padding:2px 0}#composer textarea::placeholder,.thread-reply textarea::placeholder{color:var(--muted)}.composer-foot{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-top:8px;padding-top:8px;border-top:1px solid var(--line)}.hint{color:var(--muted);font-size:11px;display:flex;gap:4px;align-items:center;margin-left:auto}.chip{font-size:11px;font-weight:500;color:var(--mark);background:#e5484d1a;padding:3px 7px;border-radius:99px}#thread{max-height:min(70vh,560px);display:flex;flex-direction:column}.thread-head{display:flex;align-items:center;justify-content:space-between;padding:8px 8px 8px 12px;border-bottom:1px solid var(--line)}.thread-head .t-title{font-weight:600;font-size:12.5px}.thread-head .t-actions{display:flex;gap:2px}.thread-body{overflow:auto;padding:4px 0}.msg{padding:10px 12px}.msg+.msg{border-top:1px solid var(--line)}.msg-head{display:flex;align-items:center;gap:7px;margin-bottom:4px}.msg-head .av{width:18px;height:18px;border-radius:50%;color:#fff;display:grid;place-items:center;font:600 9px/1 var(--font)}.msg-head b{font-weight:600;font-size:12.5px}.msg-head time{color:var(--muted);font-size:11px}.msg-text{white-space:pre-wrap;word-wrap:break-word}.agent-line{display:flex;gap:8px;align-items:flex-start;margin-top:8px;padding:8px 10px;background:var(--surface-2);border-radius:8px;font-size:12.5px;color:var(--ink-2)}.agent-line .a-ic{flex:none;width:16px;height:16px;margin-top:1px;border-radius:4px;background:var(--ink);display:grid;place-items:center}.agent-line .a-ic svg{width:10px;height:10px;stroke:var(--paper);fill:none;stroke-width:2.4}.agent-line.working .a-ic{background:none;border:1.6px solid var(--accent-soft);border-top-color:var(--accent);border-radius:50%;animation:spin .7s linear infinite}.agent-line.working .a-ic svg{display:none}.agent-line.working .a-text,.m-work .a-text{background:linear-gradient(90deg,var(--muted) 0%,var(--muted) 35%,var(--ink) 50%,var(--muted) 65%,var(--muted) 100%);background-size:250% 100%;-webkit-background-clip:text;background-clip:text;color:transparent;animation:shimmer 1.8s linear infinite}.agent-line.error{background:#e5484d14;color:var(--mark)}.agent-line.error .a-ic{background:var(--mark)}.agent-line.waiting .a-ic{background:var(--line-strong)}.agent-line .a-actions{display:flex;gap:10px;margin-top:6px}.agent-line .a-actions button{font-size:12px;font-weight:500;color:var(--accent)}.agent-line .a-actions button.quiet{color:var(--muted)}.thread-reply{display:flex;align-items:flex-end;gap:8px;padding:10px 12px;border-top:1px solid var(--line)}#ink-chip{position:fixed;z-index:22}#ink-chip button{height:30px;padding:0 11px;border-radius:99px;background:var(--ink);color:var(--paper);font-weight:500;font-size:12px;box-shadow:var(--shadow-lg)}.modal{position:fixed;inset:0;z-index:40;display:grid;place-items:start center;padding-top:18vh;background:#1414162e}.modal-card{width:min(560px,calc(100vw - 32px));background:var(--surface);border:1px solid var(--line);border-radius:14px;box-shadow:var(--shadow-lg);padding:14px}.modal-card.narrow{width:min(380px,calc(100vw - 32px))}.modal-head{display:flex;align-items:center;justify-content:space-between;font-weight:600;margin-bottom:10px}.modal-card textarea,.modal-card input{width:100%;border:1px solid var(--line);background:var(--surface-2);border-radius:10px;padding:10px 12px;outline:0;resize:none;font-size:14px}.modal-card textarea:focus,.modal-card input:focus{border-color:var(--accent)}.modal-foot{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-top:12px}.size-pick{display:flex;gap:2px;padding:3px;border-radius:9px;background:var(--surface-2);border:1px solid var(--line)}.size-pick button{height:26px;padding:0 10px;border-radius:6px;color:var(--muted);font-weight:500;font-size:12px}.size-pick button.on{background:var(--surface);color:var(--ink);box-shadow:0 1px 2px #00000014}#empty{position:absolute;inset:0;display:grid;place-items:center;pointer-events:none}.empty-card{max-width:420px;text-align:center;pointer-events:auto;padding:0 16px}.empty-mark{width:44px;height:44px;margin:0 auto 16px;border-radius:12px;border:1.5px dashed var(--line-strong)}.empty-card h1{font-size:18px;font-weight:600;margin:0 0 6px;letter-spacing:-.01em}.empty-card p{margin:0 0 10px;color:var(--ink-2)}.empty-card code{display:block;margin:0 0 14px;padding:10px 12px;border-radius:10px;background:var(--surface);border:1px solid var(--line);color:var(--ink);text-align:left;user-select:all}#toast{position:fixed;left:50%;bottom:76px;transform:translate(-50%);z-index:50;padding:8px 14px;border-radius:10px;background:var(--ink);color:var(--paper);font-weight:500;box-shadow:var(--shadow-lg)}#share-menu{width:360px;max-height:calc(100vh - 80px);overflow:auto}.btn-google{width:100%;height:38px;display:flex;align-items:center;justify-content:center;gap:10px;border-radius:10px;border:1px solid var(--line-strong);background:var(--surface);font-weight:500;margin-bottom:12px}.btn-google:hover{background:var(--surface-2)}.btn-google svg{width:18px;height:18px}.btn-dark{height:32px;padding:0 12px;border-radius:8px;background:var(--ink);color:var(--paper);font-weight:500}.btn-dark:disabled{opacity:.5}.members{margin:0 0 12px;display:flex;flex-direction:column;gap:2px}.member{display:flex;align-items:center;gap:9px;padding:6px 2px}.member .m-av{width:26px;height:26px;border-radius:50%;background:var(--surface-2);border:1px solid var(--line);display:grid;place-items:center;font:600 10px/1 var(--font);color:var(--ink-2);overflow:hidden;flex:none}.member .m-av img,.av-sm img{width:100%;height:100%;object-fit:cover}.member .m-text{flex:1;min-width:0}.member .m-name{font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.member .m-sub{font-size:11.5px;color:var(--muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.member .m-x{color:var(--muted);font-size:16px;width:22px;height:22px;border-radius:6px}.member .m-x:hover{background:var(--surface-2);color:var(--mark)}.signed-as{display:flex;align-items:center;gap:7px;font-size:12px;color:var(--muted);margin:2px 0 12px}.signed-as #me-email{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.av-sm{width:18px;height:18px;border-radius:50%;overflow:hidden;background:var(--surface-2);flex:none}.lan-share{border-top:1px solid var(--line);padding-top:10px}.avatar.me{cursor:pointer}.lan-share.only{border-top:0;padding-top:0}.lan-share summary{cursor:pointer;color:var(--ink-2);font-weight:500;font-size:12.5px;margin-bottom:10px}.agent-line .a-meta{font:500 11px/1.4 var(--mono);color:var(--muted);margin-top:5px}.agent-line .a-model{font:500 10.5px/1 var(--mono);color:var(--muted);padding:2px 5px;border-radius:4px;border:1px solid var(--line);margin-right:4px}.msg-agent{background:var(--surface-2)}.av-agent{background:var(--ink)!important}.av-agent svg{width:10px;height:10px;stroke:var(--paper);fill:none;stroke-width:2.4}.sc-card{width:min(720px,calc(100vw - 32px))}.sc-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:18px 28px}.sc-group{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.06em;color:var(--muted);margin-bottom:6px}.sc-row{display:flex;justify-content:space-between;gap:12px;padding:5px 0;border-bottom:1px solid var(--line);font-size:12.5px}.sc-keys{display:flex;gap:4px;flex:none}@media(max-width:640px){.sc-grid{grid-template-columns:1fr}}#composer.soft{animation:softIn .22s ease-out}#composer.soft textarea::placeholder{color:var(--accent)}@keyframes softIn{0%{opacity:0;transform:translateY(4px) scale(.98)}to{opacity:1;transform:none}}.prompt-head,.prompt-ideas{display:none}#composer.prompt{width:400px;padding:14px}#composer.prompt .prompt-head{display:flex;align-items:center;gap:8px;font-weight:600;font-size:14px;margin-bottom:10px}#composer.prompt .prompt-head b{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}#composer.prompt .prompt-ideas{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:10px}.prompt-ideas button{height:26px;padding:0 10px;border-radius:99px;border:1px solid var(--line);background:var(--surface-2);font-size:12px;font-weight:500;color:var(--ink-2)}.prompt-ideas button:hover{border-color:var(--accent);color:var(--accent);background:var(--accent-soft)}#composer.prompt textarea{min-height:44px;font-size:14px}.frame.empty .shield{cursor:pointer}.canvas-name.editable{cursor:text;border-radius:6px;padding:2px 4px;margin:-2px -4px}.canvas-name.editable:hover{background:var(--surface-2)}.canvas-rename{font:inherit;color:var(--ink);background:var(--surface-2);border:1px solid var(--accent);border-radius:6px;padding:1px 5px;outline:0;width:220px}#fp-name{width:100%;font:600 13px var(--font);color:var(--ink);border:1px solid transparent;background:transparent;border-radius:6px;padding:3px 5px;margin-left:-5px;outline:0}#fp-name:hover{border-color:var(--line)}#fp-name:focus{border-color:var(--accent);background:var(--surface-2)}.deep-box{position:absolute;pointer-events:none;border:calc(2px / var(--z, 1)) solid var(--accent);background:#2f5bff14;border-radius:calc(2px / var(--z, 1))}.deep-box:before{content:attr(data-tag);position:absolute;left:calc(-2px / var(--z, 1));bottom:100%;transform-origin:0 100%;scale:calc(1 / var(--z, 1));font:500 10.5px/1 var(--mono);color:#fff;background:var(--accent);padding:4px 5px;border-radius:3px 3px 3px 0;margin-bottom:calc(2px / var(--z, 1));white-space:nowrap}.area{position:absolute;pointer-events:none;border:calc(2px / var(--z, 1)) solid var(--accent);background:#2f5bff1a;border-radius:calc(3px / var(--z, 1));opacity:0;transition:opacity .15s}.area.show,.area.hover{opacity:1}.area:before{content:"Area";position:absolute;left:calc(-2px / var(--z, 1));bottom:100%;transform-origin:0 100%;scale:calc(1 / var(--z, 1));font:600 10px/1 var(--font);letter-spacing:.02em;color:#fff;background:var(--accent);padding:4px 6px;border-radius:4px 4px 4px 0;margin-bottom:calc(2px / var(--z, 1));white-space:nowrap}.frame .area.draft,.frame .area.picking{box-shadow:none}.area.picking{border-style:dashed}.chip-area{color:var(--accent);background:var(--accent-soft)}.scope-pick{display:flex;gap:2px;padding:3px;margin-bottom:8px;border-radius:8px;background:var(--surface-2);border:1px solid var(--line)}.scope-pick button{flex:1;height:24px;border-radius:6px;font-size:11.5px;font-weight:500;color:var(--muted)}.scope-pick button.on{background:var(--surface);color:var(--ink);box-shadow:0 1px 2px #00000014}.scope-pick button:disabled{opacity:.4;cursor:default}#canvas-pins{position:absolute;left:0;top:0;width:0;height:0}#marquee{position:absolute;pointer-events:none;border:calc(1px / var(--z, 1)) solid var(--accent);background:#2f5bff14}#align-bar{position:fixed;z-index:22;display:flex;align-items:center;gap:2px;padding:4px;background:var(--surface);border:1px solid var(--line);border-radius:12px;box-shadow:var(--shadow-lg);animation:softIn .15s ease-out}#align-bar button{width:32px;height:32px;border-radius:8px;display:grid;place-items:center;color:var(--ink-2)}#align-bar button:hover{background:var(--surface-2);color:var(--ink)}#align-bar button:disabled{opacity:.35;cursor:default;background:none}#align-bar svg{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round}#align-bar .ab-count{font:500 12px var(--font);color:var(--ink-2);padding:0 8px 0 6px;white-space:nowrap}#align-bar .ab-sep{width:1px;height:20px;background:var(--line);margin:0 3px}#align-bar .ab-spacing{display:flex;align-items:center;gap:6px;padding-right:4px;animation:softIn .18s ease-out}#align-bar .ab-spacing[hidden]{display:none}#align-bar .ab-scrub{width:26px;height:28px;display:grid;place-items:center;color:var(--accent);cursor:ew-resize;border-radius:6px}#align-bar .ab-scrub:hover{background:var(--accent-soft)}#align-bar .ab-range{width:120px;accent-color:var(--accent);cursor:pointer}#align-bar .ab-num{display:flex;align-items:center;gap:2px;height:28px;padding:0 6px;border-radius:7px;border:1px solid var(--line);background:var(--surface-2)}#align-bar .ab-num:focus-within{border-color:var(--accent)}#align-bar .ab-val{width:38px;border:0;outline:0;background:transparent;font:12px var(--mono);color:var(--ink);text-align:right}#align-bar .ab-num small{font:11px var(--mono);color:var(--muted)}#guides{position:absolute;left:0;top:0;overflow:visible;pointer-events:none;z-index:8}#guides line{stroke:#ff2d55;stroke-width:calc(.6px / var(--z, 1));shape-rendering:crispEdges}#dup-ghost{position:absolute;pointer-events:none;border:calc(1.5px / var(--z, 1)) dashed var(--accent);background:var(--accent-soft);border-radius:2px}#dup-ghost span{position:absolute;left:0;bottom:100%;transform-origin:0 100%;scale:calc(1 / var(--z, 1));padding-bottom:6px;font:500 12.5px var(--font);color:var(--accent);white-space:nowrap}#viewport.alt[data-tool=select] .frame-label{cursor:copy}#viewport[data-tool=frame],#viewport[data-tool=frame] .shield{cursor:crosshair}#draw-box{position:absolute;border:calc(1.5px / var(--z, 1)) solid var(--accent);background:var(--accent-soft);pointer-events:none}#draw-box span{position:absolute;left:50%;top:100%;transform-origin:50% 0;translate:-50% 0;scale:calc(1 / var(--z, 1));margin-top:6px;font:500 11px/1 var(--mono);color:#fff;background:var(--accent);padding:4px 6px;border-radius:4px;white-space:nowrap}.frame-label .dims{flex:none;display:none;font:500 10.5px/1 var(--mono);color:var(--muted)}.frame.selected .frame-label .dims{display:inline}.frame .empty-hint{position:absolute;inset:0;display:none;pointer-events:none}.frame .empty-hint b{position:absolute;left:var(--plx, 11%);right:var(--plx, 11%);top:var(--pty, 27%);color:#b9b9c0;font:500 var(--pfs, 30px)/1.25 var(--font);letter-spacing:-.022em}.frame[data-on=dark] .empty-hint b{color:#fff6}.frame[data-on=canvas] .empty-hint b{color:var(--muted)}.frame.empty.prompting .empty-hint{display:none}.frame.empty .empty-hint{display:flex}.frame.empty .frame-body{box-shadow:0 0 0 1px var(--line-strong),var(--frame-shadow)}.panel{position:fixed;right:12px;top:60px;z-index:21;width:268px;max-height:calc(100vh - 140px);overflow:auto;background:var(--surface);border:1px solid var(--line);border-radius:12px;box-shadow:var(--shadow-lg);padding:10px}.panel-head{display:flex;align-items:center;justify-content:space-between;font-weight:600;padding:2px 2px 10px}.panel-head span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fp-quick{display:grid;grid-template-columns:repeat(3,1fr);gap:6px}.fp-q{display:flex;flex-direction:column;align-items:center;gap:3px;padding:10px 4px 8px;border-radius:10px;border:1px solid var(--line);background:var(--surface-2)}.fp-q:hover{border-color:var(--accent);background:var(--accent-soft)}.fp-q svg{width:22px;height:22px;fill:none;stroke:var(--ink-2);stroke-width:1.6;stroke-linecap:round;margin-bottom:2px}.fp-q b{font-weight:500;font-size:12.5px}.fp-q small,.fp-row small{font:10.5px/1 var(--mono);color:var(--muted)}.fp-hint{color:var(--muted);font-size:12px;margin:10px 2px}.fp-group{border-top:1px solid var(--line);padding:6px 0}.fp-group summary{cursor:pointer;font-weight:500;font-size:12.5px;color:var(--ink-2);padding:4px 2px}.fp-row{display:flex;justify-content:space-between;align-items:center;width:100%;padding:7px 6px;border-radius:7px;font-size:12.5px;text-align:left}.fp-row:hover{background:var(--surface-2)}.fp-custom,.fp-size{display:flex;gap:6px;align-items:center;border-top:1px solid var(--line);padding-top:10px;margin-top:4px}.fp-size{border-top:0;padding-top:0;margin:0 0 8px}.fp-custom label,.fp-size label{flex:1;display:flex;align-items:center;gap:6px;height:32px;padding:0 8px;border-radius:8px;border:1px solid var(--line);background:var(--surface-2);font:500 11px var(--mono);color:var(--muted)}.fp-custom input,.fp-size input{width:100%;min-width:0;border:0;outline:0;background:transparent;font:12.5px var(--mono);color:var(--ink)}.fp-custom label:focus-within,.fp-size label:focus-within{border-color:var(--accent)}.fp-chips{display:flex;gap:4px;margin-bottom:6px}.fp-chip{flex:1;height:28px;border-radius:7px;border:1px solid var(--line);font-size:12px;font-weight:500;color:var(--ink-2)}.fp-chip:hover{background:var(--surface-2)}.fp-chip.on{border-color:var(--ink);color:var(--ink)}#fp-describe{display:block;margin:12px 2px 2px;text-align:left}#viewport.dragging iframe,#viewport.panning iframe{pointer-events:none}#agent-pill.offline .agent-dot{background:var(--muted);box-shadow:none}@keyframes spin{to{transform:rotate(360deg)}}@keyframes shimmer{0%{background-position:125% 0}to{background-position:-125% 0}}@keyframes sweep{0%{left:-35%}to{left:100%}}@keyframes ring{0%{opacity:.9;transform:scale(.9)}to{opacity:0;transform:scale(1.35)}}@keyframes pulse{50%{opacity:.45}}@keyframes fadeout{0%,70%{opacity:1}to{opacity:0}}@media(max-width:640px){.canvas-name,.sep{display:none}#toolbar{bottom:12px}#zoom{display:none}.pop,.menu{width:calc(100vw - 32px)}}#composer{width:340px;padding:0;border-radius:18px}#composer.prompt{width:400px;padding:14px 0 0}#composer.prompt .prompt-head,#composer.prompt .prompt-ideas{margin-left:14px;margin-right:14px}#composer.prompt.onpage{--p-ink: #17171A;--p-2: #48484D;--p-mut: #88888F;--p-ph: #B9B9C0;--p-line: #E4E4E7;--p-hover: #F4F4F5;--p-on: #fff;display:flex;flex-direction:column;gap:calc(var(--pfs, 24px) * .6);padding:0;background:none;border:0;border-radius:0;box-shadow:none;animation:none}#composer.prompt.onpage[hidden]{display:none}#composer.prompt.onpage[data-on=dark]{--p-ink: #fff;--p-2: rgba(255,255,255,.82);--p-mut: rgba(255,255,255,.6);--p-ph: rgba(255,255,255,.4);--p-line: rgba(255,255,255,.2);--p-hover: rgba(255,255,255,.12);--p-on: #17171A}#composer.prompt.onpage[data-on=canvas]{--p-ink: var(--ink);--p-2: var(--ink-2);--p-mut: var(--muted);--p-ph: var(--muted);--p-line: var(--line);--p-hover: var(--surface-2);--p-on: var(--paper)}#composer.prompt.onpage .prompt-head,#composer.prompt.onpage .c-chips{display:none}#composer.prompt.onpage .cbox{display:contents}#composer.prompt.onpage textarea{order:1;min-height:0;max-height:45vh;padding:0;color:var(--p-ink);caret-color:#2f5bff;font:500 var(--pfs, 24px)/1.25 var(--font);letter-spacing:-.022em}#composer.prompt.onpage textarea::placeholder{color:var(--p-ph)}#composer.prompt.onpage .c-files{order:2}#composer.prompt.onpage .prompt-ideas{order:3;margin:0}#composer.prompt.onpage .prompt-ideas button{background:none;border-color:var(--p-line);color:var(--p-2)}#composer.prompt.onpage .prompt-ideas button:hover{background:var(--p-hover);border-color:var(--p-line);color:var(--p-ink)}#composer.prompt.onpage .c-foot{order:4;margin-left:0;padding-top:8px;border-top:1px solid var(--p-line)}#composer.prompt.onpage .c-foot>:first-child{margin-left:-6px}#composer.prompt.onpage .c-btn,#composer.prompt.onpage .c-model{color:var(--p-mut)}#composer.prompt.onpage .c-btn:hover,#composer.prompt.onpage .c-model.pick:hover{background:var(--p-hover);color:var(--p-ink)}#composer.prompt.onpage .c-send{background:var(--p-ink);color:var(--p-on)}.cbox{display:flex;flex-direction:column;gap:6px;padding:12px 8px 8px 14px;border-radius:inherit}.cbox.drop{box-shadow:inset 0 0 0 2px var(--accent);background:var(--accent-soft)}.cbox textarea{width:100%;resize:none;border:0;outline:0;background:transparent;color:var(--ink);font:14px/1.45 var(--font);max-height:180px;padding:2px 6px 2px 0}.cbox textarea::placeholder{color:var(--muted)}.c-chips{display:flex;gap:6px;flex-wrap:wrap}.c-chips:not(:has(.chip:not([hidden]))){display:none}.c-foot{display:flex;align-items:center;gap:2px;margin-left:-6px}.c-model{margin-left:auto;margin-right:2px;font-size:12.5px;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0}.c-btn,.c-send{flex:none;width:30px;height:30px;border-radius:50%;display:grid;place-items:center;color:var(--ink-2)}.c-btn:hover{background:var(--surface-2);color:var(--ink)}.c-btn svg,.c-send svg{width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round}.c-btn.on{color:#fff;background:var(--mark);animation:micPulse 1.4s ease-in-out infinite}@keyframes micPulse{50%{box-shadow:0 0 0 5px #e5484d2e}}.c-send{margin-left:2px;background:var(--accent);color:#fff}.c-send svg{stroke-width:1.9}.c-send:disabled{opacity:.3;cursor:default}.c-files{display:flex;flex-wrap:wrap;gap:6px;padding-right:6px}.c-file{position:relative;height:48px;max-width:180px;display:flex;align-items:center;gap:6px;padding:0 10px;border-radius:10px;background:var(--surface-2);border:1px solid var(--line);font-size:12px;color:var(--ink-2)}.c-file span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.c-file svg{flex:none;width:15px;height:15px;fill:none;stroke:currentColor;stroke-width:1.4}.c-file.img{width:48px;padding:0;overflow:hidden}.c-file.img img{width:100%;height:100%;object-fit:cover}.c-file button{position:absolute;top:3px;right:3px;width:16px;height:16px;border-radius:50%;background:#000000a6;color:#fff;display:none;place-items:center}.c-file button svg{width:10px;height:10px;stroke:#fff;stroke-width:1.6}.c-file:hover button{display:grid}#thread{width:360px;border-radius:18px;max-height:min(72vh,620px)}.t-tools{display:flex;justify-content:flex-end;gap:2px;padding:6px 6px 0;opacity:0;transition:opacity .15s}#thread:hover .t-tools,#thread:focus-within .t-tools{opacity:1}#thread .thread-body{overflow:auto;padding:0 14px 10px;display:flex;flex-direction:column;gap:14px}.m-user{align-self:flex-end;max-width:86%;display:flex;flex-direction:column;align-items:flex-end;gap:4px}.m-user .bubble{background:color-mix(in srgb,var(--accent) 20%,var(--surface));color:var(--ink);padding:8px 12px;border-radius:16px;white-space:pre-wrap;word-wrap:break-word;font-size:13.5px;line-height:1.45}.m-meta{font-size:11px;color:var(--muted);opacity:0;transition:opacity .15s}.m-user:hover .m-meta{opacity:1}.m-files{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:6px}.m-files img{display:block;max-width:150px;max-height:110px;border-radius:10px;border:1px solid var(--line)}.m-files a.f{display:inline-flex;align-items:center;gap:6px;max-width:200px;padding:6px 10px;border-radius:10px;background:var(--surface-2);border:1px solid var(--line);font-size:12px;color:var(--ink-2);text-decoration:none}.m-files a.f span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.m-files a.f svg{flex:none;width:14px;height:14px;fill:none;stroke:currentColor;stroke-width:1.4}.m-agent{font-size:13.5px;line-height:1.5;color:var(--ink)}.m-worked{font-size:12px;color:var(--muted);padding-bottom:6px;margin-bottom:6px;border-bottom:1px solid var(--line)}.m-text{white-space:pre-wrap;word-wrap:break-word}.m-agent.error .m-text{color:var(--mark)}.m-agent.quiet .m-text{color:var(--muted)}.m-acts{display:flex;align-items:center;gap:12px;min-height:22px;margin-top:4px;font-size:12px;color:var(--muted);opacity:0;transition:opacity .15s}.m-agent:hover .m-acts,.m-acts.show{opacity:1}.m-acts button{font:500 12px/1 var(--font);color:var(--ink-2);padding:4px 6px;margin:0 -6px;border-radius:6px}.m-acts button:hover{background:var(--surface-2);color:var(--ink)}.m-acts button.primary{color:var(--accent)}.m-work{display:flex;align-items:center;gap:8px;font-size:12.5px;color:var(--muted)}.m-work .spin{flex:none;width:12px;height:12px;border-radius:50%;border:1.6px solid var(--accent-soft);border-top-color:var(--accent);animation:spin .7s linear infinite}#thread .thread-reply{display:block;padding:0 8px 8px;border-top:0}#thread .thread-reply .cbox{background:var(--surface-2);border:1px solid var(--line);border-radius:16px;padding:10px 6px 6px 12px}#thread .t-tools{align-items:center;gap:2px;padding:8px 8px 6px 14px}.t-state{margin-right:auto;font-size:12px;font-weight:500;color:var(--muted)}.t-btn{width:28px;height:28px;border-radius:8px;display:grid;place-items:center;color:var(--muted)}.t-btn:hover{background:var(--surface-2);color:var(--ink)}.t-btn svg,.t-menu svg,.cp-x svg,.cp-res svg,.comments-btn svg{width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round}.t-btn[data-act=more] svg{fill:currentColor;stroke:none}.t-more{position:relative}.t-menu{position:absolute;right:0;top:32px;z-index:2;min-width:150px;padding:4px;border-radius:10px;background:var(--surface);border:1px solid var(--line);box-shadow:var(--shadow-lg)}.t-menu:not([hidden]){display:block}.t-menu button{width:100%;display:flex;align-items:center;gap:8px;padding:7px 8px;border-radius:7px;font-size:12.5px;color:var(--mark)}.t-menu button:hover{background:#e5484d14}#thread .thread-body{padding-top:2px;gap:16px}.m-agent{display:grid;grid-template-columns:18px 1fr;gap:9px}.m-mark{width:18px;height:18px;margin-top:1px;display:grid;place-items:center;color:var(--muted)}.m-mark svg{width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:2.4}.m-body{min-width:0}.m-agent.error .m-mark{color:var(--mark)}.m-acts span{color:var(--muted)}.comments-btn{gap:6px}.comments-btn.has span{font-weight:600;color:var(--ink)}#comments-panel{position:fixed;z-index:24;top:60px;right:12px;width:352px;max-height:calc(100vh - 150px);display:flex;flex-direction:column;background:var(--surface);border:1px solid var(--line);border-radius:16px;box-shadow:var(--shadow-lg);overflow:hidden}#comments-panel[hidden]{display:none}.cp-head{display:flex;align-items:center;gap:10px;padding:12px 10px 10px 16px}.cp-head>b{font-size:14px;font-weight:600}.cp-tabs{display:flex;gap:2px;padding:2px;margin-left:auto;border-radius:9px;background:var(--surface-2)}.cp-tabs button{padding:5px 10px;border-radius:7px;font:500 12px/1 var(--font);color:var(--muted)}.cp-tabs button span{margin-left:2px}.cp-tabs button.on{background:var(--surface);color:var(--ink);box-shadow:0 1px 2px #0000001f}.cp-x{width:28px;height:28px;border-radius:8px;display:grid;place-items:center;color:var(--muted)}.cp-x:hover{background:var(--surface-2);color:var(--ink)}.cp-list{overflow:auto;padding:0 6px 6px}.cp-item{position:relative;display:flex;gap:10px;padding:10px;border-radius:12px;cursor:pointer}.cp-item+.cp-item{margin-top:2px}.cp-item:hover,.cp-item.on{background:var(--surface-2)}.cp-av{flex:none;width:24px;height:24px;border-radius:50%;display:grid;place-items:center;color:#fff;font:600 10px/1 var(--font)}.cp-main{min-width:0;flex:1;display:flex;flex-direction:column;gap:3px}.cp-top{display:flex;align-items:baseline;gap:6px;font-size:12px;color:var(--muted);padding-right:26px}.cp-top b{color:var(--ink);font-weight:600;font-size:12.5px}.cp-where{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}.cp-top time{margin-left:auto;flex:none}.cp-text{font-size:13px;line-height:1.45;color:var(--ink);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.cp-foot{display:flex;align-items:center;gap:10px;font-size:12px;color:var(--muted);min-width:0}.cp-foot:empty{display:none}.cp-reply{display:flex;align-items:center;gap:5px;min-width:0}.cp-reply span:last-child{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.cp-reply .m-mark{width:14px;height:14px;margin:0;flex:none}.cp-reply .m-mark svg{width:12px;height:12px}.cp-n{flex:none}.cp-st{display:inline-flex;align-items:center;gap:5px}.cp-st i{width:6px;height:6px;border-radius:50%;background:var(--muted)}.cp-st.working i{background:var(--accent);animation:micPulse 1.4s infinite}.cp-st.wait i{background:#e5a500}.cp-st.err{color:var(--mark)}.cp-st.err i{background:var(--mark)}.cp-res{position:absolute;top:8px;right:8px;width:26px;height:26px;border-radius:7px;display:grid;place-items:center;color:var(--muted);opacity:0}.cp-item:hover .cp-res{opacity:1}.cp-res:hover{background:var(--surface);color:var(--ink)}.cp-empty{padding:28px 16px 32px;text-align:center;font-size:12.5px;color:var(--muted)}#composer-ink{display:inline-flex;align-items:center;gap:5px;color:var(--ink-2);background:var(--surface-2);border:1px solid var(--line)}#composer-ink[hidden]{display:none}#composer-ink svg{width:12px;height:12px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}.m-marks{display:inline-flex;align-items:center;gap:5px;padding:3px 9px;border-radius:99px;font:500 11.5px/1.4 var(--font);color:var(--ink-2);background:var(--surface-2);border:1px solid var(--line)}.m-marks:hover{color:var(--ink);border-color:var(--line-strong)}.m-marks.on{color:var(--mark);border-color:#e5484d59}.m-marks svg{width:11px;height:11px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}.m-user .bubble{display:flex;flex-direction:column;gap:6px}.m-user .bubble.has-files{padding-top:6px}.bubble .m-files{justify-content:flex-start;margin:0 -6px}.bubble .m-files img{max-width:100%;max-height:160px;border-color:transparent;border-radius:11px}.bubble .m-files a.f{background:color-mix(in srgb,var(--surface) 55%,transparent);border-color:transparent}.bubble .m-marks{align-self:flex-start;margin:0 -4px -2px;background:color-mix(in srgb,var(--surface) 55%,transparent);border-color:transparent}.bubble .m-marks.on{border-color:#e5484d59}.c-steer{flex:none;height:24px;padding:0 9px;margin-left:4px;border-radius:99px;font:500 11.5px/1 var(--font);color:var(--muted);border:1px solid var(--line);background:transparent}.c-steer:hover{color:var(--ink)}.c-steer.on{color:var(--accent);border-color:color-mix(in srgb,var(--accent) 40%,transparent);background:var(--accent-soft)}.m-agent .m-text{line-height:1.55}.area,.deep-box{border:0!important;background:none!important;border-radius:0!important}.area:before,.deep-box:before{display:none!important}.area:after,.deep-box:after{content:"";position:absolute;inset:-16%;border-radius:46%;pointer-events:none;background:linear-gradient(105deg,transparent 32%,rgba(255,255,255,.55) 48%,rgba(255,255,255,.2) 54%,transparent 68%),radial-gradient(42% 52% at 32% 42%,rgba(124,152,255,.55),transparent 72%),radial-gradient(46% 56% at 70% 60%,rgba(197,139,255,.45),transparent 72%),radial-gradient(38% 44% at 55% 30%,rgba(124,212,255,.35),transparent 72%);background-size:260% 100%,100% 100%,100% 100%,100% 100%;-webkit-backdrop-filter:blur(4px) saturate(1.2);backdrop-filter:blur(4px) saturate(1.2);-webkit-mask-image:radial-gradient(closest-side,#000 52%,rgba(0,0,0,.6) 72%,transparent 100%);mask-image:radial-gradient(closest-side,#000 52%,rgba(0,0,0,.6) 72%,transparent 100%);animation:auraShimmer 2.6s linear infinite,auraBreathe 3.4s ease-in-out infinite}.deep-box:after{inset:calc(-24% - 8px);filter:saturate(1.4)}.area.working:after{animation-duration:1.5s,2.2s;-webkit-backdrop-filter:blur(6px) saturate(1.3);backdrop-filter:blur(6px) saturate(1.3)}@keyframes auraShimmer{0%{background-position:130% 0,0 0,0 0,0 0}to{background-position:-130% 0,0 0,0 0,0 0}}@keyframes auraBreathe{0%,to{transform:scale(1);filter:hue-rotate(0deg)}50%{transform:scale(1.05);filter:hue-rotate(28deg)}}.area{transition:opacity .45s ease}#ink g.auras .aura-stroke{fill:none;stroke-width:26;stroke-linecap:round;stroke-linejoin:round;opacity:.75;animation:auraPulse 2.2s ease-in-out infinite}@keyframes auraPulse{50%{opacity:.45}}@media(prefers-reduced-motion:reduce){.area:after,.deep-box:after,#ink g.auras .aura-stroke{animation:none}}#thread{max-height:min(56vh,440px)}#thread .t-title{display:none;margin-right:auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:13px;font-weight:600;color:var(--ink)}#thread.docked{left:12px!important;top:60px!important;bottom:84px;width:380px;max-height:none;height:auto;animation:dockIn .18s ease-out}#thread.docked .t-tools{opacity:1;padding:10px 8px 8px 16px;border-bottom:1px solid var(--line);margin-bottom:10px}#thread.docked .t-title{display:block}#thread.docked .t-state{margin-right:4px}#thread.docked .thread-body{flex:1}@keyframes dockIn{0%{opacity:0;transform:translate(-8px)}}.m-opts{display:flex;flex-wrap:wrap;align-items:center;gap:6px;margin-top:10px}.m-opts .opt{display:inline-flex;align-items:center;gap:6px;height:30px;padding:0 11px 0 5px;border-radius:99px;border:1px solid var(--line);background:var(--surface-2);color:var(--ink);font:500 12.5px/1 var(--font);cursor:pointer;transition:border-color .15s,background .15s}.m-opts .opt b{display:grid;place-items:center;width:20px;height:20px;border-radius:50%;background:var(--surface);color:var(--ink-2);font:600 11px/1 var(--font)}.m-opts .opt:hover{border-color:var(--line-strong)}.m-opts .opt.on{border-color:var(--accent);background:var(--accent-soft)}.m-opts .opt.on b{background:var(--accent);color:#fff}.m-opts .opt[disabled]{cursor:default}.opt-note{font-size:11.5px;color:var(--muted)}.opt-acts{display:inline-flex;gap:6px;margin-left:2px}.opt-use{height:30px;padding:0 12px;border-radius:99px;background:var(--accent);color:#fff;font:600 12.5px/1 var(--font)}.opt-orig{height:30px;padding:0 10px;border-radius:99px;color:var(--muted);font:500 12.5px/1 var(--font)}.opt-orig:hover{color:var(--ink);background:var(--surface-2)}.m-opts.chosen .opt{cursor:default}.m-text.md{white-space:normal}.m-text.md p{margin:0}.m-text.md p+p,.m-text.md ul+p,.m-text.md p+ul{margin-top:8px}.m-text.md ul{margin:0;padding-left:18px}.m-text.md li+li{margin-top:4px}.m-text.md code{font:12px/1.4 var(--mono);padding:1px 5px;border-radius:5px;background:var(--surface-2)}.m-text.md b{font-weight:600}.bubble .m-files{gap:6px}.bubble .m-files a{display:block;flex:none}.bubble .m-files img{width:auto;height:88px;max-width:132px;max-height:88px;object-fit:cover;border-radius:10px}.bubble .m-files a:only-child img{max-width:160px}.frame>.stage-btn{position:absolute;right:0;bottom:100%;margin-bottom:calc(5px / var(--z, 1));transform-origin:100% 100%;scale:calc(1 / var(--z, 1));display:inline-flex;align-items:center;gap:4px;height:22px;padding:0 8px 0 6px;border-radius:7px;font:500 11.5px/1 var(--font);color:var(--muted);background:var(--surface);border:1px solid var(--line);opacity:0;pointer-events:none;transition:opacity .15s;z-index:9;cursor:pointer}.frame>.stage-btn svg{width:12px;height:12px;fill:none;stroke:currentColor;stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round}.frame:hover>.stage-btn,.frame.selected>.stage-btn,.frame.live>.stage-btn{opacity:1;pointer-events:auto}.frame>.stage-btn:hover{color:var(--ink);border-color:var(--line-strong)}body.staging .frame.staged>.stage-btn{opacity:1;pointer-events:auto;color:var(--accent)}body.staging .frame.staged>.stage-btn span:after{content:" \b7 on"}.frame:hover .frame-label,.frame.selected .frame-label{max-width:calc(var(--fw) * var(--z, 1) - 74px)}body.staging #world .frame:not(.staged){opacity:.04;pointer-events:none}#world .frame{transition:opacity .35s ease}body.staging #ink,body.staging #canvas-pins,body.staging .frame:not(.staged) .pins{opacity:0;pointer-events:none;transition:opacity .3s}body.staging #viewport{background-image:none!important}body.staging .frame.staged .frame-label .dims,body.staging .frame.staged .frame-label .kind{display:none}#stage-bar{position:fixed;z-index:40;top:14px;left:50%;transform:translate(-50%);display:flex;align-items:center;gap:4px;padding:5px;border-radius:14px;background:var(--surface);border:1px solid var(--line);box-shadow:var(--shadow-lg);animation:sbIn .25s ease-out;max-width:calc(100vw - 24px)}@keyframes sbIn{0%{opacity:0;transform:translate(-50%,-6px)}}#stage-bar svg{width:15px;height:15px;fill:none;stroke:currentColor;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;flex:none}.sb-btn{width:30px;height:30px;border-radius:9px;display:grid;place-items:center;color:var(--ink-2)}.sb-btn:hover:not([disabled]){background:var(--surface-2);color:var(--ink)}.sb-btn[disabled]{opacity:.35}.sb-name{display:flex;flex-direction:column;align-items:center;min-width:120px;max-width:220px;padding:0 6px;line-height:1.2}.sb-name b{font-size:13px;font-weight:600;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sb-name span{font:500 10.5px/1.3 var(--mono);color:var(--muted)}.sb-sep{width:1px;height:20px;background:var(--line);margin:0 4px}.sb-tog{display:inline-flex;align-items:center;gap:6px;height:30px;padding:0 10px;border-radius:9px;font:500 12.5px/1 var(--font);color:var(--ink-2)}.sb-tog:hover{background:var(--surface-2);color:var(--ink)}.sb-tog.on{background:var(--accent-soft);color:var(--accent)}.sb-tog svg{width:14px!important;height:14px!important}.sb-exit{display:inline-flex;align-items:center;gap:6px;height:30px;padding:0 12px 0 9px;border-radius:9px;font:600 12.5px/1 var(--font);color:var(--ink);background:var(--surface-2)}.sb-exit:hover{background:var(--line)}.frame.staged.device .frame-body{border-radius:46px;box-shadow:none}.frame.staged.device:before{content:"";position:absolute;inset:-13px;z-index:-1;border-radius:59px;background:linear-gradient(150deg,#4a4a4e,#1f1f22 18%,#0e0e10 60%,#2b2b2f);box-shadow:inset 0 0 0 1.5px #5c5c60,inset 0 0 0 4px #121214,0 40px 90px -20px #000000bf,0 0 0 1px #0009}.frame.staged.device:after{content:"";position:absolute;right:-16px;top:24%;width:3px;height:92px;border-radius:2px;background:linear-gradient(90deg,#3a3a3e,#1a1a1c);z-index:-1}.frame.staged.device .frame-body:after{content:"";position:absolute;z-index:8;left:50%;top:11px;width:124px;height:36px;transform:translate(-50%);border-radius:20px;background:#000;pointer-events:none}.frame.staged.device.landscape .frame-body:after{left:11px;top:50%;width:36px;height:124px;transform:translateY(-50%)}.frame.staged.device.landscape:after{right:auto;left:22%;top:-16px;width:92px;height:3px}.area:after,.deep-box:after{background:radial-gradient(42% 52% at 32% 42%,rgba(124,152,255,.3),transparent 72%),radial-gradient(46% 56% at 70% 60%,rgba(197,139,255,.24),transparent 72%),radial-gradient(38% 44% at 55% 30%,rgba(124,212,255,.18),transparent 72%);background-size:100% 100%;-webkit-backdrop-filter:blur(5px) saturate(1.15);backdrop-filter:blur(5px) saturate(1.15);-webkit-mask-image:radial-gradient(closest-side,#000 52%,rgba(0,0,0,.6) 72%,transparent 100%),linear-gradient(105deg,#000 0 38%,rgba(0,0,0,.15) 47%,rgba(0,0,0,.15) 53%,#000 62% 100%);mask-image:radial-gradient(closest-side,#000 52%,rgba(0,0,0,.6) 72%,transparent 100%),linear-gradient(105deg,#000 0 38%,#00000026 47% 53%,#000 62% 100%);-webkit-mask-size:100% 100%,320% 100%;mask-size:100% 100%,320% 100%;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-composite:source-in;mask-composite:intersect;animation:auraClear 7s ease-in-out infinite,auraBreathe 6s ease-in-out infinite}.area.working:after{animation-duration:5s,5s}@keyframes auraClear{0%{-webkit-mask-position:0 0,100% 0;mask-position:0 0,100% 0}to{-webkit-mask-position:0 0,0% 0;mask-position:0 0,0% 0}}@media(prefers-reduced-motion:reduce){.area:after,.deep-box:after{animation:none}}.frame>.opt-strip{position:absolute;left:0;bottom:100%;margin-bottom:calc(34px / var(--z, 1));transform-origin:0 100%;scale:calc(1 / var(--z, 1));z-index:10;display:flex;align-items:flex-end;gap:8px;padding:8px;border-radius:14px;background:var(--surface);border:1px solid var(--line);box-shadow:var(--shadow-lg);animation:sbIn .25s ease-out}.os-label{align-self:center;writing-mode:vertical-rl;transform:rotate(180deg);font:600 10px/1 var(--font);letter-spacing:.1em;text-transform:uppercase;color:var(--muted)}.os-tile{display:flex;flex-direction:column;gap:6px;padding:0;border:0;background:none;cursor:pointer;text-align:left;color:var(--ink-2)}.os-img{display:grid;place-items:center;border-radius:8px;overflow:hidden;background:var(--surface-2);box-shadow:0 0 0 1px var(--line);transition:box-shadow .15s,transform .15s}.os-img img{width:100%;height:100%;object-fit:cover;object-position:top center;display:block}.os-img b{font:600 18px/1 var(--font);color:var(--muted)}.os-tile:hover .os-img{transform:translateY(-1px);box-shadow:0 0 0 1px var(--line-strong),0 6px 16px #00000040}.os-tile.on .os-img{box-shadow:0 0 0 2px var(--accent)}.os-name{display:flex;align-items:center;gap:5px;max-width:150px;font:500 11.5px/1.2 var(--font);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.os-name i{font-style:normal;display:grid;place-items:center;width:15px;height:15px;border-radius:50%;background:var(--surface-2);font:600 9.5px/1 var(--font);flex:none}.os-tile.on .os-name{color:var(--accent)}.os-tile.on .os-name i{background:var(--accent);color:#fff}.os-use{align-self:center;height:32px;padding:0 14px;margin-left:2px;border-radius:99px;background:var(--accent);color:#fff;font:600 12.5px/1 var(--font);white-space:nowrap}body.staging .frame:not(.staged)>.opt-strip{display:none}body.staging .frame.staged>.stage-btn{height:32px;padding:0 14px 0 11px;gap:7px;border-radius:10px;font:600 13px/1 var(--font);color:#fff;background:var(--accent);border-color:var(--accent);box-shadow:0 6px 18px -6px color-mix(in srgb,var(--accent) 70%,transparent);margin-bottom:calc(8px / var(--z, 1))}body.staging .frame.staged>.stage-btn svg{width:14px;height:14px}body.staging .frame.staged>.stage-btn span{font-size:0}body.staging .frame.staged>.stage-btn span:after{content:"Exit stage";font-size:13px}body.staging .frame.staged>.stage-btn:hover{filter:brightness(1.08)}.frame>.edge-zone{position:absolute;left:0;right:0;bottom:100%;height:calc(40px / var(--z, 1))}.frame>.stage-btn{visibility:hidden;transition:opacity .18s ease .35s,visibility 0s linear .53s}.frame:hover>.stage-btn,.frame.selected>.stage-btn,.frame.live>.stage-btn,body.staging .frame.staged>.stage-btn{visibility:visible;transition-delay:0s,0s}.frame>.stage-btn{pointer-events:auto}.area:not(.working),.deep-box{border:calc(1.5px / var(--z, 1)) solid var(--accent)!important;background:#2f5bff14!important;border-radius:calc(4px / var(--z, 1))!important}.area.picking{border-style:dashed!important}.area:not(.working):after,.deep-box:after{display:none!important}.deep-box:before{display:block!important}.area.working:after{animation-duration:3.2s,4s}.area.working:before{content:""!important;display:block!important;position:absolute;border-radius:22%;pointer-events:none;background:none;padding:0;scale:none;margin:0;font-size:0;inset:-6%;width:auto;height:auto;box-shadow:0 0 0 1px #a0afff73,0 0 16px 3px #8296ff73,0 0 34px 8px #af87ff38,inset 0 0 18px 2px #a091ff59;animation:edgeGlow 2.6s ease-in-out infinite}@keyframes edgeGlow{50%{box-shadow:0 0 0 1px #aab9ffa6,0 0 22px 5px #8ca0ff99,0 0 44px 12px #b991ff4d,inset 0 0 22px 3px #aa9bff73}}@media(prefers-reduced-motion:reduce){.area.working:before{animation:none}}.frame>.edge-zone{z-index:0}.frame>.frame-label{z-index:2}#viewport.dragging[data-tool=select]:not(.panning){cursor:default}.m{display:contents}#peek{z-index:26;width:340px;max-height:340px;padding:12px 0 0;border-radius:18px;display:flex;flex-direction:column;cursor:pointer;overflow:hidden}#peek[hidden]{display:none}#peek.at-pin,#thread.at-pin:not(.docked){border-bottom-left-radius:5px}#peek.in{animation:cardOpen .24s cubic-bezier(.2,.8,.2,1)}#peek.in>*{animation:softFade .2s ease .07s both}@keyframes cardOpen{0%{clip-path:inset(calc(100% - 26px) calc(100% - 34px) 0 0 round 13px 13px 13px 3px)}to{clip-path:inset(0 0 0 0 round 18px 18px 18px 5px)}}@keyframes softFade{0%{opacity:0}}#peek .thread-body{padding:0 14px 10px;display:flex;flex-direction:column;gap:12px;overflow:hidden}#peek .b-text,#peek .m-text{display:-webkit-box;-webkit-box-orient:vertical;overflow:hidden}#peek .b-text{-webkit-line-clamp:4}#peek .m-text{-webkit-line-clamp:5}#peek .m-acts,#peek .m-meta,#peek .m-opts,#peek .m-work .a-btn{display:none}#peek .bubble .m-files img{height:56px}.pk-gap{align-self:center;font-size:11.5px;color:var(--muted)}.pk-bar{display:flex;align-items:center;gap:2px;padding:0 8px 8px 14px}.pk-who{margin-right:auto;font-size:11.5px;color:var(--muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}#thread.in:not(.docked){animation:threadOpen .2s cubic-bezier(.2,.8,.2,1);transform-origin:0 100%}@keyframes threadOpen{0%{opacity:.6;transform:scale(.975)}}.m-acts{gap:2px}.m-acts .a-btn,.m-work .a-btn{flex:none;width:26px;height:26px;margin:0;padding:0;border-radius:7px;display:inline-grid;place-items:center;color:var(--muted)}.a-btn svg{width:15px;height:15px;fill:none;stroke:currentColor;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round}.a-btn [d^="M5.5 3.5v9"]{fill:currentColor;stroke:none}.m-acts .a-btn:hover,.m-work .a-btn:hover{background:var(--surface-2);color:var(--ink)}.m-acts .a-btn.lbl{width:auto;display:inline-flex;align-items:center;gap:5px;padding:0 9px 0 6px;font:500 12px/1 var(--font)}.m-acts .a-btn.primary{color:var(--accent);background:var(--accent-soft);margin-right:4px}.m-acts .a-btn.primary:hover{color:var(--accent);background:color-mix(in srgb,var(--accent) 20%,transparent)}.m-acts .a-btn.ok{color:var(--ok)}.m-acts .a-btn+span,.m-acts .a-btn+time{margin-left:6px}.m-acts span+time:before{content:"\b7 "}.m-work{min-height:22px}.m-work .m-time{font:11px/1 var(--mono);color:var(--muted)}.m-work .a-btn{margin-left:auto;opacity:0;transition:opacity .15s}.m-agent:hover .m-work .a-btn,.m-work .a-btn:focus-visible{opacity:1}.m-work .a-btn:hover{color:var(--mark)}.m-stream{margin-top:6px;color:var(--ink-2)}.frame .progress,.frame-label .spinner{display:none!important}.frame.working .frame-body{box-shadow:0 0 0 1px var(--line),var(--frame-shadow)}.frame.working.selected .frame-body{box-shadow:0 0 0 calc(1.5px / var(--z, 1)) var(--accent),var(--frame-shadow)}.frame.working .frame-label .stop{display:none}.frame.working:hover .frame-label .stop,.frame.working.selected .frame-label .stop{display:inline-block}.pill.busy .agent-dot{animation:none}.frame iframe.incoming{visibility:hidden}.frame>.stage-btn{display:none!important}#edge{position:fixed;z-index:19;display:flex;gap:4px;animation:softFade .15s ease}#edge[hidden]{display:none}.eg-btn{display:inline-flex;align-items:center;gap:5px;height:24px;padding:0 9px 0 7px;border-radius:8px;font:500 11.5px/1 var(--font);color:var(--muted);background:transparent}.eg-btn svg{width:13px;height:13px;flex:none;fill:none;stroke:currentColor;stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round}.eg-btn:hover{color:var(--ink);background:var(--surface-2)}#edge.compact .eg-btn{padding:0 6px}#edge.compact .eg-btn span{display:none}#edge.inside .eg-btn{background:var(--surface);box-shadow:0 0 0 1px var(--line),var(--shadow);color:var(--ink-2)}#edge.inside .eg-btn:hover{background:var(--surface-2)}#edge.exit .eg-btn{height:32px;padding:0 14px 0 11px;gap:7px;border-radius:10px;font:600 13px/1 var(--font);color:#fff;background:var(--accent);box-shadow:0 6px 18px -6px color-mix(in srgb,var(--accent) 70%,transparent)}#edge.exit .eg-btn:hover{filter:brightness(1.08);background:var(--accent);color:#fff}.frame:hover .frame-label,.frame.selected .frame-label,.frame.live .frame-label{max-width:calc(var(--fw) * var(--z, 1) - 78px)}#viewport[data-tool=select] .frame:not(.selected):has(>.frame-label:hover) .frame-body{box-shadow:0 0 0 calc(1.5px / var(--z, 1)) var(--accent),var(--frame-shadow)}#viewport[data-tool=select] .frame-label .name{transition:color .12s}#topbar{left:10px;right:10px;top:8px}.brand,.pill,.share-btn{background:color-mix(in srgb,var(--paper) 72%,transparent);-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);border:0;box-shadow:none}.brand{gap:9px;padding:5px 10px 5px 6px;border-radius:9px}.logo svg{width:18px;height:18px}.logo rect{fill:var(--ink-2)}.canvas-name{color:var(--ink);font-weight:500}.canvas-name.editable:hover{background:var(--surface-hover)}.top-right{gap:2px}.pill{height:30px;padding:0 9px;border-radius:8px;color:var(--ink-2);transition:background .12s}.pill:hover{background:var(--surface-hover);color:var(--ink)}.share-btn{font-weight:500;color:var(--ink);padding:0 11px}.comments-btn span:empty{display:none}.comments-btn.has span{font-weight:500;color:var(--ink-2)}#agent-pill{gap:0}#agent-label{max-width:0;opacity:0;overflow:hidden;white-space:nowrap;transition:max-width .3s cubic-bezier(.2,.8,.2,1),opacity .2s,margin .3s;margin-left:0;font-weight:400}#agent-pill:hover #agent-label,#agent-pill:focus-visible #agent-label,#agent-pill.say #agent-label,#agent-pill.offline #agent-label{max-width:46vw;opacity:1;margin-left:8px}.agent-dot,.pill.busy .agent-dot,.pill.inbox .agent-dot{box-shadow:none}.avatar{width:24px;height:24px;font-size:10px}.presence{margin-right:6px}.presence:empty{display:none}:root{--surface-hover: color-mix(in srgb, var(--ink) 7%, transparent)}#zoom{right:12px;bottom:14px;background:transparent;border:0;box-shadow:none;overflow:visible;opacity:.55;transition:opacity .2s}#zoom:hover,#zoom:focus-within,#zoom.awake{opacity:1}#zoom button{height:28px;min-width:28px;border-radius:7px}#zoom button:hover{background:var(--surface-hover)}#zoom-level{min-width:48px;border:0!important}#zoom-out,#zoom-in{opacity:0;transition:opacity .15s}#zoom:hover #zoom-out,#zoom:hover #zoom-in,#zoom:focus-within #zoom-out,#zoom:focus-within #zoom-in{opacity:1}#toolbar{bottom:14px;padding:4px;border-radius:13px;box-shadow:var(--shadow)}#toolbar button{width:34px;height:34px;border-radius:9px}#toolbar button:hover{background:var(--surface-hover)}#toolbar svg{width:18px;height:18px}#toolbar .tb-new{padding:0 11px 0 8px}.frame-label .kind{border:0;background:none;padding:0;text-transform:none;letter-spacing:0;font:400 11.5px/1 var(--font);opacity:0;transition:opacity .15s}.frame:hover .frame-label .kind,.frame.selected .frame-label .kind,.frame.live .frame-label .kind{opacity:1}.frame-label .ic[data-k=live]{display:none}.frame-label .count{color:var(--muted);font:500 11px/1 var(--font)}.frame.selected .frame-label .count{color:var(--accent)}.icon-btn:hover,.menu-item:hover,.t-btn:hover,.cp-x:hover,.c-btn:hover{background:var(--surface-hover)}.panel,#comments-panel{top:50px}.frame-label .count{display:inline-flex;align-items:center;gap:3px;height:18px;padding:0 5px 0 4px;margin:0 -2px;border-radius:5px;color:var(--muted);font:500 11px/1 var(--font);cursor:pointer;flex:none}.frame-label .count[hidden]{display:none}.frame-label .count svg{width:11px;height:11px;fill:none;stroke:currentColor;stroke-width:1.5;stroke-linejoin:round;stroke-linecap:round}.frame-label .count:hover{background:var(--surface-hover);color:var(--ink)}.frame.narrow .frame-label .count{display:none}body.versions-on #world{opacity:.05;pointer-events:none}#world{transition:opacity .3s ease}body.versions-on #toolbar,body.versions-on #zoom,body.versions-on #edge{opacity:0;pointer-events:none}#toolbar,#zoom{transition:opacity .2s}#tip{position:fixed;z-index:60;pointer-events:none;display:flex;align-items:center;gap:7px;max-width:280px;padding:5px 8px;border-radius:7px;background:var(--ink);color:var(--paper);font:500 11.5px/1.35 var(--font);box-shadow:0 4px 14px #00000038;animation:tipIn .09s ease-out}#tip[hidden]{display:none}#tip.up{animation-name:tipInUp}#tip kbd{flex:none;padding:1px 4px;border-radius:4px;border:0;background:color-mix(in srgb,var(--paper) 18%,transparent);color:inherit;font:500 10.5px/1.3 var(--mono)}@keyframes tipIn{0%{opacity:0;transform:translateY(-2px)}}@keyframes tipInUp{0%{opacity:0;transform:translateY(2px)}}.sb-name{min-width:96px;justify-content:center}.sb-exit{color:#fff;background:var(--accent);padding:0 13px 0 10px}.sb-exit:hover{background:var(--accent);filter:brightness(1.08)}#stage-bar .sb-btn:hover:not([disabled]),.sb-tog:hover{background:var(--surface-hover)}.eg-btn{font:500 12.5px/1 var(--font);gap:5px;padding:0 8px 0 6px}.eg-btn svg{width:13px;height:13px;display:block;position:relative;top:-.5px}.eg-btn span{display:block;line-height:16px}#peek.in,#thread.in:not(.docked){animation:none}#peek.in>*{animation:none}@keyframes cardGrow{0%{opacity:0;transform:scale(.55)}}#thread.grow:not(.docked){animation:cardSettle .12s ease-out}@keyframes cardSettle{0%{opacity:.85}}#peek,#thread{will-change:transform,opacity}@media(prefers-reduced-motion:reduce){#peek.in,#thread.in,#thread.grow{animation:none}}:root{--lz: 1}.frame-label{scale:calc(var(--lz) / var(--z, 1));max-width:calc(var(--fw) * var(--z, 1) / var(--lz));color:color-mix(in srgb,var(--muted) calc((1.5 - var(--lz)) * 200%),var(--ink-2))}.frame:hover .frame-label,.frame.selected .frame-label,.frame.live .frame-label{max-width:calc((var(--fw) * var(--z, 1) - 84px) / var(--lz))}.frame.selected .frame-label{color:var(--accent)}.frame.working .frame-label{color:var(--ink)}.eg-btn{height:calc(24px * var(--lz));font-size:calc(12.5px * var(--lz));padding:0 calc(8px * var(--lz)) 0 calc(6px * var(--lz));gap:calc(5px * var(--lz));color:color-mix(in srgb,var(--muted) calc((1.5 - var(--lz)) * 200%),var(--ink-2))}.eg-btn svg{width:calc(13px * var(--lz));height:calc(13px * var(--lz))}.eg-btn span{line-height:calc(16px * var(--lz))}.frame>.edge-zone{height:calc(40px * var(--lz) / var(--z, 1))}body.versions-on #topbar{opacity:0;pointer-events:none}#topbar{transition:opacity .2s}.sb-exit{color:var(--ink-2);background:transparent;padding:0 11px 0 8px;font-weight:500;white-space:nowrap}.sb-exit:hover{background:var(--surface-hover);color:var(--ink);filter:none}#stage-bar,.vs-bar{white-space:nowrap}body.no-comments .pin,body.no-comments .area,body.no-comments #ink path.used,body.no-comments #ink g.auras{display:none!important}.comments-btn.off{opacity:.45}.comments-btn.off svg{stroke-dasharray:2.2 2}.area.working{border:0!important;background:color-mix(in srgb,var(--accent) 5%,transparent)!important;border-radius:calc(6px / var(--z, 1))!important;overflow:hidden;box-shadow:none}.area.working:before{content:none!important;display:none!important}.area.working:after{content:"";display:block!important;position:absolute;inset:0;border-radius:0;filter:none;transform:none;-webkit-backdrop-filter:none;backdrop-filter:none;-webkit-mask-image:none;mask-image:none;background:linear-gradient(100deg,transparent 38%,rgba(255,255,255,.16) 50%,transparent 62%);background-size:260% 100%;animation:shimmer 2.4s linear infinite}#ink g.auras .aura-stroke{stroke-width:12;opacity:.32;filter:none;animation:auraPulse 2.6s ease-in-out infinite}@keyframes auraPulse{50%{opacity:.16}}@media(prefers-reduced-motion:reduce){.area.working:after{animation:none;background:none}}body.staging .frame:not(.staged)>.ver-strip{display:none}.frame-body>.ver-prev{position:absolute;inset:0;z-index:5;background:#fff;opacity:0;transition:opacity .14s ease;pointer-events:none}.frame-body>.ver-prev.on{opacity:1}.frame-body>.ver-prev.live{pointer-events:auto}.ver-prev img,.ver-prev iframe{position:absolute;inset:0;width:100%;height:100%;border:0;display:block}.ver-prev img{object-fit:cover;object-position:top center}.ver-prev iframe{opacity:0;background:#fff}.ver-prev iframe.ready{opacity:1}.frame.previewing .pins,.frame.previewing .areas{opacity:0;pointer-events:none;transition:opacity .12s}.frame.previewing .frame-body{box-shadow:0 0 0 calc(1.5px / var(--z, 1)) color-mix(in srgb,var(--accent) 55%,transparent),var(--frame-shadow)}#sections{position:absolute;left:0;top:0}.section{position:absolute;border-radius:calc(10px / var(--z, 1));background:color-mix(in srgb,var(--ink) 4%,transparent);box-shadow:inset 0 0 0 calc(1px / var(--z, 1)) var(--line)}.section.selected{box-shadow:inset 0 0 0 calc(1.5px / var(--z, 1)) var(--accent)}.sec-label{position:absolute;left:0;bottom:100%;display:flex;align-items:center;gap:8px;height:28px;padding:0 2px 6px;transform-origin:0 100%;scale:calc(var(--lz) / var(--z, 1));max-width:calc(var(--sw) * var(--z, 1) / var(--lz));white-space:nowrap;font:600 12.5px/1 var(--font);color:var(--ink-2);cursor:default}.sec-name{overflow:hidden;text-overflow:ellipsis;padding:3px 6px;margin-left:-6px;border-radius:6px}#viewport[data-tool=select] .sec-label:hover .sec-name{background:var(--surface-hover);color:var(--ink)}.section.selected .sec-name{color:var(--accent)}.sec-label .rename{font:inherit;color:var(--ink);background:var(--surface);border:1px solid var(--accent);border-radius:5px;padding:2px 6px;outline:0;width:220px}.sec-clear{flex:none;height:20px;padding:0 7px;border-radius:6px;font:500 11px/1 var(--font);color:var(--muted);opacity:0;transition:opacity .15s}.section:hover .sec-clear,.section.selected .sec-clear{opacity:1}.sec-clear:hover{background:var(--surface-hover);color:var(--ink)}.section .srz{position:absolute;display:none;--t: calc(10px / var(--z, 1))}#viewport[data-tool=select] .section.selected .srz{display:block}.section .rz-n,.section .rz-s{left:var(--t);right:var(--t);height:var(--t);cursor:ns-resize}.section .rz-n{top:calc(var(--t) / -2)}.section .rz-s{bottom:calc(var(--t) / -2)}.section .rz-e,.section .rz-w{top:var(--t);bottom:var(--t);width:var(--t);cursor:ew-resize}.section .rz-e{right:calc(var(--t) / -2)}.section .rz-w{left:calc(var(--t) / -2)}.section .rz-ne,.section .rz-nw,.section .rz-se,.section .rz-sw{width:calc(var(--t) * 1.4);height:calc(var(--t) * 1.4)}.section .rz-nw{left:calc(var(--t) * -.7);top:calc(var(--t) * -.7);cursor:nwse-resize}.section .rz-se{right:calc(var(--t) * -.7);bottom:calc(var(--t) * -.7);cursor:nwse-resize}.section .rz-ne{right:calc(var(--t) * -.7);top:calc(var(--t) * -.7);cursor:nesw-resize}.section .rz-sw{left:calc(var(--t) * -.7);bottom:calc(var(--t) * -.7);cursor:nesw-resize}.section .rz-ne:after,.section .rz-nw:after,.section .rz-se:after,.section .rz-sw:after{content:"";position:absolute;inset:30%;background:#fff;border:calc(1.5px / var(--z, 1)) solid var(--accent);border-radius:calc(1.5px / var(--z, 1))}#viewport[data-tool=section],#viewport[data-tool=section] .shield{cursor:crosshair}body.staging #sections,body.versions-on #sections{opacity:0;pointer-events:none;transition:opacity .3s}#world.gliding .frame,#world.gliding .section{transition:left .45s cubic-bezier(.2,.8,.2,1),top .45s cubic-bezier(.2,.8,.2,1),opacity .35s ease}.eg-btn[hidden]{display:none}.eg-use{color:var(--accent)}.eg-use:hover{color:var(--accent);background:var(--accent-soft)}.eg-use.done{color:var(--ok);pointer-events:none}#comments-panel{width:320px}.cp-item{align-items:flex-start;gap:10px;padding:9px 34px 9px 10px}.cp-item .cp-text{flex:1;min-width:0;-webkit-line-clamp:3;font-size:13px;line-height:1.45;padding-top:2px}.cp-av{position:relative}.cp-av.busy:after,.cp-av.err:after{content:"";position:absolute;right:-2px;bottom:-2px;width:8px;height:8px;border-radius:50%;background:var(--accent);box-shadow:0 0 0 2px var(--surface)}.cp-av.busy:after{animation:pulse 1.2s ease-in-out infinite}.cp-av.err:after{background:var(--mark)}.cp-item:hover,.cp-item.on{background:var(--surface-hover)}.pin.ping .pin-dot:before{content:"";position:absolute;inset:-4px;border-radius:inherit;border:2px solid var(--accent);pointer-events:none;animation:pinPing .7s ease-out 3}.pin.ping .pin-dot{animation:pinPop .35s cubic-bezier(.3,1.6,.5,1)}@keyframes pinPing{0%{opacity:.9;transform:scale(1)}to{opacity:0;transform:scale(1.9)}}@keyframes pinPop{50%{transform:scale(1.18)}}@media(prefers-reduced-motion:reduce){.pin.ping .pin-dot,.pin.ping .pin-dot:before{animation:none}.pin.ping .pin-dot{box-shadow:0 0 0 2px #fff,0 0 0 5px var(--accent)}}body.versions-on #comments-panel,body.versions-on .panel,body.versions-on #align-bar,body.versions-on #thread,body.versions-on #peek{display:none!important}.pin-n{flex:none;display:inline-grid;place-items:center;min-width:20px;height:20px;padding:0 6px;border-radius:10px 10px 10px 3px;background:#17171a;color:#fff;font:600 11px/1 var(--font);box-shadow:0 0 0 1px #ffffffd9}.pk-bar .pin-n{margin-right:8px}#thread .t-tools{opacity:1}#thread .t-tools .pin-n{margin-right:auto}#thread .t-tools .pin-n+.t-title{margin-left:8px}#thread.docked .t-tools .pin-n{margin-right:0}#thread:not(.docked) .t-tools>.t-btn,#thread:not(.docked) .t-tools>.t-more,#thread:not(.docked) .t-tools>.t-state{opacity:0;transition:opacity .15s}#thread:not(.docked):hover .t-tools>*,#thread:not(.docked):focus-within .t-tools>*{opacity:1}.frame.building .frame-body:after{content:"";position:absolute;inset:0;z-index:4;pointer-events:none;background:linear-gradient(100deg,color-mix(in srgb,var(--paper) 62%,transparent) 30%,color-mix(in srgb,var(--paper) 38%,transparent),color-mix(in srgb,var(--paper) 62%,transparent) 70%);background-size:250% 100%;animation:shimmer 2s linear infinite;transition:opacity .5s ease}.frame.building.filling .frame-body:after{background:linear-gradient(100deg,transparent 38%,rgba(255,255,255,.2) 50%,transparent 62%);background-size:250% 100%}.frame.building .frame-label .name{background:linear-gradient(90deg,var(--muted) 0%,var(--muted) 35%,var(--ink) 50%,var(--muted) 65%,var(--muted) 100%);background-size:250% 100%;-webkit-background-clip:text;background-clip:text;color:transparent;animation:shimmer 1.8s linear infinite}.frame.building .frame-label .count{display:none}@media(prefers-reduced-motion:reduce){.frame.building .frame-body:after,.frame.building .frame-label .name{animation:none}}.sec-label{scale:calc(var(--slz, 1) / var(--z, 1));max-width:calc(var(--sw) * var(--z, 1) / var(--slz, 1))}.frame.in-section .frame-label{transition:opacity .15s ease}.sec-clear{display:none}.m-user .bubble{color:var(--ink);border-radius:16px}.m-steps{list-style:none;margin:0 0 6px;padding:0;display:flex;flex-direction:column;gap:5px}.m-steps[hidden]{display:none}.m-steps li{display:flex;align-items:center;gap:7px;font-size:12.5px;line-height:1.3;color:var(--muted);min-width:0}.m-steps li span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.m-steps svg{flex:none;width:13px;height:13px;fill:none;stroke:currentColor;stroke-width:1.3;stroke-linecap:round;stroke-linejoin:round;opacity:.8}.m-did{margin:0 0 8px;font-size:12.5px;color:var(--muted)}.m-did summary{display:inline-flex;align-items:center;gap:4px;cursor:pointer;list-style:none;border-radius:6px;padding:2px 6px;margin:-2px -6px}.m-did summary::-webkit-details-marker{display:none}.m-did summary:hover{background:var(--surface-hover);color:var(--ink-2)}.m-did summary svg{width:11px;height:11px;fill:none;stroke:currentColor;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;transition:transform .15s}.m-did[open] summary svg{transform:rotate(90deg)}.m-did .m-steps{margin:8px 0 2px;padding-left:2px}.m-work .a-text{font-size:12.5px}#peek .m-did,#peek .m-steps{display:none}.frame>.dims{position:absolute;left:50%;top:100%;translate:-50% 0;margin-top:calc(8px / var(--z, 1));transform-origin:50% 0;scale:calc(1 / var(--z, 1));display:none;padding:3px 6px;border-radius:4px;background:var(--accent);color:#fff;font:500 10.5px/1 var(--mono);white-space:nowrap;cursor:pointer;z-index:8}.frame.selected>.dims{display:block}body.staging .frame>.dims{display:none}#viewport[data-tool=select] .frame.far:not(.selected):hover .frame-body{box-shadow:0 0 0 calc(1.5px / var(--z, 1)) var(--accent),var(--frame-shadow)}#viewport[data-tool=select] .frame.far .shield{cursor:default}.section.target{box-shadow:inset 0 0 0 calc(1.5px / var(--z, 1)) var(--accent);background:color-mix(in srgb,var(--accent) 6%,transparent)}.m-steps li.say{display:block;color:var(--ink-2);font-size:12.5px;line-height:1.45}.m-steps li.say .md p{margin:0}.m-steps li.say .md{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:3;overflow:hidden}.m-did[open] .m-steps li.say .md{-webkit-line-clamp:unset}.frame.staged.device{isolation:isolate}.frame.staged.device .frame-body{border-radius:55px;box-shadow:none}.frame.staged.device:before{content:"";position:absolute;inset:-15px;z-index:-1;border-radius:70px;background:#050506;box-shadow:inset 0 0 0 1px #ffffff47,inset 0 0 0 4.5px #6f6f75,inset 0 0 0 5.5px #18181a,inset 0 0 2px 7px #ffffff0d,0 0 0 1px #000000a6,0 2px 3px #ffffff0f,0 50px 100px -24px #000c,0 26px 50px -22px #0009}.frame.staged.device:before{background-image:linear-gradient(180deg,rgba(255,255,255,.07),transparent 22%,transparent 78%,rgba(0,0,0,.35))}.frame.staged.device:after{content:"";position:absolute;inset:0 -18px;width:auto;height:auto;z-index:-2;border-radius:0;pointer-events:none;background:linear-gradient(90deg,#4a4a4f,#7b7b82 60%,#5a5a60) left 0 top 15% / 4px 4.2% no-repeat,linear-gradient(90deg,#4a4a4f,#7b7b82 60%,#5a5a60) left 0 top 24.5% / 4px 7.6% no-repeat,linear-gradient(90deg,#4a4a4f,#7b7b82 60%,#5a5a60) left 0 top 34.5% / 4px 7.6% no-repeat,linear-gradient(270deg,#4a4a4f,#7b7b82 60%,#5a5a60) right 0 top 29% / 4px 12% no-repeat}.frame.staged.device .frame-body:after{content:"";position:absolute;z-index:9;left:50%;top:11px;width:126px;height:37px;transform:translate(-50%);border-radius:20px;pointer-events:none;animation:none;opacity:1;background:radial-gradient(circle at 78% 50%,#1b1f2c 0 4.5px,#0a0a0c 5px 7px,transparent 7.5px),#000}.frame.staged.device .frame-body:before{content:"";position:absolute;z-index:9;left:50%;bottom:8px;width:139px;height:5px;transform:translate(-50%);border-radius:3px;background:#fff;mix-blend-mode:difference;opacity:.82;pointer-events:none}.frame.staged.device.kb-on .frame-body:before{background:#000;mix-blend-mode:normal;opacity:.85}.frame.staged.device.landscape .frame-body:after{left:11px;top:50%;width:37px;height:126px;transform:translateY(-50%);background:#000}.frame.staged.device.landscape .frame-body:before{bottom:6px;width:200px}.frame.staged.device.landscape:after{display:none}.frame.staged.device .kb{padding-bottom:46px}.kb.num{height:291px!important;gap:7px;padding:8px 6px 40px;background:#d1d4da}.frame.kb-on:has(.kb.num) iframe{height:calc(100% - 291px)}.kb.num .kb-row{gap:6px}.kb.num .k{height:47px;flex-direction:column;display:flex;align-items:center;justify-content:center;gap:1px;font-size:25px;line-height:1}.kb.num .k b{font-weight:400}.kb.num .k i{font:600 10px/1 -apple-system,SF Pro Text,system-ui,sans-serif;letter-spacing:.12em;font-style:normal;color:#000;min-height:10px}.kb.num .k.plain{background:transparent;box-shadow:none;flex:1;font-size:22px}.frame .parked-hint{overflow:hidden}.frame .parked-hint img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:top center;display:block}.frame .parked-hint img[hidden]{display:none}svg.hi{fill:none!important;stroke:currentColor!important;stroke-width:2!important;stroke-linecap:round;stroke-linejoin:round;flex:none}svg.hi.s{stroke-width:2.5!important}#toolbar svg.hi{width:20px;height:20px;stroke-width:1.6!important}.frame-label .ic svg.hi,.frame-label .count svg.hi{width:12px;height:12px;stroke-width:2.3!important}.m-steps svg.hi{width:14px;height:14px;opacity:.85}.c-file button svg.hi{color:#fff}.fp-q svg.hi{stroke-width:1.5!important}.pin{animation:pinIn .22s cubic-bezier(.2,.9,.3,1.2)}@keyframes pinIn{0%{opacity:0;transform:scale(.5)}}.pin-dot{position:absolute;left:0;bottom:0;transform-origin:0 100%;scale:calc(var(--lz) / var(--z, 1));box-sizing:border-box;display:inline-flex;align-items:center;height:28px;min-width:28px;padding:3px;white-space:nowrap;cursor:pointer;border-radius:14px 14px 14px 4px;background:#fff;color:#fff;box-shadow:0 0 0 .5px #17171a29,0 1px 2px #17171a1f,0 4px 12px -2px #17171a3d;transition:transform .16s cubic-bezier(.2,.8,.2,1),opacity .1s ease,background .22s ease,box-shadow .2s ease,padding .3s cubic-bezier(.2,.8,.2,1)}.pin-dot .pn{box-sizing:border-box;display:grid;place-items:center;min-width:22px;height:22px;padding:0 6px;border-radius:11px;background:var(--c, #17171A);color:#fff;font:600 11px/1 var(--font);font-variant-numeric:tabular-nums;letter-spacing:-.01em;transition:background .22s ease,box-shadow .22s ease}.pin:active .pin-dot{transform:scale(.96)}.pin.error .pn{background:var(--mark)}.pin.waiting .pn{background:transparent;color:#17171a;box-shadow:inset 0 0 0 1.5px #17171a}.pin.draft .pn{background:#2f5bff}.pin.resolved .pin-dot{opacity:.5}.pin.active .pin-dot{box-shadow:0 0 0 2px #2f5bff,0 4px 12px -2px #17171a3d}.pin.carded .pin-dot{opacity:0;pointer-events:none}.pin.talking .pin-dot{background:#17171a;padding-right:12px;box-shadow:0 0 0 1.5px #ffffffeb,0 6px 20px -6px #0000008c}.pin.talking .pn{background:#ffffff29}.pin-dot .pw{display:none;flex:none;width:13px;height:13px;margin-left:7px;fill:none;stroke:#fff;stroke-width:1.7;stroke-linecap:round;transform-origin:50% 50%}.pin.working .pin-dot .pw{display:block;animation:loopTurn 1.5s linear infinite}.pin.working .pin-dot .pw circle{stroke-dasharray:34.6;animation:loopDraw 1.5s ease-in-out infinite}@keyframes loopTurn{to{transform:rotate(360deg)}}@keyframes loopDraw{0%{stroke-dashoffset:31}50%{stroke-dashoffset:9}to{stroke-dashoffset:31}}.pin-dot .pl{display:inline-block;max-width:0;opacity:0;margin-left:0;overflow:hidden;text-overflow:ellipsis;font:500 12px/22px var(--font);letter-spacing:0;color:#fff;transition:max-width .4s cubic-bezier(.2,.8,.2,1),opacity .25s ease,margin .4s cubic-bezier(.2,.8,.2,1)}.pin.talking .pl{max-width:240px;opacity:1;margin-left:7px}.pin.working .pl{background:linear-gradient(90deg,#ffffff9e 0% 38%,#fff 50%,#ffffff9e 62% 100%);background-size:250% 100%;-webkit-background-clip:text;background-clip:text;color:transparent;animation:shimmer 1.8s linear infinite}.pin-dot .pl.tick{animation:plIn .3s ease-out,shimmer 1.8s linear infinite}@keyframes plIn{0%{opacity:0;transform:translateY(6px)}}.pin.low .pin-dot{bottom:auto;top:0;transform-origin:0 0;border-radius:4px 14px 14px}.frame.far .pin-dot{scale:calc(.68 * var(--lz) / var(--z, 1))}body.zoom-tiny .pin:not(.talking) .pin-dot{min-width:9px;width:9px;height:9px;padding:0;border-radius:50%;scale:calc(1 / var(--z, 1));background:var(--c, #17171A);box-shadow:0 0 0 1.5px #fff}body.zoom-tiny .pin:not(.talking) .pin-dot>*{display:none}@media(prefers-reduced-motion:reduce){.pin,.pin.working .pin-dot .pw,.pin.working .pin-dot .pw circle{animation:none}.pin:hover .pin-dot,.pin:active .pin-dot{transform:none}.pin.working .pl,.pin-dot .pl.tick{animation:none;color:#fff;background:none}}.pin-n{min-width:20px;height:20px;padding:0 6px;border-radius:10px 10px 10px 3px;background:#17171a;color:#fff;font:600 10.5px/1 var(--font);font-variant-numeric:tabular-nums;box-shadow:none}.av{--c: #88888F;flex:none;box-sizing:border-box;width:24px;height:24px;border-radius:50%;display:inline-grid;place-items:center;overflow:hidden;user-select:none;background:color-mix(in srgb,var(--c) 18%,var(--surface));color:color-mix(in srgb,var(--c) 68%,var(--ink));box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--c) 24%,transparent);font:600 11px/1 var(--font);letter-spacing:0}.av img{width:100%;height:100%;object-fit:cover;display:block}.avatar{width:auto;height:auto;display:grid;margin-left:-6px;border:0;border-radius:50%;background:none;box-shadow:0 0 0 2px var(--paper)}.avatar .av{width:26px;height:26px}.cp-av{width:auto;height:auto;display:grid;background:none}.cp-av .av{width:22px;height:22px;font-size:10.5px}.cp-av.busy:after,.cp-av.err:after{right:-1px;bottom:-1px;width:7px;height:7px}.cp-item{gap:10px;padding:8px 34px 8px 10px;border-radius:10px}.cp-item .cp-text{font-size:13px;line-height:20px;padding-top:1px;letter-spacing:-.003em}.cp-res{top:6px;right:6px}.m-agent{grid-template-columns:20px 1fr;gap:10px}.m-mark{width:20px;height:20px;margin-top:1px;color:var(--ink)}.m-mark svg.lg{width:16px;height:16px;fill:currentColor;stroke:none}.m-mark svg.lg.claude{fill:#d97757}.m-mark svg.lg.ring{fill:none;stroke:currentColor;stroke-width:2.6}.m-agent.quiet .m-mark{opacity:.5}.m-agent.error .m-mark svg.lg{fill:currentColor}.m-user .bubble{background:color-mix(in srgb,var(--accent) 20%,var(--surface))}#thread .thread-body{gap:16px}.m-user{max-width:84%;gap:4px}.m-user .bubble{padding:8px 14px;border-radius:18px;font-size:13.5px;line-height:1.55}.m-agent,.m-agent .m-text{font-size:13.5px;line-height:1.6}.m-text.md p+p,.m-text.md ul+p,.m-text.md p+ul{margin-top:10px}.m-text.md ul{padding-left:20px}.m-text.md code{font-size:.92em;padding:1px 5px;border-radius:5px}.m-acts{gap:2px;min-height:24px;margin-top:6px;margin-left:-4px}.m-acts .a-btn,.m-work .a-btn{width:24px;height:24px;border-radius:6px}.a-btn svg.hi{width:16px;height:16px}.m-acts .a-btn.lbl{width:auto;padding:0 8px 0 5px}.m-acts time,.m-work .m-time{font:12px/1 var(--font);font-variant-numeric:tabular-nums}.m-steps{gap:4px}.m-steps li{gap:6px;font-size:13px;line-height:20px;color:color-mix(in srgb,var(--ink) 58%,transparent)}.m-did{font-size:13px}.m-did summary{padding:0;margin:0;gap:4px;color:var(--muted);transition:color .15s}.m-did summary:hover{background:none;color:var(--ink)}.m-did summary svg.hi{width:14px;height:14px;opacity:0;transition:transform .3s cubic-bezier(.19,1,.22,1),opacity .15s}.m-did summary:hover svg.hi,.m-did[open] summary svg.hi,.m-did summary:focus-visible svg.hi{opacity:1}.m-did .m-steps{margin:8px 0 4px;padding-left:0}.m-work .a-text{font-size:13px}.c-btn,.c-send{width:28px;height:28px}.c-send{background:var(--ink);color:var(--paper);transition:opacity .15s,transform .12s}.c-send:not(:disabled):active{transform:scale(.94)}.c-send:disabled{opacity:.22}#thread .thread-reply .cbox{border-radius:18px}.t-btn{width:26px;height:26px;border-radius:6px}.frame>.ver-strip{position:absolute;left:0;bottom:100%;margin-bottom:calc(36px * var(--lz, 1) / var(--z, 1));transform-origin:0 100%;scale:calc(1 / var(--z, 1));z-index:10;display:flex;flex-direction:column;width:max-content;min-width:300px;max-width:min(700px,92vw);padding:6px;border-radius:12px;background:var(--surface);box-shadow:0 0 0 1px var(--line),0 6px 20px -8px #00000029;animation:stripIn .18s cubic-bezier(.2,.8,.2,1)}@keyframes stripIn{0%{opacity:0;transform:translateY(6px)}}.vt-row{display:flex;gap:6px;padding:2px 2px 0;overflow-x:auto;overflow-y:hidden;scrollbar-width:none}.vt-row::-webkit-scrollbar{display:none}.vt{flex:none;display:flex;flex-direction:column;align-items:center;gap:5px;padding:0 0 2px;color:var(--muted);cursor:pointer}.vt-img{display:block;border-radius:6px;overflow:hidden;background:linear-gradient(100deg,var(--surface-2) 30%,var(--line) 50%,var(--surface-2) 70%);background-size:250% 100%;animation:shimmer 1.6s linear infinite;box-shadow:0 0 0 1px var(--line);transition:box-shadow .12s ease}.vt-img:has(img){animation:none;background:var(--surface-2)}.vt-img img{width:100%;height:100%;object-fit:cover;object-position:top center;display:block}.vt:hover .vt-img{box-shadow:0 0 0 1px var(--line-strong),0 2px 6px #00000014}.vt.on .vt-img{box-shadow:0 0 0 1.5px var(--surface),0 0 0 3px var(--accent)}.vt-name{font:500 10.5px/1 var(--font);font-variant-numeric:tabular-nums;transition:color .12s}.vt:hover .vt-name{color:var(--ink-2)}.vt.on .vt-name{color:var(--ink);font-weight:600}.vt-foot{display:flex;align-items:center;gap:8px;min-height:28px;margin-top:6px;padding-left:4px}.vt-cap{flex:1;width:0;min-width:0;display:flex;align-items:baseline;gap:6px;font-size:12px;line-height:1.3;color:var(--ink-2);white-space:nowrap}.vt-cap b{flex:none;font-weight:600;color:var(--ink);font-variant-numeric:tabular-nums}.vt-cap span{min-width:0;overflow:hidden;text-overflow:ellipsis}.vt-cap time{flex:none;color:var(--muted)}.vt-acts{flex:none;display:flex;align-items:center;gap:2px}.vt-btn{width:26px;height:26px;border-radius:6px;display:grid;place-items:center;color:var(--muted)}.vt-btn:hover{background:var(--surface-hover);color:var(--ink)}.vt-btn svg,.vt-go svg{width:15px;height:15px}.vt-go{display:inline-flex;align-items:center;gap:5px;height:26px;padding:0 9px 0 6px;margin-right:2px;border-radius:6px;font:500 12px/1 var(--font);color:var(--ink);background:var(--surface-2);white-space:nowrap}.vt-go:hover{background:var(--surface-hover)}.frame>.opt-strip{border-radius:12px;border:0;background:var(--surface);box-shadow:0 0 0 1px var(--line),0 6px 20px -8px #00000029}.os-img{border-radius:6px}.os-tile.on .os-img{box-shadow:0 0 0 1.5px var(--surface),0 0 0 3px var(--accent)}body.versions-on #world{opacity:0}#versions{position:fixed;inset:0;z-index:35}.vs-rig{position:absolute;perspective:1500px;perspective-origin:50% -40%;transform-origin:0 0;transition:transform .42s cubic-bezier(.2,.8,.2,1)}.vs-layer{position:absolute;inset:0;border-radius:5px;overflow:hidden;background:var(--surface);opacity:0;cursor:pointer;box-shadow:0 0 0 1px var(--line-strong),0 26px 60px -20px #00000059;transition:transform .42s cubic-bezier(.2,.8,.2,1),opacity .3s ease,filter .2s ease}.vs-layer.front{opacity:1;cursor:default}.vs-layer.gone{pointer-events:none}.vs-layer:not(.front):hover{filter:none!important}#versions.closing .vs-layer{transform:none!important}#versions.closing .vs-layer:not(.front){opacity:0!important}.vs-layer img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:top center;display:block}.vs-layer:not(:has(img)){background:linear-gradient(100deg,var(--surface) 30%,var(--surface-2) 50%,var(--surface) 70%);background-size:250% 100%;animation:shimmer 1.6s linear infinite}#versions.failed .vs-layer:not(:has(img)){animation:none;background:var(--surface)}.vs-live{position:absolute;inset:0;z-index:200;border-radius:5px;overflow:hidden;background:#fff;opacity:0;pointer-events:none;transition:opacity .18s ease}.vs-live.ready{opacity:1;pointer-events:auto}#versions.closing .vs-live{opacity:0}.vs-live iframe{border:0;display:block;transform-origin:0 0;background:#fff}.vs-bar{position:absolute;left:50%;bottom:22px;transform:translate(-50%);display:flex;align-items:center;gap:2px;padding:4px;border-radius:12px;white-space:nowrap;max-width:calc(100vw - 24px);background:var(--surface);box-shadow:0 0 0 1px var(--line),0 6px 20px -8px #0003;opacity:0;transition:opacity .25s ease .12s}#versions.open .vs-bar{opacity:1}.vs-pos{display:flex;align-items:baseline;justify-content:center;gap:6px;min-width:88px;padding:0 4px}.vs-pos b{font-size:13px;font-weight:600;font-variant-numeric:tabular-nums}.vs-pos span,.vs-what time{font-size:12px;color:var(--muted);font-variant-numeric:tabular-nums}.vs-what{display:flex;align-items:baseline;gap:8px;min-width:0;max-width:min(380px,34vw);padding:0 8px;font-size:12.5px;color:var(--ink-2)}.vs-what span{min-width:0;overflow:hidden;text-overflow:ellipsis}.vs-what time{flex:none}@media(prefers-reduced-motion:reduce){.vs-rig,.vs-layer{transition:none}}body.staging #topbar,body.staging #zoom,body.staging .frame.staged .frame-label{opacity:0;pointer-events:none}body.staging .frame.staged:not(.device) .frame-body{box-shadow:0 0 0 1px var(--line),0 30px 80px -28px #00000059}#stage-bar{top:12px;gap:2px;padding:4px;border:0;border-radius:12px;white-space:nowrap;box-shadow:0 0 0 1px var(--line),0 6px 20px -8px #0003}#stage-bar svg.hi,.vs-bar svg.hi{width:16px;height:16px}.sb-btn{width:28px;height:28px;border-radius:8px}.sb-btn.on{background:var(--surface-2);color:var(--ink)}.sb-name{flex-direction:row;align-items:baseline;justify-content:center;gap:7px;min-width:0;max-width:300px;padding:0 6px}.sb-name i{flex:none;font-style:normal;font-size:12px;color:var(--muted);font-variant-numeric:tabular-nums}.sb-sep{height:16px;margin:0 4px}.sb-tog{height:28px;padding:0 9px;border-radius:8px;gap:6px}.sb-tog svg.hi{width:15px!important;height:15px!important}.sb-exit{height:28px;padding:0 10px 0 7px;border-radius:8px}.section{border-top-left-radius:0}.sec-label{left:0;bottom:100%;height:24px;padding:0 10px;gap:6px;box-sizing:border-box;border:1px solid var(--line);border-bottom:0;border-radius:8px 8px 0 0;background:color-mix(in srgb,var(--ink) 4%,var(--paper));font:500 12px/1 var(--font);color:var(--ink-2);transition:color .12s}.sec-name{padding:0;margin:0;border-radius:0}#viewport[data-tool=select] .sec-label:hover .sec-name{background:none;color:var(--ink)}.section.selected .sec-label{border-color:var(--accent)}.section.target .sec-label{border-color:var(--accent);background:color-mix(in srgb,var(--accent) 6%,var(--paper))}.sec-label .rename{margin:0 -5px;padding:1px 4px;width:200px}#toolbar{padding:4px;gap:2px;border-radius:999px}#toolbar button{border-radius:999px;transition:background .12s ease,color .12s ease}#toolbar button.on,#toolbar button[data-tool=comment].on{background:color-mix(in srgb,var(--ink) 10%,transparent);color:var(--ink)}#toolbar .tb-new{padding:0 13px 0 10px}#hover-box{border:1.5px solid var(--accent);background:none;border-radius:2px;transition:none;z-index:7}#hover-box:after{top:auto;bottom:100%;left:-1.5px;margin-bottom:1px;padding:3px 6px;border-radius:4px 4px 4px 0;font:500 10.5px/1.2 var(--font);max-width:220px;overflow:hidden;text-overflow:ellipsis}#hover-box.sel{border-color:transparent}#hover-box.sel:after{display:none}#hover-box i{position:absolute;border:1px dashed color-mix(in srgb,var(--accent) 70%,transparent);border-radius:1px;pointer-events:none}.deep-box{border:calc(1.5px / var(--z, 1)) solid var(--accent)!important;background:none!important;border-radius:calc(2px / var(--z, 1))!important}.deep-box:before{font:500 10.5px/1.2 var(--font)!important;padding:3px 6px!important;border-radius:4px 4px 4px 0!important;max-width:220px;overflow:hidden;text-overflow:ellipsis}.deep-box.par{border:calc(1px / var(--z, 1)) dashed color-mix(in srgb,var(--accent) 60%,transparent)!important}.deep-box.par:before{display:none!important}#viewport[data-use="1"] .frame:not(.live):not(.far) .shield{cursor:pointer}#quick{display:flex;align-items:center;gap:2px;padding:8px 10px 0;min-height:36px}#quick[hidden]{display:none}.q-btn{flex:none;width:26px;height:26px;border-radius:6px;display:grid;place-items:center;color:var(--ink-2)}.q-btn:hover{background:var(--surface-hover);color:var(--ink)}.q-btn svg.hi{width:15px;height:15px}.q-sep{flex:none;width:1px;height:16px;margin:0 5px;background:var(--line)}.q-sw{position:relative;flex:none;display:inline-flex;align-items:center;gap:5px;height:26px;padding:0 6px 0 5px;border-radius:6px;font:500 11.5px/1 var(--font);color:var(--ink-2);cursor:pointer}.q-sw:hover{background:var(--surface-hover);color:var(--ink)}.q-sw i{width:14px;height:14px;border-radius:50%;box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--ink) 40%,transparent)}.q-sw.none i{background:linear-gradient(135deg,transparent 46%,var(--mark) 46% 54%,transparent 54%),var(--surface)}.q-sw input{position:absolute;inset:0;width:100%;height:100%;opacity:0;cursor:pointer;border:0;padding:0}.q-num{flex:none;display:inline-flex;align-items:center;gap:4px;height:26px;padding:0 2px 0 6px;border-radius:6px;font:500 11px/1 var(--font);color:var(--muted)}.q-num:hover,.q-num:focus-within{background:var(--surface-hover)}.q-num input{width:30px;border:0;outline:0;background:transparent;color:var(--ink);font:500 12px/1 var(--font);font-variant-numeric:tabular-nums;padding:0;-moz-appearance:textfield}.q-num input::-webkit-outer-spin-button,.q-num input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.q-note{margin-left:auto;padding-left:6px;font:500 11.5px/1 var(--font);color:var(--muted);white-space:nowrap}.q-send{height:24px;padding:0 9px;border-radius:6px;font:500 11.5px/1 var(--font);color:var(--ink);background:var(--surface-2)}.q-send:hover{background:var(--surface-hover)}#hover-box:after,.deep-box:before{display:none!important}#quick{position:fixed;z-index:27;padding:4px;min-height:0;gap:1px;border-radius:10px;background:var(--surface);box-shadow:0 0 0 1px var(--line),0 6px 20px -8px #00000040;white-space:nowrap;animation:softIn .12s ease-out}.q-count{padding:0 6px;font:500 12px/1 var(--font);color:var(--ink-2)}.q-note{display:inline-flex;align-items:center;gap:6px}.q-note:empty{display:none}.q-num{gap:0;padding:0 4px 0 0}.q-scrub{display:grid;place-items:center;width:26px;height:26px;color:var(--muted);cursor:ew-resize;border-radius:6px;touch-action:none}.q-scrub:hover{color:var(--ink)}.q-scrub .qi{width:15px;height:15px;fill:none;stroke:currentColor;stroke-width:1.4;stroke-linecap:round;stroke-linejoin:round}.q-num input{width:28px;padding:0 0 0 4px;text-align:left;border-radius:4px;cursor:text}.q-num input:focus{background:var(--surface-2)}body.scrubbing,body.scrubbing *{cursor:ew-resize!important;user-select:none!important}.q-sw{border:0;background:none}.q-sw.on{background:var(--surface-hover);color:var(--ink)}#cpick{position:fixed;z-index:30;width:232px;padding:10px;border-radius:12px;background:var(--surface);box-shadow:0 0 0 1px var(--line),0 12px 32px -10px #00000059;animation:softIn .12s ease-out}#cpick[hidden]{display:none}.cp-sv{position:relative;height:140px;border-radius:8px;cursor:crosshair;touch-action:none}.cp-sv i,.cp-hue i{position:absolute;width:14px;height:14px;border-radius:50%;transform:translate(-50%,-50%);box-shadow:0 0 0 2px #fff,0 0 0 3px #0003,0 1px 4px #0000004d;pointer-events:none}.cp-hue{position:relative;height:12px;margin-top:10px;border-radius:6px;cursor:pointer;touch-action:none;background:linear-gradient(to right,red,#ff0 17%,#0f0 33%,#0ff,#00f 67%,#f0f 83%,red)}.cp-hue i{top:50%}.cp-row{display:flex;align-items:center;gap:8px;margin-top:10px}.cp-now{flex:none;width:26px;height:26px;border-radius:6px;box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--ink) 18%,transparent)}.cp-hex{flex:1;min-width:0;height:28px;padding:0 8px;border:0;border-radius:6px;outline:0;background:var(--surface-2);color:var(--ink);font:500 12px/1 var(--mono);letter-spacing:.02em}.cp-hex:focus{box-shadow:0 0 0 1.5px var(--accent)}.cp-label{margin:12px 0 6px;font:500 11px/1 var(--font);color:var(--muted)}.cp-used{display:grid;grid-template-columns:repeat(7,1fr);gap:6px}.cp-used button{aspect-ratio:1;border-radius:6px;box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--ink) 16%,transparent)}.cp-used button:hover{transform:scale(1.08)}#canvas-pins,.frame .pins{z-index:9}.pin.queued .pin-dot:after{content:"";position:absolute;inset:-4px;border-radius:inherit;border:1.5px solid rgba(23,23,26,.35);animation:queuedBreathe 1.8s ease-in-out infinite;pointer-events:none}@keyframes queuedBreathe{0%,to{opacity:0;transform:scale(.94)}50%{opacity:1;transform:scale(1)}}@media(prefers-reduced-motion:reduce){.pin.queued .pin-dot:after{animation:none;opacity:.6}}.pin.needs .pin-dot{padding-right:4px}.pin.needs .pl{display:inline-flex;align-items:center;gap:8px;max-width:320px;color:#ffffffb8}.pin.needs .pin-dot:after{display:none}.pin-act{height:20px;padding:0 9px;border-radius:10px;background:#fff;color:#17171a;font:600 11.5px/20px var(--font);white-space:nowrap;cursor:pointer;transition:background .12s}.pin-act:hover{background:#ebebed}.frame-label{scale:calc(1 / var(--z, 1));max-width:calc(var(--fw) * var(--z, 1));height:20px;padding:0 0 4px;gap:4px;font:400 11px/16px var(--font);color:var(--muted)}.frame:hover .frame-label,.frame.selected .frame-label,.frame.live .frame-label{max-width:calc(var(--fw) * var(--z, 1) - 70px)}.frame.noname .frame-label,.section.noname .sec-label{visibility:hidden}.frame-label .count{font-size:11px}.sec-label{scale:calc(1 / var(--z, 1));max-width:calc(var(--sw) * var(--z, 1));height:22px;padding:0 8px;font:500 11px/1 var(--font)}.section.lift{border-top-left-radius:calc(10px / var(--z, 1))}.section.lift .sec-label{bottom:calc(100% + 22px / var(--z, 1));border-bottom:1px solid var(--line);border-radius:8px}.section.lift.selected .sec-label{border-color:var(--accent)}#viewport{background-image:none!important}#theme-btn{display:grid;place-items:center;color:var(--ink-2)}#theme-btn svg.hi{width:16px;height:16px}.frame:hover .frame-label,.frame.selected .frame-label,.frame.live .frame-label{max-width:calc(var(--fw) * var(--z, 1))}.frame:not(.narrow):hover .frame-label,.frame.selected:not(.narrow) .frame-label{max-width:calc(var(--fw) * var(--z, 1) - 70px)}#viewport[data-tool=select] .frame-label:hover .name,#viewport[data-tool=select] .frame-label:hover{color:var(--accent)}#done{position:fixed;z-index:45;top:12px;left:50%;transform:translate(-50%);display:flex;align-items:center;gap:10px;padding:6px 6px 6px 10px;border-radius:12px;background:var(--surface);box-shadow:0 0 0 1px var(--line),0 10px 30px -10px #00000059;font-size:13px;color:var(--ink-2);white-space:nowrap}#done[hidden]{display:none}#done.in{animation:doneIn .22s cubic-bezier(.2,.9,.3,1.2)}@keyframes doneIn{0%{opacity:0;transform:translate(-50%,-8px)}}.dn-ic{display:grid;place-items:center;width:20px;height:20px;border-radius:50%;background:var(--ink);color:var(--paper)}.dn-ic.err{background:var(--mark);color:#fff}.dn-ic svg.hi{width:12px;height:12px}.dn-text{max-width:360px;overflow:hidden;text-overflow:ellipsis}.dn-text b{color:var(--ink);font-weight:600}.dn-go{height:28px;padding:0 12px;border-radius:8px;background:var(--ink);color:var(--paper);font:500 12.5px/1 var(--font)}.dn-go:hover{opacity:.9}.dn-x{width:26px;height:26px;border-radius:7px;display:grid;place-items:center;color:var(--muted)}.dn-x:hover{background:var(--surface-hover);color:var(--ink)}.dn-x svg.hi{width:13px;height:13px}#stage-bar{background:transparent;box-shadow:none;border:0;gap:4px;padding:0}#stage-bar .sb-btn,#stage-bar .sb-exit{color:var(--ink-2)}#stage-bar .sb-btn:hover,#stage-bar .sb-exit:hover{background:var(--surface-hover);color:var(--ink)}body.staging .frame.staged .frame-label{opacity:1;pointer-events:none}body.staging .frame.staged .frame-label .count,body.staging .frame.staged .frame-label .dims{display:none}body.staging #world .frame:not(.staged){pointer-events:auto;cursor:pointer}body.staging #world .frame:not(.staged) .shield{display:block!important;cursor:pointer}#del-ask{position:fixed;z-index:45;top:12px;left:50%;transform:translate(-50%);display:flex;align-items:center;gap:10px;padding:6px 6px 6px 12px;border-radius:12px;background:var(--surface);box-shadow:0 0 0 1px var(--line),0 10px 30px -10px #00000059;font-size:13px;color:var(--ink-2);animation:doneIn .2s ease-out}#del-ask button{height:28px;padding:0 12px;border-radius:8px;background:var(--ink);color:var(--paper);font:500 12.5px/1 var(--font)}.section.making .sec-label:after{content:"Making options\2026";margin-left:8px;font-weight:400;color:var(--muted);background:linear-gradient(90deg,var(--muted) 0%,var(--muted) 35%,var(--ink) 50%,var(--muted) 65%,var(--muted) 100%);background-size:250% 100%;-webkit-background-clip:text;background-clip:text;color:transparent;animation:shimmer 1.8s linear infinite}.pin.making .pl{cursor:pointer;text-decoration:underline;text-decoration-color:#ffffff4d;text-underline-offset:3px}.pin.making .pl:hover{text-decoration-color:#fff}@media(prefers-reduced-motion:reduce){.section.making .sec-label:after{animation:none;color:var(--muted);background:none}}@keyframes shimmer{0%{background-position:130% 0;animation-timing-function:cubic-bezier(.45,.05,.25,1)}62%{background-position:-130% 0}to{background-position:-130% 0}}.agent-line.working .a-text,.m-work .a-text,.pin.working .pl,.section.making .sec-label:after,.frame.working .frame-label .name,.frame.building .frame-label .name{animation-duration:2.2s}@keyframes shimmer{0%{background-position:130% 0;animation-timing-function:steps(30,end)}62%{background-position:-130% 0}to{background-position:-130% 0}}.frame.building .frame-body:after{background:color-mix(in srgb,var(--paper) 55%,transparent)!important;animation:none!important}.frame.building.filling .frame-body:after{background:transparent!important}.frame.building .frame-body:before{content:"";position:absolute;top:0;bottom:0;left:0;width:45%;z-index:5;pointer-events:none;background:linear-gradient(100deg,transparent,rgba(255,255,255,.22) 50%,transparent);transform:translate(-110%);will-change:transform;animation:veilSweep 2.2s cubic-bezier(.45,.05,.25,1) infinite}@keyframes veilSweep{0%{transform:translate(-110%)}62%,to{transform:translate(240%)}}@media(prefers-reduced-motion:reduce){.frame.building .frame-body:before{animation:none;display:none}}#toolbar .tb-group{display:flex;align-items:center}#toolbar .tb-caret{width:16px!important;height:34px;margin-left:-2px;border-radius:999px;color:var(--muted)}#toolbar .tb-caret svg.hi{width:12px!important;height:12px!important;stroke-width:2.4!important}#toolbar .tb-caret:hover{color:var(--ink);background:transparent}.tool-menu{width:180px;padding:4px;bottom:auto}.tm-item{display:flex;align-items:center;gap:8px;width:100%;height:32px;padding:0 8px;border-radius:8px;font:500 13px/1 var(--font);color:var(--ink-2)}.tm-item:hover{background:var(--surface-hover);color:var(--ink)}.tm-item svg.hi{width:16px;height:16px}.tm-item span:not(.tm-check){flex:1;text-align:left}.tm-item kbd{border:0;background:none;color:var(--muted);font:500 11.5px/1 var(--font);padding:0}.tm-check{width:14px;height:14px;flex:none}.tm-item.on .tm-check{background:no-repeat center/12px url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' fill='none' stroke='%23888' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M2.5 6.5l2.2 2.2L9.5 3.5'/%3E%3C/svg%3E")}.tm-item.on{color:var(--ink)}#viewport[data-tool=comment] .frame-label,#viewport[data-tool=comment] .frame-label *{cursor:inherit}#viewport[data-tool=comment] .frame-label{pointer-events:auto}#viewport[data-tool=comment] .frame-label:hover .name,.frame.whole .frame-label .name{background:#2f5bff;color:#fff!important;padding:2px 8px;margin-left:-8px;border-radius:999px;box-shadow:none;transition:background .12s}#viewport[data-tool=comment] .frame:has(>.frame-label:hover) .frame-body,.frame.whole .frame-body{box-shadow:0 0 0 calc(2px / var(--z, 1)) #2f5bff,var(--frame-shadow)}#viewport[data-tool=comment] .frame-label:hover,.frame.whole .frame-label{overflow:visible}#viewport[data-tool=comment] .frame-label:hover .name,.frame.whole .frame-label .name{margin-left:0}.sec-label{z-index:8}#viewport[data-tool=select] .section:has(>.sec-label:hover):not(.selected){box-shadow:inset 0 0 0 calc(1.5px / var(--z, 1)) var(--accent)}#viewport[data-tool=select] .section:has(>.sec-label:hover):not(.selected) .sec-label{border-color:var(--accent)}#viewport[data-tool=select] .sec-label{cursor:default}.m-blocked{display:flex;flex-direction:column;gap:4px;margin-top:10px}.blk{display:flex;align-items:center;gap:8px;min-height:32px;padding:4px 4px 4px 10px;border-radius:8px;background:var(--surface-2);font:500 12px/1.3 var(--font)}.blk-k{color:var(--muted);flex:none}.blk code{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font:11.5px/1.3 var(--mono);color:var(--ink)}.blk-go{flex:none;height:24px;padding:0 10px;border-radius:6px;background:var(--ink);color:var(--surface);font:600 12px/24px var(--font);cursor:pointer;transition:opacity .12s}.blk-go:hover{opacity:.85}.blk-go:disabled{opacity:.5;cursor:default}.blk.ok{background:none;padding-left:0;min-height:0}.blk.ok code{color:var(--muted)}.agent-allowed{border-top:1px solid var(--line);margin-top:6px;padding-top:8px}.agent-allowed .menu-title{font-weight:500;color:var(--muted);font-size:12px}.al-row{display:flex;align-items:center;gap:6px;padding:2px 4px 2px 8px;border-radius:8px}.al-row:hover{background:var(--surface-2)}.al-row code{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font:11.5px/24px var(--mono)}.al-row button{width:24px;height:24px;border-radius:6px;display:grid;place-items:center;color:var(--muted)}.al-row button:hover{color:var(--ink)}.al-row button svg{width:14px;height:14px}body.staging .frame.staged.device .frame-label{left:-15px;bottom:calc(100% + 15px);padding-bottom:8px}.c-model.pick{cursor:pointer;padding:4px 6px;margin-right:0;border-radius:6px;transition:background .12s,color .12s}.c-model.pick:hover{background:var(--surface-2);color:var(--ink)}.model-menu{position:fixed;z-index:400;width:228px;padding:4px;right:auto;bottom:auto}.mm-title{padding:8px 8px 4px;font:500 11.5px/1 var(--font);color:var(--muted)}.mm-title:not(:first-child){margin-top:4px;border-top:1px solid var(--line);padding-top:10px}.mm-note{margin:6px 0 0;padding:8px 8px 6px;border-top:1px solid var(--line);font:12px/1.4 var(--font);color:var(--muted)}:root{--work: 64 148 255}@property --wa{syntax: "<angle>"; inherits: false; initial-value: 0deg;}@keyframes workTurn{to{--wa: 360deg}}@keyframes workBlur{0%{transform:translate(-100%)}to{transform:translate(77%)}}.area.working{background:rgb(var(--work) / .07)!important;overflow:hidden;border-radius:calc(6px / var(--z, 1))!important}.area.working:after{content:""!important;display:block!important;position:absolute;inset:0 auto 0 0!important;width:130%;border-radius:0;background:linear-gradient(100deg,transparent 15%,rgb(var(--work) / .1) 50%,transparent 85%)!important;background-size:auto!important;-webkit-backdrop-filter:blur(2.6px)!important;backdrop-filter:blur(2.6px)!important;-webkit-mask-image:linear-gradient(90deg,transparent,#000 38%,#000 62%,transparent)!important;mask-image:linear-gradient(90deg,transparent,#000 38%,#000 62%,transparent)!important;transform:translate(-100%);will-change:transform;animation:workBlur 5.2s cubic-bezier(.37,0,.63,1) infinite!important}.area.working:before{content:""!important;display:block!important;position:absolute;inset:0;border-radius:inherit;pointer-events:none;z-index:1;padding:calc(1.25px / var(--z, 1));background:conic-gradient(from var(--wa),rgb(var(--work) / .16) 0 30%,rgb(var(--work) / .95) 96%,rgb(var(--work) / .16) 100%);-webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);-webkit-mask-composite:xor;mask-composite:exclude;filter:none;animation:workTurn 4.4s linear infinite!important}.area.working.whole{border-radius:14px!important}@media(prefers-reduced-motion:reduce){.area.working:after{animation:none!important;transform:translate(-20%)}.area.working:before{animation:none!important}}.pin.working.talking .pin-dot{box-shadow:0 0 0 1.5px rgb(var(--work)),0 6px 20px -6px #0000008c}.pin.working .pin-dot .pw{stroke:rgb(var(--work))}.pin.working.talking .pn{background:rgb(var(--work) / .34)}.pin.draft .pn{background:#17171a}.frame.working .frame-label .step,.agent-line.working .a-text,.m-work .a-text{background-image:linear-gradient(90deg,rgb(var(--work) / .55) 0% 35%,rgb(var(--work)) 50%,rgb(var(--work) / .55) 65% 100%)!important}.frame.building .frame-body:before{background:linear-gradient(100deg,transparent,rgb(var(--work) / .22) 50%,transparent)!important}.area.working:before{z-index:2}.area>canvas.dz{position:absolute;inset:0;width:100%;height:100%;z-index:1;pointer-events:none;image-rendering:pixelated;opacity:.75;-webkit-mask:radial-gradient(circle,#000 36%,transparent 50%) 0 0 / calc(100% / var(--cols, 1)) calc(100% / var(--rows, 1));mask:radial-gradient(circle,#000 36%,transparent 50%) 0 0 / calc(100% / var(--cols, 1)) calc(100% / var(--rows, 1))}.area:not(.working)>canvas.dz{display:none}.area.working.whole{border-radius:2px!important}.area.queued{background:none!important;border:0!important;outline:calc(1px / var(--z, 1)) dashed rgb(var(--work) / .6);outline-offset:calc(-1px / var(--z, 1))}.area.queued:before,.area.queued:after{display:none!important}.frame>.work-edge{display:none}.frame.working.work-far>.work-edge{display:block;position:absolute;inset:calc(-5px / var(--z, 1));border-radius:calc(2px + 5px / var(--z, 1));pointer-events:none;z-index:3;padding:calc(2px / var(--z, 1));background:conic-gradient(from var(--wa),rgb(var(--work) / .18) 0 30%,rgb(var(--work)) 96%,rgb(var(--work) / .18) 100%);-webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);-webkit-mask-composite:xor;mask-composite:exclude;animation:workTurn 4.4s linear infinite}.frame.working.work-far:has(.area.working.whole)>.work-edge{display:none}@media(prefers-reduced-motion:reduce){.frame.working.work-far>.work-edge{animation:none}}#ink path.working{stroke:rgb(var(--work));opacity:1}#ink g.auras{display:none}.pin.done-new .pin-dot{background:#1f9d55;padding-right:12px;box-shadow:0 0 0 1.5px #ffffffeb,0 6px 20px -6px #00000073}.pin.done-new .pn{width:22px;min-width:22px;padding:0;border-radius:50%;background:#fff;color:#116b38}.pin.done-new .pn svg{width:14px;height:14px;fill:none;stroke:currentColor;stroke-width:2.1;stroke-linecap:round;stroke-linejoin:round}.pin.done-new .pn svg path{stroke-dasharray:14;animation:doneTick .45s .1s cubic-bezier(.3,.8,.3,1) both}@keyframes doneTick{0%{stroke-dashoffset:14}to{stroke-dashoffset:0}}.pin.done-new .pl{color:#fff;background:none;animation:none}.pin.queued:not(.talking) .pn{background:transparent;color:#6c6c72;box-shadow:inset 0 0 0 1.5px #a5a5ac}.pin.queued:not(.talking) .pin-dot:after{display:none}.pin.resolved .pn{background:#88888f}@media(prefers-reduced-motion:reduce){.pin.done-new .pn svg path{animation:none}}.frame-body,.frame iframe{background:var(--fill, #fff)}.fp-fill{display:flex;align-items:center;gap:6px;margin:2px 0 6px;font-size:12px;color:var(--muted)}.fp-fill>span{min-width:28px}.fp-fill .q-sw span{font:500 11.5px/1 var(--mono);color:var(--ink-2)}.fp-fill-x{width:24px;height:24px;border-radius:6px;display:grid;place-items:center;color:var(--muted)}.fp-fill-x:hover{background:var(--surface-hover);color:var(--ink)}.fp-fill-x svg{width:13px;height:13px}.section.drawing{pointer-events:none}.frame.waking .parked-hint{display:flex;z-index:6;animation:none}.frame:not(.parked):not(.waking) .parked-hint{display:flex;opacity:0;visibility:hidden;transition:opacity .2s ease,visibility 0s .2s}#el-ghost{position:absolute;left:0;top:0;z-index:50;pointer-events:none;opacity:.92;transform-origin:0 0;outline:calc(1.5px / var(--z, 1)) solid var(--accent);outline-offset:calc(2px / var(--z, 1));box-shadow:0 12px 32px -12px #00000059}.frame.drop-into .frame-body{box-shadow:0 0 0 calc(2px / var(--z, 1)) var(--accent)}.update-pill{gap:6px;color:var(--ink-2)}.update-pill svg{width:14px;height:14px}.update-pill:disabled{cursor:default;opacity:.8}.update-pill.failed{color:var(--mark)}.up-spin{width:12px;height:12px;border-radius:50%;border:1.5px solid var(--line-strong);border-top-color:var(--ink);animation:spin .8s linear infinite}.frame.nofill:not(.selected):not(.working):not(.previewing):not(.drop-into):not(.whole) .frame-body{box-shadow:none}.frame.nofill iframe{color-scheme:light}.fp-fill .q-sw.is-none i{background:repeating-conic-gradient(#d4d4d8 0 25%,#fff 0 50%) 0 0 / 8px 8px}.fp-fill-none{height:24px;padding:0 8px;border-radius:6px;font:500 11.5px/24px var(--font);color:var(--muted)}.fp-fill-none:hover,.fp-fill-none.on{background:var(--surface-hover);color:var(--ink)}.frame>.dims{display:none;align-items:center;gap:5px}.frame.selected>.dims{display:inline-flex}.frame>.dims .fill-dot{width:12px;height:12px;padding:0;border-radius:50%;display:grid;place-items:center;cursor:pointer}.frame>.dims .fill-dot i{width:10px;height:10px;border-radius:50%;background:#fff;box-shadow:0 0 0 1px #ffffffe6,0 0 0 1.5px #0003}.frame>.dims .fill-dot.is-none i{background:repeating-conic-gradient(#d4d4d8 0 25%,#fff 0 50%) 0 0 / 5px 5px}.frame>.dims .fill-dot:hover i{box-shadow:0 0 0 1.5px #fff,0 0 0 2.5px #00000040}#cpick .cp-none{flex:none;height:24px;padding:0 8px;margin-left:auto;border-radius:6px;font:500 11.5px/24px var(--font);color:var(--muted)}#cpick .cp-none:hover{background:var(--surface-hover);color:var(--ink)}.chip-area.chip-frame{display:inline-flex;align-items:center;gap:6px;max-width:100%;padding:3px 9px 3px 7px}.chip-frame svg{width:12px;height:12px;flex:none}.chip-frame b{font-weight:600;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.chip-frame span{flex:none;opacity:.7;font-weight:500}.chip-frame span:before{content:"\b7";margin-right:6px}.frame.whole .frame-label{visibility:hidden}.frame-tray{display:flex;align-items:center;gap:2px;max-width:0;opacity:0;overflow:hidden;pointer-events:none;transition:max-width .32s cubic-bezier(.2,.8,.2,1),opacity .2s ease,margin .32s cubic-bezier(.2,.8,.2,1),padding .32s cubic-bezier(.2,.8,.2,1)}#toolbar.tray-open .frame-tray{max-width:440px;opacity:1;pointer-events:auto;margin-left:4px;padding-left:6px;box-shadow:inset 1px 0 0 var(--line)}#toolbar .frame-tray button{flex:none}#toolbar .frame-tray .tr-dev{color:var(--muted)}#toolbar .frame-tray .tr-dev:hover{color:var(--ink)}#toolbar .frame-tray .tr-dev.on{background:color-mix(in srgb,var(--ink) 10%,transparent);color:var(--ink)}#toolbar .frame-tray .tr-more{width:auto;display:flex;align-items:center;gap:6px;padding:0 8px 0 10px;font:500 12.5px/1 var(--font);color:var(--ink-2);white-space:nowrap}#toolbar .frame-tray .tr-more small{font:500 11px/1 var(--mono);color:var(--muted)}#toolbar .frame-tray .tr-more svg{width:12px;height:12px;color:var(--muted)}#toolbar .frame-tray .tr-more.on{background:color-mix(in srgb,var(--ink) 10%,transparent);color:var(--ink)}@media(prefers-reduced-motion:reduce){.frame-tray{transition:none}}.preset-menu{position:fixed;left:50%;bottom:72px;translate:-50% 0;z-index:30;width:320px;max-height:min(520px,calc(100vh - 160px));overflow:auto;padding:6px;border-radius:14px}.preset-menu:not([hidden]){animation:trayUp .2s cubic-bezier(.2,.8,.2,1)}@keyframes trayUp{0%{opacity:0;transform:translateY(6px)}}.pm-group+.pm-group{margin-top:4px;padding-top:4px;border-top:1px solid var(--line)}.pm-title{display:flex;align-items:center;gap:6px;padding:8px 8px 4px;font:500 11.5px/1 var(--font);color:var(--muted)}.pm-title svg{width:13px;height:13px}.pm-row{display:flex;align-items:center;justify-content:space-between;width:100%;height:32px;padding:0 8px;border-radius:8px;font:500 13px/1 var(--font);color:var(--ink-2)}.pm-row small{font:500 11px/1 var(--mono);color:var(--muted)}.pm-row:hover{background:var(--surface-hover);color:var(--ink)}.pm-row.on{color:var(--ink);background:var(--surface-hover)}.pm-custom{display:flex;align-items:center;gap:6px;margin-top:4px;padding:8px 4px 4px 8px;border-top:1px solid var(--line);font:500 12px/1 var(--font);color:var(--muted)}.pm-custom>span{margin-right:auto}.pm-custom label{display:flex;align-items:center;gap:4px;height:28px;padding:0 6px;border-radius:7px;background:var(--surface-2);box-shadow:inset 0 0 0 1px var(--line);font:500 10.5px/1 var(--mono)}.pm-custom input{width:42px;border:0;background:none;color:var(--ink);font:500 12px/1 var(--mono);outline:none}.pm-custom button{height:28px;padding:0 10px;border-radius:7px;background:var(--ink);color:var(--surface);font:500 12px/28px var(--font)}.pm-describe{display:flex;align-items:center;gap:8px;width:100%;height:32px;margin-top:4px;padding:0 8px;border-radius:8px;font:500 12.5px/1 var(--font);color:var(--muted)}.pm-describe:hover{background:var(--surface-hover);color:var(--ink)}.pm-describe svg{width:14px;height:14px}.pm-describe kbd{margin-left:auto;border:0;background:none;font:500 11px/1 var(--font);color:var(--muted)}.preset-menu.for-frame{translate:none;bottom:auto}.pm-top{margin:0 0 4px;padding:6px 4px 8px 8px;border-top:0;border-bottom:1px solid var(--line)}.pm-acts{display:flex;flex-wrap:wrap;gap:4px;margin-top:4px;padding:6px 2px 2px;border-top:1px solid var(--line)}.pm-act{display:inline-flex;align-items:center;gap:6px;height:28px;padding:0 8px;border-radius:7px;font:500 12px/1 var(--font);color:var(--ink-2)}.pm-act:hover,.pm-act.on{background:var(--surface-hover);color:var(--ink)}.pm-act svg{width:13px;height:13px}.pm-act kbd{border:0;background:none;font:500 11px/1 var(--font);color:var(--muted)}