@netnodeag/kraftwerk 0.19.0 → 0.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -205,14 +205,20 @@ editing the files — the definition is read fresh for each new session).
205
205
 
206
206
  Chats — general ones and team sessions — can use skills: Claude-style
207
207
  instruction packages, one folder per skill with a `SKILL.md` (YAML
208
- frontmatter `name` + `description`, then the instructions). Two roots are
209
- discovered, with a project skill shadowing a same-named user skill:
208
+ frontmatter `name` + `description`, then the instructions). Discovered
209
+ roots, each shadowing same-named skills in the roots below it:
210
210
 
211
211
  ```
212
- <project>/.claude/skills/<name>/SKILL.md # git-tracked, per project
213
- ~/.claude/skills/<name>/SKILL.md # personal, per user
212
+ <project>/agents/<slug>/skills/<name>/SKILL.md # private to that one team agent
213
+ <project>/<skills root>/<name>/SKILL.md # workspace, git-tracked (kraftwerk.yml `skills`, default skills/)
214
+ <project>/.claude/skills/<name>/SKILL.md # git-tracked, per project
215
+ ~/.claude/skills/<name>/SKILL.md # personal, per user
214
216
  ```
215
217
 
218
+ Agent skills are visible only to that agent's sessions and always apply —
219
+ a member's `skills:` allowlist narrows the shared roots only. They're
220
+ managed in the agent profile ("own skills") or by editing the files.
221
+
216
222
  Every chat lists its visible skills as context ("## Your skills"), so the
217
223
  agent reaches for one when the request matches. Typing `/` in the composer
218
224
  opens an autocomplete over them; sending `/<name> <args>` expands the
package/dist/cli/ui.js CHANGED
@@ -1,16 +1,21 @@
1
1
  import { existsSync } from "node:fs";
2
2
  import path from "node:path";
3
3
  import { fileURLToPath } from "node:url";
4
- import { spawnSync } from "node:child_process";
4
+ import { spawn, spawnSync } from "node:child_process";
5
5
  import chalk from "chalk";
6
6
  import { resolveProject } from "../config.js";
7
- import { startInspector } from "../inspector/server.js";
7
+ import { RESTART_EXIT_CODE, startInspector } from "../inspector/server.js";
8
8
  /**
9
9
  * `kraftwerk ui` — start the inspector web UI pointed at the current
10
10
  * project's output dir. The server is dependency-free node:http (part of
11
11
  * this package); the frontend is a prebuilt Vite bundle shipped in
12
12
  * inspector/dist. Nothing to install at runtime — the server starts
13
13
  * instantly and runs in the foreground until Ctrl-C.
14
+ *
15
+ * The command is a thin supervisor: the actual server runs as a child
16
+ * process and is respawned whenever it exits with RESTART_EXIT_CODE
17
+ * (POST /api/restart, offered by the UI when a newer version landed on
18
+ * disk) — the fresh process loads the freshly installed code.
14
19
  */
15
20
  /** Package root is two levels up from this file (src/cli/ or dist/cli/). */
16
21
  const packageRoot = () => path.join(path.dirname(fileURLToPath(import.meta.url)), "../..");
@@ -41,6 +46,8 @@ function ensureBuilt() {
41
46
  return dist;
42
47
  }
43
48
  export async function runUi(cwd, opts) {
49
+ if (process.env.KRAFTWERK_UI_SUPERVISED !== "1")
50
+ return superviseUi(opts);
44
51
  const staticDir = ensureBuilt();
45
52
  const project = await resolveProject(cwd);
46
53
  const outputDir = opts.output ? path.resolve(cwd, opts.output) : project.outputDir;
@@ -50,3 +57,29 @@ export async function runUi(cwd, opts) {
50
57
  console.log(`${chalk.green("✔")} Kraftwerk UI: ${chalk.cyan(`http://localhost:${port}`)} ` +
51
58
  chalk.dim(`(output: ${outputDir})`));
52
59
  }
60
+ /**
61
+ * Respawn loop around the real server. Spawns this same bin script via the
62
+ * current node — works identically for global installs, local node_modules,
63
+ * npx, and a file: dev checkout. Any exit other than RESTART_EXIT_CODE
64
+ * (including Ctrl-C, which signals the whole foreground group) ends the loop.
65
+ */
66
+ async function superviseUi(opts) {
67
+ const args = [
68
+ process.argv[1],
69
+ "ui",
70
+ ...(opts.port ? ["--port", opts.port] : []),
71
+ ...(opts.output ? ["--output", opts.output] : []),
72
+ ];
73
+ for (;;) {
74
+ const child = spawn(process.execPath, args, {
75
+ stdio: "inherit",
76
+ env: { ...process.env, KRAFTWERK_UI_SUPERVISED: "1" },
77
+ });
78
+ const code = await new Promise((resolve) => {
79
+ child.once("exit", (c, signal) => resolve(signal ? null : c));
80
+ });
81
+ if (code !== RESTART_EXIT_CODE)
82
+ process.exit(code ?? 0);
83
+ console.log(chalk.dim("↻ relaunching the UI with the current install ..."));
84
+ }
85
+ }
@@ -74,18 +74,20 @@ function emit(state, ev) {
74
74
  /* ---------- skills ---------- */
75
75
  /**
76
76
  * Skills visible to a chat: every discovered skill (workspace skills root
77
- * + .claude/skills roots), narrowed by the team member's allowlist when the chat
78
- * is a team session (absent allowlist = all, empty = none).
77
+ * + .claude/skills roots, plus the member's own agents/<slug>/skills for team
78
+ * sessions), narrowed by the team member's allowlist when the chat is a team
79
+ * session (absent allowlist = all, empty = none). The agent's own skills
80
+ * always apply — the allowlist narrows shared skills only.
79
81
  */
80
82
  async function availableSkills(scope) {
81
- const all = await listSkills().catch(() => []);
82
- if (scope.kind !== "team" || all.length === 0)
83
+ const all = await listSkills(scope.kind === "team" ? scope.member : undefined).catch(() => []);
84
+ if (scope.kind !== "team")
83
85
  return all;
84
86
  const member = await getMember(scope.member).catch(() => null);
85
87
  if (!member || member.skills === undefined)
86
88
  return all;
87
89
  const allowed = new Set(member.skills.map((n) => n.toLowerCase()));
88
- return all.filter((s) => allowed.has(s.name.toLowerCase()));
90
+ return all.filter((s) => s.source === "agent" || allowed.has(s.name.toLowerCase()));
89
91
  }
90
92
  /** "## Your skills" context block (empty when no skills are visible). */
91
93
  function skillsBlock(skills) {
@@ -1,4 +1,6 @@
1
1
  import http from "node:http";
2
+ /** Exit code the `kraftwerk ui` supervisor treats as "relaunch me". */
3
+ export declare const RESTART_EXIT_CODE = 75;
2
4
  export interface InspectorOptions {
3
5
  outputDir: string;
4
6
  staticDir: string;
@@ -9,7 +9,7 @@ import { dockerStatus, triggerRun, stopRun } from "./runner.js";
9
9
  import { cancelChat, createChat, deleteChat, disposeAllBackends, getChat, listChats, postMessage, resolvePermission, subscribeChat, } from "./chat/sessions.js";
10
10
  import { bundleDetail, conceptDetail, createBundle, knowledgeIndex, putConcept, verifyFromUi, } from "./knowledge.js";
11
11
  import { deleteMember, getMember, listMembers, saveMember, teamRoot, } from "./team.js";
12
- import { getSkill, listSkills, skillsRoot } from "./skills.js";
12
+ import { deleteAgentSkill, getSkill, listAgentSkills, listSkills, readSkill, saveAgentSkill, skillsRoot, } from "./skills.js";
13
13
  import { deleteRoutine, routineStatuses, runRoutineNow, saveRoutine, startRoutineScheduler, } from "./routines.js";
14
14
  /**
15
15
  * The inspector server: a plain node:http server with no dependencies.
@@ -55,18 +55,24 @@ function readBody(req) {
55
55
  req.on("error", reject);
56
56
  });
57
57
  }
58
- /** Package version, read once. Works from src/ (tsx) and dist/ alike. */
58
+ /** Exit code the `kraftwerk ui` supervisor treats as "relaunch me". */
59
+ export const RESTART_EXIT_CODE = 75;
60
+ /** Whether a supervisor is around to respawn us (set by `kraftwerk ui`). */
61
+ const supervised = () => process.env.KRAFTWERK_UI_SUPERVISED === "1";
62
+ /** Package version as it is on disk right now (re-read per call, detects upgrades). */
63
+ async function getDiskVersion() {
64
+ try {
65
+ const raw = await fs.readFile(new URL("../../package.json", import.meta.url), "utf8");
66
+ return JSON.parse(raw).version ?? "";
67
+ }
68
+ catch {
69
+ return "";
70
+ }
71
+ }
72
+ /** Package version this process loaded with, read once. Works from src/ (tsx) and dist/ alike. */
59
73
  let pkgVersion;
60
74
  async function getPkgVersion() {
61
- if (pkgVersion === undefined) {
62
- try {
63
- const raw = await fs.readFile(new URL("../../package.json", import.meta.url), "utf8");
64
- pkgVersion = JSON.parse(raw).version ?? "";
65
- }
66
- catch {
67
- pkgVersion = "";
68
- }
69
- }
75
+ pkgVersion ??= await getDiskVersion();
70
76
  return pkgVersion;
71
77
  }
72
78
  async function handleApi(req, res, url) {
@@ -78,11 +84,27 @@ async function handleApi(req, res, url) {
78
84
  const projectName = project?.config.name ?? (project ? path.basename(project.root) : "");
79
85
  return json(res, {
80
86
  version: await getPkgVersion(),
87
+ // A differing disk version means an upgrade landed while this process
88
+ // runs — the UI offers a relaunch when a supervisor can respawn us.
89
+ diskVersion: await getDiskVersion(),
90
+ restartable: supervised(),
81
91
  projectName,
82
92
  projectIcon: project?.config.icon ?? "",
83
93
  switcher: project?.config.switcher ?? [],
84
94
  });
85
95
  }
96
+ // POST /api/restart — exit with the respawn code; the `kraftwerk ui` supervisor relaunches
97
+ if (seg.length === 2 && seg[1] === "restart" && method === "POST") {
98
+ if (!supervised()) {
99
+ return json(res, { error: "not supervised — restart `kraftwerk ui` manually" }, 400);
100
+ }
101
+ json(res, { ok: true });
102
+ setTimeout(() => {
103
+ disposeAllBackends();
104
+ process.exit(RESTART_EXIT_CODE);
105
+ }, 150);
106
+ return;
107
+ }
86
108
  // GET /api/runs
87
109
  if (seg.length === 2 && seg[1] === "runs" && method === "GET") {
88
110
  return json(res, { outputDir: getOutputDir(), runs: await listRuns() });
@@ -279,6 +301,41 @@ async function handleApi(req, res, url) {
279
301
  }
280
302
  }
281
303
  }
304
+ // GET/POST /api/team/:slug/skills — the agent's own skills / create or update one
305
+ if (seg.length === 4 && seg[1] === "team" && seg[3] === "skills") {
306
+ const slug = decodeURIComponent(seg[2]);
307
+ try {
308
+ if (method === "GET")
309
+ return json(res, { skills: await listAgentSkills(slug) });
310
+ if (method === "POST") {
311
+ const body = JSON.parse(await readBody(req));
312
+ return json(res, await saveAgentSkill(slug, String(body.name ?? ""), String(body.content ?? "")));
313
+ }
314
+ }
315
+ catch (err) {
316
+ return json(res, { error: err.message }, 400);
317
+ }
318
+ }
319
+ // GET/DELETE /api/team/:slug/skills/:name — one agent skill with content / delete
320
+ if (seg.length === 5 && seg[1] === "team" && seg[3] === "skills") {
321
+ const slug = decodeURIComponent(seg[2]);
322
+ const name = decodeURIComponent(seg[4]);
323
+ try {
324
+ if (method === "GET") {
325
+ const skill = (await listAgentSkills(slug)).find((s) => s.name.toLowerCase() === name.toLowerCase());
326
+ if (!skill)
327
+ return json(res, { error: "not found" }, 404);
328
+ return json(res, { ...skill, content: await readSkill(skill) });
329
+ }
330
+ if (method === "DELETE") {
331
+ await deleteAgentSkill(slug, name);
332
+ return json(res, { ok: true });
333
+ }
334
+ }
335
+ catch (err) {
336
+ return json(res, { error: err.message }, 400);
337
+ }
338
+ }
282
339
  // GET/POST /api/team/:slug/routines — list (with run state) / upsert
283
340
  if (seg.length === 4 && seg[1] === "team" && seg[3] === "routines") {
284
341
  const slug = decodeURIComponent(seg[2]);
@@ -12,6 +12,14 @@
12
12
  * shadows a same-named project skill, which shadows a same-named global
13
13
  * skill. Skills are surfaced to every chat as context (and expanded on
14
14
  * /<name> invocation), so they work identically on claude, codex, and pi.
15
+ *
16
+ * On top of the shared roots, each team agent can carry private skills in
17
+ *
18
+ * agents/<slug>/skills/<name>/SKILL.md (agent, git-tracked)
19
+ *
20
+ * Agent skills are visible only to that agent's sessions, always apply
21
+ * (the member's allowlist narrows shared skills only), and shadow
22
+ * same-named shared skills.
15
23
  */
16
24
  export interface SkillInfo {
17
25
  /** Frontmatter `name`, falling back to the folder name. */
@@ -21,8 +29,10 @@ export interface SkillInfo {
21
29
  path: string;
22
30
  /** Absolute path to the skill folder (for harnesses that take a dir). */
23
31
  dir: string;
24
- /** workspace = kraftwerk skills root; project = .claude/skills; user = ~/.claude/skills. */
25
- source: "workspace" | "project" | "user";
32
+ /** workspace = kraftwerk skills root; project = .claude/skills; user = ~/.claude/skills; agent = agents/<slug>/skills. */
33
+ source: "workspace" | "project" | "user" | "agent";
34
+ /** For source "agent": the owning member's slug. */
35
+ agent?: string;
26
36
  }
27
37
  export interface SkillDetail extends SkillInfo {
28
38
  /** Full SKILL.md contents. */
@@ -32,8 +42,21 @@ export interface SkillDetail extends SkillInfo {
32
42
  }
33
43
  /** Absolute workspace skills root (kraftwerk.yml `skills`, default skills/). */
34
44
  export declare function skillsRoot(): Promise<string>;
35
- /** All discovered skills; workspace shadows project shadows user (global). */
36
- export declare function listSkills(): Promise<SkillInfo[]>;
45
+ /** The private skills root of one team agent: agents/<slug>/skills. */
46
+ export declare function agentSkillsRoot(slug: string): Promise<string>;
47
+ /** One agent's private skills (agents/<slug>/skills/<name>/SKILL.md). */
48
+ export declare function listAgentSkills(slug: string): Promise<SkillInfo[]>;
49
+ /**
50
+ * All discovered skills; agent (when a member is given) shadows workspace
51
+ * shadows project shadows user (global).
52
+ */
53
+ export declare function listSkills(member?: string): Promise<SkillInfo[]>;
54
+ /** Create or update one agent skill; writes agents/<slug>/skills/<name>/SKILL.md. */
55
+ export declare function saveAgentSkill(slug: string, name: string, content: string): Promise<SkillInfo & {
56
+ content: string;
57
+ }>;
58
+ /** Delete one agent skill (removes its folder). */
59
+ export declare function deleteAgentSkill(slug: string, name: string): Promise<void>;
37
60
  /** Read a skill's SKILL.md contents (empty string when unreadable). */
38
61
  export declare function readSkill(skill: SkillInfo): Promise<string>;
39
62
  /** One skill by name (post-shadowing), with SKILL.md content + bundled files. */
@@ -4,6 +4,7 @@ import path from "node:path";
4
4
  import { parse } from "yaml";
5
5
  import { resolveProject } from "../config.js";
6
6
  import { getProjectRoot } from "./context.js";
7
+ import { safeMemberSlug, teamRoot } from "./team.js";
7
8
  const NAME_RE = /^[a-z0-9][a-z0-9_-]{0,63}$/i;
8
9
  function frontmatter(md) {
9
10
  const m = /^---\r?\n([\s\S]*?)\r?\n---(\r?\n|$)/.exec(md);
@@ -57,16 +58,29 @@ async function scanRoot(root, source) {
57
58
  }));
58
59
  return skills.filter(Boolean).sort((a, b) => a.name.localeCompare(b.name));
59
60
  }
60
- /** All discovered skills; workspace shadows project shadows user (global). */
61
- export async function listSkills() {
62
- const [workspace, project, user] = await Promise.all([
61
+ /** The private skills root of one team agent: agents/<slug>/skills. */
62
+ export async function agentSkillsRoot(slug) {
63
+ return path.join(await teamRoot(), safeMemberSlug(slug), "skills");
64
+ }
65
+ /** One agent's private skills (agents/<slug>/skills/<name>/SKILL.md). */
66
+ export async function listAgentSkills(slug) {
67
+ const skills = await scanRoot(await agentSkillsRoot(slug), "agent");
68
+ return skills.map((s) => ({ ...s, agent: slug }));
69
+ }
70
+ /**
71
+ * All discovered skills; agent (when a member is given) shadows workspace
72
+ * shadows project shadows user (global).
73
+ */
74
+ export async function listSkills(member) {
75
+ const [agent, workspace, project, user] = await Promise.all([
76
+ member ? listAgentSkills(member).catch(() => []) : [],
63
77
  skillsRoot().then((root) => scanRoot(root, "workspace")),
64
78
  scanRoot(path.join(getProjectRoot(), ".claude", "skills"), "project"),
65
79
  scanRoot(path.join(os.homedir(), ".claude", "skills"), "user"),
66
80
  ]);
67
- const out = [...workspace];
81
+ const out = [...agent];
68
82
  const seen = new Set(out.map((s) => s.name.toLowerCase()));
69
- for (const s of [...project, ...user]) {
83
+ for (const s of [...workspace, ...project, ...user]) {
70
84
  if (seen.has(s.name.toLowerCase()))
71
85
  continue;
72
86
  seen.add(s.name.toLowerCase());
@@ -74,6 +88,37 @@ export async function listSkills() {
74
88
  }
75
89
  return out;
76
90
  }
91
+ /** Create or update one agent skill; writes agents/<slug>/skills/<name>/SKILL.md. */
92
+ export async function saveAgentSkill(slug, name, content) {
93
+ const n = name.trim().toLowerCase();
94
+ if (!NAME_RE.test(n)) {
95
+ throw new Error("skill name must be letters, digits, - or _ (e.g. report-html)");
96
+ }
97
+ if (!content.trim())
98
+ throw new Error("content (SKILL.md) is required");
99
+ const dir = path.join(await agentSkillsRoot(slug), n);
100
+ await fs.mkdir(dir, { recursive: true });
101
+ const file = path.join(dir, "SKILL.md");
102
+ await fs.writeFile(file, content.endsWith("\n") ? content : content + "\n");
103
+ const fm = frontmatter(content);
104
+ const display = String(fm.name ?? n).trim() || n;
105
+ return {
106
+ name: NAME_RE.test(display) ? display : n,
107
+ description: String(fm.description ?? "").trim(),
108
+ path: file,
109
+ dir,
110
+ source: "agent",
111
+ agent: slug,
112
+ content,
113
+ };
114
+ }
115
+ /** Delete one agent skill (removes its folder). */
116
+ export async function deleteAgentSkill(slug, name) {
117
+ const skill = (await listAgentSkills(slug)).find((s) => s.name.toLowerCase() === name.toLowerCase());
118
+ if (!skill)
119
+ throw new Error(`skill "${name}" not found`);
120
+ await fs.rm(skill.dir, { recursive: true, force: true });
121
+ }
77
122
  /** Read a skill's SKILL.md contents (empty string when unreadable). */
78
123
  export function readSkill(skill) {
79
124
  return fs.readFile(skill.path, "utf8").catch(() => "");
@@ -0,0 +1 @@
1
+ @font-face{font-family:Roboto;font-style:normal;font-display:swap;font-weight:400;src:url(/assets/roboto-latin-400-normal-BqEyEoaF.woff2) format("woff2"),url(/assets/roboto-latin-400-normal-D27F5sTu.woff) format("woff")}@font-face{font-family:Roboto;font-style:normal;font-display:swap;font-weight:500;src:url(/assets/roboto-latin-500-normal-7RbcRiD8.woff2) format("woff2"),url(/assets/roboto-latin-500-normal-fsTFPL3E.woff) format("woff")}@font-face{font-family:Roboto;font-style:normal;font-display:swap;font-weight:700;src:url(/assets/roboto-latin-700-normal-BZpUvMxY.woff2) format("woff2"),url(/assets/roboto-latin-700-normal-YuyVweIx.woff) format("woff")}@font-face{font-family:Roboto Mono;font-style:normal;font-display:swap;font-weight:400;src:url(/assets/roboto-mono-latin-400-normal-GekRknry.woff2) format("woff2"),url(/assets/roboto-mono-latin-400-normal-DBZPkcnn.woff) format("woff")}@font-face{font-family:Roboto Mono;font-style:normal;font-display:swap;font-weight:500;src:url(/assets/roboto-mono-latin-500-normal-pxIOXZmA.woff2) format("woff2"),url(/assets/roboto-mono-latin-500-normal-D6j6AMzd.woff) format("woff")}@font-face{font-family:Roboto Mono;font-style:normal;font-display:swap;font-weight:700;src:url(/assets/roboto-mono-latin-700-normal-foxDnrFi.woff2) format("woff2"),url(/assets/roboto-mono-latin-700-normal-CHYrj1DZ.woff) format("woff")}:root{--font-sans: "Roboto";--font-mono: "Roboto Mono";--topbar-h: 53px;--primary: #f2bd57;--on-primary: #422c00;--primary-container: #5f4100;--on-primary-container: #ffdea9;--secondary: #d9c4a0;--on-secondary: #3b2f15;--secondary-container: #53452a;--on-secondary-container: #f6e0bb;--tertiary: #b1cfa1;--tertiary-container: #354d2a;--on-tertiary-container: #cdebbb;--error: #ffb4ab;--on-error: #690005;--error-container: #93000a;--on-error-container: #ffdad6;--success: #8fd48c;--success-container: #12411a;--on-success-container: #aaf2a4;--surface: #16130e;--on-surface: #eae1d6;--on-surface-variant: #cfc5b4;--surface-container-lowest: #100d08;--surface-container-low: #1e1b14;--surface-container: #221f18;--surface-container-high: #2d2921;--surface-container-highest: #38332b;--outline: #99907f;--outline-variant: #4d4639;--inverse-surface: #eae1d6;--inverse-on-surface: #34302a;--elev-1: 0 1px 2px rgba(0, 0, 0, .3), 0 1px 3px 1px rgba(0, 0, 0, .15);--elev-2: 0 1px 2px rgba(0, 0, 0, .3), 0 2px 6px 2px rgba(0, 0, 0, .15);--elev-3: 0 1px 3px rgba(0, 0, 0, .3), 0 4px 8px 3px rgba(0, 0, 0, .15);color-scheme:dark}:root[data-theme=light]{--primary: #7e5700;--on-primary: #ffffff;--primary-container: #ffdea9;--on-primary-container: #281900;--secondary: #6d5c3f;--on-secondary: #ffffff;--secondary-container: #f6e0bb;--on-secondary-container: #251a04;--tertiary: #4c6540;--tertiary-container: #cdebbb;--on-tertiary-container: #0a2005;--error: #ba1a1a;--on-error: #ffffff;--error-container: #ffdad6;--on-error-container: #410002;--success: #2e6b30;--success-container: #b0f1ab;--on-success-container: #002204;--surface: #fff8f2;--on-surface: #201b13;--on-surface-variant: #4e4639;--surface-container-lowest: #ffffff;--surface-container-low: #faf2e9;--surface-container: #f4ede3;--surface-container-high: #eee7dd;--surface-container-highest: #e9e1d8;--outline: #807663;--outline-variant: #d2c5b1;--inverse-surface: #35302a;--inverse-on-surface: #faf0e7;--elev-1: 0 1px 2px rgba(32, 27, 19, .18), 0 1px 3px 1px rgba(32, 27, 19, .08);--elev-2: 0 1px 2px rgba(32, 27, 19, .18), 0 2px 6px 2px rgba(32, 27, 19, .08);--elev-3: 0 1px 3px rgba(32, 27, 19, .18), 0 4px 8px 3px rgba(32, 27, 19, .08);color-scheme:light}*{box-sizing:border-box;margin:0;padding:0}html{height:100%}body{min-height:100%;background:var(--surface);color:var(--on-surface);font-family:var(--font-sans),system-ui,sans-serif;font-size:14px;line-height:1.5;letter-spacing:.01em;-webkit-font-smoothing:antialiased}a{color:inherit;text-decoration:none}button{font:inherit;color:inherit;background:none;border:0;cursor:pointer}code,pre,.mono{font-family:var(--font-mono),monospace}.topbar{position:sticky;top:0;z-index:10;height:var(--topbar-h);display:flex;align-items:center;gap:14px;padding:0 20px;background:color-mix(in srgb,var(--surface-container) 92%,transparent);-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);border-bottom:1px solid var(--outline-variant)}.wordmark,.wordmark-link{display:flex;align-items:center;gap:10px}.wordmark .lamp-block{width:26px;height:26px;border-radius:9px;background:var(--primary);display:grid;place-items:center}.wordmark .lamp-block span{width:8px;height:8px;border-radius:50%;background:var(--on-primary)}.wordmark b{font-size:15px;font-weight:500;letter-spacing:0}.wordmark small{font-size:12px;color:var(--on-surface-variant)}.wordmark .env-name{font-size:12px;font-weight:500;letter-spacing:.01em;color:var(--on-surface-variant);padding:2px 9px;border-radius:999px;border:1px solid var(--outline-variant);white-space:nowrap;max-width:220px;overflow:hidden;text-overflow:ellipsis}.switcher-wrap{position:relative;display:inline-flex}.env-switch{display:inline-flex;align-items:center;gap:4px;transition:background .12s ease,color .12s ease}.env-switch:hover{color:var(--on-surface);background:color-mix(in srgb,var(--on-surface) 8%,transparent)}.env-switch svg{flex:none;opacity:.7}.switcher-pop{position:absolute;top:calc(100% + 8px);left:0;z-index:20;min-width:240px;max-width:min(360px,90vw);background:var(--surface-container-high);border-radius:12px;box-shadow:var(--elev-2);padding:6px}.switcher-item{display:flex;align-items:center;gap:9px;padding:8px 10px;border-radius:8px;font-size:13px;color:var(--on-surface);transition:background .12s ease}a.switcher-item:hover{background:color-mix(in srgb,var(--on-surface) 8%,transparent)}.switcher-item.current{cursor:default}.switcher-icon{flex:none;width:18px;text-align:center;font-size:14px}.switcher-name{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.switcher-hint{margin-left:auto;font-size:11px;color:var(--on-surface-variant)}.switcher-url{margin-left:auto;padding-left:12px;font-size:11px;color:var(--on-surface-variant);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:160px}.topbar .spacer{flex:1}.topbar nav{display:flex;gap:4px;position:absolute;left:50%;transform:translate(-50%)}@media(max-width:1100px){.topbar nav{position:static;transform:none;margin-left:12px}}.topbar nav a{font-size:13px;font-weight:500;letter-spacing:.01em;text-transform:capitalize;color:var(--on-surface-variant);padding:6px 14px;border-radius:999px;transition:background .12s ease,color .12s ease}.topbar nav a:hover{color:var(--on-surface);background:color-mix(in srgb,var(--on-surface) 8%,transparent)}.topbar nav .nav-apart{margin-left:28px;position:relative}.topbar nav .nav-apart:before{content:"";position:absolute;left:-16px;top:50%;height:18px;width:1px;transform:translateY(-50%);background:var(--outline-variant)}.info-wrap{position:relative;display:inline-flex}.info-btn{display:grid;place-items:center;width:32px;height:32px;border-radius:50%;color:var(--on-surface-variant);transition:background .12s ease,color .12s ease}.info-btn:hover{background:color-mix(in srgb,var(--on-surface) 8%,transparent);color:var(--on-surface)}.info-pop{position:absolute;top:calc(100% + 8px);right:0;z-index:20;min-width:340px;max-width:min(480px,90vw);background:var(--surface-container-high);border-radius:12px;box-shadow:var(--elev-2);padding:8px 0}.info-row{display:flex;flex-direction:column;gap:2px;padding:8px 16px}.info-row+.info-row{border-top:1px solid color-mix(in srgb,var(--outline-variant) 55%,transparent)}.info-v{font-size:13px;color:var(--on-surface)}.info-path{font-size:11px;color:var(--on-surface-variant);overflow-wrap:break-word;word-break:break-all}.info-actions{flex-direction:row;align-items:center;justify-content:space-between}.info-actions .theme-btn{flex:none}.theme-btn{border:1px solid var(--outline);border-radius:999px;padding:6px 14px;font-size:12.5px;font-weight:500;color:var(--on-surface-variant);transition:background .12s ease,color .12s ease}.theme-btn:hover{background:color-mix(in srgb,var(--primary) 10%,transparent);color:var(--on-surface)}.relaunch-note{margin-right:10px;padding:4px 12px;border-radius:999px;font:inherit;font-size:12px;cursor:pointer;color:var(--primary);border:1px solid var(--primary);background:color-mix(in srgb,var(--primary) 10%,transparent)}.relaunch-note:hover{background:color-mix(in srgb,var(--primary) 18%,transparent)}.relaunch-note:disabled{opacity:.7;cursor:default}.expert-toggle{display:inline-flex;align-items:center;gap:7px;padding:4px 8px;margin-right:2px;border-radius:999px;font-family:var(--font-mono),monospace;font-size:11px;letter-spacing:.5px;color:var(--on-surface-variant);transition:color .12s ease}.expert-toggle:hover{color:var(--on-surface)}.expert-track{position:relative;width:26px;height:15px;border-radius:999px;background:color-mix(in srgb,var(--on-surface) 14%,transparent);transition:background .14s ease}.expert-knob{position:absolute;top:2px;left:2px;width:11px;height:11px;border-radius:50%;background:var(--surface);transition:left .14s ease,background .14s ease}.expert-toggle.on{color:var(--on-surface)}.expert-toggle.on .expert-track{background:var(--primary)}.expert-toggle.on .expert-knob{left:13px;background:var(--on-primary, var(--surface))}html[data-expert=off] .topbar nav,html[data-expert=off] .chat-thread .detail-head .chip.agent,html[data-expert=off] .chat-thread .detail-head .rid{display:none}.shell{max-width:1240px;margin:0 auto;padding:26px 20px 80px}.microlabel{font-size:11px;font-weight:500;letter-spacing:.045em;text-transform:capitalize;color:var(--on-surface-variant)}.num{font-variant-numeric:tabular-nums}.lamp{width:9px;height:9px;border-radius:50%;flex:none;position:relative}.lamp.ok{background:var(--success)}.lamp.failed,.lamp.blocked{background:var(--error)}.lamp.aborted{background:var(--outline-variant)}.lamp.pending{background:transparent;border:1.5px solid var(--outline)}.lamp.running{background:var(--primary);animation:lamp-pulse 1.4s ease-in-out infinite}@keyframes lamp-pulse{0%,to{box-shadow:0 0 color-mix(in srgb,var(--primary) 45%,transparent);opacity:1}50%{box-shadow:0 0 0 5px color-mix(in srgb,var(--primary) 18%,transparent);opacity:.8}}.status-word{font-size:12px;font-weight:500;letter-spacing:.03em;text-transform:capitalize}.status-word.ok{color:var(--success)}.status-word.failed,.status-word.blocked{color:var(--error)}.status-word.running{color:var(--primary)}.status-word.aborted,.status-word.pending{color:var(--on-surface-variant)}.page-head{display:flex;align-items:baseline;gap:14px;margin:6px 2px 20px}.page-head .spacer{flex:1}.page-head h1{font-size:24px;font-weight:400;letter-spacing:0}.page-head .count{color:var(--on-surface-variant);font-size:13px}.run-list{display:grid;gap:10px}.run-card{display:grid;grid-template-columns:12px 200px 1fr auto;gap:8px 16px;align-items:center;background:var(--surface-container-low);border:0;border-radius:12px;padding:14px 20px;box-shadow:var(--elev-1);transition:box-shadow .15s ease,background .15s ease}.run-card:hover{background:color-mix(in srgb,var(--on-surface) 5%,var(--surface-container-low));box-shadow:var(--elev-2)}.run-card .rid{font-family:var(--font-mono),monospace;font-size:12.5px;color:var(--on-surface-variant)}.run-card .wf{font-weight:500;font-size:14px}.run-card .req{color:var(--on-surface-variant);font-size:12.5px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:52ch}.run-card .meta{display:flex;gap:18px;align-items:center;font-family:var(--font-mono),monospace;font-size:12px;color:var(--on-surface-variant)}.progress-track{width:90px;height:4px;border-radius:999px;background:var(--surface-container-highest);overflow:hidden}.progress-track i{display:block;height:100%;background:var(--primary);border-radius:999px}.run-card.is-ok .progress-track i{background:var(--success)}.run-card.is-failed .progress-track i{background:var(--error)}.empty{border:1px dashed var(--outline-variant);border-radius:16px;padding:40px;text-align:center;color:var(--on-surface-variant)}.crumbs{display:flex;align-items:center;gap:8px;font-size:12.5px;color:var(--on-surface-variant);margin-bottom:14px}.crumbs a:hover{color:var(--primary)}.crumbs .sep{color:var(--outline-variant)}.detail-head{display:flex;flex-wrap:wrap;align-items:center;gap:10px 16px;margin-bottom:6px}.detail-head h1{font-size:22px;font-weight:400}.detail-head .rid{font-family:var(--font-mono),monospace;font-size:12px;color:var(--on-surface-variant)}.detail-req{color:var(--on-surface-variant);font-size:13px;margin-bottom:18px;max-width:90ch}.statgrid{display:flex;flex-wrap:wrap;gap:26px;margin-bottom:22px}.stat .microlabel{margin-bottom:1px}.stat .v{font-family:var(--font-mono),monospace;font-size:15px;font-weight:500}.columns{display:grid;grid-template-columns:minmax(430px,5fr) minmax(360px,4fr);gap:18px;align-items:start}@media(max-width:1020px){.columns{grid-template-columns:1fr}}.panel{background:var(--surface-container-low);border:0;border-radius:16px;box-shadow:var(--elev-1);overflow:hidden}.panel-head{display:flex;align-items:center;gap:10px;padding:12px 18px;border-bottom:1px solid var(--outline-variant);background:var(--surface-container)}.panel-head .microlabel{color:var(--on-surface-variant);font-size:12px}.panel-head .spacer{flex:1}.phases{padding:6px 0}.phase-row{position:relative;padding:10px 18px 10px 42px}.phase-row+.phase-row{border-top:1px solid color-mix(in srgb,var(--outline-variant) 55%,transparent)}.phase-row .lamp{position:absolute;left:19px;top:16px}.phase-row:before{content:"";position:absolute;left:23px;top:0;bottom:0;width:1px;background:var(--outline-variant)}.phase-row:first-child:before{top:16px}.phase-row:last-child:before{bottom:auto;height:16px}.phase-row .lamp{z-index:1}.phase-top{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap}.phase-name{font-weight:500;font-size:14px}.chip{font-family:var(--font-mono),monospace;font-size:11px;border:1px solid var(--outline-variant);border-radius:8px;padding:2px 10px;color:var(--on-surface-variant)}.chip.agent{border-color:transparent;background:var(--secondary-container);color:var(--on-secondary-container)}.phase-top .right{margin-left:auto;display:flex;gap:14px;font-family:var(--font-mono),monospace;font-size:11.5px;color:var(--on-surface-variant)}.phase-sub{margin-top:3px;font-size:12.5px;color:var(--on-surface-variant);max-width:72ch}.phase-activity{margin-top:3px;font-family:var(--font-mono),monospace;font-size:11.5px;color:var(--primary)}.phase-activity:before{content:"▸ "}.gate-line{margin-top:5px;display:flex;flex-wrap:wrap;gap:6px}.gate{display:inline-flex;align-items:center;gap:5px;font-family:var(--font-mono),monospace;font-size:11px;border-radius:8px;padding:2px 10px;background:var(--success-container);color:var(--on-success-container)}.gate.failed{background:var(--error-container);color:var(--on-error-container)}.gate-fail-msg{margin-top:4px;font-size:12px;color:var(--error)}.file-list{max-height:300px;overflow:auto}.file-row{display:flex;align-items:center;gap:10px;width:100%;text-align:left;padding:8px 18px;font-family:var(--font-mono),monospace;font-size:12.5px;border-bottom:1px solid color-mix(in srgb,var(--outline-variant) 55%,transparent);color:var(--on-surface-variant);transition:background .1s ease}.file-row:last-child{border-bottom:0}.file-row:hover{background:color-mix(in srgb,var(--on-surface) 6%,transparent);color:var(--on-surface)}.file-row.active{background:var(--secondary-container);color:var(--on-secondary-container)}.file-row .fname{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.file-row .fsize{color:var(--outline);font-size:11px}.viewer{border-top:1px solid var(--outline-variant)}.viewer-body pre{padding:14px 18px;overflow:auto;max-height:560px;font-size:12px;line-height:1.55;white-space:pre-wrap;word-break:break-word;color:var(--on-surface-variant)}.viewer-body iframe{width:100%;height:620px;border:0;background:#fff;display:block}.viewer-body img{max-width:100%;display:block;padding:14px 18px}.viewer-note{padding:6px 18px;font-size:11px;color:var(--on-surface-variant);border-bottom:1px solid color-mix(in srgb,var(--outline-variant) 55%,transparent)}.open-raw{font-size:12px;font-weight:500;color:var(--primary);border:1px solid var(--outline);border-radius:999px;padding:3px 12px;transition:background .12s ease}.open-raw:hover{background:color-mix(in srgb,var(--primary) 10%,transparent)}.live-note{display:inline-flex;align-items:center;gap:7px;font-size:11px;color:var(--on-surface-variant)}.wf-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:14px}.wf-card{display:flex;flex-direction:column;gap:6px;background:var(--surface-container-low);border:0;border-radius:16px;padding:18px 20px;box-shadow:var(--elev-1);transition:box-shadow .15s ease,background .15s ease}.wf-card:hover{background:color-mix(in srgb,var(--on-surface) 5%,var(--surface-container-low));box-shadow:var(--elev-2)}.wf-card-head{display:flex;align-items:baseline;gap:10px}.wf-name{font-weight:500;font-size:16px}.wf-desc{color:var(--on-surface-variant);font-size:13px;flex:1}.wf-meta{display:flex;gap:8px;font-family:var(--font-mono),monospace;font-size:11.5px;color:var(--on-surface-variant)}.wf-workspace{font-size:11.5px;color:var(--on-surface-variant);white-space:pre-wrap}.aid-0{--aid: var(--primary)}.aid-1{--aid: #4fb8a8}.aid-2{--aid: #a78bfa}.aid-3{--aid: #e5793b}.agent-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:0}.agent-card{padding:14px 18px;border-right:1px solid color-mix(in srgb,var(--outline-variant) 55%,transparent);border-bottom:1px solid color-mix(in srgb,var(--outline-variant) 55%,transparent)}.agent-head{display:flex;align-items:center;gap:8px;flex-wrap:wrap}.agent-head b{font-size:14px;font-weight:500}.agent-head .spacer{flex:1}.agent-id{font-size:11px;color:var(--on-surface-variant)}.agent-dot{width:10px;height:10px;border-radius:50%;background:var(--aid)}.agent-tools{display:flex;flex-wrap:wrap;gap:5px;margin-top:8px}.tool-chip{font-family:var(--font-mono),monospace;font-size:11px;border:1px solid var(--outline-variant);border-radius:8px;padding:1px 8px;color:var(--on-surface-variant)}.agent-persona{margin-top:8px;font-size:12px;color:var(--on-surface-variant);line-height:1.55;white-space:pre-wrap}.pipeline{padding:8px 0}.step-node{position:relative;display:flex;gap:14px;padding:12px 18px}.step-node+.step-node{border-top:1px solid color-mix(in srgb,var(--outline-variant) 55%,transparent)}.step-node:before{content:"";position:absolute;left:31px;top:0;bottom:0;width:1px;background:var(--outline-variant)}.step-node:first-child:before{top:18px}.step-node:last-child:before{bottom:auto;height:18px}.step-index{position:relative;z-index:1;flex:none;width:26px;height:26px;border-radius:50%;margin-top:1px;display:grid;place-items:center;font-family:var(--font-mono),monospace;font-size:11.5px;font-weight:700;background:color-mix(in srgb,var(--aid) 18%,var(--surface-container-low));border:1px solid color-mix(in srgb,var(--aid) 55%,var(--outline-variant));color:var(--aid)}.step-index.is-script{--aid: var(--on-surface-variant)}.step-body{flex:1;min-width:0}.agent-chip{border-color:color-mix(in srgb,var(--aid) 50%,var(--outline-variant));color:var(--aid);background:transparent}.step-source{margin-top:6px}.step-source summary{cursor:pointer;font-size:12px;font-weight:500;color:var(--on-surface-variant);-webkit-user-select:none;user-select:none}.step-source summary:hover{color:var(--primary)}.step-source pre{margin-top:6px;padding:10px 12px;border:0;border-radius:12px;background:var(--surface-container-high);font-size:11.5px;line-height:1.55;white-space:pre-wrap;word-break:break-word;color:var(--on-surface-variant);max-height:360px;overflow:auto}.gate.neutral{background:var(--surface-container-high);color:var(--on-surface-variant);border:0}::-webkit-scrollbar{width:10px;height:10px}::-webkit-scrollbar-thumb{background:var(--outline-variant);border-radius:999px;border:2px solid transparent;background-clip:content-box}::-webkit-scrollbar-track{background:transparent}.run-form{display:flex;gap:10px}.run-form input[type=text]{flex:1;font:13px/1.4 var(--font-mono),monospace;color:var(--on-surface);background:var(--surface-container-high);border:1px solid transparent;border-radius:999px;padding:10px 18px;outline:none;transition:border-color .12s ease,background .12s ease}.run-form input[type=text]:focus{border-color:var(--primary);background:var(--surface-container-highest)}.run-btn{font:500 13.5px/1 var(--font-sans),sans-serif;white-space:nowrap;color:var(--on-primary);background:var(--primary);border-radius:999px;padding:11px 24px;transition:box-shadow .12s ease,filter .12s ease}.run-btn:hover{box-shadow:var(--elev-1);filter:brightness(1.06)}.run-btn:disabled{opacity:.38;cursor:not-allowed;filter:none;box-shadow:none}.run-btn.tonal{color:var(--on-secondary-container);background:var(--secondary-container)}.run-opts{display:flex;flex-wrap:wrap;gap:6px 22px;margin-top:12px}.run-opts label{display:inline-flex;align-items:center;gap:8px;font-size:13px;color:var(--on-surface-variant);cursor:pointer}.run-opts input[type=checkbox]{accent-color:var(--primary);width:15px;height:15px}.run-opts .opt-hint{color:var(--outline)}.sandbox-chip{border:1px solid var(--outline-variant);color:var(--on-surface-variant)}.stop-btn{font:500 13px/1 var(--font-sans),sans-serif;color:var(--error);background:transparent;border:1px solid var(--outline);border-radius:999px;padding:8px 18px;transition:background .12s ease,border-color .12s ease}.stop-btn:hover{background:color-mix(in srgb,var(--error) 10%,transparent);border-color:var(--error)}.stop-btn:disabled{opacity:.38;cursor:default}.shell:has(.runs-screen){max-width:none;padding:0}.runs-screen{display:grid;grid-template-columns:300px minmax(0,1fr);align-items:start}.runs-side{position:sticky;top:var(--topbar-h);height:calc(100vh - var(--topbar-h));display:flex;flex-direction:column;border-right:1px solid var(--outline-variant);background:var(--surface-container-low)}.side-head{display:flex;align-items:center;gap:10px;padding:12px 16px;border-bottom:1px solid var(--outline-variant);background:var(--surface-container)}.side-head .spacer{flex:1}.side-list{flex:1;overflow-y:auto;padding:6px}.side-pinned{padding:6px;border-top:1px solid var(--outline-variant)}.side-pinned .side-row{margin-bottom:0}.side-row{display:flex;align-items:flex-start;gap:9px;padding:9px 12px;border-radius:12px;margin-bottom:2px;transition:background .1s ease}.side-row .lamp{margin-top:4px}.side-row:hover{background:color-mix(in srgb,var(--on-surface) 6%,transparent)}.side-row.active{background:var(--secondary-container)}.side-row.active .side-wf{color:var(--on-secondary-container)}.side-row-body{flex:1;min-width:0}.side-row-top{display:flex;align-items:baseline;gap:8px}.side-wf{font-weight:500;font-size:12.5px;flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.side-when{font-family:var(--font-mono),monospace;font-size:10.5px;color:var(--on-surface-variant)}.side-row-sub{display:flex;align-items:baseline;gap:8px;margin-top:1px}.side-row-sub .side-when{font-size:9px;opacity:.8}.side-req{flex:1;font-size:11.5px;color:var(--on-surface-variant);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.side-row.active .side-req{color:var(--on-secondary-container)}.side-meta{font-family:var(--font-mono),monospace;font-size:10.5px;color:var(--on-surface-variant)}.runs-main{padding:18px 22px 40px;min-width:0}.runs-main:has(>.chat-main){padding:0}.runs-main .detail-head .spacer{flex:1}.tabs{display:flex;gap:0;background:transparent;border:1px solid var(--outline);border-radius:999px;padding:0;overflow:hidden}.tabs button{font-size:12.5px;font-weight:500;letter-spacing:.01em;text-transform:capitalize;color:var(--on-surface-variant);padding:7px 18px;border-radius:0;transition:background .12s ease,color .12s ease}.tabs button+button{border-left:1px solid var(--outline)}.tabs button:hover{background:color-mix(in srgb,var(--on-surface) 6%,transparent);color:var(--on-surface)}.tabs button.active{background:var(--secondary-container);color:var(--on-secondary-container);box-shadow:none}.run-tab{max-width:1080px}.art-layout{display:grid;grid-template-columns:280px minmax(0,1fr);gap:14px;height:calc(100vh - 172px);min-height:420px}.art-files{display:flex;flex-direction:column;min-height:0}.art-files .file-list{flex:1;max-height:none}.art-viewer{display:flex;flex-direction:column;min-height:0}.art-viewer .viewer{flex:1;display:flex;flex-direction:column;min-height:0;border-top:0}.art-viewer .viewer-body{flex:1;min-height:0}.art-viewer .viewer-body iframe{height:100%}.art-viewer .viewer-body pre{max-height:none;height:100%;box-sizing:border-box}.art-viewer .viewer-body img{max-height:100%;object-fit:contain}.art-viewer .empty{flex:1;display:grid;place-items:center}.md-toolbar{display:flex;align-items:center;gap:12px}.md-toolbar .tabs button{font-size:11px;padding:3px 12px;text-transform:none}.md-body{height:100%;box-sizing:border-box;overflow:auto;padding:16px 22px;font-size:13.5px;line-height:1.6;color:var(--on-surface)}.md-body>:first-child{margin-top:0}.md-body h1,.md-body h2,.md-body h3,.md-body h4{margin:1.4em 0 .5em;line-height:1.25;font-weight:600}.md-body h1{font-size:20px}.md-body h2{font-size:16px;border-bottom:1px solid var(--outline-variant);padding-bottom:4px}.md-body h3{font-size:14px}.md-body p,.md-body ul,.md-body ol{margin:.6em 0}.md-body ul,.md-body ol{padding-left:1.6em}.md-body li+li{margin-top:.2em}.md-body a{color:var(--primary)}.md-body code{font-family:var(--font-mono),monospace;font-size:12px;background:color-mix(in srgb,var(--on-surface) 8%,transparent);padding:1px 5px;border-radius:4px}.md-body pre{background:color-mix(in srgb,var(--on-surface) 6%,transparent);border:1px solid var(--outline-variant);border-radius:8px;padding:10px 14px;overflow-x:auto;margin:.8em 0}.md-body pre code{background:none;padding:0}.md-body blockquote{margin:.8em 0;padding:2px 14px;border-left:3px solid var(--outline);color:var(--on-surface-variant)}.md-body table{border-collapse:collapse;margin:.8em 0;font-size:12.5px}.md-body th,.md-body td{border:1px solid var(--outline-variant);padding:5px 10px;text-align:left}.md-body th{background:color-mix(in srgb,var(--on-surface) 5%,transparent)}.md-body hr{border:0;border-top:1px solid var(--outline-variant);margin:1.2em 0}.md-body img{max-width:100%}@media(max-width:940px){.runs-screen{grid-template-columns:1fr}.runs-side{display:none}.art-layout{grid-template-columns:1fr;height:auto}.art-files .file-list{max-height:240px}.art-viewer .viewer-body iframe{height:560px}}.chat-main{display:flex;flex-direction:column;height:calc(100vh - var(--topbar-h));padding:16px 20px}.chat-thread{display:flex;flex-direction:column;flex:1;min-height:0;max-width:980px;width:100%;margin:0 auto}.chat-thread .detail-head{flex:none}.chat-thread .detail-head .rid{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:34ch}.chat-scroll{flex:1;min-height:0;overflow-y:auto;padding:14px 2px 20px;display:flex;flex-direction:column;gap:10px}.chat-scroll .empty{margin:auto;border:0}.msg{max-width:76ch;white-space:pre-wrap;word-break:break-word;font-size:14px;line-height:1.6}.msg.user{align-self:flex-end;background:var(--primary-container);color:var(--on-primary-container);border:0;border-radius:20px 20px 6px;padding:10px 16px}.msg.agent{align-self:flex-start;background:var(--surface-container);border:0;border-radius:20px 20px 20px 6px;padding:10px 16px}.msg.agent.chat-md{white-space:normal;height:auto;overflow:visible;padding:10px 16px;font-size:14px}.msg.agent.chat-md img{border-radius:10px;margin:4px 0;display:block}.msg.agent.chat-md pre{max-width:100%}.msg.error{align-self:flex-start;color:var(--error);font-size:12.5px}.msg.thought{align-self:flex-start;max-width:76ch}.msg.thought summary{cursor:pointer;font-size:12px;font-weight:500;color:var(--on-surface-variant);-webkit-user-select:none;user-select:none}.msg.thought div{margin-top:5px;padding:8px 12px;border-left:2px solid var(--outline-variant);color:var(--on-surface-variant);font-size:12px;white-space:pre-wrap;word-break:break-word}.tool-card{align-self:flex-start;display:inline-flex;align-items:flex-start;gap:8px;font-family:var(--font-mono),monospace;font-size:11px;color:var(--on-surface-variant);background:transparent;border:0;padding:0 2px;max-width:90ch}.tool-card+.tool-card{margin-top:-6px}.tool-card .lamp{margin-top:4px;width:7px;height:7px}.tool-card .chip.tool-kind{flex-shrink:0;border:0;background:transparent;padding:0;font-size:10px;text-transform:uppercase;letter-spacing:.5px;min-width:64px}.tool-card .tool-title{white-space:pre-wrap;word-break:break-word;overflow:visible;line-height:1.5;min-width:0}.perm-card{align-self:flex-start;border:0;background:var(--tertiary-container);color:var(--on-tertiary-container);border-radius:16px;padding:12px 16px;max-width:76ch;box-shadow:var(--elev-1)}.perm-card .perm-title{font-size:13.5px}.perm-card .perm-title .microlabel{color:var(--tertiary);margin-right:8px;font-weight:700}:root[data-theme=light] .perm-card .perm-title .microlabel{color:var(--on-tertiary-container)}.perm-actions{display:flex;flex-wrap:wrap;gap:8px;margin-top:10px}.perm-btn{font:500 13px/1 var(--font-sans),sans-serif;border-radius:999px;padding:8px 18px;border:1px solid var(--outline);transition:background .12s ease,filter .12s ease}.perm-btn.allow{color:var(--on-primary);background:var(--primary);border-color:transparent}.perm-btn.allow:hover{filter:brightness(1.06);box-shadow:var(--elev-1)}.perm-btn.deny{color:inherit}.perm-btn.deny:hover{border-color:var(--error);color:var(--error)}.perm-resolved{margin-top:6px;font-size:12px;color:var(--on-surface-variant);font-family:var(--font-mono),monospace}.chat-working{display:flex;align-items:center;gap:8px;font-size:12px;color:var(--on-surface-variant)}.composer{flex:none;display:flex;gap:10px;align-items:flex-end;padding:12px 0 4px;border-top:1px solid var(--outline-variant);position:relative}.skill-menu{position:absolute;bottom:100%;left:0;right:0;margin-bottom:6px;display:flex;flex-direction:column;overflow:hidden;background:var(--surface-container-high);border:1px solid var(--outline-variant);border-radius:14px;box-shadow:var(--elev-1);z-index:5}.skill-menu button{display:flex;align-items:baseline;gap:6px;text-align:left;padding:9px 14px;font-size:13px;background:transparent;border:0}.skill-menu button b{font-weight:500;font-family:var(--font-mono),monospace;font-size:12.5px}.skill-menu button span{color:var(--on-surface-variant);font-size:12px;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.skill-menu button .skill-src{margin-left:auto;flex:none;font-size:10.5px;text-transform:uppercase;letter-spacing:.04em}.skill-menu button:hover,.skill-menu button.active{background:color-mix(in srgb,var(--on-surface) 7%,transparent)}.composer textarea{flex:1;resize:none;font:14px/1.5 var(--font-sans),sans-serif;color:var(--on-surface);background:var(--surface-container-high);border:1px solid transparent;border-radius:24px;padding:12px 18px;outline:none;transition:border-color .12s ease,background .12s ease}.composer textarea:focus{border-color:var(--primary);background:var(--surface-container-highest)}.new-chat{max-width:640px;margin:0 auto;width:100%}.new-chat-panel{overflow:visible}.agent-pick{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;padding:14px 16px}.agent-pick-btn{display:flex;flex-direction:column;gap:3px;text-align:left;border:1px solid var(--outline-variant);border-radius:12px;padding:12px 14px;background:transparent;transition:background .12s ease,border-color .12s ease}.agent-pick-btn b{font-size:13.5px;font-weight:500}.agent-pick-btn span{font-size:11.5px;color:var(--on-surface-variant)}.agent-pick-btn:hover{background:color-mix(in srgb,var(--on-surface) 5%,transparent)}.agent-pick-btn.active{border-color:transparent;background:var(--secondary-container);color:var(--on-secondary-container)}.agent-pick-btn.active span{color:var(--on-secondary-container)}@media(max-width:940px){.chat-main{height:auto;min-height:calc(100vh - var(--topbar-h))}.agent-pick{grid-template-columns:1fr}}.know-intro{padding:12px 18px;font-size:13px;line-height:1.6;color:var(--on-surface-variant)}.know-intro code{font-size:11.5px}.know-newbundle{display:flex;gap:10px;padding:14px 18px}.know-newbundle input{flex:1;font:13px/1.4 var(--font-mono),monospace;color:var(--on-surface);background:var(--surface-container-high);border:1px solid transparent;border-radius:999px;padding:10px 18px;outline:none;transition:border-color .12s ease,background .12s ease}.know-newbundle input:focus{border-color:var(--primary);background:var(--surface-container-highest)}.know-table{width:100%;border-collapse:collapse;font-size:13px}.know-table td{padding:9px 18px;border-bottom:1px solid color-mix(in srgb,var(--outline-variant) 55%,transparent);vertical-align:baseline}.know-table tr:last-child td{border-bottom:none}.know-table a{color:var(--on-surface);text-decoration:none}.know-table a:hover b{color:var(--primary)}.know-id{font-family:var(--font-mono),monospace;font-size:11px;color:var(--on-surface-variant);margin-left:8px}.know-type{font-size:11.5px;color:var(--on-surface-variant);white-space:nowrap}.know-flags{text-align:right;white-space:nowrap}.chip.trust.unverified{color:var(--on-surface-variant)}.chip.trust.machine-confirmed{border-color:transparent;background:var(--secondary-container);color:var(--on-secondary-container)}.chip.trust.human-reviewed{border-color:transparent;color:var(--on-success-container);background:var(--success-container)}.chip.stale,.chip.deprecated{border-color:transparent;color:var(--on-error-container);background:var(--error-container)}.chip.draft{border-color:color-mix(in srgb,var(--primary) 45%,var(--outline-variant));color:var(--primary)}.dash{width:100%;max-width:1180px;margin:0 auto;padding:24px 28px 40px;box-sizing:border-box}.dash-actions{display:flex;gap:10px;margin:0 0 18px}.wf-pick-wrap{position:relative}.wf-pick-pop{position:absolute;top:calc(100% + 6px);left:0;z-index:30;min-width:280px;max-height:340px;overflow-y:auto;background:var(--surface-container);border:1px solid var(--outline-variant);border-radius:12px;padding:6px;box-shadow:var(--elev-2, 0 8px 24px rgb(0 0 0 / .18));display:flex;flex-direction:column}.wf-pick-item{display:flex;flex-direction:column;gap:2px;padding:8px 10px;border-radius:8px;text-decoration:none;color:inherit}.wf-pick-item:hover{background:color-mix(in srgb,var(--on-surface) 6%,transparent)}.wf-pick-name{font-size:13px;font-weight:500}.wf-pick-desc{font-size:11.5px;color:var(--on-surface-variant)}.wf-pick-empty{padding:8px 10px;font-size:12px;color:var(--on-surface-variant)}.dash-team{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:14px;margin-bottom:18px}.dash-team-empty{margin-bottom:18px}.dash-member{display:flex;flex-direction:column;background:var(--surface-container-low, var(--surface-container));border:1px solid var(--outline-variant);border-radius:16px;overflow:hidden;cursor:pointer}.dash-member:hover{border-color:var(--outline)}.lamp.idle{background:transparent;border:1.5px solid var(--outline-variant)}.dash-member-id{display:flex;flex-direction:column;align-items:center;gap:6px;padding:20px 16px 12px;text-align:center;text-decoration:none;color:inherit;flex:1}.dash-member-id:hover .dash-member-name{color:var(--primary)}.dash-member-name{font-size:15px;font-weight:600}.dash-member-foot{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:10px 14px;border-top:1px solid color-mix(in srgb,var(--outline-variant) 55%,transparent)}.dash-member-state{font-size:11px;color:var(--on-surface-variant)}.dash-member-state a{color:var(--primary);text-decoration:none}.dash-chat-btn{padding:4px 13px;font-size:12px;color:var(--primary);background:transparent;border:1px solid var(--outline)}.dash-chat-btn:hover{background:color-mix(in srgb,var(--primary) 10%,transparent);box-shadow:none;filter:none}.dash-feed{margin:0}.agent-avatar{position:relative;flex:none;width:38px;height:38px;border-radius:50%;display:grid;place-items:center;background:var(--secondary-container);font-size:19px;line-height:1}.agent-avatar .lamp{position:absolute;right:-1px;bottom:-1px;width:10px;height:10px;border:2px solid var(--surface-container-low)}.agent-avatar .lamp.idle{background:var(--outline-variant)}.agent-avatar.sm{width:30px;height:30px;font-size:15px}.agent-avatar.lg{width:56px;height:56px;font-size:28px}.agent-avatar.lg .lamp{width:12px;height:12px;right:1px;bottom:1px}.dash-alert{display:flex;align-items:center;gap:8px;width:100%;margin:0 0 14px;padding:9px 14px;text-align:left;cursor:pointer;font-size:12.5px;border:1px solid color-mix(in srgb,var(--error) 40%,transparent);border-radius:12px;background:var(--error-container);color:var(--on-error-container)}.dash-alert:hover{filter:brightness(1.04)}.dash-feed-filter{display:flex;gap:6px}.feed-chip{font-size:11px;border:1px solid var(--outline-variant);border-radius:8px;padding:2px 10px;background:transparent;color:var(--on-surface-variant);cursor:pointer}.feed-chip:hover{color:var(--on-surface)}.feed-chip.on{border-color:transparent;background:var(--primary-container);color:var(--on-primary-container)}.feed-chip.on.failed{background:var(--error-container);color:var(--on-error-container)}.feed-day{padding:12px 18px 3px;border-top:1px solid color-mix(in srgb,var(--outline-variant) 55%,transparent)}.feed-group:first-child .feed-day{border-top:none;padding-top:6px}.feed-group+.feed-group .m3-row{border-top:1px solid color-mix(in srgb,var(--outline-variant) 55%,transparent)}.feed-group .feed-day+.m3-row{border-top:none}.dash-mini{display:flex;gap:18px;font-size:12px;color:var(--on-surface-variant);flex-wrap:wrap}.dash-mini a{color:inherit;text-decoration:none}.dash-mini a:hover{color:var(--primary);text-decoration:underline}.dash-mini b{font-weight:600;color:var(--on-surface)}.dash-mini a:hover b{color:var(--primary)}.chip.dash-kind{flex:none}.chip.status{flex:none;border-color:transparent;font-family:var(--font-sans),sans-serif;font-weight:500}.chip.status.ok{background:var(--success-container);color:var(--on-success-container)}.chip.status.failed{background:var(--error-container);color:var(--on-error-container)}.chip.status.running{background:var(--primary-container);color:var(--on-primary-container)}.chip.status.aborted{background:var(--surface-container-high);color:var(--on-surface-variant)}.chip.dash-kind.run{border-color:transparent;background:var(--primary-container);color:var(--on-primary-container)}.chip.dash-kind.session{border-color:transparent;background:var(--tertiary-container);color:var(--on-tertiary-container)}.chip.dash-kind.knowledge{border-color:transparent;background:var(--success-container);color:var(--on-success-container)}html[data-expert=off] .dash-mini,html[data-expert=off] .chip.dash-kind{display:none}.lamp.dim{background:var(--outline-variant)}.chip.skill-src{flex:none}.chip.skill-src.workspace{border-color:transparent;background:var(--success-container);color:var(--on-success-container)}.chip.skill-src.project,.chip.skill-src.user{color:var(--on-surface-variant)}.chip.skill-src.agent{border-color:transparent;background:var(--secondary-container);color:var(--on-secondary-container)}.skills-local-head{border-top:1px solid var(--outline-variant);margin-top:10px}.skill-desc{margin:-6px 2px 14px}.skill-path{word-break:break-all}.know-sub{display:flex;align-items:center;gap:8px;margin:-8px 2px 14px}.know-sub .rid{font-family:var(--font-mono),monospace;font-size:12px;color:var(--on-surface-variant)}.know-meta{display:flex;flex-direction:column;gap:8px;padding:12px 18px;font-size:13px}.know-meta>div{display:flex;gap:14px;align-items:baseline}.know-meta .microlabel{width:90px;flex:none}.know-verify-entry{display:inline-block;margin-right:14px}.know-folder-row td{padding:10px 18px 4px;border-bottom:none}.know-folder{font-family:var(--font-mono),monospace;font-size:11px;color:var(--on-surface-variant);letter-spacing:.04em}.know-indent{padding-left:32px!important}.side-group{border-radius:10px}.side-group+.side-group{margin-top:12px}.side-group.drop-over{outline:1.5px dashed var(--primary);outline-offset:-1.5px;background:color-mix(in srgb,var(--primary) 7%,transparent)}.side-group-head{display:flex;align-items:center;gap:6px;padding:6px 10px 2px}.side-group-count{font-size:10px;color:var(--on-surface-variant)}.side-group-x{padding:0 4px;font:inherit;font-size:11px;color:var(--on-surface-variant);background:transparent;border:none;cursor:pointer;opacity:0}.side-group:hover .side-group-x{opacity:1}.side-group-x:hover{color:var(--on-surface)}.side-group-empty{padding:6px 10px 8px;font-size:11px;color:var(--on-surface-variant)}.side-row.dragging{opacity:.4}.side-group-add{display:block;margin:12px 10px 4px;padding:4px 10px;font:inherit;font-size:11px;color:var(--on-surface-variant);background:transparent;border:1px dashed var(--outline-variant);border-radius:8px;cursor:pointer;text-align:left}.side-group-add:hover{color:var(--primary);border-color:var(--outline)}.side-group-new{padding:10px 10px 4px}.side-group-new input{width:100%;box-sizing:border-box}.side-group-rename{flex:1;min-width:0;font:inherit;font-size:11px}.team-screen{grid-template-columns:240px minmax(0,1fr)}.team-screen.has-sessions{grid-template-columns:240px 260px minmax(0,1fr)}.team-screen.has-sessions.has-knowledge{grid-template-columns:240px 260px minmax(0,1fr) var(--kside-w, 460px)}.knowledge-side{position:sticky;border-left:1px solid var(--outline-variant);border-right:0}.kside-resizer{position:absolute;left:-3px;top:0;bottom:0;width:7px;cursor:col-resize;z-index:4}.kside-resizer:hover{background:color-mix(in srgb,var(--primary) 25%,transparent)}.kside-headline{display:flex;flex-direction:column;gap:1px;min-width:0}.kside-hint{font-size:10.5px;color:var(--on-surface-variant);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.kside-bundle{padding:6px 8px 10px}.kside-bundle+.kside-bundle{border-top:1px solid var(--outline-variant)}.kside-bundle-head{display:flex;align-items:center;gap:2px;padding:2px 0}.kside-bundle-toggle{display:flex;align-items:center;gap:7px;flex:1;min-width:0;padding:6px 8px;border-radius:10px;text-align:left}.kside-bundle-toggle:hover{background:color-mix(in srgb,var(--on-surface) 5%,transparent)}.kside-bundle-name{font-size:12px;font-weight:600;color:var(--on-surface);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kside-count{flex:none;font-size:10.5px;line-height:17px;color:var(--on-surface-variant);background:var(--surface-container-highest);border-radius:999px;padding:0 7px}.kside-open{flex:none;width:26px;height:26px;display:grid;place-items:center;border-radius:50%;color:var(--on-surface-variant);font-size:13px}.kside-open:hover{background:color-mix(in srgb,var(--on-surface) 8%,transparent);color:var(--on-surface)}.kside-chev{flex:none;width:13px;font-size:11px;line-height:1;color:var(--on-surface-variant);display:inline-block;transition:transform .14s ease}.kside-chev.open{transform:rotate(90deg)}.kside-row{display:flex;align-items:center;gap:7px;width:100%;text-align:left;padding:6px 8px 6px 18px;font-size:12px;color:var(--on-surface-variant);border-radius:10px}.kside-row:hover{background:color-mix(in srgb,var(--on-surface) 5%,transparent);color:var(--on-surface)}.kside-concept.open>.kside-row{background:var(--secondary-container);color:var(--on-secondary-container);font-weight:500}.kside-concept.open>.kside-row .kside-chev{color:inherit}.kside-title{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kside-stale{flex:none;font-size:9px;text-transform:uppercase;letter-spacing:.05em;color:var(--error, #b3261e);border:1px solid currentColor;border-radius:999px;padding:0 6px;cursor:help}.kside-card{margin:4px 0 10px 18px;border-radius:12px;overflow:hidden;background:var(--surface-container-high);border:1px solid color-mix(in srgb,var(--outline-variant) 70%,transparent)}.kside-card>.viewer-note{padding:12px 14px}.kside-card-bar{display:flex;align-items:center;gap:10px;padding:7px 12px;border-bottom:1px solid color-mix(in srgb,var(--outline-variant) 55%,transparent);background:color-mix(in srgb,var(--surface-container-highest) 65%,transparent)}.kside-type{font-size:9px;text-transform:uppercase;letter-spacing:.06em;color:var(--on-surface-variant);border:1px solid var(--outline-variant);border-radius:999px;padding:1px 7px}.kside-updated{font-size:10.5px;color:var(--on-surface-variant)}.kside-md.md-body{height:auto;overflow:visible;padding:12px 14px 14px;font-size:12px}.concept-md{height:auto;overflow:visible}.kside-actions{display:flex;justify-content:flex-end;gap:8px;margin:2px 0 0}.kside-edit{padding:10px 12px}.kside-edit .concept-edit{width:100%;box-sizing:border-box}.kside-edit .kside-actions{margin-top:8px}.kside-reopen{position:fixed;right:14px;top:60px;z-index:5;font-size:11px;color:var(--on-surface-variant);background:var(--surface-container-high);border:1px solid var(--outline-variant);border-radius:999px;padding:4px 12px}.kside-reopen:hover{color:var(--on-surface);background:var(--surface-container-highest, var(--surface-container-high))}@media(max-width:1099px){.knowledge-side,.kside-reopen{display:none}.team-screen.has-sessions.has-knowledge{grid-template-columns:240px 260px minmax(0,1fr)}}.member-view{display:flex;flex-direction:column;gap:16px}.member-view .detail-head{margin-bottom:0}.m3-list{display:flex;flex-direction:column;padding:4px 0}.m3-row{display:flex;align-items:center;gap:14px;padding:12px 18px;text-align:left;color:inherit}.m3-row+.m3-row,.m3-expand+.m3-row{border-top:1px solid color-mix(in srgb,var(--outline-variant) 55%,transparent)}button.m3-toggle{background:none;border:0;width:100%;font:inherit;cursor:pointer}button.m3-toggle:hover{background:color-mix(in srgb,var(--on-surface) 4%,transparent)}.m3-ico{flex:none;width:32px;height:32px;display:grid;place-items:center;font-size:14px;color:var(--on-secondary-container);background:var(--secondary-container);border-radius:50%}.m3-body{flex:1;min-width:0;display:flex;flex-direction:column;gap:3px}.m3-head{font-size:13.5px;font-weight:500;display:flex;align-items:center;gap:8px}.m3-sub{font-size:12px;color:var(--on-surface-variant);line-height:1.5}.m3-sub code{font-size:11px}.m3-sub a{color:inherit}.m3-ellipsis{display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.m3-chev{flex:none;color:var(--on-surface-variant);font-size:11px;transition:transform .14s ease}.m3-chev.open{transform:rotate(180deg)}.m3-expand{padding:2px 18px 16px 64px}.m3-expand pre{margin:0;white-space:pre-wrap;font:12.5px/1.65 var(--font-mono),monospace}.m3-chips{display:flex;flex-wrap:wrap;gap:6px;margin-top:3px}.m3-chips .chip{text-decoration:none}.m3-switch{position:relative;flex:none;display:inline-block;width:44px;height:24px;cursor:pointer}.m3-switch input{position:absolute;inset:0;opacity:0;margin:0;cursor:pointer}.m3-switch-track{position:absolute;inset:0;border-radius:999px;pointer-events:none;background:var(--surface-container-highest);border:2px solid var(--outline-variant);transition:background .14s ease,border-color .14s ease}.m3-switch-track:after{content:"";position:absolute;top:2px;left:2px;width:16px;height:16px;border-radius:50%;background:var(--on-surface-variant);transition:transform .14s ease,background .14s ease}.m3-switch input:checked+.m3-switch-track{background:var(--primary);border-color:var(--primary)}.m3-switch input:checked+.m3-switch-track:after{transform:translate(20px);background:var(--on-primary)}a.m3-row{text-decoration:none}a.m3-row:hover{background:color-mix(in srgb,var(--on-surface) 4%,transparent)}a.m3-row:hover .m3-head{color:var(--primary)}.m3-subhead{padding:14px 18px 4px;font-family:var(--font-mono),monospace;font-size:11px;letter-spacing:.05em;color:var(--on-surface-variant)}.m3-row+.m3-subhead{border-top:1px solid color-mix(in srgb,var(--outline-variant) 55%,transparent);margin-top:4px}.know-log{padding:2px 0 10px}.know-log-row{display:flex;gap:10px;padding:4px 18px;align-items:baseline}.know-log-text{font-size:12.5px;color:var(--on-surface-variant);line-height:1.55;min-width:0;overflow-wrap:break-word}.know-log-text a{color:var(--primary)}.chip.log-kind{flex:none}.chip.log-verification{border-color:transparent;background:var(--success-container);color:var(--on-success-container)}.chip.log-creation,.chip.log-initialization{border-color:transparent;background:var(--secondary-container);color:var(--on-secondary-container)}.detail-cols{display:grid;grid-template-columns:minmax(0,1fr) 320px;gap:16px;align-items:start}@media(max-width:1020px){.detail-cols{grid-template-columns:1fr}}.detail-rail{display:flex;flex-direction:column;gap:16px;min-width:0}.rail-list{padding:4px 0}.rail-kv{display:flex;flex-direction:column;gap:3px;padding:10px 18px}.rail-kv+.rail-kv{border-top:1px solid color-mix(in srgb,var(--outline-variant) 55%,transparent)}.rail-kv .v{font-size:12.5px;color:var(--on-surface);overflow-wrap:break-word;display:flex;align-items:center;gap:8px;flex-wrap:wrap}.rail-kv .v.dim{color:var(--on-surface-variant)}.rail-kv a{color:var(--primary)}.concept-edit{display:block;width:100%;border:0;outline:none;resize:vertical;padding:14px 18px;background:var(--surface-container-lowest);color:var(--on-surface);font:12.5px/1.65 var(--font-mono),monospace;border-bottom:1px solid color-mix(in srgb,var(--outline-variant) 55%,transparent)}.side-row .row-x{flex:none;align-self:center;opacity:0;border:0;background:transparent;color:var(--on-surface-variant);font-size:11px;line-height:1;padding:4px 6px;border-radius:8px;cursor:pointer;transition:opacity .1s ease,background .1s ease,color .1s ease}.side-row:hover .row-x,.side-row .row-x:focus-visible{opacity:1}.side-row .row-x:hover{background:color-mix(in srgb,var(--error) 18%,transparent);color:var(--error)}.team-wf-list{display:flex;flex-wrap:wrap;gap:8px;padding:12px 18px}.team-wf-list .chip{text-decoration:none}.team-form{display:flex;flex-direction:column;gap:14px;padding:18px;max-width:680px}.team-form-row{display:flex;gap:10px;align-items:flex-end}.team-field{display:flex;flex-direction:column;gap:5px}.team-field,.team-field-label{font-size:11px;font-weight:500;color:var(--on-surface-variant);letter-spacing:.045em;text-transform:capitalize}.team-field input,.team-field select,.team-field textarea{font:13px/1.5 var(--font-mono),monospace;color:var(--on-surface);background:var(--surface-container-high);border:1px solid transparent;border-radius:12px;padding:9px 14px;outline:none;text-transform:none;letter-spacing:normal;transition:border-color .12s ease,background .12s ease}.team-field textarea{resize:vertical;font-family:var(--font-mono),monospace}.team-field input:focus,.team-field select:focus,.team-field textarea:focus{border-color:var(--primary);background:var(--surface-container-highest)}.emoji-pick{display:flex;gap:6px;flex-wrap:wrap}.emoji-pick button{font-size:16px;padding:6px 10px;background:transparent;border:1px solid var(--outline-variant);border-radius:12px;cursor:pointer;transition:background .12s ease,border-color .12s ease}.emoji-pick button:hover{background:color-mix(in srgb,var(--on-surface) 6%,transparent)}.emoji-pick button.active{border-color:transparent;background:var(--secondary-container)}.wf-checks{display:flex;flex-direction:column;gap:7px;padding:4px 0}.wf-checks label{display:flex;align-items:baseline;gap:8px;font-size:13px;color:var(--on-surface-variant);text-transform:none;letter-spacing:normal;cursor:pointer}.wf-checks input[type=checkbox]{accent-color:var(--primary)}.wf-checks b{font-family:var(--font-mono),monospace;font-size:12px}.wf-checks .opt-hint{color:var(--outline);font-size:11.5px}@media(max-width:900px){.team-screen,.team-screen.has-sessions,.team-screen.has-sessions.has-knowledge{grid-template-columns:1fr}.team-form-row{flex-direction:column;align-items:stretch}}