cubefarm 0.1.0 → 0.2.0
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 +93 -91
- package/bin/cubefarm.js +2 -1
- package/dist/assets/ToyWorld-CrlIe2hV.js +2 -0
- package/dist/assets/index-CazA79UU.css +1 -0
- package/dist/assets/index-DDIwWVME.js +4316 -0
- package/dist/assets/rapier-B1_J71Lw.js +1 -0
- package/dist/index.html +2 -2
- package/dist-server/index.js +674 -135
- package/dist-server/index.js.map +4 -4
- package/package.json +78 -79
- package/dist/assets/ToyWorld-Bj5kLnpv.js +0 -2
- package/dist/assets/index-8tdBZH9c.css +0 -1
- package/dist/assets/index-uo74me0U.js +0 -4316
- package/dist/assets/rapier-DO_XuNdK.js +0 -1
package/package.json
CHANGED
|
@@ -1,79 +1,78 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "cubefarm",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "A cartoon 3D office where a team of Claude Code agents works through your GitHub issues.",
|
|
5
|
-
"keywords": [
|
|
6
|
-
"claude-code",
|
|
7
|
-
"claude-agent-sdk",
|
|
8
|
-
"ai-agents",
|
|
9
|
-
"coding-agents",
|
|
10
|
-
"github-issues",
|
|
11
|
-
"automation",
|
|
12
|
-
"threejs"
|
|
13
|
-
],
|
|
14
|
-
"homepage": "https://github.com/leonvanzyl/cubefarm#readme",
|
|
15
|
-
"bugs": "https://github.com/leonvanzyl/cubefarm/issues",
|
|
16
|
-
"repository": {
|
|
17
|
-
"type": "git",
|
|
18
|
-
"url": "git+https://github.com/leonvanzyl/cubefarm.git"
|
|
19
|
-
},
|
|
20
|
-
"license": "MIT",
|
|
21
|
-
"author": "Leon van Zyl",
|
|
22
|
-
"type": "module",
|
|
23
|
-
"bin": {
|
|
24
|
-
"cubefarm": "bin/cubefarm.js"
|
|
25
|
-
},
|
|
26
|
-
"files": [
|
|
27
|
-
"bin",
|
|
28
|
-
"dist",
|
|
29
|
-
"dist-server"
|
|
30
|
-
],
|
|
31
|
-
"engines": {
|
|
32
|
-
"node": ">=22"
|
|
33
|
-
},
|
|
34
|
-
"scripts": {
|
|
35
|
-
"dev": "
|
|
36
|
-
"demo": "
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
"
|
|
49
|
-
"
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
"@
|
|
55
|
-
"@react-three/
|
|
56
|
-
"@react-three/
|
|
57
|
-
"@
|
|
58
|
-
"@types/
|
|
59
|
-
"@types/
|
|
60
|
-
"@types/react": "^19.3.0",
|
|
61
|
-
"@types/
|
|
62
|
-
"@types/
|
|
63
|
-
"@
|
|
64
|
-
"
|
|
65
|
-
"
|
|
66
|
-
"
|
|
67
|
-
"react": "^19.3.0",
|
|
68
|
-
"react-
|
|
69
|
-
"
|
|
70
|
-
"remark-
|
|
71
|
-
"
|
|
72
|
-
"
|
|
73
|
-
"
|
|
74
|
-
"
|
|
75
|
-
"
|
|
76
|
-
"
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "cubefarm",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "A cartoon 3D office where a team of Claude Code agents works through your GitHub issues.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"claude-code",
|
|
7
|
+
"claude-agent-sdk",
|
|
8
|
+
"ai-agents",
|
|
9
|
+
"coding-agents",
|
|
10
|
+
"github-issues",
|
|
11
|
+
"automation",
|
|
12
|
+
"threejs"
|
|
13
|
+
],
|
|
14
|
+
"homepage": "https://github.com/leonvanzyl/cubefarm#readme",
|
|
15
|
+
"bugs": "https://github.com/leonvanzyl/cubefarm/issues",
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "git+https://github.com/leonvanzyl/cubefarm.git"
|
|
19
|
+
},
|
|
20
|
+
"license": "MIT",
|
|
21
|
+
"author": "Leon van Zyl",
|
|
22
|
+
"type": "module",
|
|
23
|
+
"bin": {
|
|
24
|
+
"cubefarm": "bin/cubefarm.js"
|
|
25
|
+
},
|
|
26
|
+
"files": [
|
|
27
|
+
"bin",
|
|
28
|
+
"dist",
|
|
29
|
+
"dist-server"
|
|
30
|
+
],
|
|
31
|
+
"engines": {
|
|
32
|
+
"node": ">=22"
|
|
33
|
+
},
|
|
34
|
+
"scripts": {
|
|
35
|
+
"dev": "node scripts/office.mjs --dev",
|
|
36
|
+
"demo": "node scripts/office.mjs --dev --demo",
|
|
37
|
+
"build": "tsc --noEmit -p tsconfig.json && vite build && node scripts/build-server.mjs",
|
|
38
|
+
"start": "node scripts/office.mjs",
|
|
39
|
+
"typecheck": "tsc --noEmit -p tsconfig.json",
|
|
40
|
+
"test": "vitest run",
|
|
41
|
+
"test:watch": "vitest",
|
|
42
|
+
"test:e2e": "playwright test",
|
|
43
|
+
"prepublishOnly": "npm test && npm run build"
|
|
44
|
+
},
|
|
45
|
+
"dependencies": {
|
|
46
|
+
"@anthropic-ai/claude-agent-sdk": "^0.3.283",
|
|
47
|
+
"express": "^5.2.1",
|
|
48
|
+
"ws": "^8.22.0",
|
|
49
|
+
"zod": "^4.0.0"
|
|
50
|
+
},
|
|
51
|
+
"devDependencies": {
|
|
52
|
+
"@dimforge/rapier3d-compat": "0.19.2",
|
|
53
|
+
"@playwright/test": "1.56.1",
|
|
54
|
+
"@react-three/drei": "^10.7.9",
|
|
55
|
+
"@react-three/fiber": "^9.8.1",
|
|
56
|
+
"@react-three/rapier": "^2.2.0",
|
|
57
|
+
"@types/express": "^5.0.6",
|
|
58
|
+
"@types/node": "^26.6.3",
|
|
59
|
+
"@types/react": "^19.3.0",
|
|
60
|
+
"@types/react-dom": "^19.3.0",
|
|
61
|
+
"@types/three": "^0.186.0",
|
|
62
|
+
"@types/ws": "^8.18.1",
|
|
63
|
+
"@vitejs/plugin-react": "^6.1.1",
|
|
64
|
+
"concurrently": "^10.0.5",
|
|
65
|
+
"esbuild": "^0.28.2",
|
|
66
|
+
"react": "^19.3.0",
|
|
67
|
+
"react-dom": "^19.3.0",
|
|
68
|
+
"react-markdown": "^10.1.0",
|
|
69
|
+
"remark-breaks": "^4.0.0",
|
|
70
|
+
"remark-gfm": "^4.0.1",
|
|
71
|
+
"three": "^0.186.1",
|
|
72
|
+
"tsx": "^4.23.15",
|
|
73
|
+
"typescript": "^7.0.2",
|
|
74
|
+
"vite": "^8.3.1",
|
|
75
|
+
"vitest": "^5.0.2",
|
|
76
|
+
"zustand": "^5.0.15"
|
|
77
|
+
}
|
|
78
|
+
}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/rapier-DO_XuNdK.js","assets/index-uo74me0U.js","assets/index-8tdBZH9c.css"])))=>i.map(i=>d[i]);
|
|
2
|
-
import{A as e,C as t,D as n,E as r,N as i,O as a,S as o,T as s,_ as c,a as l,b as u,c as d,d as f,f as p,g as m,h,i as g,j as _,k as v,l as y,m as b,n as x,o as S,p as C,r as w,s as T,t as E,u as D,v as O,w as k,x as A,y as ee}from"./index-uo74me0U.js";import{a as te,i as j,n as ne,r as re,t as M}from"./rapier-DO_XuNdK.js";var N=i(_());function ie(e,t){if(typeof e!=`object`||!e)return e;var n=e[Symbol.toPrimitive];if(n!==void 0){var r=n.call(e,t||`default`);if(typeof r!=`object`)return r;throw TypeError(`@@toPrimitive must return a primitive value.`)}return(t===`string`?String:Number)(e)}function P(e){var t=ie(e,`string`);return typeof t==`symbol`?t:t+``}function F(e,t,n){return(t=P(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function ae(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function I(e){for(var t=1;t<arguments.length;t++){var n=arguments[t]==null?{}:arguments[t];t%2?ae(Object(n),!0).forEach(function(t){F(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):ae(Object(n)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}var oe=new n;new o;var se=new e;new r;var L=new k,R=new e,z=new n,B=new e,ce=t=>{let[n,r,i]=t;return new e(n,r,i)},le=({x:e,y:t,z:n,w:r})=>oe.set(e,t,n,r),ue=e=>{if(Array.isArray(e))return new j(e[0],e[1],e[2]);if(typeof e==`number`)return new j(e,e,e);{let t=e;return new j(t.x,t.y,t.z)}},de={fixed:1,dynamic:0,kinematicPosition:2,kinematicVelocity:3},fe=e=>de[e],pe=(e,t)=>{let n=Array.from(e);for(let r=0;r<e.length/3;r++)n[r*3]*=t.x,n[r*3+1]*=t.y,n[r*3+2]*=t.z;return n},me=t=>t?t instanceof n?[t.x,t.y,t.z,t.w]:t instanceof e||t instanceof o?[t.x,t.y,t.z]:Array.isArray(t)?t:[t]:[0];function V(e){let t=(0,N.useRef)(void 0);return t.current===void 0&&(t.current={value:typeof e==`function`?e():e}),t.current.value}var he=e=>{let t=(0,N.useRef)(e),n=(0,N.useRef)(0),r=(0,N.useRef)(0);(0,N.useEffect)(()=>{t.current=e},[e]),(0,N.useEffect)(()=>{let e=()=>{let i=performance.now(),a=i-r.current;n.current=requestAnimationFrame(e),t.current(a/1e3),r.current=i};return n.current=requestAnimationFrame(e),()=>cancelAnimationFrame(n.current)},[])},ge=({onStep:e,updatePriority:t})=>(b((t,n)=>{e(n)},t),null),_e=({onStep:e})=>(he(t=>{e(t)}),null),ve=(0,N.memo)(({onStep:e,type:t,updatePriority:n})=>t===`independent`?N.createElement(_e,{onStep:e}):N.createElement(ge,{onStep:e,updatePriority:n}));function ye(e,t){if(e==null)return{};var n={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(t.indexOf(r)!==-1)continue;n[r]=e[r]}return n}function be(e,t){if(e==null)return{};var n,r,i=ye(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)===-1&&{}.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var xe=[`mass`,`linearDamping`,`angularDamping`,`type`,`onCollisionEnter`,`onCollisionExit`,`onIntersectionEnter`,`onIntersectionExit`,`onContactForce`,`children`,`canSleep`,`ccd`,`gravityScale`,`softCcdPrediction`,`ref`],Se=(e,t,n)=>{let r=t.slice();if(e===`heightfield`){let e=r[3];return e.x*=n.x,e.x*=n.y,e.x*=n.z,r}if(e===`trimesh`||e===`convexHull`)return r[0]=pe(r[0],n),r;let i=[n.x,n.y,n.z,n.x,n.x];return r.map((e,t)=>i[t]*e)},Ce=(e,t,n,r)=>{let i=Se(e.shape,e.args,n),a=re[e.shape](...i);return t.createCollider(a,r?.())},we=[`shape`,`args`],Te="Please pick ONLY ONE of the `density`, `mass` and `massProperties` options.",Ee=(e,t)=>{if(t.density!==void 0){if(t.mass!==void 0||t.massProperties!==void 0)throw Error(Te);e.setDensity(t.density);return}if(t.mass!==void 0){if(t.massProperties!==void 0)throw Error(Te);e.setMass(t.mass);return}t.massProperties!==void 0&&e.setMassProperties(t.massProperties.mass,t.massProperties.centerOfMass,t.massProperties.principalAngularInertia,t.massProperties.angularInertiaLocalFrame)},De={sensor:(e,t)=>{e.setSensor(t)},collisionGroups:(e,t)=>{e.setCollisionGroups(t)},solverGroups:(e,t)=>{e.setSolverGroups(t)},friction:(e,t)=>{e.setFriction(t)},frictionCombineRule:(e,t)=>{e.setFrictionCombineRule(t)},restitution:(e,t)=>{e.setRestitution(t)},restitutionCombineRule:(e,t)=>{e.setRestitutionCombineRule(t)},activeCollisionTypes:(e,t)=>{e.setActiveCollisionTypes(t)},contactSkin:(e,t)=>{e.setContactSkin(t)},quaternion:()=>{},position:()=>{},rotation:()=>{},scale:()=>{}},Oe=Object.keys(De),ke=(e,t,n)=>{let r=n.get(e.handle);if(r){let n=r.object.parent.getWorldScale(se),i=r.worldParent?.matrixWorld.clone().invert();r.object.updateWorldMatrix(!0,!1),L.copy(r.object.matrixWorld),i&&L.premultiply(i),L.decompose(R,z,B),e.parent()?(e.setTranslationWrtParent({x:R.x*n.x,y:R.y*n.y,z:R.z*n.z}),e.setRotationWrtParent(z)):(e.setTranslation({x:R.x*n.x,y:R.y*n.y,z:R.z*n.z}),e.setRotation(z)),Oe.forEach(n=>{if(n in t){let r=t[n];De[n](e,r,t)}}),Ee(e,t)}},Ae=(e,t,n)=>{let r=(0,N.useMemo)(()=>Oe.flatMap(e=>me(t[e])),[t]);(0,N.useEffect)(()=>{ke(e(),t,n)},[...r,e])},je=e=>{let t=!1;return e.traverseAncestors(e=>{e.userData.r3RapierType===`MeshCollider`&&(t=!0)}),t},Me=(e,t,n)=>({collider:e,worldParent:n||void 0,object:t}),Ne={cuboid:`cuboid`,ball:`ball`,hull:`convexHull`,trimesh:`trimesh`},Pe=({object:e,ignoreMeshColliders:t=!0,options:n})=>{let r=[];e.updateWorldMatrix(!0,!1);let i=e.matrixWorld.clone().invert(),a=e=>{if(`isMesh`in e){if(t&&je(e))return;let a=e.getWorldScale(B),s=Ne[n.colliders||`cuboid`];e.updateWorldMatrix(!0,!1),L.copy(e.matrixWorld).premultiply(i).decompose(R,z,B);let c=new o().setFromQuaternion(z,`XYZ`),{geometry:l}=e,{args:u,offset:d}=Fe(l,n.colliders||`cuboid`),f=I(I({},Re(n)),{},{args:u,shape:s,rotation:[c.x,c.y,c.z],position:[R.x+d.x*a.x,R.y+d.y*a.y,R.z+d.z*a.z],scale:[a.x,a.y,a.z]});r.push(f)}};return n.includeInvisible?e.traverse(a):e.traverseVisible(a),r},Fe=(t,n)=>{switch(n){case`cuboid`:{t.computeBoundingBox();let{boundingBox:n}=t,r=n.getSize(new e);return{args:[r.x/2,r.y/2,r.z/2],offset:n.getCenter(new e)}}case`ball`:{t.computeBoundingSphere();let{boundingSphere:e}=t;return{args:[e.radius],offset:e.center}}case`trimesh`:{let n=t.index?t.clone():C(t);return{args:[n.attributes.position.array,n.index?.array],offset:new e}}case`hull`:return{args:[t.clone().attributes.position.array],offset:new e}}return{args:[],offset:new e}},Ie=e=>({collision:!!(e!=null&&e.onCollisionEnter||e!=null&&e.onCollisionExit||e!=null&&e.onIntersectionEnter||e!=null&&e.onIntersectionExit),contactForce:!!(e!=null&&e.onContactForce)}),Le=(e,t,n,r={})=>{let{onCollisionEnter:i,onCollisionExit:a,onIntersectionEnter:o,onIntersectionExit:s,onContactForce:c}=t;(0,N.useEffect)(()=>{let l=e();if(l){let{collision:e,contactForce:u}=Ie(t),d=e||r.collision,f=u||r.contactForce;d&&f?l.setActiveEvents(M.COLLISION_EVENTS|M.CONTACT_FORCE_EVENTS):d?l.setActiveEvents(M.COLLISION_EVENTS):f&&l.setActiveEvents(M.CONTACT_FORCE_EVENTS),n.set(l.handle,{onCollisionEnter:i,onCollisionExit:a,onIntersectionEnter:o,onIntersectionExit:s,onContactForce:c})}return()=>{l&&n.delete(l.handle)}},[i,a,o,s,c,r])},Re=(e={})=>be(e,xe),ze=e=>{let t=(0,N.useRef)(e);return(0,N.useEffect)(()=>{t.current=e},[e]),t},H=()=>{let e=(0,N.useContext)(Ge);if(!e)throw Error(`react-three-rapier: useRapier must be used within <Physics />!`);return e},Be=e=>{let{beforeStepCallbacks:t}=H(),n=ze(e);(0,N.useEffect)(()=>(t.add(n),()=>{t.delete(n)}),[])},Ve=e=>{let{afterStepCallbacks:t}=H(),n=ze(e);(0,N.useEffect)(()=>(t.add(n),()=>{t.delete(n)}),[])},He=(e,t,n=!0)=>{let[r,i]=(0,N.useState)([]);return(0,N.useEffect)(()=>{e.current&&t.colliders!==!1&&i(Pe({object:e.current,options:t,ignoreMeshColliders:n}))},[t.colliders]),r},Ue=(0,N.memo)(()=>{let{world:e}=H(),t=(0,N.useRef)(null);return b(()=>{let n=t.current;if(!n)return;let r=e.debugRender(),i=new ee;i.setAttribute(`position`,new O(r.vertices,3)),i.setAttribute(`color`,new O(r.colors,4)),n.geometry.dispose(),n.geometry=i}),N.createElement(`group`,null,N.createElement(`lineSegments`,{ref:t,frustumCulled:!1},N.createElement(`lineBasicMaterial`,{color:16777215,vertexColors:!0}),N.createElement(`bufferGeometry`,null)))}),We=e=>{let t;return{proxy:new Proxy({},{get(n,r){return t||=e(),Reflect.get(t,r)},set(n,r,i){return t||=e(),Reflect.set(t,r,i)}}),reset:()=>{t=void 0},set:e=>{t=e}}},Ge=(0,N.createContext)(void 0),Ke=(e,t)=>({target:{rigidBody:e.rigidBody.object,collider:e.collider.object,colliderObject:e.collider.state?.object,rigidBodyObject:e.rigidBody.state?.object},other:{rigidBody:t.rigidBody.object,collider:t.collider.object,colliderObject:t.collider.state?.object,rigidBodyObject:t.rigidBody.state?.object},rigidBody:t.rigidBody.object,collider:t.collider.object,colliderObject:t.collider.state?.object,rigidBodyObject:t.rigidBody.state?.object}),qe=async()=>{let e=await f(()=>import(`./rapier-DO_XuNdK.js`).then(e=>e.o),__vite__mapDeps([0,1,2]));return await e.init(),e},Je=e=>{let{colliders:n=`cuboid`,children:r,timeStep:i=1/60,paused:a=!1,interpolate:o=!0,updatePriority:s,updateLoop:c=`follow`,debug:l=!1,gravity:u=[0,-9.81,0],allowedLinearError:d=.001,predictionDistance:f=.002,numSolverIterations:p=4,numInternalPgsIterations:g=1,minIslandSize:_=128,maxCcdSubsteps:v=1,contactNaturalFrequency:y=30,lengthUnit:b=1}=e,x=m(qe,[`@react-thee/rapier`,qe]),{invalidate:S}=h(),C=V(()=>new Map),w=V(()=>new Map),T=V(()=>new Map),E=V(()=>new Map),D=V(()=>new ne(!1)),O=V(()=>new Set),k=V(()=>new Set),A=V(()=>({filterContactPair:(...e)=>{for(let t of O){let n=t.current(...e);if(n!==null)return n}return null},filterIntersectionPair:(...e)=>{for(let t of k)if(t.current(...e)===!1)return!1;return!0}})),ee=V(()=>new Set),te=V(()=>new Set),{proxy:j,reset:re,set:M}=V(()=>We(()=>new x.World(ce(u))));(0,N.useEffect)(()=>()=>{j.free(),re()},[]),(0,N.useEffect)(()=>{j.gravity=ue(u),j.integrationParameters.numSolverIterations=p,j.integrationParameters.numInternalPgsIterations=g,j.integrationParameters.normalizedAllowedLinearError=d,j.integrationParameters.minIslandSize=_,j.integrationParameters.maxCcdSubsteps=v,j.integrationParameters.normalizedPredictionDistance=f,j.lengthUnit=b,j.integrationParameters.contact_natural_frequency=y},[j,...u,p,g,d,_,v,f,b,y]);let ie=(0,N.useCallback)(e=>{let t=j.getCollider(e),n=E.get(e),r=w.get(e),i=t?.parent()?.handle,a=i===void 0?void 0:j.getRigidBody(i),o=a&&i!==void 0?T.get(i):void 0,s=i===void 0?void 0:C.get(i);return{collider:{object:t,events:n,state:r},rigidBody:{object:a,events:o,state:s}}},[]),[P]=(0,N.useState)({previousState:{},accumulator:0}),F=(0,N.useCallback)(e=>{let n=j,r=i===`vary`,s=t.clamp(e,0,.5),c=e=>{ee.forEach(e=>{e.current(n)}),n.timestep=e;let t=O.size>0||k.size>0;n.step(D,t?A:void 0),te.forEach(e=>{e.current(n)})};if(r)c(s);else for(P.accumulator+=s;P.accumulator>=i;)o&&(P.previousState={},n.forEachRigidBody(e=>{P.previousState[e.handle]={position:e.translation(),rotation:e.rotation()}})),c(i),P.accumulator-=i;let l=r||!o||a?1:P.accumulator/i;C.forEach((e,t)=>{let r=n.getRigidBody(t),i=T.get(t);if(i!=null&&i.onSleep||i!=null&&i.onWake){if(r.isSleeping()&&!e.isSleeping){var a;i==null||(a=i.onSleep)==null||a.call(i)}if(!r.isSleeping()&&e.isSleeping){var o;i==null||(o=i.onWake)==null||o.call(i)}e.isSleeping=r.isSleeping()}if(!r||r.isSleeping()&&!(`isInstancedMesh`in e.object)||!e.setMatrix)return;let s=r.translation(),c=r.rotation(),u=P.previousState[t];u&&(L.compose(u.position,le(u.rotation),e.scale).premultiply(e.invertedWorldMatrix).decompose(R,z,B),e.meshType==`mesh`&&(e.object.position.copy(R),e.object.quaternion.copy(z))),L.compose(s,le(c),e.scale).premultiply(e.invertedWorldMatrix).decompose(R,z,B),e.meshType==`instancedMesh`?e.setMatrix(L):(e.object.position.lerp(R,l),e.object.quaternion.slerp(z,l))}),D.drainCollisionEvents((e,t,r)=>{let i=ie(e),a=ie(t);if(!(i!=null&&i.collider.object)||!(a!=null&&a.collider.object))return;let o=Ke(i,a),s=Ke(a,i);if(r)n.contactPair(i.collider.object,a.collider.object,(e,t)=>{var n,r,c,l,u,d,f,p;(n=i.rigidBody.events)==null||(r=n.onCollisionEnter)==null||r.call(n,I(I({},o),{},{manifold:e,flipped:t})),(c=a.rigidBody.events)==null||(l=c.onCollisionEnter)==null||l.call(c,I(I({},s),{},{manifold:e,flipped:t})),(u=i.collider.events)==null||(d=u.onCollisionEnter)==null||d.call(u,I(I({},o),{},{manifold:e,flipped:t})),(f=a.collider.events)==null||(p=f.onCollisionEnter)==null||p.call(f,I(I({},s),{},{manifold:e,flipped:t}))});else{var c,l,u,d,f,p,m,h;(c=i.rigidBody.events)==null||(l=c.onCollisionExit)==null||l.call(c,o),(u=a.rigidBody.events)==null||(d=u.onCollisionExit)==null||d.call(u,s),(f=i.collider.events)==null||(p=f.onCollisionExit)==null||p.call(f,o),(m=a.collider.events)==null||(h=m.onCollisionExit)==null||h.call(m,s)}if(r){if(n.intersectionPair(i.collider.object,a.collider.object)){var g,_,v,y,b,x,S,C;(g=i.rigidBody.events)==null||(_=g.onIntersectionEnter)==null||_.call(g,o),(v=a.rigidBody.events)==null||(y=v.onIntersectionEnter)==null||y.call(v,s),(b=i.collider.events)==null||(x=b.onIntersectionEnter)==null||x.call(b,o),(S=a.collider.events)==null||(C=S.onIntersectionEnter)==null||C.call(S,s)}}else{var w,T,E,D,O,k,A,ee;(w=i.rigidBody.events)==null||(T=w.onIntersectionExit)==null||T.call(w,o),(E=a.rigidBody.events)==null||(D=E.onIntersectionExit)==null||D.call(E,s),(O=i.collider.events)==null||(k=O.onIntersectionExit)==null||k.call(O,o),(A=a.collider.events)==null||(ee=A.onIntersectionExit)==null||ee.call(A,s)}}),D.drainContactForceEvents(e=>{var t,n,r,i,a,o,s,c;let l=ie(e.collider1()),u=ie(e.collider2());if(!(l!=null&&l.collider.object)||!(u!=null&&u.collider.object))return;let d=Ke(l,u),f=Ke(u,l);(t=l.rigidBody.events)==null||(n=t.onContactForce)==null||n.call(t,I(I({},d),{},{totalForce:e.totalForce(),totalForceMagnitude:e.totalForceMagnitude(),maxForceDirection:e.maxForceDirection(),maxForceMagnitude:e.maxForceMagnitude()})),(r=u.rigidBody.events)==null||(i=r.onContactForce)==null||i.call(r,I(I({},f),{},{totalForce:e.totalForce(),totalForceMagnitude:e.totalForceMagnitude(),maxForceDirection:e.maxForceDirection(),maxForceMagnitude:e.maxForceMagnitude()})),(a=l.collider.events)==null||(o=a.onContactForce)==null||o.call(a,I(I({},d),{},{totalForce:e.totalForce(),totalForceMagnitude:e.totalForceMagnitude(),maxForceDirection:e.maxForceDirection(),maxForceMagnitude:e.maxForceMagnitude()})),(s=u.collider.events)==null||(c=s.onContactForce)==null||c.call(s,I(I({},f),{},{totalForce:e.totalForce(),totalForceMagnitude:e.totalForceMagnitude(),maxForceDirection:e.maxForceDirection(),maxForceMagnitude:e.maxForceMagnitude()}))}),n.forEachActiveRigidBody(()=>{S()})},[a,i,o,j]),ae=(0,N.useMemo)(()=>({rapier:x,world:j,setWorld:e=>{M(e)},physicsOptions:{colliders:n,gravity:u},rigidBodyStates:C,colliderStates:w,rigidBodyEvents:T,colliderEvents:E,beforeStepCallbacks:ee,afterStepCallbacks:te,isPaused:a,isDebug:l,step:F,filterContactPairHooks:O,filterIntersectionPairHooks:k}),[a,F,l,n,u]),oe=(0,N.useCallback)(e=>{a||F(e)},[a,F]);return N.createElement(Ge.Provider,{value:ae},N.createElement(ve,{onStep:oe,type:c,updatePriority:s}),l&&N.createElement(Ue,null),r)};function U(){return U=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)({}).hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},U.apply(null,arguments)}var Ye=(e,t=null)=>{let n=(0,N.useRef)(t);return e&&typeof e!=`function`?(e.current||=n.current,e):n},Xe=(e,t,n)=>{let r=(0,N.useRef)(void 0),i=(0,N.useCallback)(()=>(r.current||=e(),r.current),n);return(0,N.useEffect)(()=>{let e=i(),n=()=>t(e);return()=>{n(),r.current=void 0}},[i]),i},Ze=e=>{let t=fe(e?.type||`dynamic`),n=new te(t);return n.canSleep=e?.canSleep??!0,n},Qe=({rigidBody:e,object:t,setMatrix:n,getMatrix:r,worldScale:i,meshType:a=`mesh`})=>(t.updateWorldMatrix(!0,!1),{object:t,rigidBody:e,invertedWorldMatrix:t.parent.matrixWorld.clone().invert(),setMatrix:n||(e=>{t.matrix.copy(e)}),getMatrix:r||(e=>e.copy(t.matrix)),scale:i||t.getWorldScale(B).clone(),isSleeping:!1,meshType:a}),$e=[`args`,`colliders`,`canSleep`],et={gravityScale:(e,t)=>{e.setGravityScale(t,!0)},additionalSolverIterations(e,t){e.setAdditionalSolverIterations(t)},linearDamping:(e,t)=>{e.setLinearDamping(t)},angularDamping:(e,t)=>{e.setAngularDamping(t)},dominanceGroup:(e,t)=>{e.setDominanceGroup(t)},enabledRotations:(e,[t,n,r])=>{e.setEnabledRotations(t,n,r,!0)},enabledTranslations:(e,[t,n,r])=>{e.setEnabledTranslations(t,n,r,!0)},lockRotations:(e,t)=>{e.lockRotations(t,!0)},lockTranslations:(e,t)=>{e.lockTranslations(t,!0)},angularVelocity:(e,[t,n,r])=>{e.setAngvel({x:t,y:n,z:r},!0)},linearVelocity:(e,[t,n,r])=>{e.setLinvel({x:t,y:n,z:r},!0)},ccd:(e,t)=>{e.enableCcd(t)},softCcdPrediction:(e,t)=>{e.setSoftCcdPrediction(t)},userData:(e,t)=>{e.userData=t},type(e,t){e.setBodyType(fe(t),!0)},position:()=>{},rotation:()=>{},quaternion:()=>{},scale:()=>{}},tt=Object.keys(et),nt=(e,t,n,r=!0)=>{if(!e)return;let i=n.get(e.handle);i&&(r&&(i.object.updateWorldMatrix(!0,!1),L.copy(i.object.matrixWorld).decompose(R,z,B),e.setTranslation(R,!1),e.setRotation(z,!1)),tt.forEach(n=>{n in t&&et[n](e,t[n])}))},rt=(e,t,n,r=!0)=>{let i=(0,N.useMemo)(()=>tt.flatMap(e=>me(t[e])),[t]);(0,N.useEffect)(()=>{nt(e(),t,n,r)},i)},it=(e,t,n)=>{let{onWake:r,onSleep:i,onCollisionEnter:a,onCollisionExit:o,onIntersectionEnter:s,onIntersectionExit:c,onContactForce:l}=t,u={onWake:r,onSleep:i,onCollisionEnter:a,onCollisionExit:o,onIntersectionEnter:s,onIntersectionExit:c,onContactForce:l};(0,N.useEffect)(()=>{let t=e();return n.set(t.handle,u),()=>{n.delete(t.handle)}},[r,i,a,o,s,c,l])},at=({x:t,y:n,z:r}={x:0,y:0,z:0})=>new e(t,n,r),W=(0,N.memo)(e=>{let{children:t,position:n,rotation:r,quaternion:i,scale:a,name:o}=e,{world:s,colliderEvents:c,colliderStates:l}=H(),u=_t(),d=Ye(e.ref),f=(0,N.useRef)(null),p=Xe(()=>{let t=f.current.getWorldScale(at()),n=Ce(e,s,t,u?.getRigidBody);return typeof e.ref==`function`&&e.ref(n),d.current=n,n},e=>{s.getCollider(e.handle)&&s.removeCollider(e,!0)},[...we.flatMap(t=>Array.isArray(e[t])?e[t]:[e[t]]),u]);(0,N.useEffect)(()=>{let e=p();return l.set(e.handle,Me(e,f.current,u?.ref.current)),()=>{l.delete(e.handle)}},[p]);let m=(0,N.useMemo)(()=>I(I({},Re(u?.options)),e),[e,u?.options]);return Ae(p,m,l),Le(p,m,c,Ie(u?.options)),N.createElement(`object3D`,{position:n,rotation:r,quaternion:i,scale:a,ref:f,name:o},t)}),G=N.forwardRef((e,t)=>N.createElement(W,U({},e,{shape:`cuboid`,ref:t})));G.displayName=`CuboidCollider`;var ot=N.forwardRef((e,t)=>N.createElement(W,U({},e,{shape:`roundCuboid`,ref:t})));ot.displayName=`RoundCuboidCollider`;var st=N.forwardRef((e,t)=>N.createElement(W,U({},e,{shape:`ball`,ref:t})));st.displayName=`BallCollider`;var ct=N.forwardRef((e,t)=>N.createElement(W,U({},e,{shape:`capsule`,ref:t})));ct.displayName=`CapsuleCollider`;var lt=N.forwardRef((e,t)=>N.createElement(W,U({},e,{shape:`heightfield`,ref:t})));lt.displayName=`HeightfieldCollider`;var ut=N.forwardRef((e,t)=>N.createElement(W,U({},e,{shape:`trimesh`,ref:t})));ut.displayName=`TrimeshCollider`;var dt=N.forwardRef((e,t)=>N.createElement(W,U({},e,{shape:`cone`,ref:t})));dt.displayName=`ConeCollider`;var ft=N.forwardRef((e,t)=>N.createElement(W,U({},e,{shape:`roundCone`,ref:t})));ft.displayName=`RoundConeCollider`;var pt=N.forwardRef((e,t)=>N.createElement(W,U({},e,{shape:`cylinder`,ref:t})));pt.displayName=`CylinderCollider`,pt.displayName=`RoundCylinderCollider`;var mt=N.forwardRef((e,t)=>N.createElement(W,U({},e,{shape:`convexHull`,ref:t})));mt.displayName=`ConvexHullCollider`;var ht=[`ref`,`children`,`type`,`position`,`rotation`,`scale`,`quaternion`,`transformState`],gt=(0,N.createContext)(void 0),_t=()=>(0,N.useContext)(gt),K=(0,N.memo)(e=>{let{ref:t,children:n,type:r,position:i,rotation:a,scale:o,quaternion:s,transformState:c}=e,l=be(e,ht),u=(0,N.useRef)(null),d=Ye(t),{world:f,rigidBodyStates:p,physicsOptions:m,rigidBodyEvents:h}=H(),g=(0,N.useMemo)(()=>I(I(I({},m),e),{},{children:void 0}),[m,e]),_=$e.flatMap(e=>Array.isArray(g[e])?[...g[e]]:g[e]),v=He(u,g),y=Xe(()=>{let e=Ze(g),n=f.createRigidBody(e);return typeof t==`function`&&t(n),d.current=n,n},e=>{f.getRigidBody(e.handle)&&f.removeRigidBody(e)},_);(0,N.useEffect)(()=>{let t=y(),n=Qe({rigidBody:t,object:u.current});return p.set(t.handle,e.transformState?e.transformState(n):n),()=>{p.delete(t.handle)}},[y]),rt(y,g,p),it(y,g,h);let b=(0,N.useMemo)(()=>({ref:u,getRigidBody:y,options:g}),[y]);return N.createElement(gt.Provider,{value:b},N.createElement(`object3D`,U({ref:u},l,{position:i,rotation:a,quaternion:s,scale:o}),n,v.map((e,t)=>N.createElement(W,U({key:t},e)))))});K.displayName=`RigidBody`;var vt=(0,N.memo)(e=>{let{children:t,type:n}=e,{physicsOptions:r}=H(),i=(0,N.useRef)(null),{options:a}=_t(),o=He(i,(0,N.useMemo)(()=>I(I(I({},r),a),{},{children:void 0,colliders:n}),[r,a]),!1);return N.createElement(`object3D`,{ref:i,userData:{r3RapierType:`MeshCollider`}},t,o.map((e,t)=>N.createElement(W,U({key:t},e))))});vt.displayName=`MeshCollider`;var yt=[`ref`],bt=[`children`,`instances`,`colliderNodes`,`position`,`rotation`,`quaternion`,`scale`],xt=(0,N.memo)(e=>{let{ref:t}=e,n=be(e,yt),r=Ye(t,[]),i=(0,N.useRef)(null),a=(0,N.useRef)(null),{children:o,instances:s,colliderNodes:c=[],position:l,rotation:u,quaternion:d,scale:f}=n,p=be(n,bt),m=He(i,I(I({},n),{},{children:void 0})),h=()=>{let e=a.current.children[0];if(e&&`isInstancedMesh`in e)return e};(0,N.useEffect)(()=>{let e=h();e?e.instanceMatrix.setUsage(A):console.warn(`InstancedRigidBodies expects exactly one child, which must be an InstancedMesh`)},[]);let g=(e,t)=>{let n=h();return n?I(I({},e),{},{getMatrix:e=>(n.getMatrixAt(t,e),e),setMatrix:e=>{n.setMatrixAt(t,e),n.instanceMatrix.needsUpdate=!0},meshType:`instancedMesh`}):e};return N.createElement(`object3D`,U({ref:i},p,{position:l,rotation:u,quaternion:d,scale:f}),N.createElement(`object3D`,{ref:a},o),s?.map((e,t)=>N.createElement(K,U({},p,e,{ref:e=>{r.current[t]=e},transformState:e=>g(e,t)}),N.createElement(N.Fragment,null,c.map((e,t)=>N.createElement(N.Fragment,{key:t},e)),m.map((e,t)=>N.createElement(W,U({key:t},e)))))))});xt.displayName=`InstancedRigidBodies`;var St=(e,t)=>(Ct(e)<<16)+(t===void 0?65535:Ct(t)),Ct=e=>[e].flat().reduce((e,t)=>e|1<<t,0),q=c(),wt=`#1f1d2b`,Tt={beach:{kind:`beach`,r:.4,restitution:.8,density:1.2,damping:.9},exercise:{kind:`exercise`,r:.45,restitution:.7,density:1.6,damping:.9},yarn:{kind:`yarn`,r:.33,restitution:.35,density:2.5,damping:1.3}},J=(e,t,n,r)=>({id:e,...Tt[t],start:{x:n,y:Tt[t].r+.02,z:r}}),Et={office:[J(`beach-ball`,`beach`,6.6,6.8),J(`exercise-ball`,`exercise`,9.8,8.6),J(`yarn-ball`,`yarn`,12.2,6.2)],lobby:[J(`beach-ball`,`beach`,-11,5.6),J(`exercise-ball`,`exercise`,-7.6,8.2),J(`yarn-ball`,`yarn`,-5.4,4.4)]},Dt=e=>Math.abs(e.x)>16||Math.abs(e.z)>12||e.y<-.5||e.y>6,Y=[`#ef476f`,`#ffffff`,`#ffd166`,`#ffffff`,`#118ab2`,`#ffffff`],X=null;function Ot(){if(X)return X;let e=new Uint8Array(Y.length*10*4);for(let t=0;t<10;t++)for(let n=0;n<Y.length;n++){let r=parseInt((t===0||t===9?`#ffffff`:Y[n]).slice(1),16),i=(t*Y.length+n)*4;e[i]=r>>16&255,e[i+1]=r>>8&255,e[i+2]=r&255,e[i+3]=255}return X=new u(e,Y.length,10,a),X.colorSpace=v,X.minFilter=s,X.magFilter=s,X.generateMipmaps=!1,X.needsUpdate=!0,X}var kt=`#8338ec`,At=`#ff70a6`,jt=[[0,0,0],[Math.PI/2,0,0],[.6,0,1.1],[-.7,.3,-1],[1.2,.9,.4]];function Mt({def:e}){let{r:t}=e;return e.kind===`beach`?(0,q.jsxs)(`mesh`,{castShadow:!0,material:g(`beach-ball`,Ot()),children:[(0,q.jsx)(`sphereGeometry`,{args:[t,24,16]}),(0,q.jsx)(p,{thickness:.02,color:wt})]}):e.kind===`exercise`?(0,q.jsxs)(`group`,{children:[(0,q.jsxs)(`mesh`,{castShadow:!0,material:w(kt),children:[(0,q.jsx)(`sphereGeometry`,{args:[t,24,16]}),(0,q.jsx)(p,{thickness:.02,color:wt})]}),(0,q.jsx)(`mesh`,{rotation:[Math.PI/2,0,0],material:w(x(kt,-.14)),children:(0,q.jsx)(`torusGeometry`,{args:[t*1.002,.018,6,40]})}),(0,q.jsx)(`mesh`,{position:[0,0,t],rotation:[Math.PI/2,0,0],material:w(`#f8f9fa`),children:(0,q.jsx)(`cylinderGeometry`,{args:[.045,.05,.04,12]})})]}):(0,q.jsxs)(`group`,{children:[(0,q.jsxs)(`mesh`,{castShadow:!0,material:w(At),children:[(0,q.jsx)(`sphereGeometry`,{args:[t,20,14]}),(0,q.jsx)(p,{thickness:.02,color:wt})]}),jt.map((e,n)=>(0,q.jsx)(`mesh`,{rotation:e,material:w(x(At,n%2?-.12:.08)),children:(0,q.jsx)(`torusGeometry`,{args:[t*1.005,.022,6,36]})},n)),(0,q.jsx)(`mesh`,{position:[t*.55,-t*.62,t*.45],rotation:[.4,0,.9],material:w(x(At,-.12)),children:(0,q.jsx)(`capsuleGeometry`,{args:[.022,.3,3,6]})})]})}var Nt=1/60,Z={building:0,doorway:1,pusher:2,toys:3},Pt=St(Z.doorway,[Z.toys]),Ft=St(Z.pusher,[Z.building,Z.toys]),It=St(Z.toys,[Z.building,Z.doorway,Z.pusher,Z.toys]),Lt=St(Z.building,[Z.pusher,Z.toys]),Q=T();function Rt({floor:e}){let t=(0,N.useMemo)(()=>e===`office`?y():d(),[e]);return(0,q.jsxs)(K,{type:`fixed`,colliders:!1,children:[(0,q.jsx)(G,{args:[17,.5,16],position:[0,-.5,2],friction:.8,restitution:.5,collisionGroups:Lt}),(0,q.jsx)(G,{args:[17,.5,16],position:[0,S+.5,2],collisionGroups:Lt}),(0,q.jsx)(G,{args:[(Q.maxX-Q.minX)/2,S/2,(Q.maxZ-Q.minZ)/2],position:[(Q.minX+Q.maxX)/2,S/2,(Q.minZ+Q.maxZ)/2],collisionGroups:Pt}),t.map((e,t)=>{let n=e.h??3.6;return(0,q.jsx)(G,{args:[(e.maxX-e.minX)/2,n/2,(e.maxZ-e.minZ)/2],position:[(e.minX+e.maxX)/2,n/2,(e.minZ+e.maxZ)/2],friction:.6,restitution:.5,collisionGroups:Lt},t)})]})}var zt={x:0,y:0,z:0},$={half:.62,y:.95,mass:4,maxSpeed:12,maxImpulse:600*Nt,teleport:1.5};function Bt(){let e=h(e=>e.camera),t=(0,N.useRef)(null),n=(0,N.useMemo)(()=>({x:0,y:$.y,z:0}),[]),r=(0,N.useMemo)(()=>({x:0,y:0,z:0}),[]),i=(0,N.useRef)({x:NaN,z:NaN});return Be(()=>{let a=t.current;if(!a)return;let{x:o,z:s}=e.position,c=i.current,l=o===c.x&&s===c.z;if(c.x=o,c.z=s,l&&a.isSleeping())return;let u=a.translation(),d=o-u.x,f=s-u.z,p=Math.hypot(d,f);if(p>$.teleport){n.x=o,n.z=s,a.setTranslation(n,!0),a.setLinvel(zt,!0);return}if(l&&p<.002){a.setLinvel(zt,!1);return}let m=$.maxImpulse*Math.min(1,Math.max(.1,(.7-p)/.4)),h=p>0?Math.min(1/Nt,$.maxSpeed/p):0,g=a.linvel();r.x=$.mass*(d*h-g.x),r.z=$.mass*(f*h-g.z);let _=Math.hypot(r.x,r.z);_>m&&(r.x*=m/_,r.z*=m/_),a.applyImpulse(r,!0)}),(0,q.jsx)(K,{ref:t,colliders:!1,position:[e.position.x,$.y,e.position.z],gravityScale:0,enabledTranslations:[!0,!1,!0],lockRotations:!0,children:(0,q.jsx)(ct,{args:[$.half,l],mass:$.mass,restitution:0,friction:.2,collisionGroups:Ft})})}var Vt={x:0,y:0,z:0,w:1};function Ht(e,t){e.setTranslation(t.start,!0),e.setRotation(Vt,!0),e.setLinvel(zt,!0),e.setAngvel(zt,!0)}function Ut({floor:e}){let t=Et[e],{world:n}=H(),r=(0,N.useRef)([]),i=(0,N.useMemo)(()=>t.map((e,t)=>e=>void(r.current[t]=e)),[t]);(0,N.useEffect)(()=>(E(()=>({bodies:n.bodies.len(),balls:t.map((e,t)=>{let n=r.current[t],i=n?n.translation():e.start;return{id:e.id,x:i.x,y:i.y,z:i.z,sleeping:!n||n.isSleeping()}})})),()=>E(null)),[n,t]);let a=(0,N.useRef)(0);return Ve((0,N.useCallback)(()=>{if(!(++a.current%15))for(let e=0;e<t.length;e++){let n=r.current[e];n&&!n.isSleeping()&&Dt(n.translation())&&Ht(n,t[e])}},[t])),t.map((e,t)=>(0,q.jsxs)(K,{ref:i[t],colliders:!1,position:[e.start.x,e.start.y,e.start.z],linearDamping:e.damping,angularDamping:e.damping,ccd:!0,userData:{toy:e.id},children:[(0,q.jsx)(st,{args:[e.r],restitution:e.restitution,friction:.7,density:e.density,collisionGroups:It}),(0,q.jsx)(Mt,{def:e})]},e.id))}function Wt({floor:e}){let t=D(e=>e.travel!==null);return(0,q.jsxs)(Je,{timeStep:Nt,paused:t,numSolverIterations:8,children:[(0,q.jsx)(Rt,{floor:e}),(0,q.jsx)(Bt,{}),(0,q.jsx)(Ut,{floor:e})]})}var Gt=(0,N.memo)(Wt);export{Gt as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
:root{--ink:#1f1d2b;--paper:#fffdf6;--muted:#6c7086;--good:#2dc653;--bad:#ef476f;--warn:#ffb703;--accent:#ff8a5b;--font:Fredoka, "Segoe UI", system-ui, sans-serif;--mono:"JetBrains Mono", Consolas, monospace;--lightningcss-light:initial;--lightningcss-dark: ;color-scheme:light}*{box-sizing:border-box}html,body,#root{height:100%;font-family:var(--font);color:var(--ink);background:#bfe3ff;margin:0;overflow:hidden}canvas{display:block}a{color:#3a56d4}kbd{border:2px solid var(--ink);min-width:1.6em;font-family:var(--font);text-align:center;background:#fff;border-bottom-width:4px;border-radius:6px;margin:0 .1em;padding:0 .4em;font-size:.85em;font-weight:600;line-height:1.5;display:inline-block}code{font-family:var(--mono);background:#0000000f;border-radius:5px;padding:1px 5px;font-size:.85em}.muted{color:var(--muted)}.small{font-size:.85rem}.spacer{flex:1}.grow{flex:1;min-width:0}.nowrap{white-space:nowrap}.btn{font-family:var(--font);border:2.5px solid var(--ink);color:var(--ink);box-shadow:0 3px 0 var(--ink);cursor:pointer;white-space:nowrap;background:#fff;border-radius:12px;padding:8px 14px;font-size:.95rem;font-weight:600;transition:transform 60ms,box-shadow 60ms}.btn:hover:not(:disabled){box-shadow:0 4px 0 var(--ink);transform:translateY(-1px)}.btn:active:not(:disabled){box-shadow:0 1px 0 var(--ink);transform:translateY(2px)}.btn:disabled{opacity:.45;cursor:not-allowed}.btn-good{background:#80ed99}.btn-bad{background:#ff8fa3}.btn-ghost{box-shadow:none;background:0 0;border-color:#1f1d2b59}.btn-small{box-shadow:0 2px 0 var(--ink);border-width:2px;border-radius:9px;padding:4px 10px;font-size:.82rem}.btn-ghost.btn-small{box-shadow:none}.btn-big{background:var(--accent);color:#fff;text-shadow:0 2px #0003;box-shadow:0 5px 0 var(--ink);border-radius:18px;padding:14px 32px;font-size:1.3rem}a.btn{text-decoration:none;display:inline-block}input,textarea,select{font-family:var(--font);color:var(--ink);background:#fff;border:2px solid #1f1d2b40;border-radius:10px;outline:none;width:100%;padding:8px 10px;font-size:.95rem}input:focus,textarea:focus,select:focus{border-color:var(--accent)}input[type=checkbox],input[type=radio]{width:auto;accent-color:var(--accent)}input[type=color]{width:42px;height:34px;padding:2px}textarea{resize:vertical}input.inline{background:0 0;border-color:#0000;padding:4px 6px}input.inline:hover,input.inline:focus{background:#fff;border-color:#1f1d2b40}.row{align-items:center;gap:8px;margin:6px 0;display:flex}.row.wrap{flex-wrap:wrap}.toggle{cursor:pointer;align-items:center;gap:6px;font-size:.92rem;display:inline-flex}.toggle.block{align-items:flex-start;margin:8px 0;display:flex}.pill,.chip{border:2px solid var(--ink);background:#fff;border-radius:999px;align-items:center;gap:4px;padding:3px 10px;font-size:.8rem;font-weight:600;display:inline-flex}.chip{color:var(--ink);border-width:1.5px;padding:1px 8px;font-size:.72rem;text-decoration:none}.chip-good,.pill-ok{background:#b9fbc0}.pill-bad{background:#ffc2d1}.pill-demo{background:#ffd166}.dot{border:2px solid var(--ink);border-radius:50%;width:12px;height:12px;display:inline-block}.agent-chip{align-items:center;gap:5px;font-size:.85rem;font-weight:600;display:inline-flex}.status{border:2px solid var(--ink);text-transform:uppercase;letter-spacing:.03em;border-radius:999px;padding:1px 9px;font-size:.75rem;font-weight:600;display:inline-block}.status-idle{background:#e9ecef}.status-preparing{background:#ffe066}.status-working{background:#74c0fc}.status-done{background:#8ce99a}.status-error{background:#ffa8a8}.status-stopped{background:#dee2e6}.status-installing,.status-starting{background:#ffe066}.status-running{background:#8ce99a}.status-unconfigured{background:#e9ecef}.hud{pointer-events:none;z-index:10;position:fixed;inset:0}.hud>*{pointer-events:auto}.hud-floor{background:var(--paper);border:3px solid var(--ink);box-shadow:0 4px 0 var(--ink);border-radius:18px;align-items:center;gap:12px;max-width:min(520px,100vw - 32px);padding:8px 16px 8px 8px;display:flex;position:absolute;top:16px;left:16px}.floor-num{background:var(--accent);border:3px solid var(--ink);color:#fff;text-shadow:0 2px #00000040;border-radius:12px;flex:none;place-items:center;width:46px;height:46px;font-size:1.5rem;font-weight:700;display:grid}.floor-name{text-overflow:ellipsis;white-space:nowrap;font-size:1.1rem;font-weight:700;overflow:hidden}.floor-sub{color:var(--muted);font-size:.85rem}.hud-status{flex-wrap:wrap;justify-content:flex-end;gap:6px;max-width:50vw;display:flex;position:absolute;top:16px;right:16px}.hud-banner{border:3px solid var(--ink);background:#ffe066;border-radius:14px;max-width:90vw;padding:8px 16px;font-weight:600;position:absolute;top:84px;left:50%;transform:translate(-50%)}.crosshair{border:2px solid var(--ink);pointer-events:none;background:#fff;border-radius:50%;width:8px;height:8px;margin:-4px 0 0 -4px;transition:transform .15s;position:absolute;top:50%;left:50%}.crosshair-hot{background:var(--accent);transform:scale(1.8)}.hud-hint{background:var(--paper);border:3px solid var(--ink);box-shadow:0 4px 0 var(--ink);white-space:nowrap;pointer-events:none;border-radius:14px;padding:8px 16px;font-size:1.05rem;font-weight:600;position:absolute;bottom:22%;left:50%;transform:translate(-50%)}.hud-resume{color:#fff;text-shadow:0 2px 0 var(--ink), 0 0 6px var(--ink);pointer-events:none;font-weight:600;position:absolute;top:calc(50% + 26px);left:50%;transform:translate(-50%)}.workers{background:var(--paper);border:3px solid var(--ink);width:min(360px,100vw - 32px);max-height:calc(100vh - 180px);box-shadow:0 4px 0 var(--ink);border-radius:18px;flex-direction:column;display:flex;position:absolute;top:60px;right:16px;overflow:hidden}.workers-closed{width:auto}.wk-head{font-family:var(--font);letter-spacing:.08em;text-transform:uppercase;color:var(--ink);cursor:pointer;text-align:left;background:0 0;border:0;justify-content:space-between;align-items:center;gap:12px;padding:8px 14px;font-size:.8rem;font-weight:600;display:flex}.wk-head b{color:#1e9e45}.wk-chevron{color:var(--muted);letter-spacing:0;text-transform:none}.wk-list{padding:0 6px 6px;overflow-y:auto}.wk-empty{color:var(--muted);padding:4px 10px 8px;font-size:.85rem}.wk-row{width:100%;font-family:var(--font);color:var(--ink);text-align:left;cursor:pointer;background:0 0;border:0;border-radius:12px;grid-template-columns:auto minmax(0,1fr);align-items:center;gap:10px;padding:5px 8px 5px 26px;display:grid}.wk-row:hover{background:#1f1d2b0f}.wk-dot{border:2px solid var(--ink);border-radius:50%;width:12px;height:12px}.wk-main{flex-direction:column;min-width:0;display:flex}.wk-name{white-space:nowrap;text-overflow:ellipsis;font-size:.95rem;font-weight:600;overflow:hidden}.wk-task{color:var(--muted);margin-left:6px;font-size:.78rem;font-weight:500}.wk-line{gap:6px;min-width:0;display:flex}.wk-last{min-width:0;font-family:var(--mono);color:var(--muted);white-space:nowrap;text-overflow:ellipsis;flex:auto;font-size:.72rem;overflow:hidden}.wk-last-text{font-family:var(--font);color:var(--ink);font-size:.8rem}.wk-last-thinking{font-style:italic}.wk-last-error{color:var(--bad)}.wk-ago{color:var(--muted);flex:none;font-size:.72rem}.wk-group+.wk-group{margin-top:4px}.wk-group-head{width:100%;font-family:var(--font);letter-spacing:.05em;text-transform:uppercase;color:var(--muted);text-align:left;cursor:pointer;background:0 0;border:0;border-radius:10px;align-items:center;gap:8px;padding:6px 8px 2px;font-size:.75rem;font-weight:600;display:flex}.wk-group-head:hover{color:var(--ink)}.wk-group-arrow{width:10px}.wk-swatch{border:2px solid var(--ink);border-radius:4px;flex:none;width:12px;height:12px}.wk-group-name{text-overflow:ellipsis;white-space:nowrap;min-width:0;color:var(--ink);overflow:hidden}.wk-group-count{color:var(--ink);background:#1f1d2b14;border-radius:999px;margin-left:auto;padding:0 7px}@media (width<=700px){.workers{display:none}}.hud-help{pointer-events:none;background:#fffdf6d9;border-radius:12px;padding:6px 10px;font-size:.85rem;position:absolute;bottom:14px;left:16px}.stats{z-index:60;font:10px/1.2 var(--mono);color:#7cffb2;white-space:nowrap;pointer-events:none;background:#15151fcc;border-bottom-right-radius:8px;padding:1px 8px;position:fixed;top:0;left:0}.fade{opacity:0;pointer-events:none;background:#15151f;place-items:center;transition:opacity .6s;display:grid;position:absolute;inset:0}.fade-in{opacity:1}.fade-label{color:#7cffb2;font-size:3rem;font-weight:700}.toasts{z-index:40;flex-direction:column;align-items:flex-end;gap:8px;max-width:min(420px,100vw - 32px);display:flex;position:absolute;bottom:16px;right:16px}.toast{background:var(--paper);border:3px solid var(--ink);box-shadow:0 4px 0 var(--ink);cursor:pointer;border-radius:14px;padding:10px 14px;font-weight:500;animation:.25s ease-out pop}.toast-success{background:#d8f9df}.toast-error{background:#ffd6de}@keyframes pop{0%{opacity:0;transform:translateY(12px)scale(.95)}}.start{z-index:50;-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);background:radial-gradient(circle at 30% 20%,#ffd6a5bf,#74c0fccc);place-items:center;padding:16px;display:grid;position:fixed;inset:0}.start-card{background:var(--paper);border:4px solid var(--ink);width:min(640px,100%);box-shadow:0 8px 0 var(--ink);text-align:center;border-radius:28px;max-height:calc(100vh - 32px);padding:28px 32px;overflow:auto}.start-logo{color:var(--accent);font-size:4rem;line-height:1;animation:12s linear infinite spin;display:inline-block}@keyframes spin{to{transform:rotate(360deg)}}.start h1{margin:6px 0 4px;font-size:2.6rem}.start-tag{color:var(--muted);margin:0 0 16px;font-size:1.1rem}.start-list{text-align:left;gap:8px;margin:0 0 22px;padding:0;list-style:none;display:grid}.start-meta{color:var(--muted);flex-wrap:wrap;justify-content:center;align-items:center;gap:10px;margin-top:16px;display:flex}.overlay{z-index:30;background:#15151f59;place-items:center;padding:16px;animation:.15s ease-out fadein;display:grid;position:fixed;inset:0}@keyframes fadein{0%{opacity:0}}.panel{background:var(--paper);border:4px solid var(--ink);width:min(640px,100%);max-height:calc(100vh - 32px);box-shadow:0 8px 0 var(--ink);border-radius:24px;flex-direction:column;animation:.2s ease-out pop;display:flex;overflow:hidden}.panel-wide{width:min(1320px,100%);height:calc(100vh - 32px)}.panel-head{background:var(--accent);border-bottom:4px solid var(--ink);align-items:center;gap:10px;padding:12px 16px;display:flex}.panel-title{text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;font-size:1.25rem;font-weight:700;overflow:hidden}.panel-title a{color:var(--ink)}.panel-x{border:3px solid var(--ink);cursor:pointer;background:#fff;border-radius:12px;flex:none;width:36px;height:36px;font-weight:700}.panel-body{flex-direction:column;flex:1;min-height:0;padding:16px;display:flex;overflow:auto}.help h3{margin:14px 0 4px}.help p{margin:0;line-height:1.55}.mouse-settings{border:2px solid var(--ink);background:#fff8ef;border-radius:12px;flex-direction:column;gap:8px;margin-top:10px;padding:10px 12px;display:flex}.mouse-sens{align-items:center;gap:10px;font-size:.92rem;display:flex}.mouse-sens input[type=range]{max-width:260px;accent-color:var(--accent,#ff8a5b);flex:1}.mouse-sens b{font-variant-numeric:tabular-nums;min-width:3.4em}.sound{gap:10px 18px}.sound-volume{flex:200px;align-items:center;gap:8px;max-width:340px;display:flex}.sound-volume input[type=range]{accent-color:var(--accent);background:0 0;border:0;flex:1;padding:0}.sound-pct{text-align:right;font-variant-numeric:tabular-nums;min-width:3.2em}.elevator{flex-direction:column;gap:10px;display:flex}.floor-btn{text-align:left;border:3px solid var(--ink);box-shadow:0 4px 0 var(--ink);cursor:pointer;font-family:var(--font);background:#fff;border-radius:16px;grid-template-rows:auto auto;grid-template-columns:54px 1fr;align-items:center;column-gap:12px;padding:10px;display:grid}.floor-btn:hover{transform:translateY(-1px)}.floor-btn-here{outline:3px dashed var(--accent);outline-offset:3px;background:#fff4e6}.floor-btn-num{border:3px solid var(--ink);background:var(--accent);color:#fff;text-shadow:0 2px #00000040;border-radius:50%;grid-row:span 2;place-items:center;width:54px;height:54px;font-size:1.5rem;font-weight:700;display:grid}.floor-btn-name{text-overflow:ellipsis;white-space:nowrap;font-size:1.1rem;font-weight:700;overflow:hidden}.floor-btn-meta{color:var(--muted);font-size:.85rem}.term-title{align-items:center;gap:10px;display:flex}.avatar{border:3px solid var(--ink);color:#fff;text-shadow:0 1px #0000004d;border-radius:50%;flex:none;place-items:center;width:34px;height:34px;font-weight:700;display:grid}.term-meta{flex-wrap:wrap;align-items:center;gap:6px 14px;margin-bottom:10px;font-size:.92rem;display:flex}.term-error{word-break:break-word;background:#ffe3e3;border:2px solid #ff8787;border-radius:10px;margin-bottom:8px;padding:6px 10px;font-size:.88rem}.term-split{flex:1;grid-template-columns:1fr;gap:12px;min-height:0;display:grid}.term-split-2{grid-template-columns:minmax(0,1.4fr) minmax(0,1fr)}.term{color:#e8e8f2;border:3px solid var(--ink);font-family:var(--mono);background:#1b1b29;border-radius:14px;min-height:200px;padding:12px 14px;font-size:13px;line-height:1.5;overflow:auto}.term-line{white-space:pre-wrap;word-break:break-word}.term-tool{color:#8be9fd}.term-result{color:#8d8da8}.term-system{color:#bd93f9}.term-error.term-line,.term-line.term-error{color:#ff6b6b;font-size:inherit;background:0 0;border:none;margin:0;padding:0}.term-manager{color:#ffb86c;font-weight:600}.term-done{color:#50fa7b;font-weight:600}.term-thinking{color:#f1fa8c;font-style:italic}.term-spin{color:#ff9e64;animation:1.4s ease-in-out infinite blink}@keyframes blink{50%{opacity:.55}}.browser{flex-direction:column;gap:6px;min-height:0;display:flex}.browser-bar{border:3px solid var(--ink);text-overflow:ellipsis;white-space:nowrap;background:#e9ecf2;border-bottom:none;border-radius:14px 14px 0 0;padding:6px 12px;font-size:.85rem;overflow:hidden}.browser-view{border:3px solid var(--ink);background:#fff;border-radius:0 0 14px 14px;flex:1;min-height:0;margin-top:-6px;overflow:auto}.browser-view img{width:100%;display:block}.term-input{gap:8px;margin-top:12px;display:flex}.term-actions{flex-wrap:wrap;align-items:center;gap:8px;margin-top:10px;display:flex}.term-actions select{width:auto;max-width:420px}.kanban-toolbar{flex-wrap:wrap;align-items:center;gap:12px;margin-bottom:12px;display:flex}.issue-form{background:#fff;border:3px dashed #1f1d2b4d;border-radius:16px;flex-direction:column;gap:8px;margin-bottom:12px;padding:12px;display:flex}.issue-form .row select{flex:1}.kanban{flex:1;grid-template-columns:repeat(4,minmax(220px,1fr));gap:12px;min-height:0;display:grid;overflow-x:auto}.kcol{border:3px solid var(--ink);background:#f4f1ea;border-radius:18px;flex-direction:column;min-height:0;display:flex;overflow:hidden}.kcol-head{border-bottom:3px solid var(--ink);padding:10px 12px;font-weight:700}.kcol-backlog .kcol-head{background:#ffd166}.kcol-progress .kcol-head{background:#4cc9f0}.kcol-review .kcol-head{background:#80ed99}.kcol-qa .kcol-head{background:#ff9f68}.kanban-5{grid-template-columns:repeat(5,minmax(210px,1fr))}.kcol-merged .kcol-head{background:#c77dff}.count{border:2px solid var(--ink);text-align:center;background:#fff;border-radius:999px;min-width:24px;padding:0 6px;font-size:.8rem;display:inline-block}.kcol-body{flex-direction:column;gap:8px;padding:10px;display:flex;overflow:auto}.kempty{padding:8px}.kcard{border:2.5px solid var(--ink);background:#fff;border-radius:12px;padding:8px 10px;box-shadow:0 3px #1f1d2bcc}.kcard-warn{background:#fff3d6}.kcard-bad{background:#ffe0e6}.kcard-good{background:#e3fbe7}.kcard-title{font-size:.92rem;font-weight:500;line-height:1.35}.kcard-title a{font-weight:700}.kcard-foot{align-items:center;gap:6px;margin-top:6px;display:flex}.kcard-foot select{width:auto;margin-left:auto;padding:3px 6px;font-size:.82rem}.kcard-foot-wrap{flex-wrap:wrap}.panel-app{width:100%;max-width:1600px}.panel-app .panel-body{padding:12px 16px}.app-title{align-items:center;gap:10px;min-width:0;display:flex}.app-title-name,.app-title-ref{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}.app-title-name{flex:0 auto}.app-title-ref{color:var(--ink);opacity:.75;flex:0 2 auto;font-weight:500}.app-title .status{flex:none}.app-toolbar{flex-wrap:wrap;align-items:center;gap:8px;margin-bottom:10px;display:flex}.app-ref{flex:0 auto;width:260px;min-width:0;padding:5px 8px;font-size:.88rem}.seg{border:2px solid var(--ink);box-shadow:0 2px 0 var(--ink);border-radius:9px;display:inline-flex;overflow:hidden}.seg-btn{font-family:var(--font);color:var(--ink);cursor:pointer;white-space:nowrap;background:#fff;border:0;padding:4px 10px;font-size:.82rem;font-weight:600}.seg-btn+.seg-btn{border-left:2px solid var(--ink)}.seg-btn.seg-on{background:var(--accent)}.seg-btn:focus-visible{outline-offset:-3px;outline:3px solid #3a56d4}.app-stage{border:3px solid var(--ink);background:repeating-linear-gradient(45deg,#efeadf 0 12px,#f6f2e9 12px 24px);border-radius:14px;flex:1;justify-content:center;min-height:280px;display:flex;position:relative;overflow:hidden}.app-frame{background:#fff;border:0;width:100%;height:100%;display:block}.app-stage-phone .app-frame{border-left:3px solid var(--ink);border-right:3px solid var(--ink);width:396px;max-width:100%}.app-frame-hint{border:2.5px solid var(--ink);width:min(560px,100% - 24px);box-shadow:0 3px 0 var(--ink);background:#fff3d6;border-radius:12px;padding:10px 14px;font-size:.9rem;line-height:1.4;position:absolute;bottom:16px;left:50%;transform:translate(-50%)}.app-foot{margin:8px 0 0;line-height:1.4}.app-state{text-align:center;background:#fff;border:3px dashed #1f1d2b4d;border-radius:14px;flex-direction:column;flex:1;align-items:center;gap:10px;min-height:0;padding:24px 16px;display:flex;overflow:auto}.app-state h3{margin:0}.app-state p{max-width:560px;margin:0}.app-state-left{text-align:left;align-items:stretch}.app-state-left p{max-width:none}.app-state-icon{font-size:2.6rem;line-height:1}.app-spin{animation:2.4s linear infinite spin}.app-steps{text-align:left;color:var(--muted);margin:0;padding:0;font-weight:500;list-style:none}.app-steps li{padding:2px 0}.app-step-done{color:#1b873a}.app-step-now{color:var(--ink);font-weight:700}.app-log{text-align:left;white-space:pre-wrap;word-break:break-word;width:100%;max-width:900px;min-height:0;max-height:320px;margin:0;font-size:12px}.app-state-left .app-log{flex:0 auto;max-width:none}.app-settings{width:min(640px,100%)}.preview-form{flex-direction:column;gap:2px;display:flex}.preview-form input,.preview-form textarea{font-family:var(--mono);font-size:.85rem}.preview-form p{margin:2px 0 4px}.preview-details summary{cursor:pointer;font-weight:600}.preview-details summary code{word-break:break-all;font-weight:400}.preview-details[open] summary{margin-bottom:6px}.preview-details .status{font-size:.68rem}@media (width<=520px){.panel-app .panel-body{padding:10px}.app-ref{flex:100%;max-width:none}.app-toolbar .spacer,.app-title-ref{display:none}}.tabs{flex-wrap:wrap;gap:6px;margin-bottom:12px;display:flex}.tab{font-family:var(--font);border:2.5px solid var(--ink);cursor:pointer;background:#fff;border-radius:12px;padding:8px 14px;font-size:.95rem;font-weight:600}.tab-on{background:var(--accent);color:#fff;text-shadow:0 1px #00000040;box-shadow:0 3px 0 var(--ink)}.tab-body{flex:1;min-height:0;overflow:auto}.tab-grid{grid-template-columns:minmax(0,1.2fr) minmax(0,1fr);align-items:start;gap:16px;display:grid}@media (width<=900px){.tab-grid{grid-template-columns:1fr}.kanban,.kanban-5{grid-template-columns:repeat(5,250px)}.term-split-2{grid-template-rows:minmax(200px,1fr) auto;grid-template-columns:1fr}}.section{margin:0 0 10px}.card{border:3px solid var(--ink);background:#fff;border-radius:18px;flex-direction:column;gap:6px;margin-bottom:12px;padding:12px 14px;display:flex}.card h3{margin:0 0 4px}.floor-card{border-left:12px solid var(--accent)}.floor-badge{background:var(--accent);border:2.5px solid var(--ink);color:#fff;text-shadow:0 1px #00000040;border-radius:10px;flex:none;place-items:center;width:36px;height:36px;font-weight:700;display:grid}.repo-list{border:2px solid #1f1d2b1f;border-radius:12px;flex-direction:column;gap:4px;max-height:260px;padding:6px;display:flex;overflow:auto}.repo-list.tall{max-height:520px}.repo-row{border-radius:10px;justify-content:space-between;align-items:center;gap:10px;padding:6px 8px;display:flex}.repo-row:hover{background:#fff4e6}.repo-row select{width:auto}.links{font-size:.85rem}.team{border-collapse:collapse;width:100%}.team td{vertical-align:middle;border-top:1.5px solid #1f1d2b14;padding:4px 6px}.team select{width:auto;padding:4px 6px}.field{flex-direction:column;gap:4px;margin:6px 0;font-size:.9rem;font-weight:600;display:flex}.wizard{text-align:left;width:min(680px,100%)}.wizard h1,.wizard .start-logo,.wizard .start-tag,.wizard h2,.wizard-icon{text-align:center}.wizard h2{margin:4px 0 6px;font-size:1.9rem}.wizard-icon{font-size:3rem;line-height:1.1}.wizard .start-logo{width:fit-content;margin:0 auto;display:block}.wizard .btn-big{margin:0 auto;display:block}.wizard-steps{justify-content:center;gap:8px;margin-bottom:10px;display:flex}.wizard-dot{border:2px solid var(--ink);background:#fff;border-radius:50%;width:12px;height:12px}.wizard-dot-done{background:#80ed99}.wizard-dot-on{background:var(--accent);transform:scale(1.25)}.wizard-nav{align-items:center;gap:10px;margin-top:18px;display:flex}.wizard-done{text-align:center;padding:10px 0}.wizard-done p{margin:6px 0}.ceo-setup{align-items:center;gap:18px;display:flex}.ceo-portrait{flex:none;width:120px;height:120px}.swatch{border:2.5px solid var(--ink);cursor:pointer;border-radius:50%;width:24px;height:24px;padding:0}.swatch-on{box-shadow:0 0 0 3px #fff, 0 0 0 5px var(--ink)}.picker{flex-direction:column;gap:8px;display:flex}.picker-tabs{flex-wrap:wrap;gap:6px;display:flex}.picker-tab{font-family:var(--font);border:2.5px solid var(--ink);cursor:pointer;white-space:nowrap;background:#fff;border-radius:12px;flex:1;padding:8px 10px;font-size:.88rem;font-weight:600}.picker-tab-on{background:var(--accent);color:#fff;text-shadow:0 1px #00000040;box-shadow:0 3px 0 var(--ink)}.picker-mode{flex-direction:column;gap:6px;display:flex}.picker-mode .row{margin:0}.folder-list{max-height:240px}.chip-warn{background:#fff3bf}.tour{z-index:45;background:var(--paper);border:3px solid var(--ink);border-left:10px solid var(--accent);width:min(390px,100vw - 32px);box-shadow:0 5px 0 var(--ink);border-radius:18px;padding:10px 14px;animation:.25s ease-out pop;position:fixed;bottom:16px;left:16px}.tour-cheer{border-left-color:var(--good);background:#eafbee}.tour-head{align-items:center;display:flex}.tour-count{color:var(--muted);font-size:.78rem;font-weight:700}.tour-title{margin:2px 0 4px;font-size:1.1rem;font-weight:700}.tour-body{font-size:.9rem;line-height:1.5}.tour-nav{align-items:center;margin-top:8px;display:flex}.ceo-term{flex:none;height:340px}.job-brief{margin:0 0 8px}.job-brief summary{cursor:pointer;font-weight:600}.job-brief .md{margin-top:4px;line-height:1.45}.confirm-overlay{z-index:60;background:#15151f73;place-items:center;padding:16px;animation:.12s ease-out fadein;display:grid;position:fixed;inset:0}.confirm{background:var(--paper);border:4px solid var(--ink);width:min(440px,100%);box-shadow:0 8px 0 var(--ink);text-align:center;border-radius:24px;padding:20px 22px 14px;animation:.18s ease-out pop}.confirm-danger{border-top:12px solid var(--bad)}.confirm-warn{border-top:12px solid var(--warn)}.confirm-good{border-top:12px solid var(--good)}.confirm-icon{font-size:2.4rem;line-height:1}.confirm h3{margin:8px 0 6px;font-size:1.25rem}.confirm-body{color:#4a4e69;margin-bottom:4px;line-height:1.5}.confirm-actions{justify-content:center;gap:10px;margin-top:14px;display:flex}.confirm-keys{margin-top:10px}.btn-warn{background:#ffd166}.badge{background:var(--bad);color:#fff;border:2px solid var(--ink);border-radius:999px;place-items:center;min-width:20px;height:20px;padding:0 6px;font-size:.72rem;font-weight:700;line-height:1;display:inline-grid}.toasts{bottom:88px}.phone-btn{font-family:var(--font);color:var(--ink);background:var(--paper);border:3px solid var(--ink);box-shadow:0 4px 0 var(--ink);cursor:pointer;border-radius:18px;align-items:center;gap:8px;padding:6px 14px 6px 8px;font-size:.9rem;font-weight:600;display:flex;position:absolute;bottom:16px;right:16px}.phone-btn:hover{transform:translateY(-1px)}.phone-btn-icon{font-size:1.7rem;line-height:1;display:inline-block}.phone-btn-ring .phone-btn-icon{animation:2.4s ease-in-out infinite ring}@keyframes ring{0%,72%,to{transform:rotate(0)}76%{transform:rotate(-16deg)}80%{transform:rotate(14deg)}84%{transform:rotate(-10deg)}88%{transform:rotate(8deg)}}.phone-btn-badge{position:absolute;top:-8px;left:26px}.phone-overlay{background:#15151f47;place-items:end;padding:16px 24px}.phone{border:4px solid var(--ink);width:min(400px,100%);height:min(760px,100vh - 32px);box-shadow:0 10px 0 var(--ink), inset 0 0 0 3px #3b3f5c;background:#23263a;border-radius:38px;flex-direction:column;padding:10px 10px 8px;animation:.22s ease-out slideup;display:flex}@keyframes slideup{0%{opacity:0;transform:translateY(40px)}}.phone-status{color:#e9e9f5;justify-content:space-between;align-items:center;padding:2px 16px 8px;font-size:.8rem;font-weight:600;display:flex}.phone-notch{background:#15151f;border-radius:999px;width:90px;height:18px}.phone-screen{background:var(--paper);border-radius:26px 26px 12px 12px;flex-direction:column;flex:1;min-height:0;display:flex;overflow:hidden}.phone-tabs{gap:4px;padding:8px 4px 2px;display:flex}.phone-tab{color:#b8bbd6;font-family:var(--font);cursor:pointer;background:0 0;border:none;border-radius:14px;flex-direction:column;flex:1;align-items:center;gap:2px;padding:6px 4px;font-size:.78rem;font-weight:600;display:flex}.phone-tab-on{color:#fff;background:#3b3f5c}.phone-tab-icon{font-size:1.3rem;position:relative}.badge-dot{min-width:18px;height:18px;font-size:.65rem;position:absolute;top:-6px;right:-14px}.phone-hint{text-align:center;color:#8e92b3;padding-top:4px;font-size:.72rem}.phone-hint kbd{font-size:.7rem}.phone-scroll{flex:1;padding:12px;overflow:auto}.phone-h{align-items:center;gap:6px;margin:10px 2px 8px;font-size:1rem;display:flex}.phone-h:first-child{margin-top:0}.phone-empty{padding:10px 6px;line-height:1.5}.linkish{color:#3a56d4;font-family:var(--font);cursor:pointer;text-align:left;background:0 0;border:none;padding:0;font-weight:600}.phone-chat{flex-direction:column;flex:1;min-height:0;display:flex}.chat-head{background:#fff;border-bottom:2px solid #1f1d2b14;align-items:center;gap:10px;padding:10px 12px;display:flex}.presence-busy{color:#d9480f;font-weight:600}.chat-log{background:#f4f1ea;flex-direction:column;flex:1;gap:8px;padding:10px;display:flex;overflow:auto}.bubble-row{display:flex}.bubble-row-me{justify-content:flex-end}.bubble{border:2px solid var(--ink);border-radius:16px;max-width:86%;padding:8px 11px 5px;font-size:.9rem;line-height:1.4}.bubble-them{background:#fff;border-bottom-left-radius:4px}.bubble-me{background:#ffd6a5;border-bottom-right-radius:4px}.bubble-from{color:var(--muted);font-size:.72rem;font-weight:700}.bubble-text{white-space:pre-wrap;overflow-wrap:anywhere}.bubble:has(.md pre,.md-table){width:86%}.md{overflow-wrap:anywhere;min-width:0}.md>:first-child{margin-top:0}.md>:last-child{margin-bottom:0}.md p,.md ul,.md ol,.md pre,.md blockquote,.md .md-table{margin:0 0 .55em}.md ul,.md ol{padding-left:1.3em}.md li>ul,.md li>ol{margin:.15em 0 .2em}.md li+li{margin-top:.15em}.md li>p{margin:0}.md h1,.md h2,.md h3,.md h4,.md h5,.md h6{margin:.7em 0 .3em;font-size:1em;line-height:1.25}.md h1{font-size:1.15em}.md h2{font-size:1.08em}.md h5,.md h6{color:var(--muted)}.md a{color:#3a56d4;overflow-wrap:anywhere;font-weight:600}.md a:focus-visible{outline:2px solid var(--accent);outline-offset:1px;border-radius:3px}.md-deadlink{-webkit-text-decoration:underline dotted;text-decoration:underline dotted}.md code{font-family:var(--mono);background:#1f1d2b14;border-radius:5px;padding:.1em .3em;font-size:.86em}.md pre,.md-table{contain:inline-size;overflow-x:auto}.md pre{background:#1f1d2b14;border-radius:8px;padding:7px 9px;line-height:1.35}.md pre code{white-space:pre;overflow-wrap:normal;background:0 0;padding:0}.md blockquote{color:#4a4e69;border-left:3px solid #1f1d2b40;padding:0 0 0 9px}.md hr{border:none;border-top:1.5px solid #1f1d2b26;margin:.6em 0}.md table{border-collapse:collapse;font-size:.9em}.md th,.md td{text-align:left;overflow-wrap:normal;border:1px solid #1f1d2b33;padding:3px 7px}.md th{background:#1f1d2b0f}.md td code{white-space:nowrap}.md input[type=checkbox]{vertical-align:middle;margin:0 4px 0 0}.md li:has(>input[type=checkbox]){margin-left:-1.1em;list-style:none}.bubble-time{text-align:right;color:var(--muted);margin-top:2px;font-size:.65rem}.bubble-office{text-align:center;color:#4a4e69;background:#1f1d2b12;border-radius:999px;align-self:center;max-width:92%;padding:3px 10px;font-size:.76rem}.bubble-typing{gap:4px;padding:10px 12px;display:flex}.bubble-typing span{background:var(--muted);border-radius:50%;width:7px;height:7px;animation:1.2s infinite typing}.bubble-typing span:nth-child(2){animation-delay:.15s}.bubble-typing span:nth-child(3){animation-delay:.3s}@keyframes typing{0%,60%,to{opacity:.5;transform:translateY(0)}30%{opacity:1;transform:translateY(-4px)}}.quick{background:#fff;gap:6px;padding:6px 10px 0;display:flex;overflow-x:auto}.quick-chip{font-family:var(--font);cursor:pointer;background:#fff;border:1.5px solid #1f1d2b4d;border-radius:999px;flex:none;padding:4px 10px;font-size:.75rem;font-weight:600}.quick-chip:hover{border-color:var(--accent)}.chat-input{background:#fff;gap:6px;padding:8px 10px 10px;display:flex}.resume{border:3px solid var(--ink);color:var(--ink);background:#fff;border-radius:16px;flex-direction:column;gap:6px;margin-bottom:10px;padding:10px 12px;display:flex}.bubble .resume{border-width:2px;margin:6px 0 2px}.resume-letgo{background:#fff4f2}.resume-hot{box-shadow:0 0 0 4px var(--accent)}.resume-done{opacity:.75}.resume-head{align-items:center;gap:10px;display:flex}.resume-name{font-size:1.05rem;font-weight:700}.resume-title{color:var(--muted);font-size:.85rem;font-weight:600}.resume-meta{flex-wrap:wrap;align-items:center;gap:6px;display:flex}.resume-reason{border-left:3px solid #1f1d2b33;padding-left:9px;font-size:.88rem;line-height:1.45}.resume-brief{background:#f6f3ec;border-radius:10px;margin:0;padding:8px;font-size:.82rem;line-height:1.45}.tiles{grid-template-columns:repeat(3,1fr);gap:8px;display:grid}.tile{border:2.5px solid var(--ink);text-align:center;background:#fff;border-radius:14px;padding:8px}.tile-value{white-space:nowrap;font-size:1.15rem;font-weight:700}.tile-label{color:var(--muted);font-size:.7rem;font-weight:600}.report{flex-direction:column;gap:6px;margin:0;padding:0;list-style:none;display:flex}.report li{background:#fff;border:2px solid #1f1d2b1f;border-radius:12px;align-items:flex-start;gap:8px;padding:7px 10px;font-size:.86rem;line-height:1.4;display:flex}.report li.report-good{background:#e7fbe9;border-color:#80ed99}.report li.report-warn{background:#fff4d6;border-color:#ffd166}.proj{border:2.5px solid var(--ink);border-left:10px solid var(--accent);background:#fff;border-radius:14px;margin-bottom:8px;padding:6px 10px 8px}.proj .row{margin:2px 0}.proj .floor-badge{width:30px;height:30px}.proj-name{text-overflow:ellipsis;white-space:nowrap;display:block;overflow:hidden}.proj-sum{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.proj-stats{flex-wrap:wrap;gap:10px;font-weight:600;display:flex}.proj-ready{color:#1b873a}@media (width<=520px){.phone-overlay{place-items:center;padding:8px}.phone-btn-label{display:none}}
|