@ra3orblade/swarm 0.13.0 → 0.13.1
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/dist/swarm-hook.js +9 -5
- package/dist/swarmd.js +100 -51
- package/package.json +1 -1
- package/web/dashboard.css +1 -1
- package/web/dashboard.js +22 -17
- package/web/index.html +2 -3
- package/web/release-notes.js +1 -1
package/dist/swarm-hook.js
CHANGED
|
@@ -196,22 +196,26 @@ function otherLiveInSameTree(current, sessions, now, withinMs = LIVE_WINDOW_MS)
|
|
|
196
196
|
}
|
|
197
197
|
return null;
|
|
198
198
|
}
|
|
199
|
+
var GIT_GLOBAL_OPTS = "(?:\\s+(?:-C\\s+\\S+|-c\\s+\\S+|--git-dir(?:=|\\s+)\\S+|--work-tree(?:=|\\s+)\\S+|--namespace(?:=|\\s+)\\S+|--no-pager|--paginate|--bare|--literal-pathspecs|--exec-path(?:=\\S+)?))*";
|
|
200
|
+
function gitVerb(verb, tail) {
|
|
201
|
+
return new RegExp(`\\bgit${GIT_GLOBAL_OPTS}\\s+${verb}${tail}`);
|
|
202
|
+
}
|
|
199
203
|
function isBroadStage(cmd) {
|
|
200
204
|
const c = cmd.trim();
|
|
201
|
-
if (
|
|
205
|
+
if (gitVerb("add", "\\s+(-A\\b|--all\\b|\\.(\\s|$))").test(c))
|
|
202
206
|
return true;
|
|
203
|
-
if (
|
|
207
|
+
if (gitVerb("commit", "\\b[^|&;]*\\s-[a-zA-Z]*a").test(c))
|
|
204
208
|
return true;
|
|
205
|
-
if (
|
|
209
|
+
if (gitVerb("add", "\\s*$").test(c))
|
|
206
210
|
return true;
|
|
207
211
|
return false;
|
|
208
212
|
}
|
|
209
213
|
function isDestructiveGit(cmd) {
|
|
210
214
|
const c = cmd.trim();
|
|
211
|
-
return
|
|
215
|
+
return gitVerb("reset", "\\s+[^|&;]*--hard\\b").test(c) || gitVerb("checkout", "\\s+(--\\s+)?\\.(\\s|$)").test(c) || gitVerb("checkout", "\\s+-f\\b").test(c) || gitVerb("restore", "\\s+(--\\s+)?\\.(\\s|$)").test(c) || gitVerb("clean", "\\s+[^|&;]*-[a-zA-Z]*f").test(c) || gitVerb("stash", "\\s+(drop|clear)\\b").test(c) || gitVerb("branch", "\\s+[^|&;]*-[a-zA-Z]*D").test(c);
|
|
212
216
|
}
|
|
213
217
|
function isPatternKill(cmd) {
|
|
214
|
-
return /\bpkill\s
|
|
218
|
+
return /\bpkill\s+(-[a-zA-Z]*f\b|--full\b)/.test(cmd) || /\bkillall\b/.test(cmd) || /\bpgrep\s+(-[a-zA-Z]*f\b|--full\b)[^|]*\|\s*[^|]*\bkill\b/.test(cmd);
|
|
215
219
|
}
|
|
216
220
|
function killedPorts(cmd) {
|
|
217
221
|
const ports = new Set;
|
package/dist/swarmd.js
CHANGED
|
@@ -1678,22 +1678,26 @@ function otherLiveInSameTree(current, sessions, now, withinMs = LIVE_WINDOW_MS)
|
|
|
1678
1678
|
}
|
|
1679
1679
|
return null;
|
|
1680
1680
|
}
|
|
1681
|
+
var GIT_GLOBAL_OPTS = "(?:\\s+(?:-C\\s+\\S+|-c\\s+\\S+|--git-dir(?:=|\\s+)\\S+|--work-tree(?:=|\\s+)\\S+|--namespace(?:=|\\s+)\\S+|--no-pager|--paginate|--bare|--literal-pathspecs|--exec-path(?:=\\S+)?))*";
|
|
1682
|
+
function gitVerb(verb, tail) {
|
|
1683
|
+
return new RegExp(`\\bgit${GIT_GLOBAL_OPTS}\\s+${verb}${tail}`);
|
|
1684
|
+
}
|
|
1681
1685
|
function isBroadStage(cmd) {
|
|
1682
1686
|
const c = cmd.trim();
|
|
1683
|
-
if (
|
|
1687
|
+
if (gitVerb("add", "\\s+(-A\\b|--all\\b|\\.(\\s|$))").test(c))
|
|
1684
1688
|
return true;
|
|
1685
|
-
if (
|
|
1689
|
+
if (gitVerb("commit", "\\b[^|&;]*\\s-[a-zA-Z]*a").test(c))
|
|
1686
1690
|
return true;
|
|
1687
|
-
if (
|
|
1691
|
+
if (gitVerb("add", "\\s*$").test(c))
|
|
1688
1692
|
return true;
|
|
1689
1693
|
return false;
|
|
1690
1694
|
}
|
|
1691
1695
|
function isDestructiveGit(cmd) {
|
|
1692
1696
|
const c = cmd.trim();
|
|
1693
|
-
return
|
|
1697
|
+
return gitVerb("reset", "\\s+[^|&;]*--hard\\b").test(c) || gitVerb("checkout", "\\s+(--\\s+)?\\.(\\s|$)").test(c) || gitVerb("checkout", "\\s+-f\\b").test(c) || gitVerb("restore", "\\s+(--\\s+)?\\.(\\s|$)").test(c) || gitVerb("clean", "\\s+[^|&;]*-[a-zA-Z]*f").test(c) || gitVerb("stash", "\\s+(drop|clear)\\b").test(c) || gitVerb("branch", "\\s+[^|&;]*-[a-zA-Z]*D").test(c);
|
|
1694
1698
|
}
|
|
1695
1699
|
function isPatternKill(cmd) {
|
|
1696
|
-
return /\bpkill\s
|
|
1700
|
+
return /\bpkill\s+(-[a-zA-Z]*f\b|--full\b)/.test(cmd) || /\bkillall\b/.test(cmd) || /\bpgrep\s+(-[a-zA-Z]*f\b|--full\b)[^|]*\|\s*[^|]*\bkill\b/.test(cmd);
|
|
1697
1701
|
}
|
|
1698
1702
|
function killedPorts(cmd) {
|
|
1699
1703
|
const ports = new Set;
|
|
@@ -6223,7 +6227,7 @@ class ForgeService {
|
|
|
6223
6227
|
return all.sort((a, b) => a.createdAt < b.createdAt ? 1 : -1);
|
|
6224
6228
|
}
|
|
6225
6229
|
async refresh(maxAgeMs = 120000) {
|
|
6226
|
-
const projects = this.store.
|
|
6230
|
+
const projects = this.store.liveProjects();
|
|
6227
6231
|
await Promise.all(projects.map(async (p) => {
|
|
6228
6232
|
const hit = this.cache.get(p.id);
|
|
6229
6233
|
if (hit && Date.now() - hit.at < maxAgeMs)
|
|
@@ -6246,18 +6250,24 @@ class ForgeService {
|
|
|
6246
6250
|
mergedCached(projectId, root) {
|
|
6247
6251
|
const hit = this.outcomeCache.get(projectId);
|
|
6248
6252
|
const fresh = !!hit && Date.now() - hit.at < 600000;
|
|
6249
|
-
if (!fresh
|
|
6250
|
-
|
|
6251
|
-
this.outcomeInflight.set(projectId, run2);
|
|
6252
|
-
}
|
|
6253
|
+
if (!fresh)
|
|
6254
|
+
this.merged(projectId, root).catch(() => {});
|
|
6253
6255
|
return { merged: hit?.merged ?? [], reverted: hit?.reverted ?? [], fresh };
|
|
6254
6256
|
}
|
|
6255
6257
|
async merged(projectId, root) {
|
|
6256
6258
|
const hit = this.outcomeCache.get(projectId);
|
|
6257
6259
|
if (hit && Date.now() - hit.at < 600000)
|
|
6258
6260
|
return hit;
|
|
6261
|
+
const inflight = this.outcomeInflight.get(projectId);
|
|
6262
|
+
if (inflight)
|
|
6263
|
+
return inflight;
|
|
6264
|
+
const run2 = this.fetchMerged(projectId, root).finally(() => this.outcomeInflight.delete(projectId));
|
|
6265
|
+
this.outcomeInflight.set(projectId, run2);
|
|
6266
|
+
return run2;
|
|
6267
|
+
}
|
|
6268
|
+
async fetchMerged(projectId, root) {
|
|
6259
6269
|
let merged = [];
|
|
6260
|
-
const remote = this.remote(root);
|
|
6270
|
+
const remote = await this.remote(root);
|
|
6261
6271
|
if (remote?.forge === "github") {
|
|
6262
6272
|
const out = await this.run([
|
|
6263
6273
|
"gh",
|
|
@@ -6293,38 +6303,44 @@ class ForgeService {
|
|
|
6293
6303
|
mergeSha: (r.merge_commit_sha ?? null)?.toLowerCase() ?? null
|
|
6294
6304
|
}));
|
|
6295
6305
|
}
|
|
6296
|
-
const log =
|
|
6297
|
-
|
|
6298
|
-
"-C",
|
|
6299
|
-
root,
|
|
6300
|
-
"log",
|
|
6301
|
-
"--grep",
|
|
6302
|
-
"This reverts commit",
|
|
6303
|
-
"--format=%B",
|
|
6304
|
-
"-n",
|
|
6305
|
-
"300"
|
|
6306
|
-
]);
|
|
6307
|
-
const reverted = log.exitCode === 0 ? [...parseReverts(new TextDecoder().decode(log.stdout))] : [];
|
|
6306
|
+
const log = await this.run(["git", "log", "--grep", "This reverts commit", "--format=%B", "-n", "300"], root);
|
|
6307
|
+
const reverted = log ? [...parseReverts(log)] : [];
|
|
6308
6308
|
const entry = { at: Date.now(), merged, reverted };
|
|
6309
6309
|
this.outcomeCache.set(projectId, entry);
|
|
6310
6310
|
return entry;
|
|
6311
6311
|
}
|
|
6312
|
-
|
|
6313
|
-
|
|
6314
|
-
|
|
6315
|
-
|
|
6316
|
-
|
|
6312
|
+
remoteCache = new Map;
|
|
6313
|
+
async remote(root) {
|
|
6314
|
+
const hit = this.remoteCache.get(root);
|
|
6315
|
+
if (hit && Date.now() - hit.at < (hit.v ? 600000 : 60000))
|
|
6316
|
+
return hit.v;
|
|
6317
|
+
const out = await this.run(["git", "remote", "get-url", "origin"], root);
|
|
6318
|
+
const v = out ? parseRemote(out.trim()) : null;
|
|
6319
|
+
this.remoteCache.set(root, { at: Date.now(), v });
|
|
6320
|
+
return v;
|
|
6317
6321
|
}
|
|
6318
|
-
async run(cmd, cwd) {
|
|
6322
|
+
async run(cmd, cwd, timeoutMs = 20000) {
|
|
6319
6323
|
const bin = findBin(cmd[0]);
|
|
6320
6324
|
if (!bin)
|
|
6321
6325
|
return null;
|
|
6322
|
-
|
|
6323
|
-
|
|
6324
|
-
|
|
6326
|
+
let proc;
|
|
6327
|
+
try {
|
|
6328
|
+
proc = Bun.spawn([bin, ...cmd.slice(1)], { cwd, stdout: "pipe", stderr: "ignore" });
|
|
6329
|
+
} catch {
|
|
6330
|
+
return null;
|
|
6331
|
+
}
|
|
6332
|
+
const killer = setTimeout(() => proc.kill(), timeoutMs);
|
|
6333
|
+
try {
|
|
6334
|
+
const out = await new Response(proc.stdout).text();
|
|
6335
|
+
return await proc.exited === 0 ? out : null;
|
|
6336
|
+
} catch {
|
|
6337
|
+
return null;
|
|
6338
|
+
} finally {
|
|
6339
|
+
clearTimeout(killer);
|
|
6340
|
+
}
|
|
6325
6341
|
}
|
|
6326
6342
|
async poll(projectId, root) {
|
|
6327
|
-
const remote = this.remote(root);
|
|
6343
|
+
const remote = await this.remote(root);
|
|
6328
6344
|
if (!remote)
|
|
6329
6345
|
return [];
|
|
6330
6346
|
let prs = [];
|
|
@@ -6352,7 +6368,7 @@ class ForgeService {
|
|
|
6352
6368
|
ok: false,
|
|
6353
6369
|
error: `${worktree2.path} has uncommitted changes \u2014 commit them first (Swarm never commits for you)`
|
|
6354
6370
|
};
|
|
6355
|
-
const remote = this.remote(p.root);
|
|
6371
|
+
const remote = await this.remote(p.root);
|
|
6356
6372
|
if (!remote)
|
|
6357
6373
|
return { ok: false, error: "no GitHub/GitLab remote on origin" };
|
|
6358
6374
|
const cli = remote.forge === "github" ? "gh" : "glab";
|
|
@@ -6406,7 +6422,7 @@ class ForgeService {
|
|
|
6406
6422
|
const p = this.store.projects().find((x) => x.id === projectId);
|
|
6407
6423
|
if (!p)
|
|
6408
6424
|
return { ok: false, output: "unknown project" };
|
|
6409
|
-
const remote = this.remote(p.root);
|
|
6425
|
+
const remote = await this.remote(p.root);
|
|
6410
6426
|
if (!remote)
|
|
6411
6427
|
return { ok: false, output: "no forge remote" };
|
|
6412
6428
|
const cmd = remote.forge === "github" ? ["gh", "pr", "merge", String(number), "--squash"] : ["glab", "mr", "merge", String(number), "--squash", "--yes"];
|
|
@@ -8682,6 +8698,9 @@ ${err}
|
|
|
8682
8698
|
createdAt: r.created_at
|
|
8683
8699
|
}));
|
|
8684
8700
|
}
|
|
8701
|
+
liveProjects() {
|
|
8702
|
+
return this.projects().filter((p) => !(p.discovered && isScratchRoot(p.root)));
|
|
8703
|
+
}
|
|
8685
8704
|
project(id) {
|
|
8686
8705
|
const r = this.db.query("SELECT * FROM projects WHERE id = ?").get(id);
|
|
8687
8706
|
if (!r)
|
|
@@ -10206,6 +10225,7 @@ ${p2.reason ?? ""}`.trim(),
|
|
|
10206
10225
|
checkStalls() {
|
|
10207
10226
|
const live = this.db.query("SELECT id, project_id FROM sessions WHERE state IN ('active','waiting') AND ended_at IS NULL AND last_seen_at >= ?").all(new Date(Date.now() - IDLE_MS).toISOString());
|
|
10208
10227
|
const liveIds = new Set(live.map((s) => s.id));
|
|
10228
|
+
const before = JSON.stringify([...this.stalls].map(([id, v]) => [id, v.kind, v.reason]));
|
|
10209
10229
|
for (const id of [...this.stalls.keys()])
|
|
10210
10230
|
if (!liveIds.has(id))
|
|
10211
10231
|
this.stalls.delete(id);
|
|
@@ -10247,6 +10267,9 @@ ${p2.reason ?? ""}`.trim(),
|
|
|
10247
10267
|
});
|
|
10248
10268
|
this.touch();
|
|
10249
10269
|
}
|
|
10270
|
+
const after = JSON.stringify([...this.stalls].map(([id, v]) => [id, v.kind, v.reason]));
|
|
10271
|
+
if (after !== before)
|
|
10272
|
+
this.touch();
|
|
10250
10273
|
return flagged;
|
|
10251
10274
|
}
|
|
10252
10275
|
sweepOrphans() {
|
|
@@ -10580,22 +10603,31 @@ ${p2.reason ?? ""}`.trim(),
|
|
|
10580
10603
|
this.wtCache.clear();
|
|
10581
10604
|
}
|
|
10582
10605
|
async refreshAllWorktrees() {
|
|
10583
|
-
await Promise.all(this.
|
|
10606
|
+
await Promise.all(this.liveProjects().map((p) => this.refreshWorktrees(p.id)));
|
|
10584
10607
|
}
|
|
10585
10608
|
sessions() {
|
|
10609
|
+
return this.memoised("sessions", 2000, () => this.computeSessions());
|
|
10610
|
+
}
|
|
10611
|
+
computeSessions() {
|
|
10612
|
+
const page = this.db.query("SELECT id FROM sessions ORDER BY last_seen_at DESC LIMIT 200").all();
|
|
10613
|
+
if (!page.length)
|
|
10614
|
+
return [];
|
|
10615
|
+
const ids = page.map((r) => r.id);
|
|
10616
|
+
const holes = ids.map(() => "?").join(",");
|
|
10586
10617
|
const rows = this.db.query(`SELECT s.*, COUNT(t.id) AS turns, COALESCE(SUM(t.input),0) AS input, COALESCE(SUM(t.output),0) AS output,
|
|
10587
10618
|
COALESCE(SUM(t.cache_write),0) AS cache_write, COALESCE(SUM(t.cache_read),0) AS cache_read, COALESCE(SUM(t.thinking),0) AS thinking,
|
|
10588
10619
|
SUM(t.cost_usd) AS cost_usd, MAX(t.cost_usd IS NULL AND t.id IS NOT NULL) AS unpriced,
|
|
10589
10620
|
(SELECT model FROM turns lt WHERE lt.session_id = s.id AND lt.agent_id IS NULL AND lt.sidechain = 0 ORDER BY lt.ts DESC LIMIT 1) AS live_model,
|
|
10590
10621
|
(SELECT COUNT(DISTINCT model) FROM turns lm WHERE lm.session_id = s.id AND lm.agent_id IS NULL AND lm.sidechain = 0) AS model_count
|
|
10591
10622
|
FROM sessions s LEFT JOIN turns t ON t.session_id = s.id
|
|
10592
|
-
|
|
10623
|
+
WHERE s.id IN (${holes})
|
|
10624
|
+
GROUP BY s.id ORDER BY s.last_seen_at DESC`).all(...ids);
|
|
10593
10625
|
const idleBefore = Date.now() - IDLE_MS;
|
|
10594
10626
|
const sparkRows = this.db.query(`SELECT session_id, output, cost_usd FROM (
|
|
10595
10627
|
SELECT t.session_id, t.output, t.cost_usd, t.ts,
|
|
10596
10628
|
ROW_NUMBER() OVER (PARTITION BY t.session_id ORDER BY t.ts DESC) AS rn
|
|
10597
|
-
FROM turns t WHERE t.agent_id IS NULL AND t.sidechain = 0
|
|
10598
|
-
) WHERE rn <= 24 ORDER BY ts`).all();
|
|
10629
|
+
FROM turns t WHERE t.agent_id IS NULL AND t.sidechain = 0 AND t.session_id IN (${holes})
|
|
10630
|
+
) WHERE rn <= 24 ORDER BY ts`).all(...ids);
|
|
10599
10631
|
const sparks = new Map;
|
|
10600
10632
|
for (const x of sparkRows) {
|
|
10601
10633
|
const a = sparks.get(x.session_id) ?? [];
|
|
@@ -11300,13 +11332,13 @@ ${p2.reason ?? ""}`.trim(),
|
|
|
11300
11332
|
}
|
|
11301
11333
|
snapshot() {
|
|
11302
11334
|
const worktrees = {};
|
|
11303
|
-
const projects = this.
|
|
11335
|
+
const projects = this.liveProjects();
|
|
11304
11336
|
for (const p of projects)
|
|
11305
11337
|
worktrees[p.id] = this.worktrees(p.id);
|
|
11306
11338
|
return {
|
|
11307
11339
|
projects,
|
|
11308
11340
|
worktrees,
|
|
11309
|
-
sessions: this.
|
|
11341
|
+
sessions: this.sessions(),
|
|
11310
11342
|
spend: this.memoised("spend", 30000, () => this.spend()),
|
|
11311
11343
|
spendSparks: this.memoised("spendSparks", 60000, () => this.spendSparks()),
|
|
11312
11344
|
claims: this.claims(),
|
|
@@ -11831,7 +11863,7 @@ class WorkflowEngine {
|
|
|
11831
11863
|
}
|
|
11832
11864
|
|
|
11833
11865
|
// packages/daemon/src/app.ts
|
|
11834
|
-
var VERSION = "0.13.
|
|
11866
|
+
var VERSION = "0.13.1";
|
|
11835
11867
|
var WEB_DIR = (() => {
|
|
11836
11868
|
if (process.env.SWARM_WEB_DIR)
|
|
11837
11869
|
return process.env.SWARM_WEB_DIR;
|
|
@@ -11878,6 +11910,13 @@ function diskVersion() {
|
|
|
11878
11910
|
return null;
|
|
11879
11911
|
}
|
|
11880
11912
|
}
|
|
11913
|
+
function expandHome(p, home = homedir4()) {
|
|
11914
|
+
if (p === "~")
|
|
11915
|
+
return home;
|
|
11916
|
+
if (p.startsWith("~/"))
|
|
11917
|
+
return join10(home, p.slice(2));
|
|
11918
|
+
return p;
|
|
11919
|
+
}
|
|
11881
11920
|
function createApp(store = new Store, hooks2 = {}) {
|
|
11882
11921
|
const app = new Hono2;
|
|
11883
11922
|
const forge2 = new ForgeService(store);
|
|
@@ -11913,13 +11952,13 @@ function createApp(store = new Store, hooks2 = {}) {
|
|
|
11913
11952
|
schema: store.schemaVersion(),
|
|
11914
11953
|
auth: store.policyFor(null).config.daemon.auth
|
|
11915
11954
|
}));
|
|
11916
|
-
app.get("/v1/projects", (c) => c.json(store.
|
|
11955
|
+
app.get("/v1/projects", (c) => c.json(store.liveProjects()));
|
|
11917
11956
|
app.post("/v1/projects", async (c) => {
|
|
11918
11957
|
const { path, name } = await c.req.json();
|
|
11919
11958
|
if (!path)
|
|
11920
11959
|
return c.json({ error: "path required" }, 400);
|
|
11921
11960
|
try {
|
|
11922
|
-
return c.json(store.resolveProject(path, true, name), 201);
|
|
11961
|
+
return c.json(store.resolveProject(expandHome(path), true, name), 201);
|
|
11923
11962
|
} catch (e) {
|
|
11924
11963
|
return c.json({ error: e.message }, 400);
|
|
11925
11964
|
}
|
|
@@ -11939,10 +11978,12 @@ function createApp(store = new Store, hooks2 = {}) {
|
|
|
11939
11978
|
});
|
|
11940
11979
|
app.delete("/v1/projects/:id", (c) => store.removeProject(c.req.param("id")) ? c.body(null, 204) : c.json({ error: "not found" }, 404));
|
|
11941
11980
|
app.get("/v1/fs/ls", (c) => {
|
|
11942
|
-
const q = c.req.query("path");
|
|
11981
|
+
const q = expandHome(c.req.query("path") ?? "");
|
|
11982
|
+
if (q && !existsSync7(q))
|
|
11983
|
+
return c.json({ error: "no such folder", path: q }, 404);
|
|
11943
11984
|
let dir;
|
|
11944
11985
|
try {
|
|
11945
|
-
dir = realpathSync3(q
|
|
11986
|
+
dir = realpathSync3(q || homedir4());
|
|
11946
11987
|
} catch {
|
|
11947
11988
|
dir = homedir4();
|
|
11948
11989
|
}
|
|
@@ -11954,7 +11995,14 @@ function createApp(store = new Store, hooks2 = {}) {
|
|
|
11954
11995
|
return c.json({ error: e.message, path: dir }, 400);
|
|
11955
11996
|
}
|
|
11956
11997
|
});
|
|
11957
|
-
app.get("/v1/state", (c) =>
|
|
11998
|
+
app.get("/v1/state", (c) => {
|
|
11999
|
+
const body = JSON.stringify(store.snapshot());
|
|
12000
|
+
const etag = `W/"${Bun.hash(body).toString(36)}"`;
|
|
12001
|
+
const head = { etag, "cache-control": "no-cache" };
|
|
12002
|
+
if (c.req.header("if-none-match") === etag)
|
|
12003
|
+
return c.body(null, 304, head);
|
|
12004
|
+
return c.body(body, 200, { ...head, "content-type": "application/json" });
|
|
12005
|
+
});
|
|
11958
12006
|
app.get("/v1/stats", (c) => c.json(store.stats(c.req.query("project") || undefined)));
|
|
11959
12007
|
app.get("/v1/graphs/collisions", (c) => c.json(store.collisions(c.req.query("project") || undefined)));
|
|
11960
12008
|
app.get("/v1/graphs/lineage", (c) => c.json(store.lineage(c.req.query("project") || undefined, Math.max(1, Math.min(90, Number(c.req.query("days") ?? 14) || 14)), c.req.queries("expand") ?? [])));
|
|
@@ -11981,7 +12029,7 @@ function createApp(store = new Store, hooks2 = {}) {
|
|
|
11981
12029
|
})));
|
|
11982
12030
|
const outcomesFor = async (project, opts = {}) => {
|
|
11983
12031
|
const blocking = opts.blocking !== false;
|
|
11984
|
-
const sessions = store.
|
|
12032
|
+
const sessions = store.sessions().filter((s) => !project || s.projectId === project).map((s) => ({
|
|
11985
12033
|
id: s.id,
|
|
11986
12034
|
branch: s.branch,
|
|
11987
12035
|
model: s.model,
|
|
@@ -11992,8 +12040,9 @@ function createApp(store = new Store, hooks2 = {}) {
|
|
|
11992
12040
|
const prs = [];
|
|
11993
12041
|
const reverted = new Set;
|
|
11994
12042
|
let stale = false;
|
|
11995
|
-
|
|
11996
|
-
|
|
12043
|
+
const scope = store.liveProjects().filter((x) => !project || x.id === project);
|
|
12044
|
+
const outcomes2 = await Promise.all(scope.map(async (p) => blocking ? { ...await forge2.merged(p.id, p.root), fresh: true } : forge2.mergedCached(p.id, p.root)));
|
|
12045
|
+
for (const o of outcomes2) {
|
|
11997
12046
|
if (!o.fresh)
|
|
11998
12047
|
stale = true;
|
|
11999
12048
|
for (const m of o.merged)
|
|
@@ -12089,7 +12138,7 @@ function createApp(store = new Store, hooks2 = {}) {
|
|
|
12089
12138
|
acquiredAt: cl.acquiredAt,
|
|
12090
12139
|
state: cl.state
|
|
12091
12140
|
}));
|
|
12092
|
-
const sessions = store.
|
|
12141
|
+
const sessions = store.sessions().filter((s) => !project || s.projectId === project).map((s) => ({
|
|
12093
12142
|
id: s.id,
|
|
12094
12143
|
title: s.title,
|
|
12095
12144
|
agent: s.agent,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ra3orblade/swarm",
|
|
3
|
-
"version": "0.13.
|
|
3
|
+
"version": "0.13.1",
|
|
4
4
|
"description": "Local-first control plane for AI-agent development: watch every Claude Code / Codex / Grok session on your machine, ledger tasks and worktrees, enforce rules as hook denials.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
package/web/dashboard.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
:root{--bg:#f6f7f9;--panel:#fff;--panel-2:#f0f2f5;--line:#e4e7ec;--line-2:#eef0f3;--fg:#1a1d21;--fg-2:#3d4650;--dim:#8b929c;--faint:#aab1bb;--acc:#388114;--acc-fill:#559b1b;--acc-soft:#559b1b26;--ok:#1f9d55;--ok-soft:#1f9d551f;--warn:#c77800;--warn-soft:#c778001f;--bad:#d1352b;--bad-soft:#d1352b1f;--violet:#7857c9;--c0:#8b929c;--c1:#4d9e2a;--c2:#1b9e77;--c3:#9ab828;--c4:#2f7d4f;--c5:#7fb069;--c6:#0f5c3a;--c7:#c3d84a;--acc-1:#e2f6d8;--acc-2:#b8e4a1;--acc-3:#8bc866;--acc-4:#5aa12e;--acc-5:#35741f;--mono:ui-monospace,"SF Mono",SFMono-Regular,Menlo,monospace;--sans:-apple-system,BlinkMacSystemFont,"Segoe UI",system-ui,sans-serif;--fs-2xs:11px;--fs-xs:11.5px;--fs-sm:12px;--fs-mono:12.5px;--fs-md:13px;--fs-menu:13.5px;--fs-lg:14px;--fs-xl:15px;--fs-2xl:24px;--pill-h:calc(var(--fs-xs)*1.2 + 8px);--shadow:0 1px 2px #1018280a,0 1px 3px #1018280f;--shadow-pop:0 8px 24px #10182824,0 1px 3px #10182814;--overlay:#00000073;--r:9px;--r-sm:6px;--r-xs:4px;--r-pill:20px;--t-fast:.12s;--t-med:.2s;--t-in:.32s;--t-pulse:2s;--hdr-h:48px;--sb-w:240px;--inset-tl:96px;--acc-contrast:#fff;--pad-cell:9px 12px;--pad-page:20px 22px;--pad-ctl:7px 11px;--pad-row:7px 10px;--gap-sec:18px}@media (prefers-color-scheme:dark){:root:not([data-theme=light]){--bg:#0c0e12;--panel:#14171d;--panel-2:#1a1e26;--line:#242932;--line-2:#1e222a;--fg:#e6e9ee;--fg-2:#c2c8d0;--dim:#7c8592;--faint:#5a626e;--acc:#a3e635;--acc-fill:#a3e635;--acc-soft:#a3e63524;--ok:#3fb571;--ok-soft:#3fb57124;--warn:#d9a441;--warn-soft:#d9a44124;--bad:#f0655a;--bad-soft:#f0655a24;--violet:#a68bec;--c0:#7c8592;--c1:#6bbf3a;--c2:#2bb78f;--c3:#b0cf3a;--c4:#3f9d63;--c5:#93c47d;--c6:#2f8f5a;--c7:#d3e88a;--acc-1:#1c3311;--acc-2:#2f5a18;--acc-3:#4d8a24;--acc-4:#7cc02f;--acc-5:#bfef7a;--shadow:0 1px 2px #0000004d,0 2px 6px #00000040;--shadow-pop:0 8px 24px #00000080,0 1px 3px #0006;--acc-contrast:#0e1013}}:root[data-theme=dark]{--bg:#0c0e12;--panel:#14171d;--panel-2:#1a1e26;--line:#242932;--line-2:#1e222a;--fg:#e6e9ee;--fg-2:#c2c8d0;--dim:#7c8592;--faint:#5a626e;--acc:#a3e635;--acc-fill:#a3e635;--acc-soft:#a3e63524;--ok:#3fb571;--ok-soft:#3fb57124;--warn:#d9a441;--warn-soft:#d9a44124;--bad:#f0655a;--bad-soft:#f0655a24;--violet:#a68bec;--c0:#7c8592;--c1:#6bbf3a;--c2:#2bb78f;--c3:#b0cf3a;--c4:#3f9d63;--c5:#93c47d;--c6:#2f8f5a;--c7:#d3e88a;--acc-1:#1c3311;--acc-2:#2f5a18;--acc-3:#4d8a24;--acc-4:#7cc02f;--acc-5:#bfef7a;--shadow:0 1px 2px #0000004d,0 2px 6px #00000040;--shadow-pop:0 8px 24px #00000080,0 1px 3px #0006;--acc-contrast:#0e1013}*{box-sizing:border-box}html,body{height:100%}html{zoom:var(--ui-zoom,1)}body{background:var(--bg);color:var(--fg);font:var(--fs-lg)/1.5 var(--sans);-webkit-font-smoothing:antialiased;display:grid;grid-template-rows:var(--hdr-h)1fr;grid-template-columns:var(--sb-w)1fr;overflow:hidden;animation:appin var(--t-in)ease both;user-select:none;-webkit-user-select:none;margin:0}@keyframes appin{0%{opacity:0}to{opacity:1}}input,textarea,tbody td,.mono,code,kbd{user-select:text;-webkit-user-select:text}::selection{background:var(--acc-soft)}a{color:var(--acc);text-decoration:none}.dim{color:var(--dim)}.faint{color:var(--faint)}.mono{font-family:var(--mono);font-size:var(--fs-mono)}.num{text-align:right;font-variant-numeric:tabular-nums;font-feature-settings:"tnum"}kbd{font:var(--fs-mono)var(--mono);background:var(--panel-2);border:1px solid var(--line);border-radius:var(--r-xs);color:var(--fg-2);padding:1px 5px}code{font:var(--fs-md)var(--mono);color:var(--fg-2)}body.nosb{grid-template-columns:46px 1fr}body.nosb aside{overflow:hidden;padding:12px 5px}body.nosb #projects{display:none}#root>aside{grid-column:1;grid-row:2}#root>main{grid-column:2;grid-row:2}#projects h4{display:flex;align-items: center;gap:5px}.h4-act{cursor:pointer;color:var(--faint);display:inline-flex;border-radius:var(--r-xs);margin-left:auto;padding:2px}.h4-act:hover{color:var(--acc)}.pk-h input{background:var(--panel-2);border:1px solid var(--line);color:var(--fg);border-radius:var(--r-sm);font:var(--fs-mono)var(--mono);outline:none;flex:1;min-width:0;padding:5px 9px}.pk-h input:focus{border-color:var(--acc)}header{grid-column:1/3;display:flex;border-bottom:1px solid var(--line);background:var(--panel);z-index:5;align-items: center;gap:6px;padding:0 16px}html.chrome-inset header{padding-left:var(--inset-tl)}html.chrome-inset.fs header{padding-left:16px}html.chrome-inset header{cursor:default}header .logo{letter-spacing:.02em;font-weight:700;font-size:var(--fs-xl);display:flex;align-items: center;gap:8px;margin-right:14px}header .logo svg{image-rendering:pixelated;image-rendering:crisp-edges;width:22px;height:auto;transform:translateY(-2px)}header .nav{color:var(--dim);border-radius:var(--r-sm);transition:color var(--t-fast),background var(--t-fast);padding:6px 11px;font-weight:500}header .nav:hover{color:var(--fg-2)}header .nav.on{color:var(--fg);background:var(--panel-2)}header .sp{flex:1}header #today{color:var(--dim);font-variant-numeric:tabular-nums;margin-right:18px}header #today b{color:var(--fg-2);font-weight:600}#daemon{display:flex;color:var(--dim);font-size:var(--fs-md);align-items: center;gap:7px}#daemon .dot{background:var(--bad);transition:background var(--t-med);border-radius:50%;width:7px;height:7px}#daemon .dot.on{background:var(--ok);box-shadow:0 0 0 3px var(--ok-soft)}#root>aside{border-right:1px solid var(--line);background:var(--panel);overflow:auto;display:flex;flex-direction:column;padding:12px 10px}#viewnav{display:flex;align-items: center;gap:2px}#viewnav .navgrp{display:flex;color:var(--dim);border-radius:var(--r-sm);font:inherit;font-size:var(--fs-md);cursor:pointer;transition:color var(--t-fast),background var(--t-fast);background:0 0;border:0;align-items: center;gap:6px;padding:6px 10px;font-weight:500}#viewnav .navgrp:hover{color:var(--fg-2);background:var(--panel-2)}#viewnav .navgrp.on{color:var(--fg);background:var(--panel-2)}#viewnav .navview{color:var(--acc);font-weight:600}#viewnav .navview:before{content:"";display:inline-block;background:var(--line);width:1px;height:11px;margin:0 7px -1px}#viewnav .navgrp.open{color:var(--fg);background:var(--line)}#viewnav .navgrp.open .chev{opacity:.9;transform:rotate(180deg)}#viewnav .navgrp .chev{opacity:.5;flex:none}#viewnav .navcount{background:var(--bad-soft);color:var(--bad);font-size:var(--fs-2xs);border-radius:99px;padding:0 5px;font-weight:600}#root>aside h4{color:var(--faint);font-size:var(--fs-xs);text-transform:uppercase;letter-spacing:.09em;margin:14px 8px 6px;font-weight:600}#root>aside h4:first-child{margin-top:2px}.proj{position:relative;padding:var(--pad-row);border-radius:var(--r-sm);cursor:pointer;display:flex;color:var(--fg-2);transition:background var(--t-fast);user-select:none;align-items: center;gap:9px}.proj:hover{background:var(--panel-2)}.proj.sel{background:var(--acc-soft);color:var(--fg)}.proj.sel .nm{font-weight:600}.proj .st{background:var(--faint);transition:background var(--t-med);border-radius:50%;flex:none;width:7px;height:7px}.proj .st.live{background:var(--ok);box-shadow:0 0 0 3px var(--ok-soft)}.proj .nm{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1}.proj small{color:var(--dim);font-variant-numeric:tabular-nums;font-size:var(--fs-sm);text-align:right;flex:none;min-width:15px}.proj .act{position:absolute;right:var(--pad-row-x,7px);display:inline-flex;opacity:0;pointer-events:none;color:var(--faint);font-size:var(--fs-lg);border-radius:var(--r-xs);transition:color var(--t-fast),background var(--t-fast),opacity var(--t-fast);padding:2px;line-height:1;top:50%;transform:translateY(-50%)}.proj:hover .act,.proj.menu-open .act{opacity:1;pointer-events:auto}.proj .act:focus-visible{opacity:1;pointer-events:auto}.proj:hover small,.proj.menu-open small{visibility:hidden}.proj .act:hover{color:var(--fg);background:var(--line)}.proj .act.rm:hover{color:var(--bad)}.srch{display:flex;gap:8px;margin-bottom:14px}.srch input{background:var(--panel);border:1px solid var(--line);color:var(--fg);border-radius:var(--r-sm);font:var(--fs-md)var(--sans);flex:1;max-width:640px;padding:8px 12px}.srch input:focus{border-color:var(--acc);outline:none}.hit{border:1px solid var(--line);border-radius:var(--r-sm);background:var(--panel);margin-bottom:8px;padding:10px 12px}.hit .ht{display:flex;align-items: center;gap:8px;margin-bottom:4px}.hit .hs{font-size:var(--fs-sm);color:var(--fg-2);white-space:pre-wrap}.hit mark{background:var(--warn-soft);color:var(--fg);border-radius:2px;padding:0 1px}.dr-rules{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px 16px;margin:10px 0}.dr-rule{display:flex;font-size:var(--fs-sm);align-items: center;gap:8px}.dr-rule select{background:var(--panel-2);color:var(--fg);border:1px solid var(--line);border-radius:var(--r-sm);padding:2px 4px}.dr-flaky{border:1px solid var(--line);border-radius:var(--r-sm);background:var(--panel-2);margin:6px 0;padding:6px 8px}table.plain{border-collapse:collapse;font-size:var(--fs-sm);width:100%}table.plain td{border-top:1px solid var(--line);vertical-align:top;padding:3px 6px}.pk.pal{align-self: start;margin-top:9vh}.pal .pk-list{min-height:120px;max-height:min(440px,62vh)}.pal .pk-row.on{background:var(--acc-soft);color:var(--fg)}.pal-empty{padding:16px}.pal .pk-row .grp{color:var(--faint);font-size:var(--fs-xs);text-transform:uppercase;letter-spacing:.07em;margin-left:auto}#picker:empty{display:none}#picker{position:fixed;background:var(--overlay);display:grid;z-index:50;place-items: center;inset:0}.pk{display:flex;background:var(--panel);border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--shadow-pop);overflow:hidden;flex-direction:column;width:min(560px,92vw);max-height:78vh}.pk-h{display:flex;border-bottom:1px solid var(--line);align-items: center;gap:8px;padding:12px 14px}.pk-list{overflow:auto;padding:6px}.pk-row{display:flex;padding:var(--pad-row);border-radius:var(--r-sm);cursor:pointer;color:var(--fg-2);align-items: center;gap:9px}.pk-row:hover{background:var(--panel-2)}.pk-row .nm{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1}.pk-row.up{color:var(--dim)}.pk-row .badge{margin:0}.pk-b{display:grid;gap:10px;padding:12px 14px}.pk-b label{display:grid;font:500 var(--fs-sm)var(--sans);color:var(--dim);gap:4px}.pk-b input,.pk-b textarea,.pk-b select{background:var(--panel-2);border:1px solid var(--line);color:var(--fg);border-radius:var(--r-sm);font:var(--fs-md)var(--sans);outline:none;width:100%;padding:7px 9px}.pk-b textarea{resize:vertical;font-family:var(--mono);font-size:var(--fs-sm);min-height:120px;line-height:1.5}.pk-b input:focus,.pk-b textarea:focus,.pk-b select:focus{border-color:var(--acc)}.pk-b .row{display:grid;grid-template-columns:1fr 1fr 1fr;gap:10px}.pk.wide{width:min(960px,96vw)}.df-files{display:grid;overflow:auto;border:1px solid var(--line);border-radius:var(--r-sm);gap:1px;max-height:22vh}.df-files a{display:flex;color:var(--fg-2);text-decoration:none;font:var(--fs-sm)var(--mono);gap:10px;padding:4px 8px}.df-files a:hover,.df-files a.on{background:var(--panel-2);color:var(--fg)}.df-files .st{color:var(--dim);width:12px}.df-files .pl{color:var(--ok)}.df-files .mi{color:var(--warn)}.df-files .pa{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1}.df-patch{overflow:auto;background:var(--panel-2);border:1px solid var(--line);border-radius:var(--r-sm);font:var(--fs-sm)var(--mono);white-space:pre;max-height:44vh;margin:0;padding:8px 10px;line-height:1.45}.df-patch .a{color:var(--ok)}.df-patch .d{color:var(--warn)}.df-patch .h{color:var(--acc)}.df-patch .m{color:var(--dim)}.wn .pk-b{overflow:auto;gap:2px;max-height:64vh}.wn h3{font:600 var(--fs-lg)var(--sans);color:var(--fg);margin:0 0 2px}.wn .date{color:var(--dim);font-size:var(--fs-sm);margin-bottom:12px}.wn h4{font:600 var(--fs-md)var(--sans);color:var(--acc);text-transform:none;letter-spacing:0;margin:14px 0 4px}.wn ul{margin:0 0 6px;padding-left:18px}.wn li{color:var(--fg-2);margin:5px 0;line-height:1.55}.wn p{color:var(--fg-2);margin:0 0 10px;line-height:1.6}.wn code{font-family:var(--mono);font-size:var(--fs-sm);background:var(--panel-2);border-radius:var(--r-xs);padding:1px 5px}.wn a{color:var(--acc)}.wn b{color:var(--fg)}.wn .snip{background:var(--panel-2);border:1px solid var(--line);border-radius:var(--r-sm);font-family:var(--mono);font-size:var(--fs-sm);white-space:pre-wrap;word-break:break-word;color:var(--fg-2);margin:2px 0 12px;padding:9px 11px;line-height:1.5}.wn .cbtn{font-weight:500;font-size:var(--fs-sm);color:var(--acc);margin-left:8px}.rp{height:78vh}.rp .pk-b{overflow:auto;flex:1;gap:2px;min-height:0;max-height:none}.rp .snip{overflow:visible;max-height:none}.rp .pk-f input[type=range]{accent-color:var(--acc)}.perm{background:var(--warn-soft);border:1px solid var(--warn);border-radius:var(--r-sm);margin-top:10px;padding:10px 12px}.perm-t{font:500 var(--fs-md)var(--sans);color:var(--fg)}.perm-c{font-family:var(--mono);font-size:var(--fs-sm);color:var(--fg-2);word-break:break-all;background:var(--panel-2);border-radius:var(--r-xs);margin:6px 0 8px;padding:6px 8px}.perm-b{display:flex;gap:8px}.perm-b .ok{color:var(--acc);border-color:var(--acc-soft)}.perm-b .danger{color:var(--warn);border-color:var(--warn-soft)}.stdin{display:flex;align-items: center;gap:8px;margin-top:10px}.stdin input{background:var(--panel-2);border:1px solid var(--line);color:var(--fg);border-radius:var(--r-sm);font:var(--fs-md)var(--sans);outline:none;flex:1;padding:8px 10px}.stdin input:focus{border-color:var(--acc)}.stdin button.danger{color:var(--warn);border-color:var(--warn-soft)}.stdin .hint{color:var(--dim);font-size:var(--fs-sm)}.pk-f{display:flex;border-top:1px solid var(--line);gap:8px;padding:12px 14px}.pk-f button{flex:none}.grow{flex:1}.pk-f .primary{background:var(--acc);border-color:var(--acc);color:var(--acc-contrast)}.pk-f .primary:hover{filter:brightness(1.06);color:var(--acc-contrast)}.proj .nm .pdir{opacity:.5;font-weight:400}.proj[draggable]{cursor:grab}.proj.dragging{opacity:.35;background:var(--panel-2);outline:1px dashed var(--acc)}button{background:var(--panel);border:1px solid var(--line);color:var(--fg-2);padding:var(--pad-ctl);border-radius:var(--r-sm);font:600 var(--fs-md)var(--sans);cursor:pointer;transition:border-color var(--t-fast),color var(--t-fast);display:inline-flex;justify-content:center;align-items: center;gap:6px;line-height:1}.pk-h button{padding:6px;line-height:0}button:hover{border-color:var(--acc);color:var(--fg)}main{overflow:auto;padding:var(--pad-page)}h2.hrow{display:flex;flex-wrap:wrap;align-items: center;gap:7px}h2.hrow .s{margin:0}h2{font-size:var(--fs-md);color:var(--dim);text-transform:uppercase;letter-spacing:.07em;display:flex;align-items:baseline;gap:10px;margin:0 0 12px;font-weight:600}h2 span{text-transform:none;letter-spacing:0;color:var(--faint);font-weight:500;font-size:var(--fs-md)}h2 .nav{display:inline-flex;font:500 var(--fs-md)var(--sans);text-transform:none;letter-spacing:0;color:var(--acc);text-decoration:none;border-radius:var(--r-sm);transition:background var(--t-fast);align-items: center;gap:5px;padding:2px 8px}h2 .nav:hover,h2 .nav.on{background:var(--acc-soft)}h2 .nav .ph{display:block}h2 .back{color:var(--fg-2);text-transform:none;letter-spacing:0;font-weight:600;font-size:var(--fs-md);display:inline-flex;border:1px solid var(--line);border-radius:var(--r-pill);background:var(--panel);transition:border-color var(--t-fast),color var(--t-fast);align-items: center;gap:5px;padding:5px 11px 5px 8px}.card{background:var(--panel);border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--shadow);overflow-x:auto}table{border-collapse:collapse;table-layout:fixed;width:100%}.card table{background:var(--panel)}thead th{text-align:left;padding:var(--pad-cell);color:var(--dim);font-weight:500;font-size:var(--fs-sm);border-bottom:1px solid var(--line);background:var(--panel-2);white-space:nowrap}tbody td{padding:var(--pad-cell);border-bottom:1px solid var(--line-2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;vertical-align:middle}tbody tr:last-child td{border-bottom:0}tbody td.td-tools{text-overflow:clip;text-align:center;padding-left:0;padding-right:0;line-height:0}tbody td.td-badge{text-overflow:clip}tbody td.td-badge .badge{margin-right:0}tbody tr{transition:background var(--t-fast)}tbody tr[data-s]{cursor:pointer}tbody tr:hover{background:var(--panel-2)}tbody td.td-lead{overflow:visible}tbody td{--cap:calc(var(--fs-lg)*.352)}tbody td .pg{vertical-align:calc(var(--cap) - 8px)}tbody td .pg:before{content:"";display:block;width:0;height:16px}tbody td>*+.badge{vertical-align:calc(var(--cap) - var(--pill-h)/2)}tbody td:not(.td-tools)>svg.ph[width="12"]{vertical-align:calc(var(--cap) - 6px)}tbody td:not(.td-tools)>svg.ph[width="13"]{vertical-align:calc(var(--cap) - 6.5px)}tbody td:not(.td-tools)>svg.ph[width="14"]{vertical-align:calc(var(--cap) - 7px)}tbody td:not(.td-tools)>svg.ph[width="16"]{vertical-align:calc(var(--cap) - 8px)}.dt thead th{position:relative;user-select:none;-webkit-user-select:none}.dt thead tr:first-child th[data-col]:not(:last-child):after{content:"";position:absolute;border-right:1px solid var(--line);height:50%;top:25%;right:0}.dt thead th[data-sort]{cursor:pointer}.dt thead th[data-sort]:hover{color:var(--fg-2)}.dt thead th.dragging{opacity:.4}.dt .th-l{display:inline-flex;align-items: center;gap:5px}.dt th.num .th-l{justify-content:flex-end;width:100%}.dt .sort{display:inline-block;border-left:4px solid #0000;border-right:4px solid #0000;width:0;height:0}.dt .sort.asc{border-bottom:5px solid var(--acc)}.dt .sort.desc{border-top:5px solid var(--acc)}.dt .th-grip{position:absolute;cursor:col-resize;z-index:2;width:9px;height:100%;top:0;right:-4px}.dt .th-grip:hover{background:linear-gradient(to right,transparent 3px,var(--acc)3px,var(--acc)5px,transparent 5px)}.dt thead th:last-child .th-grip{right:0}.dt thead th:last-child .th-grip:hover{background:linear-gradient(to left,var(--acc)0,var(--acc)2px,transparent 2px)}body.col-resizing,body.col-resizing .dt thead th{cursor:col-resize}.dt .th-tools{text-align:right}.dt .th-tools,.dt .td-tools{position:sticky;z-index:1;right:0}.dt .th-tools{background:var(--panel-2)}.dt .td-tools{background:var(--panel)}tbody tr:hover .td-tools{background:var(--panel-2)}.dt .th-cols{cursor:pointer;color:var(--faint);display:inline-flex}.dt .th-cols:hover{color:var(--fg-2)}.dt tr.filters th{background:var(--panel);padding:4px 8px}.dt tr.filters input{background:var(--panel-2);border:1px solid var(--line);color:var(--fg);border-radius:var(--r-sm);font:var(--fs-sm)var(--mono);outline:none;width:100%;padding:3px 7px}.dt tr.filters input:focus{border-color:var(--acc)}.dt .tbl-empty td{color:var(--dim);text-align:center;cursor:default;padding:18px}td b{color:var(--fg);font-weight:600}td.now,.br{font-family:var(--mono);font-size:var(--fs-mono);color:var(--fg-2)}.br+.badge{margin-left:6px}td.now{color:var(--dim)}td a{color:var(--acc)}.num,th.num{text-align:right}.s{display:inline-block;background:var(--faint);border-radius:50%;flex:none;width:8px;height:8px}.s.active{background:var(--ok);box-shadow:0 0 0 3px var(--ok-soft);animation:pulse var(--t-pulse)ease-in-out infinite}.s.waiting{background:var(--warn);box-shadow:0 0 0 3px var(--warn-soft)}.s.idle{background:var(--faint)}.s.ended{background:var(--line);border:1px solid var(--faint);box-shadow:none}@keyframes pulse{0%,to{box-shadow:0 0 0 3px var(--ok-soft)}50%{box-shadow:0 0 0 5px #0000}}.badge{display:inline-block;font:500 var(--fs-xs)/1.2 var(--sans);border-radius:var(--r-pill);background:var(--panel-2);color:var(--dim);vertical-align:middle;margin-right:4px;padding:4px 8px}.badge.warn{color:var(--warn);background:var(--warn-soft)}.badge.acc{color:var(--acc);background:var(--acc-soft)}.badge.ok{color:var(--ok);background:var(--ok-soft)}.badge.bad{color:var(--bad);background:var(--bad-soft)}.badge.agent{color:var(--violet);background:color-mix(in srgb,var(--violet)14%,transparent);font-weight:600}.err-h{color:var(--bad);align-items: center}.err-h .err-ic{color:var(--bad);flex:none}.err-card{border:1px solid var(--bad);max-width:760px;padding:18px}.err-detail{background:var(--panel-2);border-radius:var(--r-sm);font:var(--fs-mono)/1.5 var(--mono);color:var(--fg-2);white-space:pre-wrap;overflow-x:auto;border:0;max-height:220px;margin:0;padding:10px 12px}.clusters{list-style:none;margin:0;padding:0}.clusters li{display:grid;grid-template-columns:minmax(0,13em)3.2em minmax(0,1fr);border-bottom:1px solid var(--line-2);font-size:var(--fs-md);align-items: center;gap:10px;padding:6px 0}.clusters li:last-child{border-bottom:0}.clusters li>*{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0}.clusters li b{font-family:var(--mono);font-size:var(--fs-mono);color:var(--fg)}.clusters li .n{color:var(--fg-2);text-align:right;font-variant-numeric:tabular-nums}.clusters li>span:last-child{color:var(--dim);font-family:var(--mono);font-size:var(--fs-mono)}.plainlist{list-style:none;display:flex;flex-direction:column;gap:6px;margin:0;padding:0}.plainlist li{display:flex;font-size:var(--fs-md);color:var(--fg-2);border-bottom:1px solid var(--line-2);align-items: center;gap:8px;padding:5px 0}.plainlist li:last-child{border-bottom:0}.plainlist li b{font-family:var(--mono);font-size:var(--fs-mono);color:var(--fg);font-weight:600}td.path,span.path{font-family:var(--mono);font-size:var(--fs-mono)}td.path b,span.path b{color:var(--fg);font-weight:600}td.path .dim,span.path .dim{font-size:var(--fs-xs)}.heatlist{list-style:none;display:flex;flex-direction:column;gap:2px;margin:0;padding:0}.heatlist li{position:relative;display:flex;font-size:var(--fs-md);color:var(--fg-2);border-radius:var(--r-sm);overflow:hidden;align-items: center;gap:10px;padding:6px 10px}.heatlist li .bar{position:absolute;width:var(--w);background:var(--acc-soft);border-radius:var(--r-sm);inset:0 auto 0 0}.heatlist li>span.clip{position:relative;font-family:var(--mono);font-size:var(--fs-mono);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;flex:1;min-width:0}.heatlist li b{position:relative;font-variant-numeric:tabular-nums;color:var(--fg)}.heatlist li .dim{position:relative;font-size:var(--fs-sm);white-space:nowrap}.empty{color:var(--dim);text-align:center;border:1px dashed var(--line);border-radius:var(--r);background:var(--panel);padding:44px 24px;line-height:1.7}.sess{display:grid;grid-template-columns:1fr 1fr;align-items:stretch;gap:16px}.sess>*{height:calc(100vh - 140px);min-height:320px}.sess.has-stdin>*{height:calc(100vh - 196px)}@media (max-width:980px){.sess{grid-template-columns:1fr}.sess>*{height:auto;max-height:calc(100vh - 140px)}}#log{background:var(--panel);border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--shadow);overflow:auto;padding:6px 0}.ev{display:grid;grid-template-columns:56px 54px 1fr;align-items:baseline;gap:10px;padding:5px 14px}.ev:hover{background:var(--panel-2)}.ev .t{color:var(--faint);font:var(--fs-sm)var(--mono)}.ev .k{color:var(--dim);font:500 var(--fs-sm)var(--mono);text-transform:lowercase;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ev .m{white-space:pre-wrap;word-break:break-word;color:var(--fg-2);font-size:var(--fs-menu)}.ev.assistant .k{color:var(--violet)}.ev.assistant .m{color:var(--fg)}.ev.tool\.requested .k{color:var(--acc)}.ev.tool\.requested .m{color:var(--dim);font-family:var(--mono);font-size:var(--fs-mono)}.ev.incident\.opened .k,.ev.incident\.opened .m{color:var(--warn)}.ev.session\.ended .k{color:var(--bad)}.ev.prompt\.submitted .k{color:var(--ok)}.ev.prompt\.submitted .m{color:var(--fg);font-weight:500}.side{background:var(--panel);border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--shadow);overflow:auto;padding:14px 18px}.side .stats{display:grid;grid-template-columns:1fr 1fr;gap:0 28px}.stat{display:flex;border-bottom:1px solid var(--line-2);justify-content:space-between;align-items:baseline;padding:7px 0}.stat:last-of-type{border-bottom:0}.stat span{color:var(--dim)}.stat b{font-variant-numeric:tabular-nums;font-weight:600}.stat small{color:var(--faint);font-weight:400}.side h4{color:var(--faint);font-size:var(--fs-xs);text-transform:uppercase;letter-spacing:.08em;margin:16px 0 6px;font-weight:600}table.mini{table-layout:fixed;border:0;width:100%}table.mini td{font-size:var(--fs-md);vertical-align:middle;border:0;padding:6px 0}table.mini th{vertical-align:middle;padding-top:6px;padding-bottom:6px}table.mini th+th,table.mini td+td{padding-left:14px}table.mini td:first-child{color:var(--fg-2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}table.mini td.num{color:var(--dim);width:34px}table.mini td.clip{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.bars{display:flex;background:var(--panel);border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--shadow);margin-bottom:var(--gap-sec);align-items: flex-end;gap:5px;height:110px;padding:14px 16px 26px}.bar{position:relative;display:flex;flex:1;align-items: flex-end;min-width:0;height:100%}.bar>div{background:linear-gradient(180deg,var(--acc),color-mix(in srgb,var(--acc)70%,transparent));border-radius:var(--r-xs)var(--r-xs)0 0;transition:opacity var(--t-fast);width:100%;min-height:2px}.bar:hover>div{opacity:.75}.bar span{position:absolute;text-align:center;font:var(--fs-2xs)var(--mono);color:var(--faint);bottom:-20px;left:0;right:0}.cols{display:grid;grid-template-columns:1fr 1fr;gap:var(--gap-sec);align-items: start}.chart{display:block;overflow:visible;width:100%}.chart .grid{stroke:var(--line-2);stroke-width:1;vector-effect:non-scaling-stroke}.chart .base{stroke:var(--line);stroke-width:1;vector-effect:non-scaling-stroke}.chart .ax{fill:var(--faint);font:var(--fs-2xs)var(--mono);text-anchor:start}.chart .ax.mid{text-anchor:middle}.chart .col:hover path{filter:brightness(1.12)}.chart-card{background:var(--panel);border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--shadow);margin-bottom:var(--gap-sec);padding:14px 16px 10px}.chart-card h3{font-size:var(--fs-md);color:var(--fg-2);display:flex;align-items:baseline;gap:10px;margin:0 0 10px;font-weight:600}.chart-card h3 span{color:var(--faint);font-weight:400}.legend{display:flex;font-size:var(--fs-mono);color:var(--fg-2);flex-wrap:wrap;gap:4px 14px;margin:8px 0 0}.legend span{display:inline-flex;align-items: center;gap:6px}.legend i{display:inline-block;border-radius:2px;width:9px;height:9px}.legend em{color:var(--dim);font-variant-numeric:tabular-nums;font-style:normal}.legend.small{font-size:var(--fs-sm);margin-top:6px}#tip{position:fixed;display:none;z-index:50;pointer-events:none;background:var(--fg);color:var(--bg);border-radius:var(--r-sm);font:var(--fs-mono)/1.5 var(--sans);box-shadow:var(--shadow-pop);font-variant-numeric:tabular-nums;max-width:280px;padding:7px 10px;top:0;left:0}#tip b{font-weight:600}#tip span{opacity:.7}#tip i{display:inline-block;border-radius:2px;width:8px;height:8px;margin-right:6px}.spark{display:block;overflow:visible;width:88px;height:20px}.spark path{fill:none;stroke-width:1.5;vector-effect:non-scaling-stroke;stroke-linejoin:round}.comp{display:flex;border-radius:var(--r-xs);overflow:hidden;gap:2px;height:12px;margin-top:4px}.comp i{display:block;transition:filter var(--t-fast);min-width:2px}.comp i:hover{filter:brightness(1.15)}.hbars{display:flex;flex-direction:column;gap:4px}.hb{display:grid;grid-template-columns:minmax(0,120px)1fr auto;font-size:var(--fs-md);align-items: center;gap:8px}.hb .k{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--fg-2)}.hb .t{background:var(--panel-2);overflow:hidden;border-radius:3px;height:8px}.hb .t i{display:block;border-radius:3px;min-width:2px;height:100%}.hb .n{text-align:right;white-space:nowrap;color:var(--dim);font-variant-numeric:tabular-nums;font-size:var(--fs-mono)}.cal{position:relative;padding-top:16px}.cal-months{position:absolute;height:14px;top:0;left:0;right:0}.cal-months span{position:absolute;font:var(--fs-2xs)var(--mono);color:var(--faint)}.cal-grid{display:grid;gap:2px}.cal-col{display:grid;grid-template-rows:repeat(7,1fr);aspect-ratio:1/7;gap:2px}.cal-col i{display:block;background:var(--acc);outline:1px solid var(--line-2);outline-offset:-1px;border-radius:2px}.cal-col i:hover{outline-color:var(--fg)}.chart.line .pt circle{opacity:0}.chart.line .pt:hover circle{opacity:1}.records{display:grid;grid-template-columns:1fr 1fr;gap:12px}.rec{background:var(--panel);border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--shadow);display:flex;flex-direction:column;gap:2px;padding:10px 14px}.rec .l{font-size:var(--fs-sm);color:var(--dim);text-transform:uppercase;letter-spacing:.06em;font-weight:600}.rec .v{font-size:var(--fs-lg);color:var(--fg);font-variant-numeric:tabular-nums;font-weight:600}.rec .d{font-size:var(--fs-mono);color:var(--faint);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.hm{display:grid;grid-template-columns:34px 1fr;align-items: center;gap:3px 8px}.hm-lbl{font:var(--fs-xs)var(--mono);color:var(--faint)}.hm-row{display:grid;grid-template-columns:repeat(24,1fr);gap:2px;height:16px}.hm-row i{display:block;background:var(--acc);outline:1px solid var(--line-2);outline-offset:-1px;border-radius:2px}.hm-row i:hover{outline-color:var(--fg)}.hm-hours{position:relative;font:var(--fs-2xs)var(--mono);color:var(--faint);height:14px}.hm-hours span{position:absolute;top:0}.tl{background:var(--panel);border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--shadow);padding:8px 16px 12px}.tl-row{display:grid;grid-template-columns:200px 1fr;cursor:pointer;border-radius:var(--r-xs);align-items: center;gap:12px;height:24px}.tl-row.claimlane{cursor:default}.tl-row:hover{background:var(--panel-2)}.tl-row.head{cursor:default;position:sticky;background:var(--panel);z-index:2;height:22px;margin-bottom:4px;top:-20px}.tl-row.head:hover{background:var(--panel)}.tl-name{font-size:var(--fs-md);color:var(--fg-2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding-left:10px}.tl-track{position:relative;height:100%}.tl-track>i{position:absolute;opacity:.9;border-radius:3px;min-width:3px;height:12px;top:6px}.tl-track>i.live{box-shadow:0 0 0 2px var(--panel),0 0 0 3px currentColor;animation:none}.tl-track>i:hover{opacity:1;filter:brightness(1.1)}.tl-track>i:not([data-tip]){background:var(--line-2);opacity:1;pointer-events:none;border-radius:0;width:1px;min-width:0;height:100%;top:0}.tl-axis{position:absolute;font:var(--fs-2xs)var(--mono);color:var(--faint);inset:0}.tl-axis span{position:absolute;top:3px;transform:translate(-50%)}.tl-now{position:absolute;background:var(--bad);z-index:1;pointer-events:none;width:1px;top:0;bottom:-2000px}.tl-group{position:relative;border-top:1px solid var(--line-2);margin-top:6px;padding-top:4px}.tl-proj{font-size:var(--fs-sm);color:var(--dim);text-transform:uppercase;letter-spacing:.06em;padding:4px 10px 2px;font-weight:600}.tl-proj small{text-transform:none;letter-spacing:0;color:var(--faint);margin-left:8px;font-weight:400}.tl,.tl-group{overflow:hidden}.sw{display:inline-block;vertical-align:baseline;border-radius:2px;width:9px;height:9px;margin-right:7px}.kpis{display:grid;grid-template-columns:repeat(4,1fr);margin-bottom:var(--gap-sec);gap:12px}.kpi{background:var(--panel);border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--shadow);padding:12px 14px}.kpi .l{font-size:var(--fs-sm);color:var(--dim);text-transform:uppercase;letter-spacing:.06em;font-weight:600}.kpi .v{font-size:var(--fs-2xl);font-variant-numeric:tabular-nums;color:var(--fg);margin-top:2px;font-weight:600}.kpi .d{font-size:var(--fs-mono);color:var(--faint)}.ph{display:inline-block;vertical-align:-.09em;flex:none}header .nav{display:inline-flex;align-items: center;gap:6px}.navcount{display:inline-block;font:500 var(--fs-xs)var(--sans);text-transform:none;letter-spacing:0;color:var(--warn);background:var(--warn-soft);border-radius:var(--r-pill);padding:4px 8px;line-height:1.2}header .nav .ph{opacity:.75}header .nav.on .ph{opacity:1;color:var(--acc)}.icon-btn{display:inline-flex;border-radius:var(--r-sm);color:var(--dim);background:0 0;border:1px solid #0000;justify-content:center;align-items: center;width:28px;height:28px;padding:0}.icon-btn:hover{background:var(--panel-2);color:var(--fg);border-color:#0000}.icon-btn.on{background:var(--panel-2);color:var(--fg)}header #settings{margin-left:10px}.proj .ph{color:var(--faint)}.proj.sel .ph{color:var(--acc)}.kind{color:var(--faint);margin-right:6px}td .more{opacity:0;color:var(--faint);border-radius:var(--r-xs);transition:opacity var(--t-fast),background var(--t-fast);display:inline-flex;vertical-align:middle;padding:2px;line-height:0}tr:hover td .more,.proj:hover .more,tr.menu-open td .more,.menu-open>.more,.more.menu-open{opacity:1}td .more:hover{background:var(--line);color:var(--fg)}.mini-act{display:inline-flex;color:var(--fg-2);border:1px solid var(--line);border-radius:var(--r-sm);font-size:var(--fs-sm);text-decoration:none;transition:color var(--t-fast),border-color var(--t-fast);align-items: center;padding:2px 9px;font-weight:500}.mini-act:hover{color:var(--acc);border-color:var(--acc)}.mini-act.bad:hover{color:var(--bad);border-color:var(--bad)}.track{display:inline-flex;align-items: center;gap:3px}.track i{background:var(--line);border:1px solid var(--line-2);border-radius:50%;width:7px;height:7px}.track i.on{background:var(--acc);border-color:var(--acc)}.chip.off{opacity:.4;pointer-events:none}.stat .ph{color:var(--faint);margin-right:7px}.empty .ph{display:block;color:var(--faint);margin:0 auto 10px}.empty .px{display:block;image-rendering:pixelated;margin:0 auto 14px}h2 .back:hover{border-color:var(--acc);color:var(--fg)}:root{--fm-surface-bg:var(--panel);--fm-surface-fg:var(--fg);--fm-surface-border:var(--line);--fm-surface-radius:var(--r);--fm-surface-shadow:var(--shadow-pop);--fm-accent:var(--acc);--fm-accent-fg:var(--acc-contrast);--fm-destructive:var(--bad);--fm-muted-fg:var(--dim);--fm-divider-color:var(--line-2);--fm-row-hover-bg:var(--panel-2);--fm-row-active-bg:var(--panel-2);--fm-row-active-fg:var(--fg);--fm-font-size-row:var(--fs-menu);--fm-font-size-caption:var(--fs-sm);--fm-font-size-section:var(--fs-xs);--fm-row-min-h:30px;--fm-row-radius:var(--r-sm)}.fm-row--danger,.fm-row--danger .fm-row__icon{color:var(--bad)}.fm-row--danger:hover{background:var(--bad-soft)}.fm-row[data-pressed=true]{background:var(--acc-soft);color:var(--acc);position:relative;font-weight:600}.fm-row[data-pressed=true]:before{content:"";position:absolute;border-radius:0 var(--r-xs)var(--r-xs)0;background:var(--acc);width:3px;height:58%;top:50%;left:0;transform:translateY(-50%)}.fm-row[data-pressed=true] .fm-ico{color:var(--acc)}.fm-row__icon,.fm-ico{display:inline-flex;justify-content:center;align-items: center}.fm-row__name{flex:auto;min-width:0}.fm-row__caption{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:0 auto;min-width:0;max-width:45%;margin-left:auto}.fm-ico .ph{vertical-align:0}main>h2:not(:first-child),.mt-sec{margin-top:var(--gap-sec)}.pg{display:inline-flex;font-size:var(--fs-md);color:var(--dim);overflow:visible;flex:none;justify-content:center;align-items: center;width:16px;height:16px;line-height:1}.pg-c1{color:var(--c1)}.pg-c2{color:var(--c2)}.pg-c3{color:var(--c3)}.pg-c4{color:var(--c4)}.pg-c5{color:var(--c5)}.pg-c6{color:var(--c6)}.pg-c7{color:var(--c7)}.pg-img{object-fit:cover;border-radius:var(--r-xs);display:block;width:16px;height:16px}.pg-lg{font-size:var(--fs-2xl);border:1px solid var(--line);border-radius:var(--r-sm);background:var(--panel-2);overflow:hidden;width:34px;height:34px;line-height:1}.pg-lg .pg-img{border-radius:0;width:34px;height:34px}.icon-row{display:flex;align-items: center;gap:8px}.icon-row input{flex:1}.icon-row .btn{display:inline-flex;padding:var(--pad-ctl);border:1px solid var(--line);border-radius:var(--r-sm);background:var(--panel-2);color:var(--fg-2);cursor:pointer;font:500 var(--fs-sm)var(--sans);white-space:nowrap;align-items: center;gap:5px}.icon-row .btn:hover{border-color:var(--acc)}.emoji-row{display:flex;flex-wrap:wrap;gap:4px}.emoji-all{overflow:auto;border:1px solid var(--line);border-radius:var(--r-sm);display:grid;gap:6px;max-height:200px;padding:8px}.emoji-sec{font-size:var(--fs-2xs);color:var(--dim);text-transform:uppercase;letter-spacing:.06em;margin-top:4px;font-weight:600}.more-emoji{color:var(--fg-2);font-weight:700}.emoji{display:inline-flex;border:1px solid var(--line);border-radius:var(--r-sm);cursor:pointer;font-size:var(--fs-xl);background:var(--panel-2);color:var(--dim);overflow:hidden;justify-content:center;align-items: center;width:34px;height:34px;line-height:1}.emoji .ph{width:14px;height:14px}.emoji:hover{border-color:var(--acc)}.emoji.on{border-color:var(--acc);background:var(--acc-soft)}.swatches{display:flex;gap:6px}.swatch{cursor:pointer;box-shadow:inset 0 0 0 2px var(--panel);background:currentColor;border:2px solid #0000;border-radius:50%;width:22px;height:22px}.swatch.none{background:var(--panel-2);color:var(--line);box-shadow:inset 0 0 0 1px var(--line)}.swatch:hover{border-color:var(--fg-2)}.swatch.on{border-color:var(--fg)}.pk-b label.chk{display:flex;flex-direction:row;align-items: center;gap:8px}.pk-b label.chk input{width:auto}.kpis-5{grid-template-columns:repeat(auto-fit,minmax(160px,1fr))}.kpi.hot .v{color:var(--warn)}.kpi.warm .v{color:var(--acc)}.grow{flex:1}.kanban{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));margin-bottom:var(--gap-sec);align-items: start;gap:12px}.lane{background:var(--panel-2);border:1px solid var(--line);border-radius:var(--r);display:flex;flex-direction:column;gap:8px;min-height:60px;padding:8px}.lane-h{font-size:var(--fs-sm);color:var(--dim);text-transform:uppercase;letter-spacing:.06em;padding:2px 4px;font-weight:600}.lane-h span{color:var(--faint);font-weight:500}.lane-empty{color:var(--faint);text-align:center;padding:10px 0}.lane-more{font-size:var(--fs-xs);padding:2px 4px}.tcard{background:var(--panel);border:1px solid var(--line);border-radius:var(--r-sm);box-shadow:var(--shadow);cursor:pointer;transition:border-color var(--t-fast);padding:8px 10px}.tcard:hover{border-color:var(--acc);outline:none}.tcard:focus-visible{border-color:var(--acc);outline:none}.wt:focus-visible{border-color:var(--acc);outline:none}.more:focus-visible{border-color:var(--acc);outline:none}.more:focus-visible{opacity:1}.tcard.ready{border-color:var(--ok)}.tcard.held{border-color:var(--acc)}.tcard.blocked{border-color:var(--line)}.tcard.done{opacity:.7}.tc-h{display:flex;font-size:var(--fs-sm);align-items: center;gap:8px;margin-bottom:3px}.tc-h .dim{font-family:var(--mono);font-size:var(--fs-2xs);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.tc-t{font-size:var(--fs-md);color:var(--fg);display:-webkit-box;-webkit-line-clamp:3;overflow:hidden;-webkit-box-orient:vertical;line-height:1.35}.tc-m{font-size:var(--fs-xs);color:var(--faint);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-top:4px}.tc-g{margin-top:6px}.wtmap{display:flex;margin-bottom:var(--gap-sec);flex-direction:column;gap:14px}.wt-proj{font-size:var(--fs-sm);color:var(--dim);text-transform:uppercase;letter-spacing:.06em;margin-bottom:6px;font-weight:600}.wt-proj span{color:var(--faint);font-weight:500}.wt-tiles{display:grid;grid-template-columns:repeat(auto-fill,minmax(210px,1fr));gap:8px}.wt{background:var(--panel);border:1px solid var(--line);border-radius:var(--r-sm);box-shadow:var(--shadow);cursor:pointer;transition:border-color var(--t-fast);min-width:0;padding:8px 10px}.wt:hover{border-color:var(--acc)}.wt.main{background:var(--panel-2)}.wt.live{border-color:var(--ok)}.wt.dirty{border-color:var(--warn)}.wt.merged{opacity:.6}.wt-b{display:flex;align-items: center;gap:6px;min-width:0}.wt-b .s{flex:none;margin:0}.wt-b .br{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.wt-m{font-size:var(--fs-xs);color:var(--faint);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-top:3px}.wt-m i{font-style:normal}.wt-m i.warn{color:var(--warn)}.wt-m i.acc{color:var(--acc)}.chips{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:14px}.chip{display:inline-flex;font:500 var(--fs-md)var(--sans);border-radius:var(--r-pill);background:var(--panel);border:1px solid var(--line);color:var(--dim);cursor:pointer;user-select:none;align-items: center;gap:5px;padding:4px 11px}.chip:hover{border-color:var(--acc);color:var(--fg-2)}.chip.on{background:var(--acc-soft);color:var(--acc);border-color:#0000}.seg{display:inline-flex;background:var(--panel-2);border:1px solid var(--line);border-radius:var(--r-sm);gap:2px;padding:2px}.seg a{border-radius:var(--r-sm);font:600 var(--fs-md)var(--sans);color:var(--dim);text-decoration:none;transition:color var(--t-fast),background var(--t-fast);letter-spacing:0;text-transform:none;padding:3px 10px}.seg a:hover{color:var(--fg-2)}.seg a.on{background:var(--acc-soft);color:var(--acc)}.chip b{font-weight:700}.wf-steps{display:inline-flex;flex-wrap:wrap;gap:6px}.wfs{font:500 var(--fs-sm)var(--sans);color:var(--dim);background:var(--panel-2);border:1px solid var(--line);border-radius:var(--r-pill);white-space:nowrap;padding:1px 8px}.wfs.ok{color:var(--ok);background:var(--ok-soft);border-color:#0000}.wfs.run{color:var(--acc);background:var(--acc-soft);border-color:#0000}.wfs.bad{color:var(--warn);background:var(--warn-soft);border-color:#0000}.tl-track u{position:absolute;opacity:.95;border-radius:1px;width:2px;top:4px;bottom:4px}.tl-track i.thin{opacity:.25}.tl-row.claimlane .tl-name{font-size:var(--fs-2xs);text-transform:uppercase;letter-spacing:.06em}.tl-track i.claim{background:var(--violet);opacity:.6;border-radius:2px;height:4px;top:7px}.tl-track i.claim.orphaned{background:var(--warn);opacity:.9}.tl-track i.claim.expired{background:var(--faint)}.proj-spark{display:inline-flex;opacity:.7;flex:none;width:44px}.proj-spark .spark{width:44px;height:14px}.gh-strip{display:inline-flex;gap:12px;font-weight:400}.gh{font-size:var(--fs-sm);color:var(--dim);display:inline-flex;align-items: center;gap:3px}.gh i{display:inline-block;border-radius:2px;width:7px;height:7px}.gh i.ok{background:var(--ok)}.gh i.bad{background:var(--warn)}.msgs{display:flex;overflow:auto;flex-direction:column;gap:6px;max-height:220px;margin-bottom:8px}.msg{background:var(--panel-2);border:1px solid var(--line);border-radius:var(--r-sm);font-size:var(--fs-md);color:var(--fg-2);word-break:break-word;padding:6px 9px}.msg.out{background:var(--acc-soft);border-color:#0000}.msg-f{display:block;font-size:var(--fs-2xs);color:var(--dim);margin-bottom:2px}.msg-compose{display:flex;gap:6px}.msg-compose input{background:var(--panel-2);border:1px solid var(--line);color:var(--fg);border-radius:var(--r-sm);font:400 var(--fs-md)var(--sans);flex:1;min-width:0;padding:7px 10px}.msg-compose input:focus{border-color:var(--acc);outline:none}.msg-compose button{display:inline-flex;background:var(--panel-2);border:1px solid var(--line);color:var(--fg-2);border-radius:var(--r-sm);cursor:pointer;font:500 var(--fs-sm)var(--sans);flex:none;align-items: center;gap:5px;padding:7px 11px}.msg-compose button:hover{color:var(--acc);border-color:var(--acc)}.msg-compose input:disabled,.msg-compose button:disabled{opacity:.45;cursor:not-allowed}.msg-compose button:disabled:hover{color:var(--fg-2);border-color:var(--line)}.msg-hint{display:flex;color:var(--dim);font-size:var(--fs-sm);align-items: center;gap:5px;margin:7px 0 0;line-height:1.4}.msg-hint .ph{color:var(--faint);flex:none}.msg-hint b{color:var(--fg-2);font-weight:600}.pathrow{display:flex;text-align:left;cursor:pointer;background:var(--panel-2);border:1px solid var(--line);border-radius:var(--r-sm);color:var(--fg-2);font:400 var(--fs-sm)var(--mono);align-items: center;gap:6px;width:100%;padding:6px 9px}.pathrow:hover{border-color:var(--acc);color:var(--fg)}.pathrow .dir{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--dim);flex:0 9999 auto;min-width:0}.pathrow b{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:0 auto;min-width:0;font-weight:400}.pathrow .cp{color:var(--faint);flex:none;margin-left:auto}.pathrow:hover .cp{color:var(--acc)}.pathrow.copied{border-color:var(--ok);color:var(--ok)}.pathrow.copied .dir,.pathrow.copied .cp{color:var(--ok)}.pathrow.copy-failed{border-color:var(--bad);color:var(--bad)}.pathrow.copy-failed .dir,.pathrow.copy-failed .cp{color:var(--bad)}.onboard{background:var(--panel);border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--shadow);display:flex;flex-direction:column;align-items: flex-start;gap:16px;max-width:640px;margin:40px auto;padding:28px 30px}.onboard h3{font-size:var(--fs-xl);color:var(--fg)}.onboard .px{margin:0 auto}.ob-steps{display:flex;flex-direction:column;gap:12px}.ob-step{display:flex;color:var(--fg-2);align-items: flex-start;gap:12px;line-height:1.5}.ob-step.done{color:var(--dim)}.ob-n{border:1px solid var(--line);display:inline-flex;font:600 var(--fs-sm)var(--sans);color:var(--dim);border-radius:50%;flex:none;justify-content:center;align-items: center;width:22px;height:22px;margin-top:1px}.ob-step.done .ob-n{background:var(--ok-soft);color:var(--ok);border-color:#0000}.nudge{position:fixed;z-index:40;background:var(--panel);border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--shadow-pop);display:flex;font:var(--fs-md)var(--sans);color:var(--fg-2);align-items: flex-start;gap:12px;max-width:400px;padding:14px 16px;line-height:1.5;bottom:18px;right:18px}.nudge .ic{color:var(--acc);flex:none;margin-top:1px}.nudge b{color:var(--fg);display:block;margin-bottom:2px}.nudge .row{display:flex;white-space:nowrap;align-items: center;gap:8px;margin-top:10px}.nudge button.pri{background:var(--acc-soft);color:var(--acc);border-color:#0000}.nudge a.dim{color:var(--dim);font-size:var(--fs-sm);margin-left:auto}body.nosb .nudge{right:18px}.dt .th-cols{font:inherit;background:0 0;border:0;padding:0}#root{display:contents}.note{font-size:var(--fs-sm);margin-top:10px}.proj,.chip,.h4-act,.nav-group,.mini-act{appearance:none;font:inherit;color:inherit;text-align:left;background:0 0;border:0}.proj{width:100%}.chart-card.flush{margin:0}.stack{display:flex;gap:var(--gap-sec);flex-direction:column;min-width:0}.rule-spark{display:flex;align-items: center;gap:12px;margin-bottom:10px}.rule-spark .dim{font-size:var(--fs-sm)}.rule-shape{font-size:var(--fs-md);margin:0 0 8px}.h4-note{text-transform:none;letter-spacing:0;font-weight:400}.chips.pager{margin-top:10px}.chips.pager .dim{font-size:var(--fs-sm);align-self: center}tr.clickable{cursor:pointer}.link{appearance:none;font:inherit;color:var(--acc);cursor:pointer;text-align:left;background:0 0;border:0;padding:0}.link:hover{text-decoration:underline}.h2-actions{margin-left:auto}.gpager{display:flex;border-top:1px solid var(--line);font-size:var(--fs-sm);align-items: center;gap:10px;padding:7px 12px}.gpager .gp-size{margin-left:auto}.gp-btn{appearance:none;border-radius:var(--r-xs);color:var(--dim);cursor:pointer;display:inline-flex;background:0 0;border:0;padding:2px}.gp-btn:hover:not(:disabled){color:var(--acc);background:var(--panel-2)}.gp-btn:disabled{color:var(--line-2);cursor:default}.addproj{padding:4px 0 8px}.addproj input{background:var(--panel-2);border:1px solid var(--line);color:var(--fg);border-radius:var(--r-xs);font:var(--fs-md)var(--mono);width:100%;padding:5px 7px}.addproj input:focus{outline:none;border-color:var(--acc)}.addproj-err{color:var(--bad);font-size:var(--fs-sm);margin-top:4px}.mt-panel{margin-top:14px}.bipartite{max-width:1100px}.matrix-scroll{overflow:auto}.card-pad{padding:14px}.card-scroll{overflow:auto;max-height:72vh;padding:14px}.graph-key{display:flex;font-size:var(--fs-sm);flex-wrap:wrap;align-items: center;gap:18px;margin-top:10px}.graph-key svg{vertical-align:middle}.edge-key{display:inline-flex;align-items: center;gap:6px}.dag-node{cursor:pointer}.ring-card{margin-bottom:12px}.ring-list{margin:8px 0 0;padding-left:18px}.more{appearance:none;font:inherit;color:inherit;background:0 0;border:0}.pk-sub{flex:1;margin-left:8px}.rp-summary{font-family:var(--mono);font-size:var(--fs-sm);margin-bottom:8px}.rp-range{flex:1;max-width:280px}.df-commits{font-size:var(--fs-sm)}.df-files button{appearance:none;font:inherit;color:inherit;text-align:left;background:0 0;border:0;width:100%}.wn-full{color:var(--dim);font-size:var(--fs-sm);align-self: center}.linkish{font:inherit;cursor:pointer;text-decoration:underline;background:0 0;border:0;padding:0}.linkish:hover{color:var(--fg-2)}
|
|
1
|
+
:root{--bg:#f6f7f9;--panel:#fff;--panel-2:#f0f2f5;--line:#e4e7ec;--line-2:#eef0f3;--fg:#1a1d21;--fg-2:#3d4650;--dim:#8b929c;--faint:#aab1bb;--acc:#388114;--acc-fill:#559b1b;--acc-soft:#559b1b26;--ok:#1f9d55;--ok-soft:#1f9d551f;--warn:#c77800;--warn-soft:#c778001f;--bad:#d1352b;--bad-soft:#d1352b1f;--violet:#7857c9;--c0:#8b929c;--c1:#4d9e2a;--c2:#1b9e77;--c3:#9ab828;--c4:#2f7d4f;--c5:#7fb069;--c6:#0f5c3a;--c7:#c3d84a;--acc-1:#e2f6d8;--acc-2:#b8e4a1;--acc-3:#8bc866;--acc-4:#5aa12e;--acc-5:#35741f;--mono:ui-monospace,"SF Mono",SFMono-Regular,Menlo,monospace;--sans:-apple-system,BlinkMacSystemFont,"Segoe UI",system-ui,sans-serif;--fs-2xs:11px;--fs-xs:11.5px;--fs-sm:12px;--fs-mono:12.5px;--fs-md:13px;--fs-menu:13.5px;--fs-lg:14px;--fs-xl:15px;--fs-2xl:24px;--pill-h:calc(var(--fs-xs)*1.2 + 8px);--shadow:0 1px 2px #1018280a,0 1px 3px #1018280f;--shadow-pop:0 8px 24px #10182824,0 1px 3px #10182814;--overlay:#00000073;--r:9px;--r-sm:6px;--r-xs:4px;--r-pill:20px;--t-fast:.12s;--t-med:.2s;--t-in:.32s;--t-pulse:2s;--hdr-h:48px;--sb-w:240px;--inset-tl:96px;--acc-contrast:#fff;--pad-cell:9px 12px;--pad-page:20px 22px;--pad-ctl:7px 11px;--pad-row:7px 10px;--gap-sec:18px}@media (prefers-color-scheme:dark){:root:not([data-theme=light]){--bg:#0c0e12;--panel:#14171d;--panel-2:#1a1e26;--line:#242932;--line-2:#1e222a;--fg:#e6e9ee;--fg-2:#c2c8d0;--dim:#7c8592;--faint:#5a626e;--acc:#a3e635;--acc-fill:#a3e635;--acc-soft:#a3e63524;--ok:#3fb571;--ok-soft:#3fb57124;--warn:#d9a441;--warn-soft:#d9a44124;--bad:#f0655a;--bad-soft:#f0655a24;--violet:#a68bec;--c0:#7c8592;--c1:#6bbf3a;--c2:#2bb78f;--c3:#b0cf3a;--c4:#3f9d63;--c5:#93c47d;--c6:#2f8f5a;--c7:#d3e88a;--acc-1:#1c3311;--acc-2:#2f5a18;--acc-3:#4d8a24;--acc-4:#7cc02f;--acc-5:#bfef7a;--shadow:0 1px 2px #0000004d,0 2px 6px #00000040;--shadow-pop:0 8px 24px #00000080,0 1px 3px #0006;--acc-contrast:#0e1013}}:root[data-theme=dark]{--bg:#0c0e12;--panel:#14171d;--panel-2:#1a1e26;--line:#242932;--line-2:#1e222a;--fg:#e6e9ee;--fg-2:#c2c8d0;--dim:#7c8592;--faint:#5a626e;--acc:#a3e635;--acc-fill:#a3e635;--acc-soft:#a3e63524;--ok:#3fb571;--ok-soft:#3fb57124;--warn:#d9a441;--warn-soft:#d9a44124;--bad:#f0655a;--bad-soft:#f0655a24;--violet:#a68bec;--c0:#7c8592;--c1:#6bbf3a;--c2:#2bb78f;--c3:#b0cf3a;--c4:#3f9d63;--c5:#93c47d;--c6:#2f8f5a;--c7:#d3e88a;--acc-1:#1c3311;--acc-2:#2f5a18;--acc-3:#4d8a24;--acc-4:#7cc02f;--acc-5:#bfef7a;--shadow:0 1px 2px #0000004d,0 2px 6px #00000040;--shadow-pop:0 8px 24px #00000080,0 1px 3px #0006;--acc-contrast:#0e1013}*{box-sizing:border-box}html,body{height:100%}html{zoom:var(--ui-zoom,1)}body{background:var(--bg);color:var(--fg);font:var(--fs-lg)/1.5 var(--sans);-webkit-font-smoothing:antialiased;display:grid;grid-template-rows:var(--hdr-h)1fr;grid-template-columns:var(--sb-w)1fr;overflow:hidden;animation:appin var(--t-in)ease both;user-select:none;-webkit-user-select:none;margin:0}@keyframes appin{0%{opacity:0}to{opacity:1}}input,textarea,tbody td,.mono,code,kbd{user-select:text;-webkit-user-select:text}::selection{background:var(--acc-soft)}a{color:var(--acc);text-decoration:none}.dim{color:var(--dim)}.faint{color:var(--faint)}.mono{font-family:var(--mono);font-size:var(--fs-mono)}.num{text-align:right;font-variant-numeric:tabular-nums;font-feature-settings:"tnum"}kbd{font:var(--fs-mono)var(--mono);background:var(--panel-2);border:1px solid var(--line);border-radius:var(--r-xs);color:var(--fg-2);padding:1px 5px}code{font:var(--fs-md)var(--mono);color:var(--fg-2)}body.nosb{grid-template-columns:46px 1fr}body.nosb aside{overflow:hidden;padding:12px 5px}body.nosb #projects{display:none}.sb-grip{position:fixed;top:var(--hdr-h);bottom:0;left:calc(var(--sb-w) - 4px);cursor:col-resize;z-index:40;background:0 0;border:0;border-radius:0;width:9px;padding:0}.sb-grip:hover,.sb-grip:active{outline:none;background:linear-gradient(to right,transparent 3px,var(--acc)3px,var(--acc)5px,transparent 5px)}.sb-grip:focus-visible{outline:none;background:linear-gradient(to right,transparent 3px,var(--acc)3px,var(--acc)5px,transparent 5px)}body.nosb .sb-grip{display:none}#root>aside{grid-column:1;grid-row:2}#root>main{grid-column:2;grid-row:2}#projects h4{display:flex;align-items: center;gap:5px}.h4-act{cursor:pointer;color:var(--faint);display:inline-flex;border-radius:var(--r-xs);margin-left:auto;padding:2px}.h4-act:hover{color:var(--acc)}.pk-h input{background:var(--panel-2);border:1px solid var(--line);color:var(--fg);border-radius:var(--r-sm);font:var(--fs-mono)var(--mono);outline:none;flex:1;min-width:0;padding:5px 9px}.pk-h input:focus{border-color:var(--acc)}header{grid-column:1/3;display:flex;border-bottom:1px solid var(--line);background:var(--panel);z-index:5;align-items: center;gap:6px;padding:0 16px}html.chrome-inset header{padding-left:var(--inset-tl)}html.chrome-inset.fs header{padding-left:16px}html.chrome-inset header{cursor:default}header .logo{letter-spacing:.02em;font-weight:700;font-size:var(--fs-xl);display:flex;align-items: center;gap:8px;margin-right:14px}header .logo svg{image-rendering:pixelated;image-rendering:crisp-edges;width:22px;height:auto;transform:translateY(-2px)}header .nav{color:var(--dim);border-radius:var(--r-sm);transition:color var(--t-fast),background var(--t-fast);padding:6px 11px;font-weight:500}header .nav:hover{color:var(--fg-2)}header .nav.on{color:var(--fg);background:var(--panel-2)}header .sp{flex:1}header #today{color:var(--dim);font-variant-numeric:tabular-nums;margin-right:18px}header #today b{color:var(--fg-2);font-weight:600}#daemon{display:flex;color:var(--dim);font-size:var(--fs-md);align-items: center;gap:7px}#daemon .dot{background:var(--bad);transition:background var(--t-med);border-radius:50%;width:7px;height:7px}#daemon .dot.on{background:var(--ok);box-shadow:0 0 0 3px var(--ok-soft)}#root>aside{border-right:1px solid var(--line);background:var(--panel);overflow:auto;display:flex;flex-direction:column;padding:12px 10px}#viewnav{display:flex;align-items: center;gap:2px}#viewnav .navgrp{display:flex;color:var(--dim);border-radius:var(--r-sm);font:inherit;font-size:var(--fs-md);cursor:pointer;transition:color var(--t-fast),background var(--t-fast);background:0 0;border:0;align-items: center;gap:6px;padding:6px 10px;font-weight:500}#viewnav .navgrp:hover{color:var(--fg-2);background:var(--panel-2)}#viewnav .navgrp.on{color:var(--fg);background:var(--panel-2)}#viewnav .navview{color:var(--acc);font-weight:600}#viewnav .navview:before{content:"";display:inline-block;background:var(--line);width:1px;height:11px;margin:0 7px -1px}#viewnav .navgrp.open{color:var(--fg);background:var(--line)}#viewnav .navgrp.open .chev{opacity:.9;transform:rotate(180deg)}#viewnav .navgrp .chev{opacity:.5;flex:none}#viewnav .navcount{background:var(--bad-soft);color:var(--bad);font-size:var(--fs-2xs);border-radius:99px;padding:0 5px;font-weight:600}#root>aside h4{color:var(--faint);font-size:var(--fs-xs);text-transform:uppercase;letter-spacing:.09em;margin:14px 8px 6px;font-weight:600}#root>aside h4:first-child{margin-top:2px}.proj{position:relative;padding:var(--pad-row);border-radius:var(--r-sm);cursor:pointer;display:flex;color:var(--fg-2);transition:background var(--t-fast);user-select:none;align-items: center;gap:9px}.proj:hover{background:var(--panel-2)}.proj.sel{background:var(--acc-soft);color:var(--fg)}.proj.sel .nm{font-weight:600}.proj .st{background:var(--faint);transition:background var(--t-med);border-radius:50%;flex:none;width:7px;height:7px}.proj .st.live{background:var(--ok);box-shadow:0 0 0 3px var(--ok-soft)}.proj .nm{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1}.proj small{color:var(--dim);font-variant-numeric:tabular-nums;font-size:var(--fs-sm);text-align:right;flex:none;min-width:15px}.proj .act{position:absolute;right:var(--pad-row-x,7px);display:inline-flex;opacity:0;pointer-events:none;color:var(--faint);font-size:var(--fs-lg);border-radius:var(--r-xs);transition:color var(--t-fast),background var(--t-fast),opacity var(--t-fast);padding:2px;line-height:1;top:50%;transform:translateY(-50%)}.proj:hover .act,.proj.menu-open .act{opacity:1;pointer-events:auto}.proj .act:focus-visible{opacity:1;pointer-events:auto}.proj:hover small,.proj.menu-open small{visibility:hidden}.proj .act:hover{color:var(--fg);background:var(--line)}.proj .act.rm:hover{color:var(--bad)}.srch{display:flex;gap:8px;margin-bottom:14px}.srch input{background:var(--panel);border:1px solid var(--line);color:var(--fg);border-radius:var(--r-sm);font:var(--fs-md)var(--sans);flex:1;max-width:640px;padding:8px 12px}.srch input:focus{border-color:var(--acc);outline:none}.hit{border:1px solid var(--line);border-radius:var(--r-sm);background:var(--panel);margin-bottom:8px;padding:10px 12px}.hit .ht{display:flex;align-items: center;gap:8px;margin-bottom:4px}.hit .hs{font-size:var(--fs-sm);color:var(--fg-2);white-space:pre-wrap}.hit mark{background:var(--warn-soft);color:var(--fg);border-radius:2px;padding:0 1px}.dr-rules{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px 16px;margin:10px 0}.dr-rule{display:flex;font-size:var(--fs-sm);align-items: center;gap:8px}.dr-rule select{background:var(--panel-2);color:var(--fg);border:1px solid var(--line);border-radius:var(--r-sm);padding:2px 4px}.dr-flaky{border:1px solid var(--line);border-radius:var(--r-sm);background:var(--panel-2);margin:6px 0;padding:6px 8px}table.plain{border-collapse:collapse;font-size:var(--fs-sm);width:100%}table.plain td{border-top:1px solid var(--line);vertical-align:top;padding:3px 6px}.pk.pal{align-self: start;margin-top:9vh}.pal .pk-list{min-height:120px;max-height:min(440px,62vh)}.pal .pk-row.on{background:var(--acc-soft);color:var(--fg)}.pal-empty{padding:16px}.pal .pk-row .grp{color:var(--faint);font-size:var(--fs-xs);text-transform:uppercase;letter-spacing:.07em;margin-left:auto}#picker:empty{display:none}#picker{position:fixed;background:var(--overlay);display:grid;z-index:50;place-items: center;inset:0}.pk{display:flex;background:var(--panel);border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--shadow-pop);overflow:hidden;flex-direction:column;width:min(560px,92vw);max-height:78vh}.pk-h{display:flex;border-bottom:1px solid var(--line);align-items: center;gap:8px;padding:12px 14px}.pk-list{overflow:auto;padding:6px}.pk-row{display:flex;padding:var(--pad-row);border-radius:var(--r-sm);cursor:pointer;color:var(--fg-2);align-items: center;gap:9px}button.pk-row{font:inherit;line-height:inherit;text-align:left;background:0 0;border:0;justify-content:flex-start;width:100%}.pk-row:hover{background:var(--panel-2)}.pk-row .nm{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1}.pk-row.up{color:var(--dim)}.pk-row .badge{margin:0}.pk-b{display:grid;gap:10px;padding:12px 14px}.pk-b label{display:grid;font:500 var(--fs-sm)var(--sans);color:var(--dim);gap:4px}.pk-b input,.pk-b textarea,.pk-b select{background:var(--panel-2);border:1px solid var(--line);color:var(--fg);border-radius:var(--r-sm);font:var(--fs-md)var(--sans);outline:none;width:100%;padding:7px 9px}.pk-b textarea{resize:vertical;font-family:var(--mono);font-size:var(--fs-sm);min-height:120px;line-height:1.5}.pk-b input:focus,.pk-b textarea:focus,.pk-b select:focus{border-color:var(--acc)}.pk-b .row{display:grid;grid-template-columns:1fr 1fr 1fr;gap:10px}.pk.wide{width:min(960px,96vw)}.df-files{display:grid;overflow:auto;border:1px solid var(--line);border-radius:var(--r-sm);gap:1px;max-height:22vh}.df-files a{display:flex;color:var(--fg-2);text-decoration:none;font:var(--fs-sm)var(--mono);gap:10px;padding:4px 8px}.df-files a:hover,.df-files a.on{background:var(--panel-2);color:var(--fg)}.df-files .st{color:var(--dim);width:12px}.df-files .pl{color:var(--ok)}.df-files .mi{color:var(--warn)}.df-files .pa{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1}.df-patch{overflow:auto;background:var(--panel-2);border:1px solid var(--line);border-radius:var(--r-sm);font:var(--fs-sm)var(--mono);white-space:pre;max-height:44vh;margin:0;padding:8px 10px;line-height:1.45}.df-patch .a{color:var(--ok)}.df-patch .d{color:var(--warn)}.df-patch .h{color:var(--acc)}.df-patch .m{color:var(--dim)}.wn .pk-b{overflow:auto;gap:2px;max-height:64vh}.wn h3{font:600 var(--fs-lg)var(--sans);color:var(--fg);margin:0 0 2px}.wn .date{color:var(--dim);font-size:var(--fs-sm);margin-bottom:12px}.wn h4{font:600 var(--fs-md)var(--sans);color:var(--acc);text-transform:none;letter-spacing:0;margin:14px 0 4px}.wn ul{margin:0 0 6px;padding-left:18px}.wn li{color:var(--fg-2);margin:5px 0;line-height:1.55}.wn p{color:var(--fg-2);margin:0 0 10px;line-height:1.6}.wn code{font-family:var(--mono);font-size:var(--fs-sm);background:var(--panel-2);border-radius:var(--r-xs);padding:1px 5px}.wn a{color:var(--acc)}.wn b{color:var(--fg)}.wn .snip{background:var(--panel-2);border:1px solid var(--line);border-radius:var(--r-sm);font-family:var(--mono);font-size:var(--fs-sm);white-space:pre-wrap;word-break:break-word;color:var(--fg-2);margin:2px 0 12px;padding:9px 11px;line-height:1.5}.wn .cbtn{font-weight:500;font-size:var(--fs-sm);color:var(--acc);margin-left:8px}.rp{height:78vh}.rp .pk-b{overflow:auto;flex:1;gap:2px;min-height:0;max-height:none}.rp .snip{overflow:visible;max-height:none}.rp .pk-f input[type=range]{accent-color:var(--acc)}.perm{background:var(--warn-soft);border:1px solid var(--warn);border-radius:var(--r-sm);margin-top:10px;padding:10px 12px}.perm-t{font:500 var(--fs-md)var(--sans);color:var(--fg)}.perm-c{font-family:var(--mono);font-size:var(--fs-sm);color:var(--fg-2);word-break:break-all;background:var(--panel-2);border-radius:var(--r-xs);margin:6px 0 8px;padding:6px 8px}.perm-b{display:flex;gap:8px}.perm-b .ok{color:var(--acc);border-color:var(--acc-soft)}.perm-b .danger{color:var(--warn);border-color:var(--warn-soft)}.stdin{display:flex;align-items: center;gap:8px;margin-top:10px}.stdin input{background:var(--panel-2);border:1px solid var(--line);color:var(--fg);border-radius:var(--r-sm);font:var(--fs-md)var(--sans);outline:none;flex:1;padding:8px 10px}.stdin input:focus{border-color:var(--acc)}.stdin button.danger{color:var(--warn);border-color:var(--warn-soft)}.stdin .hint{color:var(--dim);font-size:var(--fs-sm)}.pk-f{display:flex;border-top:1px solid var(--line);gap:8px;padding:12px 14px}.pk-f button{flex:none}.pk-err{color:var(--bad);font-size:var(--fs-sm)}.pk-f .pk-err{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;align-self: center}.grow{flex:1}.pk-f .primary{background:var(--acc);border-color:var(--acc);color:var(--acc-contrast)}.pk-f .primary:hover{filter:brightness(1.06);color:var(--acc-contrast)}.proj .nm .pdir{opacity:.5;font-weight:400}.proj[draggable]{cursor:grab}.proj.dragging{opacity:.35;background:var(--panel-2);outline:1px dashed var(--acc)}button{background:var(--panel);border:1px solid var(--line);color:var(--fg-2);padding:var(--pad-ctl);border-radius:var(--r-sm);font:600 var(--fs-md)var(--sans);cursor:pointer;transition:border-color var(--t-fast),color var(--t-fast);display:inline-flex;justify-content:center;align-items: center;gap:6px;line-height:1}.pk-h button{padding:6px;line-height:0}button:hover{border-color:var(--acc);color:var(--fg)}main{overflow:auto;padding:var(--pad-page)}h2.hrow{display:flex;flex-wrap:wrap;align-items: center;gap:7px}h2.hrow .s{margin:0}h2{font-size:var(--fs-md);color:var(--dim);text-transform:uppercase;letter-spacing:.07em;display:flex;align-items:baseline;gap:10px;margin:0 0 12px;font-weight:600}h2 span{text-transform:none;letter-spacing:0;color:var(--faint);font-weight:500;font-size:var(--fs-md)}h2 .nav{display:inline-flex;font:500 var(--fs-md)var(--sans);text-transform:none;letter-spacing:0;color:var(--acc);text-decoration:none;border-radius:var(--r-sm);transition:background var(--t-fast);align-items: center;gap:5px;padding:2px 8px}h2 .nav:hover,h2 .nav.on{background:var(--acc-soft)}h2 .nav .ph{display:block}h2 .back{color:var(--fg-2);text-transform:none;letter-spacing:0;font-weight:600;font-size:var(--fs-md);display:inline-flex;border:1px solid var(--line);border-radius:var(--r-pill);background:var(--panel);transition:border-color var(--t-fast),color var(--t-fast);align-items: center;gap:5px;padding:5px 11px 5px 8px}.card{background:var(--panel);border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--shadow);overflow-x:auto}table{border-collapse:collapse;table-layout:fixed;width:100%}.card table{background:var(--panel)}thead th{text-align:left;padding:var(--pad-cell);color:var(--dim);font-weight:500;font-size:var(--fs-sm);border-bottom:1px solid var(--line);background:var(--panel-2);white-space:nowrap}tbody td{padding:var(--pad-cell);border-bottom:1px solid var(--line-2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;vertical-align:middle}tbody tr:last-child td{border-bottom:0}tbody td.td-tools{text-overflow:clip;text-align:center;padding-left:0;padding-right:0;line-height:0}tbody td.td-badge{text-overflow:clip}tbody td.td-badge .badge{margin-right:0}tbody tr{transition:background var(--t-fast)}tbody tr[data-s]{cursor:pointer}tbody tr:hover{background:var(--panel-2)}tbody td.td-lead{overflow:visible}tbody td{--cap:calc(var(--fs-lg)*.352)}tbody td .pg{vertical-align:calc(var(--cap) - 8px)}tbody td .pg:before{content:"";display:block;width:0;height:16px}tbody td>*+.badge{overflow:hidden;vertical-align:calc(var(--cap) - var(--pill-h)/2)}tbody td:not(.td-tools)>svg.ph[width="12"]{vertical-align:calc(var(--cap) - 6px)}tbody td:not(.td-tools)>svg.ph[width="13"]{vertical-align:calc(var(--cap) - 6.5px)}tbody td:not(.td-tools)>svg.ph[width="14"]{vertical-align:calc(var(--cap) - 7px)}tbody td:not(.td-tools)>svg.ph[width="16"]{vertical-align:calc(var(--cap) - 8px)}.dt thead th{position:relative;user-select:none;-webkit-user-select:none}.dt thead tr:first-child th[data-col]:not(:last-child):after{content:"";position:absolute;border-right:1px solid var(--line);height:50%;top:25%;right:0}.dt thead th[data-sort]{cursor:pointer}.dt thead th[data-sort]:hover{color:var(--fg-2)}.dt thead th.dragging{opacity:.4}.dt .th-l{display:inline-flex;align-items: center;gap:5px}.dt th.num .th-l{justify-content:flex-end;width:100%}.dt .sort{display:inline-block;border-left:4px solid #0000;border-right:4px solid #0000;width:0;height:0}.dt .sort.asc{border-bottom:5px solid var(--acc)}.dt .sort.desc{border-top:5px solid var(--acc)}.dt .th-grip{position:absolute;cursor:col-resize;z-index:2;width:9px;height:100%;top:0;right:-4px}.dt .th-grip:hover{background:linear-gradient(to right,transparent 3px,var(--acc)3px,var(--acc)5px,transparent 5px)}.dt thead th:last-child .th-grip{right:0}.dt thead th:last-child .th-grip:hover{background:linear-gradient(to left,var(--acc)0,var(--acc)2px,transparent 2px)}body.col-resizing,body.col-resizing .dt thead th{cursor:col-resize}.dt .th-tools{text-align:right}.dt .th-tools,.dt .td-tools{position:sticky;z-index:1;right:0}.dt .th-tools{background:var(--panel-2)}.dt .td-tools{background:var(--panel)}tbody tr:hover .td-tools{background:var(--panel-2)}.dt .th-cols{cursor:pointer;color:var(--faint);display:inline-flex}.dt .th-cols:hover{color:var(--fg-2)}.dt tr.filters th{background:var(--panel);padding:4px 8px}.dt tr.filters input{background:var(--panel-2);border:1px solid var(--line);color:var(--fg);border-radius:var(--r-sm);font:var(--fs-sm)var(--mono);outline:none;width:100%;padding:3px 7px}.dt tr.filters input:focus{border-color:var(--acc)}.dt .tbl-empty td{color:var(--dim);text-align:center;cursor:default;padding:18px}td b{color:var(--fg);font-weight:600}td.now,.br{font-family:var(--mono);font-size:var(--fs-mono);color:var(--fg-2)}.br+.badge{margin-left:6px}td.now{color:var(--dim)}td a{color:var(--acc)}.num,th.num{text-align:right}.s{display:inline-block;background:var(--faint);border-radius:50%;flex:none;width:8px;height:8px}.s.active{background:var(--ok);box-shadow:0 0 0 3px var(--ok-soft);animation:pulse var(--t-pulse)ease-in-out infinite}.s.waiting{background:var(--warn);box-shadow:0 0 0 3px var(--warn-soft)}.s.idle{background:var(--faint)}.s.ended{background:var(--line);border:1px solid var(--faint);box-shadow:none}@keyframes pulse{0%,to{box-shadow:0 0 0 3px var(--ok-soft)}50%{box-shadow:0 0 0 5px #0000}}.badge{display:inline-block;font:500 var(--fs-xs)/1.2 var(--sans);border-radius:var(--r-pill);background:var(--panel-2);color:var(--dim);vertical-align:middle;margin-right:4px;padding:4px 8px}.badge.warn{color:var(--warn);background:var(--warn-soft)}.badge.acc{color:var(--acc);background:var(--acc-soft)}.badge.ok{color:var(--ok);background:var(--ok-soft)}.badge.bad{color:var(--bad);background:var(--bad-soft)}.badge.agent{color:var(--violet);background:color-mix(in srgb,var(--violet)14%,transparent);font-weight:600}.err-h{color:var(--bad);align-items: center}.err-h .err-ic{color:var(--bad);flex:none}.err-card{border:1px solid var(--bad);max-width:760px;padding:18px}.err-detail{background:var(--panel-2);border-radius:var(--r-sm);font:var(--fs-mono)/1.5 var(--mono);color:var(--fg-2);white-space:pre-wrap;overflow-x:auto;border:0;max-height:220px;margin:0;padding:10px 12px}.clusters{list-style:none;margin:0;padding:0}.clusters li{display:grid;grid-template-columns:minmax(0,13em)3.2em minmax(0,1fr);border-bottom:1px solid var(--line-2);font-size:var(--fs-md);align-items: center;gap:10px;padding:6px 0}.clusters li:last-child{border-bottom:0}.clusters li>*{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0}.clusters li b{font-family:var(--mono);font-size:var(--fs-mono);color:var(--fg)}.clusters li .n{color:var(--fg-2);text-align:right;font-variant-numeric:tabular-nums}.clusters li>span:last-child{color:var(--dim);font-family:var(--mono);font-size:var(--fs-mono)}.plainlist{list-style:none;display:flex;flex-direction:column;gap:6px;margin:0;padding:0}.plainlist li{display:flex;font-size:var(--fs-md);color:var(--fg-2);border-bottom:1px solid var(--line-2);align-items: center;gap:8px;padding:5px 0}.plainlist li:last-child{border-bottom:0}.plainlist li b{font-family:var(--mono);font-size:var(--fs-mono);color:var(--fg);font-weight:600}td.path,span.path{font-family:var(--mono);font-size:var(--fs-mono)}td.path b,span.path b{color:var(--fg);font-weight:600}td.path .dim,span.path .dim{font-size:var(--fs-xs)}.heatlist{list-style:none;display:flex;flex-direction:column;gap:2px;margin:0;padding:0}.heatlist li{position:relative;display:flex;font-size:var(--fs-md);color:var(--fg-2);border-radius:var(--r-sm);overflow:hidden;align-items: center;gap:10px;padding:6px 10px}.heatlist li .bar{position:absolute;width:var(--w);background:var(--acc-soft);border-radius:var(--r-sm);inset:0 auto 0 0}.heatlist li>span.clip{position:relative;font-family:var(--mono);font-size:var(--fs-mono);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;flex:1;min-width:0}.heatlist li b{position:relative;font-variant-numeric:tabular-nums;color:var(--fg)}.heatlist li .dim{position:relative;font-size:var(--fs-sm);white-space:nowrap}.empty{color:var(--dim);text-align:center;border:1px dashed var(--line);border-radius:var(--r);background:var(--panel);padding:44px 24px;line-height:1.7}.sess{display:grid;grid-template-columns:1fr 1fr;align-items:stretch;gap:16px}.sess>*{height:calc(100vh - 140px);min-height:320px}.sess.has-stdin>*{height:calc(100vh - 196px)}@media (max-width:980px){.sess{grid-template-columns:1fr}.sess>*{height:auto;max-height:calc(100vh - 140px)}}#log{background:var(--panel);border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--shadow);overflow:auto;padding:6px 0}.ev{display:grid;grid-template-columns:56px 54px 1fr;align-items:baseline;gap:10px;padding:5px 14px}.ev:hover{background:var(--panel-2)}.ev .t{color:var(--faint);font:var(--fs-sm)var(--mono)}.ev .k{color:var(--dim);font:500 var(--fs-sm)var(--mono);text-transform:lowercase;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ev .m{white-space:pre-wrap;word-break:break-word;color:var(--fg-2);font-size:var(--fs-menu)}.ev.assistant .k{color:var(--violet)}.ev.assistant .m{color:var(--fg)}.ev.tool\.requested .k{color:var(--acc)}.ev.tool\.requested .m{color:var(--dim);font-family:var(--mono);font-size:var(--fs-mono)}.ev.incident\.opened .k,.ev.incident\.opened .m{color:var(--warn)}.ev.session\.ended .k{color:var(--bad)}.ev.prompt\.submitted .k{color:var(--ok)}.ev.prompt\.submitted .m{color:var(--fg);font-weight:500}.side{background:var(--panel);border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--shadow);overflow:auto;padding:14px 18px}.side .stats{display:grid;grid-template-columns:1fr 1fr;gap:0 28px}.stat{display:flex;border-bottom:1px solid var(--line-2);justify-content:space-between;align-items:baseline;padding:7px 0}.stat:last-of-type{border-bottom:0}.stat span{color:var(--dim)}.stat b{font-variant-numeric:tabular-nums;font-weight:600}.stat small{color:var(--faint);font-weight:400}.side h4{color:var(--faint);font-size:var(--fs-xs);text-transform:uppercase;letter-spacing:.08em;margin:16px 0 6px;font-weight:600}table.mini{table-layout:fixed;border:0;width:100%}table.mini td{font-size:var(--fs-md);vertical-align:middle;border:0;padding:6px 0}table.mini th{vertical-align:middle;padding-top:6px;padding-bottom:6px}table.mini th+th,table.mini td+td{padding-left:14px}table.mini td:first-child{color:var(--fg-2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}table.mini td.num{color:var(--dim);width:34px}table.mini td.clip{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.bars{display:flex;background:var(--panel);border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--shadow);margin-bottom:var(--gap-sec);align-items: flex-end;gap:5px;height:110px;padding:14px 16px 26px}.bar{position:relative;display:flex;flex:1;align-items: flex-end;min-width:0;height:100%}.bar>div{background:linear-gradient(180deg,var(--acc),color-mix(in srgb,var(--acc)70%,transparent));border-radius:var(--r-xs)var(--r-xs)0 0;transition:opacity var(--t-fast);width:100%;min-height:2px}.bar:hover>div{opacity:.75}.bar span{position:absolute;text-align:center;font:var(--fs-2xs)var(--mono);color:var(--faint);bottom:-20px;left:0;right:0}.cols{display:grid;grid-template-columns:1fr 1fr;gap:var(--gap-sec);align-items: start}.chart{display:block;overflow:visible;width:100%}.chart .grid{stroke:var(--line-2);stroke-width:1;vector-effect:non-scaling-stroke}.chart .base{stroke:var(--line);stroke-width:1;vector-effect:non-scaling-stroke}.chart .ax{fill:var(--faint);font:var(--fs-2xs)var(--mono);text-anchor:start}.chart .ax.mid{text-anchor:middle}.chart .col:hover path{filter:brightness(1.12)}.chart-card{background:var(--panel);border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--shadow);margin-bottom:var(--gap-sec);padding:14px 16px 10px}.chart-card h3{font-size:var(--fs-md);color:var(--fg-2);display:flex;align-items:baseline;gap:10px;margin:0 0 10px;font-weight:600}.chart-card h3 span{color:var(--faint);font-weight:400}.legend{display:flex;font-size:var(--fs-mono);color:var(--fg-2);flex-wrap:wrap;gap:4px 14px;margin:8px 0 0}.legend span{display:inline-flex;align-items: center;gap:6px}.legend i{display:inline-block;border-radius:2px;width:9px;height:9px}.legend em{color:var(--dim);font-variant-numeric:tabular-nums;font-style:normal}.legend.small{font-size:var(--fs-sm);margin-top:6px}#tip{position:fixed;display:none;z-index:50;pointer-events:none;background:var(--fg);color:var(--bg);border-radius:var(--r-sm);font:var(--fs-mono)/1.5 var(--sans);box-shadow:var(--shadow-pop);font-variant-numeric:tabular-nums;max-width:280px;padding:7px 10px;top:0;left:0}#tip b{font-weight:600}#tip span{opacity:.7}#tip i{display:inline-block;border-radius:2px;width:8px;height:8px;margin-right:6px}.spark{display:block;overflow:visible;width:88px;height:20px}.spark path{fill:none;stroke-width:1.5;vector-effect:non-scaling-stroke;stroke-linejoin:round}.comp{display:flex;border-radius:var(--r-xs);overflow:hidden;gap:2px;height:12px;margin-top:4px}.comp i{display:block;transition:filter var(--t-fast);min-width:2px}.comp i:hover{filter:brightness(1.15)}.hbars{display:flex;flex-direction:column;gap:4px}.hb{display:grid;grid-template-columns:minmax(0,120px)1fr auto;font-size:var(--fs-md);align-items: center;gap:8px}.hb .k{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--fg-2)}.hb .t{background:var(--panel-2);overflow:hidden;border-radius:3px;height:8px}.hb .t i{display:block;border-radius:3px;min-width:2px;height:100%}.hb .n{text-align:right;white-space:nowrap;color:var(--dim);font-variant-numeric:tabular-nums;font-size:var(--fs-mono)}.cal{position:relative;padding-top:16px}.cal-months{position:absolute;height:14px;top:0;left:0;right:0}.cal-months span{position:absolute;font:var(--fs-2xs)var(--mono);color:var(--faint)}.cal-grid{display:grid;gap:2px}.cal-col{display:grid;grid-template-rows:repeat(7,1fr);aspect-ratio:1/7;gap:2px}.cal-col i{display:block;background:var(--acc);outline:1px solid var(--line-2);outline-offset:-1px;border-radius:2px}.cal-col i:hover{outline-color:var(--fg)}.chart.line .pt circle{opacity:0}.chart.line .pt:hover circle{opacity:1}.records{display:grid;grid-template-columns:1fr 1fr;gap:12px}.rec{background:var(--panel);border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--shadow);display:flex;flex-direction:column;gap:2px;padding:10px 14px}.rec .l{font-size:var(--fs-sm);color:var(--dim);text-transform:uppercase;letter-spacing:.06em;font-weight:600}.rec .v{font-size:var(--fs-lg);color:var(--fg);font-variant-numeric:tabular-nums;font-weight:600}.rec .d{font-size:var(--fs-mono);color:var(--faint);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.hm{display:grid;grid-template-columns:34px 1fr;align-items: center;gap:3px 8px}.hm-lbl{font:var(--fs-xs)var(--mono);color:var(--faint)}.hm-row{display:grid;grid-template-columns:repeat(24,1fr);gap:2px;height:16px}.hm-row i{display:block;background:var(--acc);outline:1px solid var(--line-2);outline-offset:-1px;border-radius:2px}.hm-row i:hover{outline-color:var(--fg)}.hm-hours{position:relative;font:var(--fs-2xs)var(--mono);color:var(--faint);height:14px}.hm-hours span{position:absolute;top:0}.tl{background:var(--panel);border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--shadow);padding:8px 16px 12px}.tl-row{display:grid;grid-template-columns:200px 1fr;cursor:pointer;border-radius:var(--r-xs);align-items: center;gap:12px;height:24px}.tl-row.claimlane{cursor:default}.tl-row:hover{background:var(--panel-2)}.tl-row.head{cursor:default;position:sticky;background:var(--panel);z-index:2;height:22px;margin-bottom:4px;top:-20px}.tl-row.head:hover{background:var(--panel)}.tl-name{font-size:var(--fs-md);color:var(--fg-2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding-left:10px}.tl-track{position:relative;height:100%}.tl-track>i{position:absolute;opacity:.9;border-radius:3px;min-width:3px;height:12px;top:6px}.tl-track>i.live{box-shadow:0 0 0 2px var(--panel),0 0 0 3px currentColor;animation:none}.tl-track>i:hover{opacity:1;filter:brightness(1.1)}.tl-track>i:not([data-tip]){background:var(--line-2);opacity:1;pointer-events:none;border-radius:0;width:1px;min-width:0;height:100%;top:0}.tl-axis{position:absolute;font:var(--fs-2xs)var(--mono);color:var(--faint);inset:0}.tl-axis span{position:absolute;top:3px;transform:translate(-50%)}.tl-now{position:absolute;background:var(--bad);z-index:1;pointer-events:none;width:1px;top:0;bottom:-2000px}.tl-group{position:relative;border-top:1px solid var(--line-2);margin-top:6px;padding-top:4px}.tl-proj{font-size:var(--fs-sm);color:var(--dim);text-transform:uppercase;letter-spacing:.06em;padding:4px 10px 2px;font-weight:600}.tl-proj small{text-transform:none;letter-spacing:0;color:var(--faint);margin-left:8px;font-weight:400}.tl,.tl-group{overflow:hidden}.sw{display:inline-block;vertical-align:baseline;border-radius:2px;width:9px;height:9px;margin-right:7px}.kpis{display:grid;grid-template-columns:repeat(4,1fr);margin-bottom:var(--gap-sec);gap:12px}.kpi{background:var(--panel);border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--shadow);padding:12px 14px}.kpi .l{font-size:var(--fs-sm);color:var(--dim);text-transform:uppercase;letter-spacing:.06em;font-weight:600}.kpi .v{font-size:var(--fs-2xl);font-variant-numeric:tabular-nums;color:var(--fg);margin-top:2px;font-weight:600}.kpi .d{font-size:var(--fs-mono);color:var(--faint)}.ph{display:inline-block;vertical-align:-.09em;flex:none}header .nav{display:inline-flex;align-items: center;gap:6px}.navcount{display:inline-block;font:500 var(--fs-xs)var(--sans);text-transform:none;letter-spacing:0;color:var(--warn);background:var(--warn-soft);border-radius:var(--r-pill);padding:4px 8px;line-height:1.2}header .nav .ph{opacity:.75}header .nav.on .ph{opacity:1;color:var(--acc)}.icon-btn{display:inline-flex;border-radius:var(--r-sm);color:var(--dim);background:0 0;border:1px solid #0000;justify-content:center;align-items: center;width:28px;height:28px;padding:0}.icon-btn:hover{background:var(--panel-2);color:var(--fg);border-color:#0000}.icon-btn.on{background:var(--panel-2);color:var(--fg)}header #settings{margin-left:10px}.proj .ph{color:var(--faint)}.proj.sel .ph{color:var(--acc)}.kind{color:var(--faint);margin-right:6px}td .more{opacity:0;color:var(--faint);border-radius:var(--r-xs);transition:opacity var(--t-fast),background var(--t-fast);display:inline-flex;vertical-align:middle;padding:2px;line-height:0}tr:hover td .more,.proj:hover .more,tr.menu-open td .more,.menu-open>.more,.more.menu-open{opacity:1}td .more:hover{background:var(--line);color:var(--fg)}.mini-act{display:inline-flex;color:var(--fg-2);border:1px solid var(--line);border-radius:var(--r-sm);font-size:var(--fs-sm);text-decoration:none;transition:color var(--t-fast),border-color var(--t-fast);align-items: center;padding:2px 9px;font-weight:500}.mini-act:hover{color:var(--acc);border-color:var(--acc)}.mini-act.bad:hover{color:var(--bad);border-color:var(--bad)}.track{display:inline-flex;align-items: center;gap:3px}.track i{background:var(--line);border:1px solid var(--line-2);border-radius:50%;width:7px;height:7px}.track i.on{background:var(--acc);border-color:var(--acc)}.chip.off{opacity:.4;pointer-events:none}.stat .ph{color:var(--faint);margin-right:7px}.empty .ph{display:block;color:var(--faint);margin:0 auto 10px}.empty .px{display:block;image-rendering:pixelated;margin:0 auto 14px}h2 .back:hover{border-color:var(--acc);color:var(--fg)}:root{--fm-surface-bg:var(--panel);--fm-surface-fg:var(--fg);--fm-surface-border:var(--line);--fm-surface-radius:var(--r);--fm-surface-shadow:var(--shadow-pop);--fm-accent:var(--acc);--fm-accent-fg:var(--acc-contrast);--fm-destructive:var(--bad);--fm-muted-fg:var(--dim);--fm-divider-color:var(--line-2);--fm-row-hover-bg:var(--panel-2);--fm-row-active-bg:var(--panel-2);--fm-row-active-fg:var(--fg);--fm-font-size-row:var(--fs-menu);--fm-font-size-caption:var(--fs-sm);--fm-font-size-section:var(--fs-xs);--fm-row-min-h:30px;--fm-row-radius:var(--r-sm)}.fm-row--danger,.fm-row--danger .fm-row__icon{color:var(--bad)}.fm-row--danger:hover{background:var(--bad-soft)}.fm-row[data-pressed=true]{background:var(--acc-soft);color:var(--acc);position:relative;font-weight:600}.fm-row[data-pressed=true]:before{content:"";position:absolute;border-radius:0 var(--r-xs)var(--r-xs)0;background:var(--acc);width:3px;height:58%;top:50%;left:0;transform:translateY(-50%)}.fm-row[data-pressed=true] .fm-ico{color:var(--acc)}.fm-row__icon,.fm-ico{display:inline-flex;justify-content:center;align-items: center}.fm-row__name{flex:auto;min-width:0}.fm-row__caption{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:0 auto;min-width:0;max-width:45%;margin-left:auto}.fm-ico .ph{vertical-align:0}main>h2:not(:first-child),.mt-sec{margin-top:var(--gap-sec)}.pg{display:inline-flex;font-size:var(--fs-md);color:var(--dim);overflow:visible;flex:none;justify-content:center;align-items: center;width:16px;height:16px;line-height:1}.pg-c1{color:var(--c1)}.pg-c2{color:var(--c2)}.pg-c3{color:var(--c3)}.pg-c4{color:var(--c4)}.pg-c5{color:var(--c5)}.pg-c6{color:var(--c6)}.pg-c7{color:var(--c7)}.pg-img{object-fit:cover;border-radius:var(--r-xs);display:block;width:16px;height:16px}.pg-lg{font-size:var(--fs-2xl);border:1px solid var(--line);border-radius:var(--r-sm);background:var(--panel-2);overflow:hidden;width:34px;height:34px;line-height:1}.pg-lg .pg-img{border-radius:0;width:34px;height:34px}.icon-row{display:flex;align-items: center;gap:8px}.icon-row input{flex:1}.icon-row .btn{display:inline-flex;padding:var(--pad-ctl);border:1px solid var(--line);border-radius:var(--r-sm);background:var(--panel-2);color:var(--fg-2);cursor:pointer;font:500 var(--fs-sm)var(--sans);white-space:nowrap;align-items: center;gap:5px}.icon-row .btn:hover{border-color:var(--acc)}.emoji-row{display:flex;flex-wrap:wrap;gap:4px}.emoji-all{overflow:auto;border:1px solid var(--line);border-radius:var(--r-sm);display:grid;gap:6px;max-height:200px;padding:8px}.emoji-sec{font-size:var(--fs-2xs);color:var(--dim);text-transform:uppercase;letter-spacing:.06em;margin-top:4px;font-weight:600}.more-emoji{color:var(--fg-2);font-weight:700}.emoji{display:inline-flex;border:1px solid var(--line);border-radius:var(--r-sm);cursor:pointer;font-size:var(--fs-xl);background:var(--panel-2);color:var(--dim);overflow:hidden;justify-content:center;align-items: center;width:34px;height:34px;line-height:1}.emoji .ph{width:14px;height:14px}.emoji:hover{border-color:var(--acc)}.emoji.on{border-color:var(--acc);background:var(--acc-soft)}.swatches{display:flex;gap:6px}.swatch{cursor:pointer;box-shadow:inset 0 0 0 2px var(--panel);background:currentColor;border:2px solid #0000;border-radius:50%;width:22px;height:22px}.swatch.none{background:var(--panel-2);color:var(--line);box-shadow:inset 0 0 0 1px var(--line)}.swatch:hover{border-color:var(--fg-2)}.swatch.on{border-color:var(--fg)}.pk-b label.chk{display:flex;flex-direction:row;align-items: center;gap:8px}.pk-b label.chk input{width:auto}.kpis-5{grid-template-columns:repeat(auto-fit,minmax(160px,1fr))}.kpi.hot .v{color:var(--warn)}.kpi.warm .v{color:var(--acc)}.grow{flex:1}.kanban{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));margin-bottom:var(--gap-sec);align-items: start;gap:12px}.lane{background:var(--panel-2);border:1px solid var(--line);border-radius:var(--r);display:flex;flex-direction:column;gap:8px;min-height:60px;padding:8px}.lane-h{font-size:var(--fs-sm);color:var(--dim);text-transform:uppercase;letter-spacing:.06em;padding:2px 4px;font-weight:600}.lane-h span{color:var(--faint);font-weight:500}.lane-empty{color:var(--faint);text-align:center;padding:10px 0}.lane-more{font-size:var(--fs-xs);padding:2px 4px}.tcard{background:var(--panel);border:1px solid var(--line);border-radius:var(--r-sm);box-shadow:var(--shadow);cursor:pointer;transition:border-color var(--t-fast);padding:8px 10px}.tcard:hover{border-color:var(--acc);outline:none}.tcard:focus-visible{border-color:var(--acc);outline:none}.wt:focus-visible{border-color:var(--acc);outline:none}.more:focus-visible{border-color:var(--acc);outline:none}.more:focus-visible{opacity:1}.tcard.ready{border-color:var(--ok)}.tcard.held{border-color:var(--acc)}.tcard.blocked{border-color:var(--line)}.tcard.done{opacity:.7}.tc-h{display:flex;font-size:var(--fs-sm);align-items: center;gap:8px;margin-bottom:3px}.tc-h .dim{font-family:var(--mono);font-size:var(--fs-2xs);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.tc-t{font-size:var(--fs-md);color:var(--fg);display:-webkit-box;-webkit-line-clamp:3;overflow:hidden;-webkit-box-orient:vertical;line-height:1.35}.tc-m{font-size:var(--fs-xs);color:var(--faint);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-top:4px}.tc-g{margin-top:6px}.wtmap{display:flex;margin-bottom:var(--gap-sec);flex-direction:column;gap:14px}.wt-proj{font-size:var(--fs-sm);color:var(--dim);text-transform:uppercase;letter-spacing:.06em;margin-bottom:6px;font-weight:600}.wt-proj span{color:var(--faint);font-weight:500}.wt-tiles{display:grid;grid-template-columns:repeat(auto-fill,minmax(210px,1fr));gap:8px}.wt{background:var(--panel);border:1px solid var(--line);border-radius:var(--r-sm);box-shadow:var(--shadow);cursor:pointer;transition:border-color var(--t-fast);min-width:0;padding:8px 10px}.wt:hover{border-color:var(--acc)}.wt.main{background:var(--panel-2)}.wt.live{border-color:var(--ok)}.wt.dirty{border-color:var(--warn)}.wt.merged{opacity:.6}.wt-b{display:flex;align-items: center;gap:6px;min-width:0}.wt-b .s{flex:none;margin:0}.wt-b .br{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.wt-m{font-size:var(--fs-xs);color:var(--faint);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-top:3px}.wt-m i{font-style:normal}.wt-m i.warn{color:var(--warn)}.wt-m i.acc{color:var(--acc)}.chips{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:14px}.chip{display:inline-flex;font:500 var(--fs-md)var(--sans);border-radius:var(--r-pill);background:var(--panel);border:1px solid var(--line);color:var(--dim);cursor:pointer;user-select:none;align-items: center;gap:5px;padding:4px 11px}.chip:hover{border-color:var(--acc);color:var(--fg-2)}.chip.on{background:var(--acc-soft);color:var(--acc);border-color:#0000}.seg{display:inline-flex;background:var(--panel-2);border:1px solid var(--line);border-radius:var(--r-sm);gap:2px;padding:2px}.seg a{border-radius:var(--r-sm);font:600 var(--fs-md)var(--sans);color:var(--dim);text-decoration:none;transition:color var(--t-fast),background var(--t-fast);letter-spacing:0;text-transform:none;padding:3px 10px}.seg a:hover{color:var(--fg-2)}.seg a.on{background:var(--acc-soft);color:var(--acc)}.chip b{font-weight:700}.wf-steps{display:inline-flex;flex-wrap:wrap;gap:6px}.wfs{font:500 var(--fs-sm)var(--sans);color:var(--dim);background:var(--panel-2);border:1px solid var(--line);border-radius:var(--r-pill);white-space:nowrap;padding:1px 8px}.wfs.ok{color:var(--ok);background:var(--ok-soft);border-color:#0000}.wfs.run{color:var(--acc);background:var(--acc-soft);border-color:#0000}.wfs.bad{color:var(--warn);background:var(--warn-soft);border-color:#0000}.tl-track u{position:absolute;opacity:.95;border-radius:1px;width:2px;top:4px;bottom:4px}.tl-track i.thin{opacity:.25}.tl-row.claimlane .tl-name{font-size:var(--fs-2xs);text-transform:uppercase;letter-spacing:.06em}.tl-track i.claim{background:var(--violet);opacity:.6;border-radius:2px;height:4px;top:7px}.tl-track i.claim.orphaned{background:var(--warn);opacity:.9}.tl-track i.claim.expired{background:var(--faint)}.proj-spark{display:inline-flex;opacity:.7;flex:none;width:44px}.proj-spark .spark{width:44px;height:14px}.gh-strip{display:inline-flex;gap:12px;font-weight:400}.gh{font-size:var(--fs-sm);color:var(--dim);display:inline-flex;align-items: center;gap:3px}.gh i{display:inline-block;border-radius:2px;width:7px;height:7px}.gh i.ok{background:var(--ok)}.gh i.bad{background:var(--warn)}.msgs{display:flex;overflow:auto;flex-direction:column;gap:6px;max-height:220px;margin-bottom:8px}.msg{background:var(--panel-2);border:1px solid var(--line);border-radius:var(--r-sm);font-size:var(--fs-md);color:var(--fg-2);word-break:break-word;padding:6px 9px}.msg.out{background:var(--acc-soft);border-color:#0000}.msg-f{display:block;font-size:var(--fs-2xs);color:var(--dim);margin-bottom:2px}.msg-compose{display:flex;gap:6px}.msg-compose input{background:var(--panel-2);border:1px solid var(--line);color:var(--fg);border-radius:var(--r-sm);font:400 var(--fs-md)var(--sans);flex:1;min-width:0;padding:7px 10px}.msg-compose input:focus{border-color:var(--acc);outline:none}.msg-compose button{display:inline-flex;background:var(--panel-2);border:1px solid var(--line);color:var(--fg-2);border-radius:var(--r-sm);cursor:pointer;font:500 var(--fs-sm)var(--sans);flex:none;align-items: center;gap:5px;padding:7px 11px}.msg-compose button:hover{color:var(--acc);border-color:var(--acc)}.msg-compose input:disabled,.msg-compose button:disabled{opacity:.45;cursor:not-allowed}.msg-compose button:disabled:hover{color:var(--fg-2);border-color:var(--line)}.msg-hint{display:flex;color:var(--dim);font-size:var(--fs-sm);align-items: center;gap:5px;margin:7px 0 0;line-height:1.4}.msg-hint .ph{color:var(--faint);flex:none}.msg-hint b{color:var(--fg-2);font-weight:600}.pathrow{display:flex;text-align:left;cursor:pointer;background:var(--panel-2);border:1px solid var(--line);border-radius:var(--r-sm);color:var(--fg-2);font:400 var(--fs-sm)var(--mono);align-items: center;gap:6px;width:100%;padding:6px 9px}.pathrow:hover{border-color:var(--acc);color:var(--fg)}.pathrow .dir{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--dim);flex:0 9999 auto;min-width:0}.pathrow b{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:0 auto;min-width:0;font-weight:400}.pathrow .cp{color:var(--faint);flex:none;margin-left:auto}.pathrow:hover .cp{color:var(--acc)}.pathrow.copied{border-color:var(--ok);color:var(--ok)}.pathrow.copied .dir,.pathrow.copied .cp{color:var(--ok)}.pathrow.copy-failed{border-color:var(--bad);color:var(--bad)}.pathrow.copy-failed .dir,.pathrow.copy-failed .cp{color:var(--bad)}.onboard{background:var(--panel);border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--shadow);display:flex;flex-direction:column;align-items: flex-start;gap:16px;max-width:640px;margin:40px auto;padding:28px 30px}.onboard h3{font-size:var(--fs-xl);color:var(--fg)}.onboard .px{margin:0 auto}.ob-steps{display:flex;flex-direction:column;gap:12px}.ob-step{display:flex;color:var(--fg-2);align-items: flex-start;gap:12px;line-height:1.5}.ob-step.done{color:var(--dim)}.ob-n{border:1px solid var(--line);display:inline-flex;font:600 var(--fs-sm)var(--sans);color:var(--dim);border-radius:50%;flex:none;justify-content:center;align-items: center;width:22px;height:22px;margin-top:1px}.ob-step.done .ob-n{background:var(--ok-soft);color:var(--ok);border-color:#0000}.nudge{position:fixed;z-index:40;background:var(--panel);border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--shadow-pop);display:flex;font:var(--fs-md)var(--sans);color:var(--fg-2);align-items: flex-start;gap:12px;max-width:400px;padding:14px 16px;line-height:1.5;bottom:18px;right:18px}.nudge .ic{color:var(--acc);flex:none;margin-top:1px}.nudge b{color:var(--fg);display:block;margin-bottom:2px}.nudge .row{display:flex;white-space:nowrap;align-items: center;gap:8px;margin-top:10px}.nudge button.pri{background:var(--acc-soft);color:var(--acc);border-color:#0000}.nudge a.dim{color:var(--dim);font-size:var(--fs-sm);margin-left:auto}body.nosb .nudge{right:18px}.dt .th-cols{font:inherit;background:0 0;border:0;padding:0}#root{display:contents}.note{font-size:var(--fs-sm);margin-top:10px}.proj,.chip,.h4-act,.nav-group,.mini-act{appearance:none;font:inherit;color:inherit;text-align:left;background:0 0;border:0}.proj{width:100%}.chart-card.flush{margin:0}.stack{display:flex;gap:var(--gap-sec);flex-direction:column;min-width:0}.rule-spark{display:flex;align-items: center;gap:12px;margin-bottom:10px}.rule-spark .dim{font-size:var(--fs-sm)}.rule-shape{font-size:var(--fs-md);margin:0 0 8px}.h4-note{text-transform:none;letter-spacing:0;font-weight:400}.chips.pager{margin-top:10px}.chips.pager .dim{font-size:var(--fs-sm);align-self: center}tr.clickable{cursor:pointer}.link{appearance:none;font:inherit;color:var(--acc);cursor:pointer;text-align:left;background:0 0;border:0;padding:0}.link:hover{text-decoration:underline}.h2-actions{margin-left:auto}.gpager{display:flex;border-top:1px solid var(--line);font-size:var(--fs-sm);align-items: center;gap:10px;padding:7px 12px}.gpager .gp-size{margin-left:auto}.gp-btn{appearance:none;border-radius:var(--r-xs);color:var(--dim);cursor:pointer;display:inline-flex;background:0 0;border:0;padding:2px}.gp-btn:hover:not(:disabled){color:var(--acc);background:var(--panel-2)}.gp-btn:disabled{color:var(--line-2);cursor:default}.mt-panel{margin-top:14px}.bipartite{max-width:1100px}.matrix-scroll{overflow:auto}.card-pad{padding:14px}.card-scroll{overflow:auto;max-height:72vh;padding:14px}.graph-key{display:flex;font-size:var(--fs-sm);flex-wrap:wrap;align-items: center;gap:18px;margin-top:10px}.graph-key svg{vertical-align:middle}.edge-key{display:inline-flex;align-items: center;gap:6px}.dag-node{cursor:pointer}.ring-card{margin-bottom:12px}.ring-list{margin:8px 0 0;padding-left:18px}.more{appearance:none;font:inherit;color:inherit;background:0 0;border:0}.pk-sub{flex:1;margin-left:8px}.rp-summary{font-family:var(--mono);font-size:var(--fs-sm);margin-bottom:8px}.rp-range{flex:1;max-width:280px}.df-commits{font-size:var(--fs-sm)}.df-files button{appearance:none;font:inherit;color:inherit;text-align:left;background:0 0;border:0;width:100%}.wn-full{color:var(--dim);font-size:var(--fs-sm);align-self: center}.linkish{font:inherit;cursor:pointer;text-decoration:underline;background:0 0;border:0;padding:0}.linkish:hover{color:var(--fg-2)}
|