friend-assistant 0.1.5 → 0.1.7
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
|
@@ -89,6 +89,7 @@ Every command starts with `friend`. If you run Friend from the source code, writ
|
|
|
89
89
|
| `friend daemon stop` | Stops the background Friend and the speech engine with it. | Shutting it down. |
|
|
90
90
|
| `friend daemon restart` | Stops it and starts it again. | After changing a setting such as `friend lan on` or a different model. |
|
|
91
91
|
| `friend daemon status` | Says whether the background Friend is running, for how long, and at which address. Exit code 0 when running, 1 when not. | Checking, or in a script. |
|
|
92
|
+
| `friend upgrade` | Updates Friend in one go: checks npm for the newest version, stops the background Friend, installs it, and starts it again. Add `--force` to reinstall the same version. If Friend runs in a terminal instead, it asks you to press Ctrl+C there first. | A new version is out. |
|
|
92
93
|
| `friend lan` (or `friend lan status`) | Shows what Friend listens on and the addresses to open. | Checking, or finding the address for your phone. |
|
|
93
94
|
| `friend lan on` | Lets other devices on your network open Friend. Prints the addresses and the things to know (plain http, no microphone on other devices, firewall prompt). | Using Friend from a phone or another PC. |
|
|
94
95
|
| `friend lan on --https` | The same, with a secure `https://` address (Friend makes its own certificate), so a phone may use the microphone and camera. | Talking to Friend from a phone. |
|
package/dist/BUILD.json
CHANGED
package/dist/friend.mjs
CHANGED
|
@@ -6884,13 +6884,13 @@ function realish(abs) {
|
|
|
6884
6884
|
tail2.unshift(cur.slice(parent.length).replace(/^[\\/]+/, ""));
|
|
6885
6885
|
cur = parent;
|
|
6886
6886
|
}
|
|
6887
|
-
let
|
|
6887
|
+
let real2;
|
|
6888
6888
|
try {
|
|
6889
|
-
|
|
6889
|
+
real2 = realpathSync.native(cur);
|
|
6890
6890
|
} catch {
|
|
6891
6891
|
return UNRESOLVABLE + abs;
|
|
6892
6892
|
}
|
|
6893
|
-
return tail2.length ? resolve3(
|
|
6893
|
+
return tail2.length ? resolve3(real2, ...tail2) : real2;
|
|
6894
6894
|
}
|
|
6895
6895
|
function within(root, target) {
|
|
6896
6896
|
if (target.startsWith(UNRESOLVABLE)) return false;
|
|
@@ -8951,6 +8951,77 @@ async function daemonCommand(args, io2, deps = realDeps) {
|
|
|
8951
8951
|
}
|
|
8952
8952
|
}
|
|
8953
8953
|
|
|
8954
|
+
// ../agent-cli/src/commands/upgrade.ts
|
|
8955
|
+
import crossSpawn5 from "cross-spawn";
|
|
8956
|
+
var PACKAGE = "friend-assistant";
|
|
8957
|
+
var real = {
|
|
8958
|
+
current: () => true ? "0.1.7" : "development",
|
|
8959
|
+
latest: () => new Promise((resolve10) => {
|
|
8960
|
+
const child = crossSpawn5("npm", ["view", PACKAGE, "version", "--prefer-online"], { stdio: ["ignore", "pipe", "ignore"] });
|
|
8961
|
+
let out = "";
|
|
8962
|
+
child.stdout?.on("data", (d) => out += d.toString());
|
|
8963
|
+
child.on("error", () => resolve10(null));
|
|
8964
|
+
child.on("close", (code) => resolve10(code === 0 && /^\d+\.\d+\.\d+/.test(out.trim()) ? out.trim().split(/\s+/)[0] : null));
|
|
8965
|
+
}),
|
|
8966
|
+
install: (version) => new Promise((resolve10) => {
|
|
8967
|
+
const child = crossSpawn5("npm", ["install", "-g", `${PACKAGE}@${version}`, "--prefer-online"], { stdio: "inherit" });
|
|
8968
|
+
child.on("error", () => resolve10(1));
|
|
8969
|
+
child.on("close", (code) => resolve10(code ?? 1));
|
|
8970
|
+
}),
|
|
8971
|
+
startAgain: () => new Promise((resolve10) => {
|
|
8972
|
+
const child = crossSpawn5("friend", ["daemon", "start"], { stdio: "inherit" });
|
|
8973
|
+
child.on("error", () => resolve10(1));
|
|
8974
|
+
child.on("close", (code) => resolve10(code ?? 1));
|
|
8975
|
+
}),
|
|
8976
|
+
daemon: realDeps
|
|
8977
|
+
};
|
|
8978
|
+
var newer = (a, b) => {
|
|
8979
|
+
const n = (v) => v.split(/[.-]/).slice(0, 3).map((x2) => Number(x2) || 0);
|
|
8980
|
+
const [x, y] = [n(a), n(b)];
|
|
8981
|
+
for (let i = 0; i < 3; i++) if ((x[i] ?? 0) !== (y[i] ?? 0)) return (x[i] ?? 0) > (y[i] ?? 0);
|
|
8982
|
+
return false;
|
|
8983
|
+
};
|
|
8984
|
+
async function upgradeCommand(args, io2, deps = real) {
|
|
8985
|
+
const force = args.includes("--force");
|
|
8986
|
+
if (args.some((a) => a !== "--force")) {
|
|
8987
|
+
io2.err("Usage: friend upgrade [--force]");
|
|
8988
|
+
return 1;
|
|
8989
|
+
}
|
|
8990
|
+
const current = deps.current();
|
|
8991
|
+
io2.out(`Installed: ${current}`);
|
|
8992
|
+
const latest = await deps.latest();
|
|
8993
|
+
if (!latest) {
|
|
8994
|
+
io2.err("Could not ask npm for the newest version. Check your internet connection and try again.");
|
|
8995
|
+
return 1;
|
|
8996
|
+
}
|
|
8997
|
+
io2.out(`Newest: ${latest}`);
|
|
8998
|
+
if (!force && !newer(latest, current)) {
|
|
8999
|
+
io2.out("Friend is already up to date.");
|
|
9000
|
+
return 0;
|
|
9001
|
+
}
|
|
9002
|
+
const cfg = loadConfig(io2.dataDir);
|
|
9003
|
+
const wasRunning = running(io2.dataDir, deps.daemon) !== null;
|
|
9004
|
+
if (wasRunning) {
|
|
9005
|
+
io2.out("Stopping the background Friend\u2026");
|
|
9006
|
+
const code2 = await daemonCommand(["stop"], io2, deps.daemon);
|
|
9007
|
+
if (code2 !== 0) return code2;
|
|
9008
|
+
} else if (await deps.daemon.portOpen(cfg.port, 500)) {
|
|
9009
|
+
io2.err(`Friend is running in a terminal (port ${cfg.port} is in use). Press Ctrl+C there to stop it, then run: friend upgrade`);
|
|
9010
|
+
return 1;
|
|
9011
|
+
}
|
|
9012
|
+
io2.out(`Installing ${PACKAGE}@${latest}\u2026`);
|
|
9013
|
+
const code = await deps.install(latest);
|
|
9014
|
+
if (code !== 0) {
|
|
9015
|
+
io2.err("The install failed. If it says EBUSY or EPERM, close whatever is using Friend (a terminal running it, a voice process) and run: friend upgrade");
|
|
9016
|
+
if (wasRunning) await deps.startAgain();
|
|
9017
|
+
return 1;
|
|
9018
|
+
}
|
|
9019
|
+
io2.out(`Upgraded ${current} \u2192 ${latest}.`);
|
|
9020
|
+
if (wasRunning) return deps.startAgain();
|
|
9021
|
+
io2.out("Start it with: friend start (or in the background: friend daemon start)");
|
|
9022
|
+
return 0;
|
|
9023
|
+
}
|
|
9024
|
+
|
|
8954
9025
|
// ../agent-cli/src/commands/claude.ts
|
|
8955
9026
|
async function check2(run2, command) {
|
|
8956
9027
|
const v = await run2(command, ["--version"]);
|
|
@@ -9088,6 +9159,7 @@ var USAGE4 = `Usage: friend <command>
|
|
|
9088
9159
|
setup create the owner account (password, PIN, assistant name)
|
|
9089
9160
|
start run the gateway and a local device node
|
|
9090
9161
|
daemon start|stop|restart|status run Friend in the background (no terminal needed), stop it, or see if it is running
|
|
9162
|
+
upgrade [--force] stop the background Friend, install the newest version, start it again
|
|
9091
9163
|
pair print a one-time code to connect another PC
|
|
9092
9164
|
node --url <ws-url> --code <code> [--roots a,b] [--name pc]
|
|
9093
9165
|
connect this PC to a Friend gateway
|
|
@@ -9114,6 +9186,8 @@ async function run(argv, io2) {
|
|
|
9114
9186
|
return await startCommand(io2);
|
|
9115
9187
|
case "daemon":
|
|
9116
9188
|
return await daemonCommand(rest, io2);
|
|
9189
|
+
case "upgrade":
|
|
9190
|
+
return await upgradeCommand(rest, io2);
|
|
9117
9191
|
case "pair":
|
|
9118
9192
|
return await pairCommand(io2);
|
|
9119
9193
|
case "node":
|
|
@@ -9134,7 +9208,7 @@ async function run(argv, io2) {
|
|
|
9134
9208
|
case "version":
|
|
9135
9209
|
case "--version":
|
|
9136
9210
|
case "-v":
|
|
9137
|
-
io2.out(true ? "0.1.
|
|
9211
|
+
io2.out(true ? "0.1.7" : "development");
|
|
9138
9212
|
return 0;
|
|
9139
9213
|
case "lan":
|
|
9140
9214
|
return await lanCommand(rest, io2);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
:root{--accent:#3fd8ff;--warn:#ffb454;--bad:#ff6b7a;--ok:#5ef0b0;--ink:#d4ecf7;--muted:#7fa3b6;--glass:#06141c9e;--edge:color-mix(in srgb, var(--accent) 48%, transparent);--ui:"Segoe UI", system-ui, -apple-system, "Helvetica Neue", Arial, sans-serif;--mono:"Cascadia Mono", "SF Mono", Consolas, ui-monospace, monospace;--lightningcss-light: ;--lightningcss-dark:initial;color-scheme:dark}*{box-sizing:border-box}html,body,#root{height:100%;margin:0}body{color:var(--ink);font:16px/1.5 var(--ui);-webkit-tap-highlight-color:transparent;background:#000;overflow:hidden}button,input{font:inherit;color:inherit}button{cursor:pointer}:focus-visible{outline:2px solid var(--accent);outline-offset:2px}.stage{touch-action:manipulation;background:#000;position:fixed;inset:0;overflow:hidden}.ambient{pointer-events:none;background:radial-gradient(ellipse at 50% 55%, color-mix(in srgb, var(--accent) 10%, transparent), transparent 62%), linear-gradient(#3fd8ff0b 1px, transparent 1px) 0 0 / 64px 64px, linear-gradient(90deg, #3fd8ff0b 1px, transparent 1px) 0 0 / 64px 64px;position:absolute;inset:0;-webkit-mask-image:radial-gradient(#000 30%,#0000 78%);mask-image:radial-gradient(#000 30%,#0000 78%)}.presence{z-index:1;transition:inset .7s cubic-bezier(.2,.7,.2,1),width .7s,height .7s,opacity .5s;position:absolute}.presence-full{inset:0}.presence-corner{left:max(10px, env(safe-area-inset-left));bottom:max(52px, calc(env(safe-area-inset-bottom) + 42px));width:clamp(96px,16vw,190px);height:clamp(96px,16vw,190px)}.objects{pointer-events:none;position:absolute;inset:0}.objects-stack{pointer-events:auto;padding:max(56px, env(safe-area-inset-top)) 14px 140px;flex-direction:column;gap:12px;display:flex;overflow-y:auto}.auto-grid{pointer-events:none;padding:max(24px, env(safe-area-inset-top)) 24px 24px clamp(120px, 20vw, 230px);grid-template-columns:repeat(auto-fit,minmax(min(280px,100%),1fr));align-content:safe center;align-items:start;gap:12px;display:grid;position:absolute;inset:0;overflow-y:auto}.auto-grid>.obj{pointer-events:auto}.objects-stack>.auto-grid{flex-direction:column;padding:0;display:flex;position:static;overflow:visible}.obj.leaving{pointer-events:none;animation:.35s forwards leave}@keyframes leave{to{opacity:0;transform:scale(.96)translateY(-6px)}}@media (prefers-reduced-motion:reduce){.obj.leaving{animation:none}}.glass{background:var(--glass);-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);border:1px solid var(--edge);box-shadow:0 0 22px color-mix(in srgb, var(--accent) 16%, transparent), inset 0 0 28px #3fd8ff0d;clip-path:polygon(0 0,calc(100% - 14px) 0,100% 14px,100% 100%,14px 100%,0 calc(100% - 14px))}.obj{pointer-events:auto;min-width:0;padding:16px 18px;animation:.45s both appear;overflow:auto}.obj.alert{border-color:var(--warn)}@keyframes appear{0%{opacity:0;transform:translateY(8px)scale(.985)}}.obj-close{width:44px;height:44px;color:var(--muted);background:0 0;border:0;font-size:1.5rem;line-height:1;position:absolute;top:2px;right:6px}.obj-close:hover{color:var(--accent)}.obj-title{letter-spacing:.16em;text-transform:uppercase;color:var(--accent);margin:0 36px 8px 0;font-size:.78rem;font-weight:600}.obj-md>:first-child{margin-top:0}.obj-md>:last-child{margin-bottom:0}.obj-md a{color:var(--accent)}.obj-md code{font-family:var(--mono);background:#3fd8ff1a;padding:0 4px;font-size:.9em}.obj-stat{gap:2px;display:grid}.obj-label{letter-spacing:.16em;text-transform:uppercase;color:var(--muted);font-size:.78rem}.obj-value{font-variant-numeric:tabular-nums;font-size:clamp(2rem,6vw,3.6rem);font-weight:300;line-height:1.05}.obj-value small{color:var(--muted);margin-left:4px;font-size:.4em}.obj-delta{color:var(--ok);font-size:.9rem}.obj-list{gap:4px;margin:0;padding-left:1.1rem;display:grid}.obj-list .done{color:var(--muted);text-decoration:line-through}.obj-table-wrap{overflow-x:auto}.obj-table{border-collapse:collapse;width:100%;font-size:.92rem}.obj-table th{text-align:left;letter-spacing:.14em;text-transform:uppercase;color:var(--accent);font-size:.72rem;font-weight:600}.obj-table th,.obj-table td{font-variant-numeric:tabular-nums;border-bottom:1px solid #3fd8ff2e;padding:6px 10px}.obj-code{font:.86rem/1.5 var(--mono);margin:0;overflow:auto}.obj-empty{color:var(--muted);margin:0}.obj-chart{width:100%;height:auto;display:block}.obj-chart .grid{stroke:#3fd8ff24;stroke-width:1px}.obj-chart .tick{fill:var(--muted);font:10px var(--mono);font-variant-numeric:tabular-nums}.legend{color:var(--muted);flex-wrap:wrap;gap:6px 14px;margin:6px 0 0;padding:0;font-size:.8rem;list-style:none;display:flex}.legend i{width:10px;height:10px;margin-right:6px;display:inline-block}.obj-gauge{justify-items:center;display:grid}.obj-gauge svg{width:min(100%,260px);height:auto}.obj-gauge .track{stroke:#3fd8ff26}.obj-gauge .value{stroke:var(--accent);filter:drop-shadow(0 0 6px var(--accent))}.obj-gauge.gauge-warn .value{stroke:var(--warn);filter:drop-shadow(0 0 6px var(--warn))}.obj-gauge.gauge-crit .value{stroke:var(--bad);filter:drop-shadow(0 0 6px var(--bad))}.gauge-read{align-items:baseline;gap:4px;margin-top:-62px;display:flex}.gauge-value{font-variant-numeric:tabular-nums;font-size:clamp(1.8rem,5vw,2.8rem);font-weight:300}.gauge-unit{color:var(--muted)}.obj-gauge .obj-label{margin-top:18px}.obj-timeline{border-left:1px solid var(--edge);gap:14px;margin:8px 0 0;padding:0 0 0 20px;list-style:none;display:grid}.obj-timeline li{gap:2px;display:grid;position:relative}.obj-timeline li:before{content:"";background:var(--accent);width:9px;height:9px;box-shadow:0 0 8px var(--accent);border-radius:50%;position:absolute;top:.5em;left:-25px}.obj-timeline time{font:.75rem/1.3 var(--mono);color:var(--accent)}.obj-timeline span{color:var(--muted);font-size:.9rem}.obj-graph{width:100%;height:auto;max-height:70vh;margin:0 auto;display:block}.obj[style*=" height:"] .obj-graph{max-height:calc(100% - 32px)}.obj-graph .edge{stroke:color-mix(in srgb, var(--accent) 55%, transparent);stroke-width:1.4px}.obj-graph .arrow{fill:var(--accent)}.obj-graph .node{fill:#3fd8ff26;stroke:var(--accent);stroke-width:1.5px}.obj-graph .node-label{fill:var(--ink);font:10px var(--ui)}.obj-graph .edge-label{fill:var(--muted);font:9px var(--ui)}.captions{z-index:20;left:50%;bottom:max(7%, env(safe-area-inset-bottom));text-align:center;pointer-events:none;text-shadow:0 0 18px #000,0 0 4px #000;text-wrap:balance;width:min(780px,100% - 32px);margin:0;font-size:clamp(1.1rem,2.6vw,1.6rem);font-weight:300;position:absolute;transform:translate(-50%)}.captions.done{animation:1.4s 8s forwards fadeOut}@keyframes fadeOut{to{opacity:0}}.command-bar{z-index:30;left:50%;bottom:max(14px, env(safe-area-inset-bottom));background:var(--glass);border:1px solid var(--edge);-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);gap:8px;width:min(640px,100% - 24px);padding:8px;display:flex;position:absolute;transform:translate(-50%)}.command-bar input{background:0 0;border:0;outline:none;flex:1;min-height:44px;padding:0 10px;font-size:1.05rem}.command-bar button{border:1px solid var(--edge);background:0 0;min-width:44px;min-height:44px}.conn-badge{top:max(10px, env(safe-area-inset-top));font:500 .78rem var(--mono);letter-spacing:.08em;color:var(--warn);border:1px solid var(--warn);background:#0009;padding:6px 12px;position:absolute;right:12px}.mic-indicator{left:50%;top:max(12px, env(safe-area-inset-top));font:500 .82rem var(--mono);letter-spacing:.1em;text-transform:uppercase;color:#ffd9a0;border:1px solid var(--warn);background:#000000c7;align-items:center;gap:10px;padding:8px 16px;display:flex;position:absolute;transform:translate(-50%)}.mic-indicator i{background:var(--bad);width:10px;height:10px;box-shadow:0 0 10px var(--bad);border-radius:50%;animation:1s ease-in-out infinite mic-pulse}.mic-transcribing i{background:var(--warn);box-shadow:0 0 10px var(--warn)}@keyframes mic-pulse{50%{opacity:.35}}@media (prefers-reduced-motion:reduce){.mic-indicator i{animation:none}}.toasts{top:max(48px, env(safe-area-inset-top));gap:6px;width:min(420px,100% - 24px);display:grid;position:absolute;left:50%;transform:translate(-50%)}.toast{border:1px solid var(--edge);background:#000000d1;padding:10px 14px;font-size:.92rem}.toast-warn{border-color:var(--warn);color:#ffd9a0}.toast-error{border-color:var(--bad);color:#ffc2c9}.approval{border-color:var(--warn);background:#020c12eb;width:min(460px,100% - 24px);max-height:calc(100% - 24px);padding:20px;position:absolute;top:50%;left:50%;overflow:auto;transform:translate(-50%,-50%);box-shadow:0 0 0 100vmax #0000008c,0 0 30px #ffb45440}.plugins{width:min(560px,100% - 24px)}.plugins-heading{letter-spacing:.14em;text-transform:uppercase;color:var(--muted);margin:14px 0 6px;font-size:.78rem}.plugin-list{gap:8px;margin:0;padding:0;list-style:none;display:grid}.plugin-list li{background:#ffffff0a;justify-content:space-between;align-items:center;gap:10px;padding:8px 10px;display:flex}.plugin-info{min-width:0}.plugin-info .auth-note{font-size:.82rem}.plugin-actions{flex-shrink:0;gap:6px;display:flex}.plugin-actions button{border:1px solid var(--edge);background:0 0;padding:0 12px}.obj-sandbox{flex-direction:column;gap:6px;width:100%;min-width:min(560px,80vw);height:min(420px,60vh);display:flex}.obj-sandbox iframe{border:1px solid var(--edge);background:#050b10;flex:1;width:100%;min-height:200px}.camera-indicator{border-color:var(--bad);color:#ffc2c9;letter-spacing:.12em;text-transform:uppercase;background:#020c12e6;align-items:center;gap:10px;padding:6px 12px 6px 6px;font-size:.8rem;display:flex;position:absolute;bottom:12px;right:12px}.camera-indicator video{object-fit:cover;background:#000;width:72px;height:54px}.camera-indicator span:before{content:"";background:var(--bad);border-radius:50%;width:8px;height:8px;margin-right:8px;display:inline-block}.challenge,.enroll{border-color:var(--accent);box-shadow:0 0 0 100vmax #0000008c,0 0 30px #3fd8ff40}.challenge .approval-title,.enroll .approval-title{color:var(--accent)}.approval-head{align-items:center;gap:10px;display:flex}.approval-title{letter-spacing:.18em;text-transform:uppercase;color:var(--warn);font-size:.8rem}.tier{font:600 .74rem var(--mono);border:1px solid;padding:2px 8px}.tier-T2{color:var(--warn)}.tier-T3{color:var(--bad)}.approval-summary{font:.95rem/1.5 var(--mono);word-break:break-all;background:#ffffff0a;max-height:40vh;margin:14px 0;padding:10px 12px;overflow:auto}.approval-actions{flex-wrap:wrap;gap:8px;margin-top:14px;display:flex}.approval-actions button,.owner-menu button,.auth button{border:1px solid var(--edge);letter-spacing:.04em;background:0 0;padding:0 16px}button.primary{background:color-mix(in srgb, var(--accent) 22%, transparent);border-color:var(--accent)}button.danger{border-color:var(--bad);color:#ffc2c9}button:disabled{opacity:.4;cursor:not-allowed}.pinpad{justify-items:center;gap:8px;display:grid}.pin-dots{letter-spacing:.4em;min-height:1.6em;color:var(--accent);font-size:1.6rem}.pin-keys{grid-template-columns:repeat(3,64px);gap:8px;display:grid}.pin-keys button{border:1px solid var(--edge);background:#3fd8ff0d;font-size:1.2rem}.owner-menu{top:max(60px, env(safe-area-inset-top));background:#020c12f0;gap:8px;width:220px;padding:12px;display:grid;left:12px}.boot{background:#000;height:100%}.auth{gap:8px;width:min(380px,100% - 28px);padding:24px;display:grid;position:fixed;top:50%;left:50%;transform:translate(-50%,-50%)}.auth h1{letter-spacing:.3em;text-transform:uppercase;color:var(--accent);margin:0 0 6px;font-size:1.1rem;font-weight:300}.auth label{letter-spacing:.12em;text-transform:uppercase;color:var(--muted);margin-top:6px;font-size:.78rem}.auth input{border:1px solid var(--edge);background:#ffffff0a;padding:0 12px}.auth button{margin-top:12px}.auth-note{color:var(--muted);margin:0;font-size:.9rem}.auth-error{color:#ffc2c9;margin:4px 0 0;font-size:.9rem}@media (width<=599px){.presence-full{inset:0}.captions{bottom:max(11%, env(safe-area-inset-bottom))}}@media (prefers-reduced-motion:reduce){.obj,.presence{transition:none;animation:none}}.status-badge{left:12px;bottom:max(12px, env(safe-area-inset-bottom));font:500 .78rem var(--mono);letter-spacing:.08em;color:var(--ink);border:1px solid var(--edge);background:#0000008c;align-items:center;gap:9px;max-width:min(60vw,360px);padding:6px 12px;display:flex;position:absolute}.status-badge span{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.status-badge i{background:var(--muted);border-radius:50%;flex:none;width:9px;height:9px}.status-idle i{background:var(--ok);box-shadow:0 0 8px var(--ok)}.status-working i,.status-speaking i{background:var(--accent);box-shadow:0 0 10px var(--accent);animation:1s ease-in-out infinite mic-pulse}.status-listening i{background:var(--bad);box-shadow:0 0 10px var(--bad);animation:1s ease-in-out infinite mic-pulse}.status-waiting{border-color:var(--warn);color:#ffd9a0}.status-waiting i{background:var(--warn);box-shadow:0 0 10px var(--warn);animation:1s ease-in-out infinite mic-pulse}.status-offline{border-color:var(--warn);color:var(--warn)}.status-offline i{background:var(--warn)}@media (prefers-reduced-motion:reduce){.status-badge i{animation:none!important}}.clock{right:12px;bottom:max(12px, env(safe-area-inset-bottom));text-align:right;color:var(--muted);line-height:1.15;font-family:var(--mono);pointer-events:none;position:absolute}.clock b{color:var(--ink);letter-spacing:.06em;font-size:1.15rem;font-weight:500;display:block}.clock span{letter-spacing:.1em;text-transform:uppercase;font-size:.7rem}.settings{flex-direction:column;width:min(520px,100% - 24px);max-height:calc(100% - 24px);display:flex}.settings-body{gap:6px;min-height:0;padding-right:4px;display:grid;overflow-y:auto}.settings-field{gap:3px;display:grid}.settings-field>span{letter-spacing:.1em;text-transform:uppercase;color:var(--muted);font-size:.74rem}.settings-field input:not([type=range]):not([type=checkbox]),.settings-field select{border:1px solid var(--edge);color:var(--ink);min-height:40px;font:inherit;background:#ffffff0a;padding:0 10px}.settings-field select option{background:#06141c}.settings-check{align-items:center;gap:10px;min-height:40px;display:flex}.slash-list{border:1px solid var(--edge);background:#020c12f5;max-height:40vh;margin:0;padding:4px;list-style:none;position:absolute;bottom:calc(100% + 6px);left:0;right:0;overflow-y:auto}.slash-list li{cursor:pointer;align-items:baseline;gap:10px;padding:7px 10px;display:flex}.slash-list li.on,.slash-list li:hover{background:color-mix(in srgb, var(--accent) 18%, transparent)}.slash-list b{font:600 .9rem var(--mono);color:var(--accent)}.slash-list i{font:.78rem var(--mono);color:var(--warn);font-style:normal}.slash-list span{color:var(--muted);font-size:.82rem}.movable{position:absolute}.movable[data-panel=status],.movable[data-panel=clock]{cursor:grab;touch-action:none;pointer-events:auto}.movable:focus-visible{outline:2px solid var(--accent);outline-offset:2px}.panel{resize:both;flex-direction:column;width:clamp(260px,28vw,420px);min-width:220px;min-height:140px;max-height:80vh;padding:0;display:flex;overflow:hidden}.panel-chat{height:62vh}.panel-tasks{width:clamp(240px,26vw,360px);height:40vh}.panel-head{cursor:grab;touch-action:none;border-bottom:1px solid var(--edge);-webkit-user-select:none;user-select:none;justify-content:space-between;align-items:center;gap:10px;padding:8px 12px;display:flex}.panel-head .obj-close{position:static}.chat-lines{flex:1;align-content:start;gap:8px;min-height:0;padding:10px 12px;display:grid;overflow-y:auto}.chat-line{white-space:pre-wrap;overflow-wrap:anywhere;max-width:92%;margin:0;padding:7px 10px;font-size:.9rem}.chat-user{background:color-mix(in srgb, var(--accent) 18%, transparent);border:1px solid var(--edge);justify-self:end}.chat-assistant{background:#ffffff0d;justify-self:start}.chat-form{border-top:1px solid var(--edge);gap:6px;padding:8px;display:flex}.chat-form input{border:1px solid var(--edge);min-width:0;color:var(--ink);min-height:40px;font:inherit;background:#ffffff0a;flex:1;padding:0 10px}.chat-form button{border:1px solid var(--edge);color:var(--ink);background:0 0;min-height:40px;padding:0 14px}.task-body{flex:1;min-height:0;padding:10px 12px;overflow-y:auto}.task-list{gap:8px;margin:0;padding:0;list-style:none;display:grid}.task-list li{border-left:3px solid var(--accent);background:#ffffff0a;gap:2px;padding:8px 10px;display:grid}.task-list li.overdue{border-left-color:var(--bad)}.task-title{overflow-wrap:anywhere;font-size:.95rem}.task-due{font:.75rem var(--mono);color:var(--muted)}.task-list li.overdue .task-due{color:var(--bad)}@media (width<=600px){.panel{resize:none;width:calc(100% - 24px);left:12px!important}.panel-chat{height:52vh;bottom:56px;top:auto!important}.panel-tasks{height:30vh;top:56px!important}}.help{flex-direction:column;width:min(560px,100% - 24px);max-height:calc(100% - 24px);display:flex}.help-list{gap:4px;min-height:0;margin:8px 0;display:grid;overflow-y:auto}.help-row{border-bottom:1px solid #ffffff0f;grid-template-columns:minmax(130px,38%) 1fr;gap:12px;padding:6px 4px;display:grid}.help-row dt{font:600 .9rem var(--mono);color:var(--accent);overflow-wrap:anywhere}.help-row dt i{color:var(--warn);font-style:normal;font-weight:400}.help-row dd{color:var(--ink);margin:0;font-size:.9rem}@media (width<=600px){.help-row{grid-template-columns:1fr;gap:2px}}.connectors{width:min(600px,100% - 24px);max-height:calc(100% - 24px);overflow-y:auto}.connector-form{gap:8px;display:grid}.connector-form textarea,.settings-field textarea{border:1px solid var(--edge);color:var(--ink);font:.85rem var(--mono);resize:vertical;background:#ffffff0a;padding:8px 10px}.connector-steps{color:var(--muted);gap:4px;margin:0;padding-left:20px;font-size:.88rem;display:grid}.connector-warning{border-left:3px solid var(--warn);color:#ffd9a0;padding-left:10px}.conn-status{font:.74rem var(--mono)}.conn-ready{color:var(--ok)}.conn-error{color:var(--bad)}.conn-connecting{color:var(--warn)}.conn-off{color:var(--muted)}.settings-wide{width:min(980px,100% - 24px);height:min(720px,100% - 24px)}.settings-layout{flex:1;grid-template-columns:190px 1fr;gap:16px;min-height:0;margin-top:8px;display:grid}.settings-tabs{align-content:start;gap:6px;display:grid}.settings-tab{text-align:left;color:var(--ink);background:0 0;border:1px solid #0000;gap:2px;padding:10px 12px;display:grid}.settings-tab small{color:var(--muted);font-size:.74rem}.settings-tab:hover{background:#ffffff0d}.settings-tab.on{border-color:var(--accent);background:color-mix(in srgb, var(--accent) 16%, transparent)}.settings-wide .settings-body{align-content:start;padding-right:8px}@media (width<=700px){.settings-wide{height:calc(100% - 24px)}.settings-layout{grid-template-columns:1fr;gap:8px}.settings-tabs{grid-auto-columns:1fr;grid-auto-flow:column;overflow-x:auto}.settings-tab small{display:none}}.look-tab{grid-template-columns:minmax(220px,300px) 1fr;align-items:start;gap:18px;display:grid}.look-side{gap:10px;display:grid;position:sticky;top:0}.look-controls{gap:6px;min-width:0;display:grid}@media (width<=860px){.look-tab{grid-template-columns:1fr}.look-side{position:static}}.look-preview{border:1px solid var(--edge);background:#000;height:230px;position:relative;overflow:hidden}.look-preview-glow{background:radial-gradient(ellipse at 50% 55%, color-mix(in srgb, var(--accent) 22%, transparent), transparent 65%);position:absolute;inset:0}.look-preview-stage{position:absolute;inset:0}.look-preview-caption{text-align:center;text-shadow:0 0 10px #000;margin:0;position:absolute;bottom:8px;left:8px;right:8px}.look-preview .presence-full{inset:0}.theme-grid{grid-template-columns:repeat(auto-fill,minmax(118px,1fr));gap:8px;display:grid}.theme-card{border:1px solid var(--edge);color:var(--ink);text-align:left;background:#ffffff08;justify-items:start;gap:1px;padding:10px;display:grid}.theme-card i{background:var(--swatch);width:22px;height:22px;box-shadow:0 0 12px var(--swatch);border-radius:50%;margin-bottom:4px}.theme-card small{color:var(--muted);font-size:.72rem}.theme-card.on,.style-choice.on{border-color:var(--accent);background:color-mix(in srgb, var(--accent) 18%, transparent)}.style-row{grid-template-columns:repeat(3,1fr);gap:8px;display:grid}.style-choice{border:1px solid var(--edge);color:var(--ink);text-align:left;background:#ffffff08;gap:2px;padding:10px;display:grid}.style-choice small{color:var(--muted);font-size:.72rem}.swatch-row{flex-wrap:wrap;align-items:center;gap:8px;display:flex}.swatch{border:2px solid #0000;border-radius:50%;width:32px;height:32px;min-height:32px;padding:0}.swatch.on{box-shadow:0 0 0 2px var(--accent);border-color:#fff}.swatch-custom{color:var(--muted);align-items:center;gap:6px;font-size:.8rem;display:flex}.swatch-custom input[type=color]{border:1px solid var(--edge);background:0 0;width:40px;height:32px;padding:0}.captions-small{font-size:clamp(.9rem,2vw,1.15rem)}.captions-medium{font-size:clamp(1.1rem,2.6vw,1.6rem)}.captions-large{font-size:clamp(1.4rem,3.6vw,2.3rem)}.voice-hear{flex-wrap:wrap;align-items:center;gap:12px;display:flex}.connector-command{border:1px solid var(--edge);font:.85rem var(--mono);-webkit-user-select:all;user-select:all;background:#ffffff0d;margin:0;padding:8px 10px;overflow-x:auto}html,body{overscroll-behavior:none}@media (pointer:coarse){.stage{-webkit-touch-callout:none;-webkit-user-select:none;user-select:none}}input,textarea,select,.connector-command{-webkit-user-select:text;user-select:text}.owner-menu{max-height:calc(100dvh - 80px);overflow-y:auto}.touch-controls{z-index:25;left:0;right:0;bottom:max(14px, env(safe-area-inset-bottom));pointer-events:none;justify-content:center;align-items:flex-end;gap:26px;display:flex;position:absolute}.touch-controls>*{pointer-events:auto}.touch-talk{justify-items:center;gap:6px;display:grid}.touch-hint{max-width:70vw;font:500 .74rem var(--mono);letter-spacing:.06em;color:var(--muted);text-align:center;text-shadow:0 0 6px #000,0 0 2px #000;padding:2px 10px}.touch-mic,.touch-side{border:1px solid var(--edge);color:var(--ink);background:var(--glass);-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);touch-action:none;-webkit-user-select:none;user-select:none;border-radius:50%;place-items:center;padding:0;display:grid}.touch-mic{border-color:var(--accent);width:76px;height:76px;box-shadow:0 0 22px color-mix(in srgb, var(--accent) 30%, transparent)}.touch-mic.on{background:color-mix(in srgb, var(--bad) 40%, transparent);border-color:var(--bad);box-shadow:0 0 28px var(--bad);animation:1s ease-in-out infinite mic-pulse}.touch-side{touch-action:manipulation;width:52px;height:52px;margin-bottom:12px}@media (prefers-reduced-motion:reduce){.touch-mic.on{animation:none}}@media (pointer:coarse){.captions{bottom:calc(max(14px, env(safe-area-inset-bottom)) + 150px)}.status-badge,.clock{bottom:max(8px, env(safe-area-inset-bottom))}.presence-corner{bottom:calc(max(14px, env(safe-area-inset-bottom)) + 70px)}}@media (width<=600px) and (pointer:coarse){.panel-chat{bottom:calc(max(14px, env(safe-area-inset-bottom)) + 150px);height:min(48vh,100dvh - 260px)}.objects-stack{padding-bottom:190px}}
|
|
1
|
+
:root{--accent:#3fd8ff;--warn:#ffb454;--bad:#ff6b7a;--ok:#5ef0b0;--ink:#d4ecf7;--muted:#7fa3b6;--glass:#06141c9e;--edge:color-mix(in srgb, var(--accent) 48%, transparent);--ui:"Segoe UI", system-ui, -apple-system, "Helvetica Neue", Arial, sans-serif;--mono:"Cascadia Mono", "SF Mono", Consolas, ui-monospace, monospace;--lightningcss-light: ;--lightningcss-dark:initial;color-scheme:dark}*{box-sizing:border-box}html,body,#root{height:100%;margin:0}body{color:var(--ink);font:16px/1.5 var(--ui);-webkit-tap-highlight-color:transparent;background:#000;overflow:hidden}button,input{font:inherit;color:inherit}button{cursor:pointer}:focus-visible{outline:2px solid var(--accent);outline-offset:2px}.stage{touch-action:manipulation;background:#000;position:fixed;inset:0;overflow:hidden}.ambient{pointer-events:none;background:radial-gradient(ellipse at 50% 55%, color-mix(in srgb, var(--accent) 10%, transparent), transparent 62%), linear-gradient(#3fd8ff0b 1px, transparent 1px) 0 0 / 64px 64px, linear-gradient(90deg, #3fd8ff0b 1px, transparent 1px) 0 0 / 64px 64px;position:absolute;inset:0;-webkit-mask-image:radial-gradient(#000 30%,#0000 78%);mask-image:radial-gradient(#000 30%,#0000 78%)}.presence{z-index:1;transition:inset .7s cubic-bezier(.2,.7,.2,1),width .7s,height .7s,opacity .5s;position:absolute}.presence-full{inset:0}.presence-corner{left:max(10px, env(safe-area-inset-left));bottom:max(52px, calc(env(safe-area-inset-bottom) + 42px));width:clamp(96px,16vw,190px);height:clamp(96px,16vw,190px)}.objects{pointer-events:none;position:absolute;inset:0}.objects-stack{pointer-events:auto;padding:max(56px, env(safe-area-inset-top)) 14px 140px;flex-direction:column;gap:12px;display:flex;overflow-y:auto}.auto-grid{pointer-events:none;padding:max(24px, env(safe-area-inset-top)) 24px 24px clamp(120px, 20vw, 230px);grid-template-columns:repeat(auto-fit,minmax(min(280px,100%),1fr));align-content:safe center;align-items:start;gap:12px;display:grid;position:absolute;inset:0;overflow-y:auto}.auto-grid>.obj{pointer-events:auto}.objects-stack>.auto-grid{flex-direction:column;padding:0;display:flex;position:static;overflow:visible}.obj.leaving{pointer-events:none;animation:.35s forwards leave}@keyframes leave{to{opacity:0;transform:scale(.96)translateY(-6px)}}@media (prefers-reduced-motion:reduce){.obj.leaving{animation:none}}.glass{background:var(--glass);-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);border:1px solid var(--edge);box-shadow:0 0 22px color-mix(in srgb, var(--accent) 16%, transparent), inset 0 0 28px #3fd8ff0d;clip-path:polygon(0 0,calc(100% - 14px) 0,100% 14px,100% 100%,14px 100%,0 calc(100% - 14px))}.obj{pointer-events:auto;min-width:0;padding:16px 18px;animation:.45s both appear;overflow:auto}.obj.alert{border-color:var(--warn)}@keyframes appear{0%{opacity:0;transform:translateY(8px)scale(.985)}}.obj-close{width:44px;height:44px;color:var(--muted);background:0 0;border:0;font-size:1.5rem;line-height:1;position:absolute;top:2px;right:6px}.obj-close:hover{color:var(--accent)}.obj-title{letter-spacing:.16em;text-transform:uppercase;color:var(--accent);margin:0 36px 8px 0;font-size:.78rem;font-weight:600}.obj-md>:first-child{margin-top:0}.obj-md>:last-child{margin-bottom:0}.obj-md a{color:var(--accent)}.obj-md code{font-family:var(--mono);background:#3fd8ff1a;padding:0 4px;font-size:.9em}.obj-stat{gap:2px;display:grid}.obj-label{letter-spacing:.16em;text-transform:uppercase;color:var(--muted);font-size:.78rem}.obj-value{font-variant-numeric:tabular-nums;font-size:clamp(2rem,6vw,3.6rem);font-weight:300;line-height:1.05}.obj-value small{color:var(--muted);margin-left:4px;font-size:.4em}.obj-delta{color:var(--ok);font-size:.9rem}.obj-list{gap:4px;margin:0;padding-left:1.1rem;display:grid}.obj-list .done{color:var(--muted);text-decoration:line-through}.obj-table-wrap{overflow-x:auto}.obj-table{border-collapse:collapse;width:100%;font-size:.92rem}.obj-table th{text-align:left;letter-spacing:.14em;text-transform:uppercase;color:var(--accent);font-size:.72rem;font-weight:600}.obj-table th,.obj-table td{font-variant-numeric:tabular-nums;border-bottom:1px solid #3fd8ff2e;padding:6px 10px}.obj-code{font:.86rem/1.5 var(--mono);margin:0;overflow:auto}.obj-empty{color:var(--muted);margin:0}.obj-chart{width:100%;height:auto;display:block}.obj-chart .grid{stroke:#3fd8ff24;stroke-width:1px}.obj-chart .tick{fill:var(--muted);font:10px var(--mono);font-variant-numeric:tabular-nums}.legend{color:var(--muted);flex-wrap:wrap;gap:6px 14px;margin:6px 0 0;padding:0;font-size:.8rem;list-style:none;display:flex}.legend i{width:10px;height:10px;margin-right:6px;display:inline-block}.obj-gauge{justify-items:center;display:grid}.obj-gauge svg{width:min(100%,260px);height:auto}.obj-gauge .track{stroke:#3fd8ff26}.obj-gauge .value{stroke:var(--accent);filter:drop-shadow(0 0 6px var(--accent))}.obj-gauge.gauge-warn .value{stroke:var(--warn);filter:drop-shadow(0 0 6px var(--warn))}.obj-gauge.gauge-crit .value{stroke:var(--bad);filter:drop-shadow(0 0 6px var(--bad))}.gauge-read{align-items:baseline;gap:4px;margin-top:-62px;display:flex}.gauge-value{font-variant-numeric:tabular-nums;font-size:clamp(1.8rem,5vw,2.8rem);font-weight:300}.gauge-unit{color:var(--muted)}.obj-gauge .obj-label{margin-top:18px}.obj-timeline{border-left:1px solid var(--edge);gap:14px;margin:8px 0 0;padding:0 0 0 20px;list-style:none;display:grid}.obj-timeline li{gap:2px;display:grid;position:relative}.obj-timeline li:before{content:"";background:var(--accent);width:9px;height:9px;box-shadow:0 0 8px var(--accent);border-radius:50%;position:absolute;top:.5em;left:-25px}.obj-timeline time{font:.75rem/1.3 var(--mono);color:var(--accent)}.obj-timeline span{color:var(--muted);font-size:.9rem}.obj-graph{width:100%;height:auto;max-height:70vh;margin:0 auto;display:block}.obj[style*=" height:"] .obj-graph{max-height:calc(100% - 32px)}.obj-graph .edge{stroke:color-mix(in srgb, var(--accent) 55%, transparent);stroke-width:1.4px}.obj-graph .arrow{fill:var(--accent)}.obj-graph .node{fill:#3fd8ff26;stroke:var(--accent);stroke-width:1.5px}.obj-graph .node-label{fill:var(--ink);font:10px var(--ui)}.obj-graph .edge-label{fill:var(--muted);font:9px var(--ui)}.captions{z-index:20;left:50%;bottom:max(7%, env(safe-area-inset-bottom));text-align:center;pointer-events:none;text-shadow:0 0 18px #000,0 0 4px #000;text-wrap:balance;width:min(780px,100% - 32px);margin:0;font-size:clamp(1.1rem,2.6vw,1.6rem);font-weight:300;position:absolute;transform:translate(-50%)}.captions.done{animation:1.4s 8s forwards fadeOut}@keyframes fadeOut{to{opacity:0}}.command-bar{z-index:30;left:50%;bottom:max(14px, env(safe-area-inset-bottom));background:var(--glass);border:1px solid var(--edge);-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);gap:8px;width:min(640px,100% - 24px);padding:8px;display:flex;position:absolute;transform:translate(-50%)}.command-bar input{background:0 0;border:0;outline:none;flex:1;min-height:44px;padding:0 10px;font-size:1.05rem}.command-bar button{border:1px solid var(--edge);background:0 0;min-width:44px;min-height:44px}.conn-badge{top:max(10px, env(safe-area-inset-top));font:500 .78rem var(--mono);letter-spacing:.08em;color:var(--warn);border:1px solid var(--warn);background:#0009;padding:6px 12px;position:absolute;right:12px}.mic-indicator{left:50%;top:max(12px, env(safe-area-inset-top));font:500 .82rem var(--mono);letter-spacing:.1em;text-transform:uppercase;color:#ffd9a0;border:1px solid var(--warn);background:#000000c7;align-items:center;gap:10px;padding:8px 16px;display:flex;position:absolute;transform:translate(-50%)}.mic-indicator i{background:var(--bad);width:10px;height:10px;box-shadow:0 0 10px var(--bad);border-radius:50%;animation:1s ease-in-out infinite mic-pulse}.mic-transcribing i{background:var(--warn);box-shadow:0 0 10px var(--warn)}@keyframes mic-pulse{50%{opacity:.35}}@media (prefers-reduced-motion:reduce){.mic-indicator i{animation:none}}.toasts{top:max(48px, env(safe-area-inset-top));gap:6px;width:min(420px,100% - 24px);display:grid;position:absolute;left:50%;transform:translate(-50%)}.toast{border:1px solid var(--edge);background:#000000d1;padding:10px 14px;font-size:.92rem}.toast-warn{border-color:var(--warn);color:#ffd9a0}.toast-error{border-color:var(--bad);color:#ffc2c9}.approval{border-color:var(--warn);background:#020c12eb;width:min(460px,100% - 24px);max-height:calc(100% - 24px);padding:20px;position:absolute;top:50%;left:50%;overflow:auto;transform:translate(-50%,-50%);box-shadow:0 0 0 100vmax #0000008c,0 0 30px #ffb45440}.plugins{width:min(560px,100% - 24px)}.plugins-heading{letter-spacing:.14em;text-transform:uppercase;color:var(--muted);margin:14px 0 6px;font-size:.78rem}.plugin-list{gap:8px;margin:0;padding:0;list-style:none;display:grid}.plugin-list li{background:#ffffff0a;justify-content:space-between;align-items:center;gap:10px;padding:8px 10px;display:flex}.plugin-info{min-width:0}.plugin-info .auth-note{font-size:.82rem}.plugin-actions{flex-shrink:0;gap:6px;display:flex}.plugin-actions button{border:1px solid var(--edge);background:0 0;padding:0 12px}.obj-sandbox{flex-direction:column;gap:6px;width:100%;min-width:min(560px,80vw);height:min(420px,60vh);display:flex}.obj-sandbox iframe{border:1px solid var(--edge);background:#050b10;flex:1;width:100%;min-height:200px}.camera-indicator{border-color:var(--bad);color:#ffc2c9;letter-spacing:.12em;text-transform:uppercase;background:#020c12e6;align-items:center;gap:10px;padding:6px 12px 6px 6px;font-size:.8rem;display:flex;position:absolute;bottom:12px;right:12px}.camera-indicator video{object-fit:cover;background:#000;width:72px;height:54px}.camera-indicator span:before{content:"";background:var(--bad);border-radius:50%;width:8px;height:8px;margin-right:8px;display:inline-block}.challenge,.enroll{border-color:var(--accent);box-shadow:0 0 0 100vmax #0000008c,0 0 30px #3fd8ff40}.challenge .approval-title,.enroll .approval-title{color:var(--accent)}.approval-head{align-items:center;gap:10px;display:flex}.approval-title{letter-spacing:.18em;text-transform:uppercase;color:var(--warn);font-size:.8rem}.tier{font:600 .74rem var(--mono);border:1px solid;padding:2px 8px}.tier-T2{color:var(--warn)}.tier-T3{color:var(--bad)}.approval-summary{font:.95rem/1.5 var(--mono);word-break:break-all;background:#ffffff0a;max-height:40vh;margin:14px 0;padding:10px 12px;overflow:auto}.approval-actions{flex-wrap:wrap;gap:8px;margin-top:14px;display:flex}.approval-actions button,.owner-menu button,.auth button{border:1px solid var(--edge);letter-spacing:.04em;background:0 0;padding:0 16px}button.primary{background:color-mix(in srgb, var(--accent) 22%, transparent);border-color:var(--accent)}button.danger{border-color:var(--bad);color:#ffc2c9}button:disabled{opacity:.4;cursor:not-allowed}.pinpad{justify-items:center;gap:8px;display:grid}.pin-dots{letter-spacing:.4em;min-height:1.6em;color:var(--accent);font-size:1.6rem}.pin-keys{grid-template-columns:repeat(3,64px);gap:8px;display:grid}.pin-keys button{border:1px solid var(--edge);background:#3fd8ff0d;font-size:1.2rem}.owner-menu{top:max(60px, env(safe-area-inset-top));background:#020c12f0;gap:8px;width:220px;padding:12px;display:grid;left:12px}.boot{background:#000;height:100%}.auth{gap:8px;width:min(380px,100% - 28px);padding:24px;display:grid;position:fixed;top:50%;left:50%;transform:translate(-50%,-50%)}.auth h1{letter-spacing:.3em;text-transform:uppercase;color:var(--accent);margin:0 0 6px;font-size:1.1rem;font-weight:300}.auth label{letter-spacing:.12em;text-transform:uppercase;color:var(--muted);margin-top:6px;font-size:.78rem}.auth input{border:1px solid var(--edge);background:#ffffff0a;padding:0 12px}.auth button{margin-top:12px}.auth-note{color:var(--muted);margin:0;font-size:.9rem}.auth-error{color:#ffc2c9;margin:4px 0 0;font-size:.9rem}@media (width<=599px){.presence-full{inset:0}.captions{bottom:max(11%, env(safe-area-inset-bottom))}}@media (prefers-reduced-motion:reduce){.obj,.presence{transition:none;animation:none}}.status-badge{left:12px;bottom:max(12px, env(safe-area-inset-bottom));font:500 .78rem var(--mono);letter-spacing:.08em;color:var(--ink);border:1px solid var(--edge);background:#0000008c;align-items:center;gap:9px;max-width:min(60vw,360px);padding:6px 12px;display:flex;position:absolute}.status-badge span{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.status-badge i{background:var(--muted);border-radius:50%;flex:none;width:9px;height:9px}.status-idle i{background:var(--ok);box-shadow:0 0 8px var(--ok)}.status-working i,.status-speaking i{background:var(--accent);box-shadow:0 0 10px var(--accent);animation:1s ease-in-out infinite mic-pulse}.status-listening i{background:var(--bad);box-shadow:0 0 10px var(--bad);animation:1s ease-in-out infinite mic-pulse}.status-waiting{border-color:var(--warn);color:#ffd9a0}.status-waiting i{background:var(--warn);box-shadow:0 0 10px var(--warn);animation:1s ease-in-out infinite mic-pulse}.status-offline{border-color:var(--warn);color:var(--warn)}.status-offline i{background:var(--warn)}@media (prefers-reduced-motion:reduce){.status-badge i{animation:none!important}}.clock{right:12px;bottom:max(12px, env(safe-area-inset-bottom));text-align:right;color:var(--muted);line-height:1.15;font-family:var(--mono);pointer-events:none;position:absolute}.clock b{color:var(--ink);letter-spacing:.06em;font-size:1.15rem;font-weight:500;display:block}.clock span{letter-spacing:.1em;text-transform:uppercase;font-size:.7rem}.settings{flex-direction:column;width:min(520px,100% - 24px);max-height:calc(100% - 24px);display:flex}.settings-body{gap:6px;min-height:0;padding-right:4px;display:grid;overflow-y:auto}.settings-field{gap:3px;display:grid}.settings-field>span{letter-spacing:.1em;text-transform:uppercase;color:var(--muted);font-size:.74rem}.settings-field input:not([type=range]):not([type=checkbox]),.settings-field select{border:1px solid var(--edge);color:var(--ink);min-height:40px;font:inherit;background:#ffffff0a;padding:0 10px}.settings-field select option{background:#06141c}.settings-check{align-items:center;gap:10px;min-height:40px;display:flex}.slash-list{border:1px solid var(--edge);background:#020c12f5;max-height:40vh;margin:0;padding:4px;list-style:none;position:absolute;bottom:calc(100% + 6px);left:0;right:0;overflow-y:auto}.slash-list li{cursor:pointer;align-items:baseline;gap:10px;padding:7px 10px;display:flex}.slash-list li.on,.slash-list li:hover{background:color-mix(in srgb, var(--accent) 18%, transparent)}.slash-list b{font:600 .9rem var(--mono);color:var(--accent)}.slash-list i{font:.78rem var(--mono);color:var(--warn);font-style:normal}.slash-list span{color:var(--muted);font-size:.82rem}.movable{position:absolute}.movable[data-panel=status],.movable[data-panel=clock]{cursor:grab;touch-action:none;pointer-events:auto}.movable:focus-visible{outline:2px solid var(--accent);outline-offset:2px}.panel{resize:both;flex-direction:column;width:clamp(260px,28vw,420px);min-width:220px;min-height:140px;max-height:80vh;padding:0;display:flex;overflow:hidden}.panel-chat{height:62vh}.panel-tasks{width:clamp(240px,26vw,360px);height:40vh}.panel-head{cursor:grab;touch-action:none;border-bottom:1px solid var(--edge);-webkit-user-select:none;user-select:none;justify-content:space-between;align-items:center;gap:10px;padding:8px 12px;display:flex}.panel-head .obj-close{position:static}.chat-lines{flex:1;align-content:start;gap:8px;min-height:0;padding:10px 12px;display:grid;overflow-y:auto}.chat-line{white-space:pre-wrap;overflow-wrap:anywhere;max-width:92%;margin:0;padding:7px 10px;font-size:.9rem}.chat-user{background:color-mix(in srgb, var(--accent) 18%, transparent);border:1px solid var(--edge);justify-self:end}.chat-assistant{background:#ffffff0d;justify-self:start}.chat-form{border-top:1px solid var(--edge);gap:6px;padding:8px;display:flex}.chat-form input{border:1px solid var(--edge);min-width:0;color:var(--ink);min-height:40px;font:inherit;background:#ffffff0a;flex:1;padding:0 10px}.chat-form button{border:1px solid var(--edge);color:var(--ink);background:0 0;min-height:40px;padding:0 14px}.task-body{flex:1;min-height:0;padding:10px 12px;overflow-y:auto}.task-list{gap:8px;margin:0;padding:0;list-style:none;display:grid}.task-list li{border-left:3px solid var(--accent);background:#ffffff0a;gap:2px;padding:8px 10px;display:grid}.task-list li.overdue{border-left-color:var(--bad)}.task-title{overflow-wrap:anywhere;font-size:.95rem}.task-due{font:.75rem var(--mono);color:var(--muted)}.task-list li.overdue .task-due{color:var(--bad)}@media (width<=600px){.panel{resize:none;width:calc(100% - 24px);left:12px!important}.panel-chat{height:52vh;bottom:56px;top:auto!important}.panel-tasks{height:30vh;top:56px!important}}.help{flex-direction:column;width:min(560px,100% - 24px);max-height:calc(100% - 24px);display:flex}.help-list{gap:4px;min-height:0;margin:8px 0;display:grid;overflow-y:auto}.help-row{border-bottom:1px solid #ffffff0f;grid-template-columns:minmax(130px,38%) 1fr;gap:12px;padding:6px 4px;display:grid}.help-row dt{font:600 .9rem var(--mono);color:var(--accent);overflow-wrap:anywhere}.help-row dt i{color:var(--warn);font-style:normal;font-weight:400}.help-row dd{color:var(--ink);margin:0;font-size:.9rem}@media (width<=600px){.help-row{grid-template-columns:1fr;gap:2px}}.connectors{width:min(600px,100% - 24px);max-height:calc(100% - 24px);overflow-y:auto}.connector-form{gap:8px;display:grid}.connector-form textarea,.settings-field textarea{border:1px solid var(--edge);color:var(--ink);font:.85rem var(--mono);resize:vertical;background:#ffffff0a;padding:8px 10px}.connector-steps{color:var(--muted);gap:4px;margin:0;padding-left:20px;font-size:.88rem;display:grid}.connector-warning{border-left:3px solid var(--warn);color:#ffd9a0;padding-left:10px}.conn-status{font:.74rem var(--mono)}.conn-ready{color:var(--ok)}.conn-error{color:var(--bad)}.conn-connecting{color:var(--warn)}.conn-off{color:var(--muted)}.settings-wide{width:min(980px,100% - 24px);height:min(720px,100% - 24px)}.settings-layout{flex:1;grid-template-columns:190px 1fr;gap:16px;min-height:0;margin-top:8px;display:grid}.settings-tabs{align-content:start;gap:6px;display:grid}.settings-tab{text-align:left;color:var(--ink);background:0 0;border:1px solid #0000;gap:2px;padding:10px 12px;display:grid}.settings-tab small{color:var(--muted);font-size:.74rem}.settings-tab:hover{background:#ffffff0d}.settings-tab.on{border-color:var(--accent);background:color-mix(in srgb, var(--accent) 16%, transparent)}.settings-wide .settings-body{align-content:start;padding-right:8px}@media (width<=700px){.settings-wide{height:calc(100% - 24px)}.settings-layout{grid-template-columns:1fr;gap:8px}.settings-tabs{grid-auto-columns:1fr;grid-auto-flow:column;overflow-x:auto}.settings-tab small{display:none}}.look-tab{grid-template-columns:minmax(220px,300px) 1fr;align-items:start;gap:18px;display:grid}.look-side{gap:10px;display:grid;position:sticky;top:0}.look-controls{gap:6px;min-width:0;display:grid}@media (width<=860px){.look-tab{grid-template-columns:1fr}.look-side{position:static}}.look-preview{border:1px solid var(--edge);background:#000;height:230px;position:relative;overflow:hidden}.look-preview-glow{background:radial-gradient(ellipse at 50% 55%, color-mix(in srgb, var(--accent) 22%, transparent), transparent 65%);position:absolute;inset:0}.look-preview-stage{position:absolute;inset:0}.look-preview-caption{text-align:center;text-shadow:0 0 10px #000;margin:0;position:absolute;bottom:8px;left:8px;right:8px}.look-preview .presence-full{inset:0}.theme-grid{grid-template-columns:repeat(auto-fill,minmax(118px,1fr));gap:8px;display:grid}.theme-card{border:1px solid var(--edge);color:var(--ink);text-align:left;background:#ffffff08;justify-items:start;gap:1px;padding:10px;display:grid}.theme-card i{background:var(--swatch);width:22px;height:22px;box-shadow:0 0 12px var(--swatch);border-radius:50%;margin-bottom:4px}.theme-card small{color:var(--muted);font-size:.72rem}.theme-card.on,.style-choice.on{border-color:var(--accent);background:color-mix(in srgb, var(--accent) 18%, transparent)}.style-row{grid-template-columns:repeat(3,1fr);gap:8px;display:grid}.style-choice{border:1px solid var(--edge);color:var(--ink);text-align:left;background:#ffffff08;gap:2px;padding:10px;display:grid}.style-choice small{color:var(--muted);font-size:.72rem}.swatch-row{flex-wrap:wrap;align-items:center;gap:8px;display:flex}.swatch{border:2px solid #0000;border-radius:50%;width:32px;height:32px;min-height:32px;padding:0}.swatch.on{box-shadow:0 0 0 2px var(--accent);border-color:#fff}.swatch-custom{color:var(--muted);align-items:center;gap:6px;font-size:.8rem;display:flex}.swatch-custom input[type=color]{border:1px solid var(--edge);background:0 0;width:40px;height:32px;padding:0}.captions-small{font-size:clamp(.9rem,2vw,1.15rem)}.captions-medium{font-size:clamp(1.1rem,2.6vw,1.6rem)}.captions-large{font-size:clamp(1.4rem,3.6vw,2.3rem)}.voice-hear{flex-wrap:wrap;align-items:center;gap:12px;display:flex}.connector-command{border:1px solid var(--edge);font:.85rem var(--mono);-webkit-user-select:all;user-select:all;background:#ffffff0d;margin:0;padding:8px 10px;overflow-x:auto}html,body{overscroll-behavior:none}@media (pointer:coarse){.stage{-webkit-touch-callout:none;-webkit-user-select:none;user-select:none}}input,textarea,select,.connector-command{-webkit-user-select:text;user-select:text}.owner-menu{max-height:calc(100dvh - 80px);overflow-y:auto}.touch-controls{z-index:25;left:0;right:0;bottom:max(14px, env(safe-area-inset-bottom));pointer-events:none;justify-content:center;align-items:flex-end;gap:26px;display:flex;position:absolute}.touch-controls>*{pointer-events:auto}.touch-talk{justify-items:center;gap:6px;display:grid}.touch-hint{max-width:70vw;font:500 .74rem var(--mono);letter-spacing:.06em;color:var(--muted);text-align:center;text-shadow:0 0 6px #000,0 0 2px #000;padding:2px 10px}.touch-mic,.touch-side{border:1px solid var(--edge);color:var(--ink);background:var(--glass);-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);touch-action:none;-webkit-user-select:none;user-select:none;-webkit-touch-callout:none;-webkit-tap-highlight-color:transparent;border-radius:50%;place-items:center;padding:0;display:grid}.touch-mic{border-color:var(--accent);width:76px;height:76px;box-shadow:0 0 22px color-mix(in srgb, var(--accent) 30%, transparent)}.touch-mic.on{background:color-mix(in srgb, var(--bad) 40%, transparent);border-color:var(--bad);box-shadow:0 0 28px var(--bad);animation:1s ease-in-out infinite mic-pulse}.touch-side{touch-action:manipulation;width:52px;height:52px;margin-bottom:12px}@media (prefers-reduced-motion:reduce){.touch-mic.on{animation:none}}@media (pointer:coarse){.captions{bottom:calc(max(14px, env(safe-area-inset-bottom)) + 150px)}.status-badge,.clock{bottom:max(8px, env(safe-area-inset-bottom))}.presence-corner{bottom:calc(max(14px, env(safe-area-inset-bottom)) + 70px)}}@media (width<=600px) and (pointer:coarse){.panel-chat{bottom:calc(max(14px, env(safe-area-inset-bottom)) + 150px);height:min(48vh,100dvh - 260px)}.objects-stack{padding-bottom:190px}}.elsewhere{z-index:3000;-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);background:#000000c7;place-items:center;padding:16px;display:grid;position:fixed;inset:0}.elsewhere-card{border:1px solid var(--edge);background:var(--glass);max-width:380px;color:var(--ink);text-align:center;border-radius:16px;padding:24px}.elsewhere-card h2{margin:0 0 10px;font-size:1.15rem}.elsewhere-card p{color:var(--muted);margin:0 0 18px;line-height:1.45}.elsewhere-btn{border:1px solid var(--accent);background:color-mix(in srgb, var(--accent) 25%, transparent);min-height:48px;color:var(--ink);font:600 1rem var(--mono);cursor:pointer;border-radius:24px;padding:0 28px}
|