flowforge-map 0.1.0__py3-none-any.whl

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.
Files changed (113) hide show
  1. flowforge/__init__.py +0 -0
  2. flowforge/_classic.html +289 -0
  3. flowforge/_dashboard/assets/geist-cyrillic-ext-wght-normal-DjL33-gN.woff2 +0 -0
  4. flowforge/_dashboard/assets/geist-cyrillic-wght-normal-BEAKL7Jp.woff2 +0 -0
  5. flowforge/_dashboard/assets/geist-latin-ext-wght-normal-DC-KSUi6.woff2 +0 -0
  6. flowforge/_dashboard/assets/geist-latin-wght-normal-BgDaEnEv.woff2 +0 -0
  7. flowforge/_dashboard/assets/geist-mono-cyrillic-ext-wght-normal-X_5orZeX.woff2 +0 -0
  8. flowforge/_dashboard/assets/geist-mono-cyrillic-wght-normal-DiZS0aHC.woff2 +0 -0
  9. flowforge/_dashboard/assets/geist-mono-latin-ext-wght-normal-Bwz-egvJ.woff2 +0 -0
  10. flowforge/_dashboard/assets/geist-mono-latin-wght-normal-XN7g48iV.woff2 +0 -0
  11. flowforge/_dashboard/assets/geist-mono-symbols2-wght-normal-CO5SzqOn.woff2 +0 -0
  12. flowforge/_dashboard/assets/geist-mono-vietnamese-wght-normal-DadHysG0.woff2 +0 -0
  13. flowforge/_dashboard/assets/geist-vietnamese-wght-normal-6IgcOCM7.woff2 +0 -0
  14. flowforge/_dashboard/assets/index-BGT5seIN.css +1 -0
  15. flowforge/_dashboard/assets/index-BoGikST6.js +52 -0
  16. flowforge/_dashboard/favicon.svg +1 -0
  17. flowforge/_dashboard/index.html +16 -0
  18. flowforge/_example/trip-planner/.env.example +3 -0
  19. flowforge/_example/trip-planner/.gitignore +2 -0
  20. flowforge/_example/trip-planner/.mcp.json +20 -0
  21. flowforge/_example/trip-planner/README.md +48 -0
  22. flowforge/_example/trip-planner/config.py +27 -0
  23. flowforge/_example/trip-planner/mcp_servers/currency.py +10 -0
  24. flowforge/_example/trip-planner/planner.py +113 -0
  25. flowforge/_example/trip-planner/requirements.txt +3 -0
  26. flowforge/_example/trip-planner/services/__init__.py +0 -0
  27. flowforge/_example/trip-planner/services/geo.py +49 -0
  28. flowforge/_example/trip-planner/services/llm.py +18 -0
  29. flowforge/_example/trip-planner/services/mcp_tools.py +26 -0
  30. flowforge/_example/trip-planner/services/weather.py +25 -0
  31. flowforge/_example/trip-planner/tools/packing_list.py +24 -0
  32. flowforge/_example/trip-planner/trips/.gitkeep +0 -0
  33. flowforge/_workflows/diamond_mock.json +71 -0
  34. flowforge/_workflows/stripe_to_razorpay.json +38 -0
  35. flowforge/agent/__init__.py +5 -0
  36. flowforge/agent/server.py +333 -0
  37. flowforge/api/__init__.py +0 -0
  38. flowforge/api/agent.py +79 -0
  39. flowforge/api/checks.py +255 -0
  40. flowforge/api/connectors.py +289 -0
  41. flowforge/api/flowmap.py +174 -0
  42. flowforge/api/runs.py +284 -0
  43. flowforge/api/scan.py +117 -0
  44. flowforge/api/security.py +31 -0
  45. flowforge/api/stats.py +80 -0
  46. flowforge/checks/__init__.py +13 -0
  47. flowforge/checks/models.py +41 -0
  48. flowforge/checks/probes.py +359 -0
  49. flowforge/cli.py +108 -0
  50. flowforge/connectors/__init__.py +0 -0
  51. flowforge/connectors/catalog.py +84 -0
  52. flowforge/connectors/models.py +149 -0
  53. flowforge/connectors/presets.py +192 -0
  54. flowforge/connectors/registry.py +85 -0
  55. flowforge/connectors/runtime.py +47 -0
  56. flowforge/connectors/secrets.py +53 -0
  57. flowforge/example_data.py +247 -0
  58. flowforge/flow/__init__.py +328 -0
  59. flowforge/flow/advice.py +132 -0
  60. flowforge/flow/curly.py +884 -0
  61. flowforge/flow/index.py +116 -0
  62. flowforge/flow/order.py +181 -0
  63. flowforge/flow/reach.py +145 -0
  64. flowforge/flow/rewrite.py +146 -0
  65. flowforge/flowmap/__init__.py +1 -0
  66. flowforge/flowmap/diff.py +145 -0
  67. flowforge/flowmap/fixture.py +283 -0
  68. flowforge/flowmap/models.py +258 -0
  69. flowforge/flowmap/planner.py +131 -0
  70. flowforge/flowmap/service.py +379 -0
  71. flowforge/flowmap/validate.py +228 -0
  72. flowforge/home.py +58 -0
  73. flowforge/main.py +137 -0
  74. flowforge/nodes/__init__.py +3 -0
  75. flowforge/nodes/base.py +74 -0
  76. flowforge/nodes/check_node.py +50 -0
  77. flowforge/nodes/http_node.py +161 -0
  78. flowforge/nodes/llm_node.py +158 -0
  79. flowforge/nodes/local_node.py +164 -0
  80. flowforge/nodes/mcp_node.py +243 -0
  81. flowforge/nodes/mock_node.py +40 -0
  82. flowforge/scan/__init__.py +6 -0
  83. flowforge/scan/facts.py +47 -0
  84. flowforge/scan/files.py +112 -0
  85. flowforge/scan/manifests.py +65 -0
  86. flowforge/scan/mcp_config.py +75 -0
  87. flowforge/scan/models.py +73 -0
  88. flowforge/scan/patterns.py +86 -0
  89. flowforge/scan/python_ast.py +246 -0
  90. flowforge/scan/scanner.py +344 -0
  91. flowforge/scan/services.py +58 -0
  92. flowforge/scan/urls.py +60 -0
  93. flowforge/scheduler/__init__.py +0 -0
  94. flowforge/scheduler/cache.py +76 -0
  95. flowforge/scheduler/critical_path.py +65 -0
  96. flowforge/scheduler/durations.py +35 -0
  97. flowforge/scheduler/executor.py +390 -0
  98. flowforge/scheduler/graph.py +108 -0
  99. flowforge/scheduler/rate_limit.py +36 -0
  100. flowforge/schema.py +81 -0
  101. flowforge/security/__init__.py +0 -0
  102. flowforge/security/finders.py +127 -0
  103. flowforge/security/findings.py +169 -0
  104. flowforge/security/logfilter.py +129 -0
  105. flowforge/spa.py +52 -0
  106. flowforge/state.py +73 -0
  107. flowforge/storage.py +481 -0
  108. flowforge/templating.py +60 -0
  109. flowforge_map-0.1.0.dist-info/METADATA +335 -0
  110. flowforge_map-0.1.0.dist-info/RECORD +113 -0
  111. flowforge_map-0.1.0.dist-info/WHEEL +4 -0
  112. flowforge_map-0.1.0.dist-info/entry_points.txt +3 -0
  113. flowforge_map-0.1.0.dist-info/licenses/LICENSE +21 -0
flowforge/__init__.py ADDED
File without changes
@@ -0,0 +1,289 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1">
6
+ <title>FlowForge</title>
7
+ <style>
8
+ :root {
9
+ --bg: #f7f7f5; --panel: #ffffff; --ink: #1c1d1f; --muted: #6b6f76; --line: #e3e3df;
10
+ --accent: #3b5bdb; --accent-soft: #e7ecff;
11
+ --pending: #c9ccd1; --ready: #f0b429; --running: #3b82f6; --ok: #2f9e44; --fail: #e03131; --skip: #adb5bd;
12
+ --cp: #d9480f;
13
+ --mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
14
+ }
15
+ @media (prefers-color-scheme: dark) {
16
+ :root {
17
+ --bg: #141517; --panel: #1c1d20; --ink: #e8e9eb; --muted: #9a9ea6; --line: #2e3035;
18
+ --accent: #7c93ff; --accent-soft: #252b44;
19
+ --pending: #4a4d54; --skip: #5c6068; --cp: #ff8a4c;
20
+ }
21
+ }
22
+ * { box-sizing: border-box; }
23
+ body { margin: 0; background: var(--bg); color: var(--ink);
24
+ font: 14px/1.45 system-ui, -apple-system, "Segoe UI", sans-serif; }
25
+ header { display: flex; flex-wrap: wrap; gap: 12px; align-items: center;
26
+ padding: 12px 16px; border-bottom: 1px solid var(--line); background: var(--panel); }
27
+ header h1 { font-size: 16px; margin: 0 12px 0 0; letter-spacing: .2px; }
28
+ header label { color: var(--muted); font-size: 13px; display: flex; gap: 6px; align-items: center; }
29
+ select, button, textarea { font: inherit; color: var(--ink); }
30
+ select { background: var(--bg); border: 1px solid var(--line); border-radius: 6px; padding: 5px 8px; }
31
+ button { background: var(--accent); color: #fff; border: 0; border-radius: 6px; padding: 7px 16px; cursor: pointer; font-weight: 600; }
32
+ button:disabled { opacity: .5; cursor: default; }
33
+ main { display: grid; grid-template-columns: minmax(280px, 380px) 1fr; gap: 16px; padding: 16px; }
34
+ @media (max-width: 860px) { main { grid-template-columns: 1fr; } }
35
+ .panel { background: var(--panel); border: 1px solid var(--line); border-radius: 10px; padding: 14px; min-width: 0; }
36
+ .panel h2 { font-size: 12px; text-transform: uppercase; letter-spacing: .6px; color: var(--muted); margin: 0 0 10px; }
37
+ textarea { width: 100%; height: 360px; resize: vertical; background: var(--bg); border: 1px solid var(--line);
38
+ border-radius: 6px; padding: 10px; font: 12px/1.5 var(--mono); }
39
+ .msg { font-size: 13px; margin-top: 8px; min-height: 1.4em; }
40
+ .msg.err { color: var(--fail); }
41
+ .right { display: flex; flex-direction: column; gap: 16px; min-width: 0; }
42
+ #graphWrap { overflow-x: auto; }
43
+ svg text { font-family: inherit; }
44
+ .stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 10px; }
45
+ .stat { background: var(--bg); border-radius: 8px; padding: 10px 12px; }
46
+ .stat b { display: block; font-size: 20px; font-variant-numeric: tabular-nums; }
47
+ .stat span { color: var(--muted); font-size: 12px; }
48
+ .paths { margin-top: 12px; font-size: 13px; }
49
+ .paths div { margin: 4px 0; overflow-wrap: anywhere; }
50
+ .paths code { font-family: var(--mono); font-size: 12px; }
51
+ .legend { display: flex; flex-wrap: wrap; gap: 12px; font-size: 12px; color: var(--muted); margin-bottom: 8px; }
52
+ .legend i { display: inline-block; width: 10px; height: 10px; border-radius: 3px; margin-right: 5px; vertical-align: -1px; }
53
+ #log { font: 12px/1.6 var(--mono); max-height: 220px; overflow: auto; margin: 0; white-space: pre-wrap; color: var(--muted); }
54
+ #detail pre { font: 12px/1.5 var(--mono); background: var(--bg); padding: 10px; border-radius: 6px;
55
+ max-height: 280px; overflow: auto; white-space: pre-wrap; margin: 8px 0 0; }
56
+ .hint { color: var(--muted); font-size: 13px; }
57
+ </style>
58
+ </head>
59
+ <body>
60
+ <header>
61
+ <h1>FlowForge</h1>
62
+ <label>Example <select id="example"></select></label>
63
+ <label>Policy
64
+ <select id="policy">
65
+ <option value="critical_path">critical path (FlowForge)</option>
66
+ <option value="fifo">FIFO</option>
67
+ <option value="levels">level by level</option>
68
+ <option value="greedy">greedy (unlimited)</option>
69
+ <option value="sequential">sequential</option>
70
+ </select>
71
+ </label>
72
+ <label><input type="checkbox" id="cache" checked> cache</label>
73
+ <button id="run">Run</button>
74
+ </header>
75
+
76
+ <main>
77
+ <section class="panel">
78
+ <h2>Workflow JSON</h2>
79
+ <textarea id="json" spellcheck="false"></textarea>
80
+ <div id="msg" class="msg"></div>
81
+ </section>
82
+
83
+ <div class="right">
84
+ <section class="panel">
85
+ <h2>Graph</h2>
86
+ <div class="legend">
87
+ <span><i style="background:var(--pending)"></i>pending</span>
88
+ <span><i style="background:var(--ready)"></i>ready</span>
89
+ <span><i style="background:var(--running)"></i>running</span>
90
+ <span><i style="background:var(--ok)"></i>succeeded</span>
91
+ <span><i style="background:var(--fail)"></i>failed</span>
92
+ <span><i style="background:var(--skip)"></i>skipped</span>
93
+ <span><i style="background:var(--cp)"></i>critical path</span>
94
+ </div>
95
+ <div id="graphWrap"><svg id="graph" role="img" aria-label="Workflow graph"></svg></div>
96
+ </section>
97
+
98
+ <section class="panel">
99
+ <h2>Run</h2>
100
+ <div class="stats">
101
+ <div class="stat"><b id="sStatus">—</b><span>status</span></div>
102
+ <div class="stat"><b id="sMakespan">—</b><span>makespan</span></div>
103
+ <div class="stat"><b id="sCalls">—</b><span>API calls</span></div>
104
+ <div class="stat"><b id="sHits">—</b><span>cache hits</span></div>
105
+ </div>
106
+ <div class="paths">
107
+ <div>Predicted critical path: <code id="pPred">—</code></div>
108
+ <div>Actual critical path: <code id="pAct">—</code></div>
109
+ </div>
110
+ </section>
111
+
112
+ <section class="panel" id="detail">
113
+ <h2>Step</h2>
114
+ <div class="hint">Click a step in the graph to see its output.</div>
115
+ </section>
116
+
117
+ <section class="panel">
118
+ <h2>Events</h2>
119
+ <pre id="log"></pre>
120
+ </section>
121
+ </div>
122
+ </main>
123
+
124
+ <script>
125
+ const $ = (id) => document.getElementById(id);
126
+ const NODE_W = 188, NODE_H = 46, COL_GAP = 64, ROW_GAP = 16, PAD = 12;
127
+ const STATE_COLOR = { pending: "--pending", ready: "--ready", running: "--running",
128
+ succeeded: "--ok", failed: "--fail", skipped: "--skip" };
129
+
130
+ let plan = null; // /validate response for the current JSON
131
+ let workflow = null; // parsed JSON
132
+ let steps = {}; // step id → {state, duration_ms, cache_hit, error}
133
+ let criticalPath = [];
134
+ let source = null;
135
+
136
+ function css(v) { return getComputedStyle(document.documentElement).getPropertyValue(v).trim(); }
137
+ function fmtMs(ms) { return ms >= 1000 ? (ms / 1000).toFixed(2) + " s" : Math.round(ms) + " ms"; }
138
+
139
+ async function loadExamples() {
140
+ const names = await (await fetch("/workflows")).json();
141
+ $("example").innerHTML = names.map((n) => `<option>${n}</option>`).join("");
142
+ const preferred = names.includes("diamond_mock") ? "diamond_mock" : names[0];
143
+ $("example").value = preferred;
144
+ await loadExample(preferred);
145
+ }
146
+
147
+ async function loadExample(name) {
148
+ const wf = await (await fetch(`/workflows/${name}`)).json();
149
+ $("json").value = JSON.stringify(wf, null, 2);
150
+ await validate();
151
+ }
152
+
153
+ async function validate() {
154
+ const msg = $("msg");
155
+ try { workflow = JSON.parse($("json").value); }
156
+ catch (e) { msg.className = "msg err"; msg.textContent = "Invalid JSON: " + e.message; $("run").disabled = true; return false; }
157
+ const res = await fetch("/validate", { method: "POST", headers: { "content-type": "application/json" },
158
+ body: JSON.stringify(workflow) });
159
+ const body = await res.json();
160
+ if (!res.ok) {
161
+ msg.className = "msg err";
162
+ msg.textContent = typeof body.detail === "string" ? body.detail
163
+ : body.detail.map((d) => `${d.loc.slice(1).join(".")}: ${d.msg}`).join("\n");
164
+ $("run").disabled = true;
165
+ return false;
166
+ }
167
+ plan = body;
168
+ criticalPath = body.critical_path;
169
+ msg.className = "msg";
170
+ msg.textContent = `${body.order.length} steps · ${body.levels.length} levels · predicted critical path ${fmtMs(body.critical_path_ms)}`;
171
+ $("run").disabled = false;
172
+ steps = Object.fromEntries(body.order.map((id) => [id, { state: "pending" }]));
173
+ $("pPred").textContent = body.critical_path.join(" → ");
174
+ draw();
175
+ return true;
176
+ }
177
+
178
+ function layout() {
179
+ const pos = {};
180
+ plan.levels.forEach((level, col) => level.forEach((id, row) => {
181
+ pos[id] = { x: PAD + col * (NODE_W + COL_GAP), y: PAD + row * (NODE_H + ROW_GAP) };
182
+ }));
183
+ return pos;
184
+ }
185
+
186
+ function draw() {
187
+ if (!plan) return;
188
+ const svg = $("graph"), pos = layout();
189
+ const w = PAD * 2 + plan.levels.length * NODE_W + (plan.levels.length - 1) * COL_GAP;
190
+ const h = PAD * 2 + Math.max(...plan.levels.map((l) => l.length)) * (NODE_H + ROW_GAP) - ROW_GAP;
191
+ svg.setAttribute("width", w); svg.setAttribute("height", h); svg.setAttribute("viewBox", `0 0 ${w} ${h}`);
192
+
193
+ const onCp = new Set(criticalPath.slice(1).map((id, i) => criticalPath[i] + ">" + id));
194
+ const typeOf = Object.fromEntries(workflow.steps.map((s) => [s.id, s.type]));
195
+ let out = "";
196
+ for (const s of workflow.steps) for (const p of s.depends_on || []) {
197
+ const a = pos[p], b = pos[s.id], cp = onCp.has(p + ">" + s.id);
198
+ const x1 = a.x + NODE_W, y1 = a.y + NODE_H / 2, x2 = b.x, y2 = b.y + NODE_H / 2, mx = (x1 + x2) / 2;
199
+ out += `<path d="M${x1},${y1} C${mx},${y1} ${mx},${y2} ${x2},${y2}" fill="none"
200
+ stroke="${cp ? css("--cp") : css("--line")}" stroke-width="${cp ? 2.5 : 1.5}"/>`;
201
+ }
202
+ for (const id of plan.order) {
203
+ const { x, y } = pos[id], st = steps[id] || { state: "pending" };
204
+ const color = css(STATE_COLOR[st.state] || "--pending");
205
+ const cp = criticalPath.includes(id);
206
+ const sub = st.state === "succeeded" ? fmtMs(st.duration_ms || 0) + (st.cache_hit ? " · cache hit" : "")
207
+ : st.state === "failed" ? "failed" : st.state === "skipped" ? "skipped" : typeOf[id];
208
+ out += `<g data-id="${id}" style="cursor:pointer">
209
+ <rect x="${x}" y="${y}" width="${NODE_W}" height="${NODE_H}" rx="8" fill="${css("--panel")}"
210
+ stroke="${cp ? css("--cp") : css("--line")}" stroke-width="${cp ? 2 : 1}"/>
211
+ <rect x="${x}" y="${y}" width="6" height="${NODE_H}" rx="3" fill="${color}"/>
212
+ <text x="${x + 14}" y="${y + 19}" font-size="12.5" font-weight="600" fill="${css("--ink")}">${clip(id, 24)}</text>
213
+ <text x="${x + 14}" y="${y + 35}" font-size="11.5" fill="${css("--muted")}">${sub}</text>
214
+ </g>`;
215
+ }
216
+ svg.innerHTML = out;
217
+ svg.querySelectorAll("g[data-id]").forEach((g) => g.addEventListener("click", () => showStep(g.dataset.id)));
218
+ }
219
+
220
+ function clip(s, n) { return s.length > n ? s.slice(0, n - 1) + "…" : s; }
221
+ function esc(s) { return String(s).replace(/[&<>]/g, (c) => ({ "&": "&amp;", "<": "&lt;", ">": "&gt;" })[c]); }
222
+
223
+ let lastResult = null;
224
+ function showStep(id) {
225
+ const st = steps[id] || {}, res = lastResult?.steps?.[id];
226
+ const body = res?.error ? "Error: " + res.error
227
+ : res?.output !== undefined && res?.output !== null ? JSON.stringify(res.output, null, 2)
228
+ : "No output yet.";
229
+ $("detail").innerHTML = `<h2>Step · ${esc(id)}</h2>
230
+ <div class="hint">${esc(st.state || "pending")}${res ? ` · ${res.attempts} attempt(s)` : ""}${st.cache_hit ? " · cache hit" : ""}</div>
231
+ <pre>${esc(body.length > 6000 ? body.slice(0, 6000) + "\n…" : body)}</pre>`;
232
+ }
233
+
234
+ function log(line) { const el = $("log"); el.textContent += line + "\n"; el.scrollTop = el.scrollHeight; }
235
+
236
+ async function run() {
237
+ if (!(await validate())) return;
238
+ if (source) source.close();
239
+ lastResult = null;
240
+ $("log").textContent = "";
241
+ ["sStatus", "sMakespan", "sCalls", "sHits"].forEach((k) => ($(k).textContent = "—"));
242
+ $("sStatus").textContent = "running";
243
+ $("pAct").textContent = "—";
244
+ $("run").disabled = true;
245
+
246
+ const params = new URLSearchParams({ policy: $("policy").value, use_cache: $("cache").checked });
247
+ const res = await fetch(`/runs?${params}`, { method: "POST", headers: { "content-type": "application/json" },
248
+ body: JSON.stringify(workflow) });
249
+ const { run_id } = await res.json();
250
+
251
+ source = new EventSource(`/runs/${run_id}/events`);
252
+ source.onmessage = (e) => {
253
+ const ev = JSON.parse(e.data);
254
+ if (ev.type === "step") {
255
+ steps[ev.step_id] = { ...steps[ev.step_id], ...ev };
256
+ log(`${ev.t.toFixed(3)}s ${ev.step_id} → ${ev.state}${ev.cache_hit ? " (cache hit)" : ""}${ev.error ? " " + ev.error : ""}${ev.reason ? " " + ev.reason : ""}`);
257
+ draw();
258
+ } else if (ev.type === "retry") {
259
+ log(`${ev.t.toFixed(3)}s ${ev.step_id} retry #${ev.attempt} in ${ev.delay_s}s (${ev.error})`);
260
+ } else if (ev.type === "run") {
261
+ log(`${ev.t.toFixed(3)}s run ${ev.state}`);
262
+ }
263
+ };
264
+ source.addEventListener("end", async () => {
265
+ source.close();
266
+ const status = await (await fetch(`/runs/${run_id}`)).json();
267
+ lastResult = status.result;
268
+ $("sStatus").textContent = status.status;
269
+ if (lastResult) {
270
+ $("sMakespan").textContent = fmtMs(lastResult.makespan_ms);
271
+ $("sCalls").textContent = lastResult.api_calls;
272
+ $("sHits").textContent = lastResult.cache_hits;
273
+ $("pAct").textContent = lastResult.actual_critical_path.join(" → ");
274
+ criticalPath = lastResult.actual_critical_path;
275
+ draw();
276
+ }
277
+ $("run").disabled = false;
278
+ });
279
+ }
280
+
281
+ let debounce;
282
+ $("json").addEventListener("input", () => { clearTimeout(debounce); debounce = setTimeout(validate, 400); });
283
+ $("example").addEventListener("change", (e) => loadExample(e.target.value));
284
+ $("run").addEventListener("click", run);
285
+ matchMedia("(prefers-color-scheme: dark)").addEventListener("change", draw);
286
+ loadExamples();
287
+ </script>
288
+ </body>
289
+ </html>
@@ -0,0 +1 @@
1
+ @font-face{font-family:Geist Variable;font-style:normal;font-display:swap;font-weight:100 900;src:url(/assets/geist-cyrillic-ext-wght-normal-DjL33-gN.woff2)format("woff2-variations");unicode-range:U+460-52F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:Geist Variable;font-style:normal;font-display:swap;font-weight:100 900;src:url(/assets/geist-cyrillic-wght-normal-BEAKL7Jp.woff2)format("woff2-variations");unicode-range:U+301,U+400-45F,U+490-491,U+4B0-4B1,U+2116}@font-face{font-family:Geist Variable;font-style:normal;font-display:swap;font-weight:100 900;src:url(/assets/geist-vietnamese-wght-normal-6IgcOCM7.woff2)format("woff2-variations");unicode-range:U+102-103,U+110-111,U+128-129,U+168-169,U+1A0-1A1,U+1AF-1B0,U+300-301,U+303-304,U+308-309,U+323,U+329,U+1EA0-1EF9,U+20AB}@font-face{font-family:Geist Variable;font-style:normal;font-display:swap;font-weight:100 900;src:url(/assets/geist-latin-ext-wght-normal-DC-KSUi6.woff2)format("woff2-variations");unicode-range:U+100-2BA,U+2BD-2C5,U+2C7-2CC,U+2CE-2D7,U+2DD-2FF,U+304,U+308,U+329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Geist Variable;font-style:normal;font-display:swap;font-weight:100 900;src:url(/assets/geist-latin-wght-normal-BgDaEnEv.woff2)format("woff2-variations");unicode-range:U+??,U+131,U+152-153,U+2BB-2BC,U+2C6,U+2DA,U+2DC,U+304,U+308,U+329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Geist Mono Variable;font-style:normal;font-display:swap;font-weight:100 900;src:url(/assets/geist-mono-cyrillic-ext-wght-normal-X_5orZeX.woff2)format("woff2-variations");unicode-range:U+460-52F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:Geist Mono Variable;font-style:normal;font-display:swap;font-weight:100 900;src:url(/assets/geist-mono-cyrillic-wght-normal-DiZS0aHC.woff2)format("woff2-variations");unicode-range:U+301,U+400-45F,U+490-491,U+4B0-4B1,U+2116}@font-face{font-family:Geist Mono Variable;font-style:normal;font-display:swap;font-weight:100 900;src:url(/assets/geist-mono-symbols2-wght-normal-CO5SzqOn.woff2)format("woff2-variations");unicode-range:U+2000-2001,U+2004-2008,U+200A,U+23B8-23BD,U+2500-259F}@font-face{font-family:Geist Mono Variable;font-style:normal;font-display:swap;font-weight:100 900;src:url(/assets/geist-mono-vietnamese-wght-normal-DadHysG0.woff2)format("woff2-variations");unicode-range:U+102-103,U+110-111,U+128-129,U+168-169,U+1A0-1A1,U+1AF-1B0,U+300-301,U+303-304,U+308-309,U+323,U+329,U+1EA0-1EF9,U+20AB}@font-face{font-family:Geist Mono Variable;font-style:normal;font-display:swap;font-weight:100 900;src:url(/assets/geist-mono-latin-ext-wght-normal-Bwz-egvJ.woff2)format("woff2-variations");unicode-range:U+100-2BA,U+2BD-2C5,U+2C7-2CC,U+2CE-2D7,U+2DD-2FF,U+304,U+308,U+329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Geist Mono Variable;font-style:normal;font-display:swap;font-weight:100 900;src:url(/assets/geist-mono-latin-wght-normal-XN7g48iV.woff2)format("woff2-variations");unicode-range:U+??,U+131,U+152-153,U+2BB-2BC,U+2C6,U+2DA,U+2DC,U+304,U+308,U+329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}.react-flow{--xy-edge-stroke-default:#b1b1b7;--xy-edge-stroke-width-default:1;--xy-edge-stroke-selected-default:#555;--xy-connectionline-stroke-default:#b1b1b7;--xy-connectionline-stroke-width-default:1;--xy-attribution-background-color-default:#ffffff80;--xy-minimap-background-color-default:#fff;--xy-minimap-mask-background-color-default:#f0f0f099;--xy-minimap-mask-stroke-color-default:transparent;--xy-minimap-mask-stroke-width-default:1;--xy-minimap-node-background-color-default:#e2e2e2;--xy-minimap-node-stroke-color-default:transparent;--xy-minimap-node-stroke-width-default:2;--xy-background-color-default:transparent;--xy-background-pattern-dots-color-default:#91919a;--xy-background-pattern-lines-color-default:#eee;--xy-background-pattern-cross-color-default:#e2e2e2;background-color:var(--xy-background-color,var(--xy-background-color-default));--xy-node-border-default:1px solid #bbb;--xy-node-border-selected-default:1px solid #555;--xy-handle-background-color-default:#333;--xy-selection-background-color-default:#9696b41a;--xy-selection-border-default:1px dotted #9b9b9bcc;--xy-resize-background-color-default:#3367d9;direction:ltr}.react-flow.dark{--xy-edge-stroke-default:#3e3e3e;--xy-edge-stroke-width-default:1;--xy-edge-stroke-selected-default:#727272;--xy-connectionline-stroke-default:#b1b1b7;--xy-connectionline-stroke-width-default:1;--xy-attribution-background-color-default:#96969640;--xy-minimap-background-color-default:#141414;--xy-minimap-mask-background-color-default:#3c3c3c99;--xy-minimap-mask-stroke-color-default:transparent;--xy-minimap-mask-stroke-width-default:1;--xy-minimap-node-background-color-default:#2b2b2b;--xy-minimap-node-stroke-color-default:transparent;--xy-minimap-node-stroke-width-default:2;--xy-background-color-default:#141414;--xy-background-pattern-dots-color-default:#555;--xy-background-pattern-lines-color-default:#333;--xy-background-pattern-cross-color-default:#333;--xy-node-color-default:#f8f8f8}.react-flow__background{background-color:var(--xy-background-color-props,var(--xy-background-color,var(--xy-background-color-default)));pointer-events:none;z-index:-1}.react-flow__container{width:100%;height:100%;position:absolute;top:0;left:0}.react-flow__pane{z-index:1;touch-action:none}.react-flow__pane.draggable{cursor:grab}.react-flow__pane.dragging{cursor:grabbing}.react-flow__pane.selection{cursor:pointer}.react-flow__viewport{transform-origin:0 0;z-index:2;pointer-events:none}.react-flow__renderer{z-index:4}.react-flow__selection{z-index:6}.react-flow__nodesselection-rect:focus,.react-flow__nodesselection-rect:focus-visible{outline:none}.react-flow__edge-path{stroke:var(--xy-edge-stroke,var(--xy-edge-stroke-default));stroke-width:var(--xy-edge-stroke-width,var(--xy-edge-stroke-width-default));fill:none}.react-flow__connection-path{stroke:var(--xy-connectionline-stroke,var(--xy-connectionline-stroke-default));stroke-width:var(--xy-connectionline-stroke-width,var(--xy-connectionline-stroke-width-default));fill:none}.react-flow .react-flow__edges{position:absolute}.react-flow .react-flow__edges svg{pointer-events:none;position:absolute;overflow:visible}.react-flow__edge{pointer-events:visibleStroke}.react-flow__edge.selectable{cursor:pointer}.react-flow__edge.animated path{stroke-dasharray:5;animation:.5s linear infinite dashdraw}.react-flow__edge.animated path.react-flow__edge-interaction{stroke-dasharray:none;animation:none}.react-flow__edge.inactive{pointer-events:none}.react-flow__edge.selected,.react-flow__edge:focus,.react-flow__edge:focus-visible{outline:none}.react-flow__edge.selected .react-flow__edge-path,.react-flow__edge.selectable:focus .react-flow__edge-path,.react-flow__edge.selectable:focus-visible .react-flow__edge-path{stroke:var(--xy-edge-stroke-selected,var(--xy-edge-stroke-selected-default))}.react-flow__edge-textwrapper{pointer-events:all}.react-flow__edge .react-flow__edge-text{pointer-events:none;-webkit-user-select:none;user-select:none}.react-flow__arrowhead polyline{stroke:var(--xy-edge-stroke,var(--xy-edge-stroke-default))}.react-flow__arrowhead polyline.arrowclosed{fill:var(--xy-edge-stroke,var(--xy-edge-stroke-default))}.react-flow__connection{pointer-events:none}.react-flow__connection .animated{stroke-dasharray:5;animation:.5s linear infinite dashdraw}svg.react-flow__connectionline{z-index:1001;position:absolute;overflow:visible}.react-flow__nodes{pointer-events:none;transform-origin:0 0}.react-flow__node{-webkit-user-select:none;user-select:none;pointer-events:all;transform-origin:0 0;box-sizing:border-box;cursor:default;position:absolute}.react-flow__node.selectable{cursor:pointer}.react-flow__node.draggable{cursor:grab;pointer-events:all}.react-flow__node.draggable.dragging{cursor:grabbing}.react-flow__nodesselection{z-index:3;transform-origin:0 0;pointer-events:none}.react-flow__nodesselection-rect{pointer-events:all;cursor:grab;position:absolute}.react-flow__handle{pointer-events:none;background-color:var(--xy-handle-background-color,var(--xy-handle-background-color-default));min-width:5px;min-height:5px;position:absolute}.react-flow__handle.connectingfrom{pointer-events:all}.react-flow__handle.connectionindicator{pointer-events:all;cursor:crosshair}.react-flow__handle-bottom{top:auto;bottom:0;left:50%;transform:translate(-50%,50%)}.react-flow__handle-top{top:0;left:50%;transform:translate(-50%,-50%)}.react-flow__handle-left{top:50%;left:0;transform:translate(-50%,-50%)}.react-flow__handle-right{top:50%;right:0;transform:translate(50%,-50%)}.react-flow__edgeupdater{cursor:move;pointer-events:all}.react-flow__pane.selection .react-flow__panel{pointer-events:none}.react-flow__panel{z-index:5;margin:15px;position:absolute}.react-flow__panel.top{top:0}.react-flow__panel.bottom{bottom:0}.react-flow__panel.top.center,.react-flow__panel.bottom.center{left:50%;transform:translate(-15px)translate(-50%)}.react-flow__panel.left{left:0}.react-flow__panel.right{right:0}.react-flow__panel.left.center,.react-flow__panel.right.center{top:50%;transform:translateY(-15px)translateY(-50%)}.react-flow__attribution{background:var(--xy-attribution-background-color,var(--xy-attribution-background-color-default));margin:0;padding:2px 3px;font-size:10px}.react-flow__attribution a{color:#999;text-decoration:none}@keyframes dashdraw{0%{stroke-dashoffset:10px}}.react-flow__edgelabel-renderer{pointer-events:none;-webkit-user-select:none;user-select:none;width:100%;height:100%;position:absolute;top:0;left:0}.react-flow__viewport-portal{-webkit-user-select:none;user-select:none;width:100%;height:100%;position:absolute;top:0;left:0}.react-flow__minimap{background:var(--xy-minimap-background-color-props,var(--xy-minimap-background-color,var(--xy-minimap-background-color-default)))}.react-flow__minimap-svg{display:block}.react-flow__minimap-mask{fill:var(--xy-minimap-mask-background-color-props,var(--xy-minimap-mask-background-color,var(--xy-minimap-mask-background-color-default)));stroke:var(--xy-minimap-mask-stroke-color-props,var(--xy-minimap-mask-stroke-color,var(--xy-minimap-mask-stroke-color-default)));stroke-width:var(--xy-minimap-mask-stroke-width-props,var(--xy-minimap-mask-stroke-width,var(--xy-minimap-mask-stroke-width-default)))}.react-flow__minimap-node{fill:var(--xy-minimap-node-background-color-props,var(--xy-minimap-node-background-color,var(--xy-minimap-node-background-color-default)));stroke:var(--xy-minimap-node-stroke-color-props,var(--xy-minimap-node-stroke-color,var(--xy-minimap-node-stroke-color-default)));stroke-width:var(--xy-minimap-node-stroke-width-props,var(--xy-minimap-node-stroke-width,var(--xy-minimap-node-stroke-width-default)))}.react-flow__background-pattern.dots{fill:var(--xy-background-pattern-color-props,var(--xy-background-pattern-color,var(--xy-background-pattern-dots-color-default)))}.react-flow__background-pattern.lines{stroke:var(--xy-background-pattern-color-props,var(--xy-background-pattern-color,var(--xy-background-pattern-lines-color-default)))}.react-flow__background-pattern.cross{stroke:var(--xy-background-pattern-color-props,var(--xy-background-pattern-color,var(--xy-background-pattern-cross-color-default)))}.react-flow__controls{flex-direction:column;display:flex}.react-flow__controls.horizontal{flex-direction:row}.react-flow__controls-button{justify-content:center;align-items:center;width:26px;height:26px;padding:4px;display:flex}.react-flow__controls-button svg{fill:currentColor;width:100%;max-width:12px;max-height:12px}.react-flow__node-input,.react-flow__node-default,.react-flow__node-output,.react-flow__node-group{border:var(--xy-node-border,var(--xy-node-border-default));color:var(--xy-node-color,var(--xy-node-color-default))}.react-flow__node-input.selected,.react-flow__node-input:focus,.react-flow__node-input:focus-visible,.react-flow__node-default.selected,.react-flow__node-default:focus,.react-flow__node-default:focus-visible,.react-flow__node-output.selected,.react-flow__node-output:focus,.react-flow__node-output:focus-visible,.react-flow__node-group.selected,.react-flow__node-group:focus,.react-flow__node-group:focus-visible{border:var(--xy-node-border-selected,var(--xy-node-border-selected-default));outline:none}.react-flow__nodesselection-rect,.react-flow__selection{background:var(--xy-selection-background-color,var(--xy-selection-background-color-default));border:var(--xy-selection-border,var(--xy-selection-border-default))}.react-flow__resize-control{position:absolute}.react-flow__resize-control.left,.react-flow__resize-control.right{cursor:ew-resize}.react-flow__resize-control.top,.react-flow__resize-control.bottom{cursor:ns-resize}.react-flow__resize-control.top.left,.react-flow__resize-control.bottom.right{cursor:nwse-resize}.react-flow__resize-control.bottom.left,.react-flow__resize-control.top.right{cursor:nesw-resize}.react-flow__resize-control.handle{background-color:var(--xy-resize-background-color,var(--xy-resize-background-color-default));border:1px solid #fff;border-radius:1px;width:5px;height:5px;translate:-50% -50%}.react-flow__resize-control.handle.left{top:50%;left:0}.react-flow__resize-control.handle.right{top:50%;left:100%}.react-flow__resize-control.handle.top{top:0;left:50%}.react-flow__resize-control.handle.bottom{top:100%;left:50%}.react-flow__resize-control.handle.top.left,.react-flow__resize-control.handle.bottom.left{left:0}.react-flow__resize-control.handle.top.right,.react-flow__resize-control.handle.bottom.right{left:100%}.react-flow__resize-control.line{border-color:var(--xy-resize-background-color,var(--xy-resize-background-color-default));border-style:solid;border-width:0}.react-flow__resize-control.line.left,.react-flow__resize-control.line.right{width:1px;height:100%;top:0;transform:translate(-50%)}.react-flow__resize-control.line.left{border-left-width:1px;left:0}.react-flow__resize-control.line.right{border-right-width:1px;left:100%}.react-flow__resize-control.line.top,.react-flow__resize-control.line.bottom{width:100%;height:1px;left:0;transform:translateY(-50%)}.react-flow__resize-control.line.top{border-top-width:1px;top:0}.react-flow__resize-control.line.bottom{border-bottom-width:1px;top:100%}:root{--bg:#eef3f5;--surface:#fff;--surface-2:#f6f9fa;--fg:#0f1d26;--muted:#4a5e6a;--line:#d3dde3;--idle:#9aaab4;--teal:#0b7a70;--teal-bg:#ddf2ef;--teal-ink:#086a61;--blue:#2457c5;--blue-bg:#e1eafb;--amber:#8a5a00;--amber-bg:#fcefd0;--amber-strong:#f2b84b;--coral:#b93c2b;--coral-bg:#fbe4df;--green:#1f7a45;--green-bg:#dcf2e4;--violet:#6b46c1;--violet-bg:#ece6fa;--slate:#3a4756;--slate-bg:#e6ebef;--on-teal:#fff;--on-violet:#fff;--b-razor:#3395ff;--b-stripe:#635bff;--b-gem:#4285f4;--b-nim:#76b900;--b-claude:#d97757;--b-sirius:#0b7a70;--b-ollama:#1f2328;--b-fetch:#5b6b78;--nav-bg:#0f1d26;--nav-fg:#c9d6dc;--nav-active:#1d3340;--nav-strong:#fff;--nav-line:#4a5e6a;--display:"Geist Variable", "Geist", ui-sans-serif, system-ui, "Segoe UI", sans-serif;--body:"Geist Variable", "Geist", ui-sans-serif, system-ui, "Segoe UI", sans-serif;--mono:"Geist Mono Variable", "Geist Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;--canvas:#f2f6f7;--dot:#0f1d261f;--raised:#fff;--line-2:#bfccd3;--edge:#93a5af;--faint:#8a9ba5;--h-up:var(--teal);--h-warn:var(--amber-strong);--h-down:var(--coral);--h-run:var(--blue);--h-none:var(--line-2);--r-sm:8px;--r-md:12px;--r-lg:16px;--r-pill:999px;--shadow-1:0 1px 2px #0f1d260f, 0 1px 1px #0f1d260a;--shadow-2:0 2px 6px #0f1d2612, 0 10px 24px -12px #0f1d262e;--shadow-3:0 12px 32px -12px #0f1d264d;--glow:0 0 0 4px color-mix(in srgb, var(--teal) 18%, transparent);--hero:linear-gradient(160deg, #183242 0%, #0f1d26 58%);--tile-sheen:linear-gradient(180deg, #ffffff8c, #fff0 60%);--t-fast:.14s;--t-med:.26s;--t-slow:.52s;--ease:cubic-bezier(.2, .7, .2, 1);--lightningcss-light:initial;--lightningcss-dark: ;color-scheme:light}@media (prefers-color-scheme:dark){:root:not([data-theme=light]){--bg:#0b1418;--surface:#122128;--surface-2:#0f1b21;--fg:#e8f0f3;--muted:#93a8b3;--line:#25363f;--idle:#5c7280;--teal:#4fd1c0;--teal-bg:#12332f;--teal-ink:#4fd1c0;--blue:#7fa8ff;--blue-bg:#16284a;--amber:#f2b84b;--amber-bg:#3a2d0e;--coral:#ff8c7a;--coral-bg:#40201b;--green:#66d18f;--green-bg:#133423;--violet:#b79cff;--violet-bg:#2a2147;--slate:#b6c3cc;--slate-bg:#1e2c34;--on-teal:#062320;--on-violet:#1a1033;--canvas:#081014;--dot:#93a8b31f;--raised:#132229;--line-2:#2c424d;--edge:#46606d;--faint:#5e7482;--nav-bg:#070e11;--nav-active:#16262e;--nav-line:#2b3c45;--shadow-1:0 1px 2px #0006;--shadow-2:0 2px 8px #00000059, 0 12px 28px -14px #0009;--shadow-3:0 14px 36px -12px #000000b3;--tile-sheen:linear-gradient(180deg, #ffffff1a, #fff0 60%);--lightningcss-light: ;--lightningcss-dark:initial;color-scheme:dark}}:root[data-theme=dark]{--bg:#0b1418;--surface:#122128;--surface-2:#0f1b21;--fg:#e8f0f3;--muted:#93a8b3;--line:#25363f;--idle:#5c7280;--teal:#4fd1c0;--teal-bg:#12332f;--teal-ink:#4fd1c0;--blue:#7fa8ff;--blue-bg:#16284a;--amber:#f2b84b;--amber-bg:#3a2d0e;--coral:#ff8c7a;--coral-bg:#40201b;--green:#66d18f;--green-bg:#133423;--violet:#b79cff;--violet-bg:#2a2147;--slate:#b6c3cc;--slate-bg:#1e2c34;--on-teal:#062320;--on-violet:#1a1033;--canvas:#081014;--dot:#93a8b31f;--raised:#132229;--line-2:#2c424d;--edge:#46606d;--faint:#5e7482;--nav-bg:#070e11;--nav-active:#16262e;--nav-line:#2b3c45;--shadow-1:0 1px 2px #0006;--shadow-2:0 2px 8px #00000059, 0 12px 28px -14px #0009;--shadow-3:0 14px 36px -12px #000000b3;--tile-sheen:linear-gradient(180deg, #ffffff1a, #fff0 60%);--lightningcss-light: ;--lightningcss-dark:initial;color-scheme:dark}*,:before,:after{box-sizing:border-box}html,body,#root{min-height:100%}body{background:var(--bg);color:var(--fg);font-family:var(--body);-webkit-font-smoothing:antialiased;text-rendering:optimizelegibility;margin:0;font-size:15px;line-height:1.5}h1,h2,h3{font-family:var(--display);letter-spacing:-.02em;margin:0;font-weight:650}h1{font-size:clamp(28px,4vw,38px);line-height:1.1}h2{font-size:21px;line-height:1.2}h3{font-size:17px}p{margin:0}a{color:var(--blue)}a:hover{color:var(--teal)}button,input,select,textarea{font:inherit;color:inherit}code,.mono{font-family:var(--mono)}:focus-visible{outline:3px solid var(--blue);outline-offset:2px;border-radius:6px}.visually-hidden{clip:rect(0 0 0 0);white-space:nowrap;width:1px;height:1px;overflow:hidden;position:absolute!important}.shell{min-height:100vh;display:flex}.skip-link{z-index:50;background:var(--surface);border-radius:var(--r-sm);padding:10px 14px;position:absolute;top:-48px;left:12px}.skip-link:focus{top:12px}.main{flex-direction:column;flex:auto;gap:24px;min-width:0;padding:28px clamp(16px,3vw,40px) 48px;display:flex}.page{flex-direction:column;gap:24px;min-width:0;display:flex}.shell.bleed{height:100vh;min-height:560px;overflow:hidden}.shell.bleed .main{gap:0;height:100%;padding:0}.shell.bleed .page{flex:1;gap:0;min-height:0}.example-banner{border-radius:var(--r-md);background:var(--violet-bg);color:var(--fg);border:1px solid color-mix(in srgb, var(--violet) 30%, transparent);flex-wrap:wrap;align-items:center;gap:8px 12px;padding:10px 14px;font-size:14px;display:flex}.example-banner b{color:var(--violet)}.rail{background:var(--nav-bg);z-index:20;flex-direction:column;flex:0 0 82px;align-items:center;gap:4px;height:100vh;padding:14px 9px;display:flex;position:sticky;top:0;overflow-y:auto}.rail-brand{border-radius:12px;place-items:center;width:44px;height:44px;margin-bottom:10px;display:grid}.rail-item{width:64px;min-height:56px;color:var(--nav-fg);font:500 11px/1.1 var(--body);cursor:pointer;text-align:center;transition:background var(--t-fast) var(--ease), color var(--t-fast) var(--ease);background:0 0;border:0;border-radius:12px;flex-direction:column;justify-content:center;align-items:center;gap:5px;text-decoration:none;display:flex;position:relative}.rail-item:hover{background:var(--nav-active);color:var(--nav-strong)}.rail-item[aria-current=page]{background:var(--nav-active);color:var(--nav-strong);box-shadow:inset 3px 0 #4fd1c0}.rail-item:focus-visible{outline-offset:1px;outline:3px solid #7fa8ff}.rail-gap{flex:1}.rail-add{border:1px dashed var(--nav-line)}.rail-add:hover{border-color:#4fd1c0}@media (width<=760px){.shell,.shell.bleed{flex-direction:column}.rail{flex-direction:row;flex:none;justify-content:flex-start;gap:2px;width:100%;height:auto;padding:6px 8px;position:sticky;overflow-x:auto}.rail-brand{margin:0 6px 0 2px}.rail-gap{display:none}.rail-item{width:auto;min-width:66px;padding:0 6px}.rail-item[aria-current=page]{box-shadow:inset 0 -3px #4fd1c0}.main{padding-top:20px}.shell.bleed{height:auto;min-height:100vh;overflow:visible}.shell.bleed .main{height:auto}}.page-head{flex-wrap:wrap;justify-content:space-between;align-items:flex-end;gap:16px;display:flex}.page-head .titles{flex-direction:column;gap:6px;min-width:0;display:flex}.eyebrow{font:500 12px/1 var(--mono);letter-spacing:.1em;text-transform:uppercase;color:var(--muted)}.lede{color:var(--muted);font-size:15px}.actions{flex-wrap:wrap;align-items:center;gap:10px;display:flex}.crumbs{color:var(--muted);flex-wrap:wrap;align-items:center;gap:8px;font-size:15px;display:flex}.crumbs b{color:var(--fg)}.card{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-lg);box-shadow:var(--shadow-1);flex-direction:column;gap:12px;min-width:0;padding:20px;display:flex}.card.raised{box-shadow:var(--shadow-2)}.card-head{flex-wrap:wrap;justify-content:space-between;align-items:baseline;gap:8px 16px;display:flex}.card-note{color:var(--muted);font-size:13px}.grid{grid-template-columns:repeat(auto-fit, minmax(min(var(--min,300px), 100%), 1fr));align-items:start;gap:16px;display:grid}.row{border-bottom:1px solid var(--line);justify-content:space-between;gap:12px;padding:9px 0;font-size:15px;display:flex}.row:last-child{border-bottom:0}.row>span:first-child{color:var(--muted)}.btn{border:1px solid var(--line);background:var(--surface);min-height:44px;color:var(--fg);cursor:pointer;white-space:nowrap;transition:transform var(--t-fast) var(--ease), box-shadow var(--t-fast) var(--ease), background var(--t-fast) var(--ease), border-color var(--t-fast);border-radius:10px;justify-content:center;align-items:center;gap:8px;padding:0 18px;font-size:15px;font-weight:600;text-decoration:none;display:inline-flex}.btn:hover{border-color:var(--idle);color:var(--fg);box-shadow:var(--shadow-1)}.btn:active{transform:translateY(1px)}.btn.primary{background:var(--teal);border-color:var(--teal);color:var(--on-teal);box-shadow:0 6px 16px -8px color-mix(in srgb, var(--teal) 70%, transparent)}.btn.primary:hover{color:var(--on-teal);filter:brightness(1.06)}.btn.violet{background:var(--violet);border-color:var(--violet);color:var(--on-violet)}.btn.danger{border-color:var(--coral);color:var(--coral);background:var(--surface)}.btn.danger:hover{background:var(--coral-bg)}.btn.ghost{color:var(--muted);background:0 0;border-color:#0000}.btn.ghost:hover{color:var(--fg);background:var(--surface-2)}.btn[disabled],.btn[aria-disabled=true]{opacity:.5;cursor:not-allowed;box-shadow:none;transform:none}.btn.small{min-height:36px;padding:0 12px;font-size:14px}.chip{border-radius:var(--r-pill);white-space:nowrap;align-items:center;gap:6px;padding:4px 11px;font-size:13px;font-weight:600;display:inline-flex}.chip .dot{background:currentColor;border-radius:50%;width:7px;height:7px}.tone-teal{background:var(--teal-bg);color:var(--teal-ink)}.tone-blue{background:var(--blue-bg);color:var(--blue)}.tone-amber{background:var(--amber-bg);color:var(--amber)}.tone-coral{background:var(--coral-bg);color:var(--coral)}.tone-violet{background:var(--violet-bg);color:var(--violet)}.tone-slate{background:var(--slate-bg);color:var(--slate)}.tag{font:500 12px/1 var(--mono);white-space:nowrap;border-radius:6px;padding:4px 8px}.filter{border-radius:var(--r-pill);border:1px solid var(--line);background:var(--surface);min-height:40px;color:var(--muted);cursor:pointer;padding:0 16px;font-size:14px}.filter[aria-pressed=true]{background:var(--teal-bg);color:var(--teal-ink);border-color:#0000;font-weight:600}.filter[disabled]{opacity:.55;cursor:not-allowed}.stats{grid-template-columns:repeat(auto-fit,minmax(min(190px,100%),1fr));gap:12px;display:grid}.stat{border-radius:var(--r-md);background:var(--surface);border:1px solid var(--line);box-shadow:var(--shadow-1);padding:14px 16px;position:relative;overflow:hidden}.stat:before{content:"";background:var(--tile-sheen);pointer-events:none;position:absolute;inset:0}.stat .value{font:700 28px/1.1 var(--display);font-variant-numeric:tabular-nums}.stat .label{color:var(--muted);font-size:13px}.stat.tone-teal{background:var(--teal-bg)}.stat.tone-blue{background:var(--blue-bg)}.stat.tone-amber{background:var(--amber-bg)}.stat.tone-coral{background:var(--coral-bg)}.stat.tone-violet{background:var(--violet-bg)}.stat.tone-teal,.stat.tone-blue,.stat.tone-amber,.stat.tone-coral,.stat.tone-violet{box-shadow:none;border-color:#0000}.table-wrap{overflow-x:auto}table.data{border-collapse:collapse;width:100%;font-size:15px}table.data th{text-align:left;color:var(--muted);border-bottom:1px solid var(--line);white-space:nowrap;padding:12px 10px 10px;font-size:13px;font-weight:600}table.data td{border-bottom:1px solid var(--line);vertical-align:top;padding:12px 10px}table.data tr:last-child td{border-bottom:0}table.data tbody tr{transition:background var(--t-fast)}table.data tbody tr:hover{background:var(--surface-2)}.num{font-variant-numeric:tabular-nums}.field{color:var(--muted);flex-direction:column;gap:6px;font-size:14px;display:flex}.field input,.field select,.field textarea{border:1px solid var(--idle);border-radius:var(--r-sm);background:var(--surface);min-height:44px;color:var(--fg);padding:0 12px;font-size:16px}.field textarea{min-height:90px;padding:10px 12px}.field input:focus,.field select:focus,.field textarea:focus{border-color:var(--teal);box-shadow:var(--glow);outline:none}.field .hint{color:var(--muted);font-size:13px}.field .error{color:var(--coral);font-size:13px}.choice{text-align:left;border-radius:var(--r-md);cursor:pointer;border:2px solid var(--line);background:var(--surface);color:var(--fg);transition:border-color var(--t-fast), background var(--t-fast), transform var(--t-fast) var(--ease);flex-direction:column;gap:4px;padding:14px;font-size:14px;line-height:1.4;display:flex}.choice:hover{border-color:var(--idle);transform:translateY(-1px)}.choice[aria-pressed=true]{border-color:var(--teal);background:var(--teal-bg)}.choice b{font-family:var(--display);font-size:18px}.choice span{color:var(--muted)}pre.code{font:500 13px/1.55 var(--mono);background:var(--surface-2);border:1px solid var(--line);white-space:pre;border-radius:10px;margin:0;padding:12px 14px;overflow-x:auto}.empty{border-radius:var(--r-lg);border:1px dashed var(--idle);background:color-mix(in srgb, var(--surface) 70%, transparent);flex-direction:column;align-items:flex-start;gap:12px;padding:28px;display:flex}.empty .art{border-radius:18px;place-items:center;width:64px;height:64px;display:grid}.empty p{color:var(--muted);max-width:60ch}.error-box{border-radius:var(--r-md);background:var(--coral-bg);color:var(--fg);border:1px solid color-mix(in srgb, var(--coral) 35%, transparent);padding:14px 16px}.error-box b{color:var(--coral)}.notice{border-radius:var(--r-md);background:var(--amber-bg);color:var(--fg);padding:12px 14px;font-size:14px}.needs-item{border-radius:var(--r-md);color:var(--fg);transition:transform var(--t-fast) var(--ease), box-shadow var(--t-fast);flex-direction:column;gap:2px;padding:12px 14px;text-decoration:none;display:flex}.needs-item:hover{color:var(--fg);box-shadow:var(--shadow-1);transform:translateY(-1px)}.needs-item span{color:var(--muted);font-size:14px}.filter[aria-selected=true]{background:var(--teal-bg);color:var(--teal-ink);border-color:#0000;font-weight:600}.chip-dot{background:var(--blue);border-radius:50%;width:12px;height:12px;display:inline-block}.event-log{font:500 13px/1.75 var(--mono);max-height:360px;margin:0;padding:0;list-style:none;overflow:auto}.event-log li{white-space:nowrap;gap:12px;display:flex}.event-log .t{color:var(--muted);min-width:52px;display:inline-block}.app-card{color:var(--fg);transition:transform var(--t-fast) var(--ease), box-shadow var(--t-fast);height:100%;text-decoration:none}.app-card:hover{color:var(--fg);box-shadow:var(--shadow-2);transform:translateY(-2px)}.task-row{background:var(--surface-2);border-radius:10px;flex-wrap:wrap;align-items:center;gap:8px 12px;padding:10px 12px;display:flex}.task-row b{text-transform:none;flex:180px}.swatch{cursor:pointer;border:3px solid var(--surface);width:44px;height:44px;color:var(--muted);border-radius:50%;place-items:center;padding:0;font-size:20px;display:grid;position:relative}.swatch.custom{box-shadow:0 0 0 2px var(--line);overflow:hidden}.swatch.custom input{opacity:0;cursor:pointer;width:100%;height:100%;position:absolute;inset:0}.swatch.custom:focus-within{outline:3px solid var(--blue);outline-offset:2px}.filter[aria-checked=true]{background:var(--teal-bg);color:var(--teal-ink);border-color:#0000;font-weight:600}.event-log a{align-items:center;min-height:26px;display:inline-flex}@keyframes ff-pulse{0%{box-shadow:0 0 0 0 color-mix(in srgb, var(--blue) 55%, transparent)}70%{box-shadow:0 0 0 10px color-mix(in srgb, var(--blue) 0%, transparent)}to{box-shadow:0 0 #0000}}@keyframes ff-heartbeat{0%,to{transform:scale(1)}50%{transform:scale(1.35)}}@keyframes ff-shimmer{0%{background-position:-240px 0}to{background-position:240px 0}}@keyframes ff-flow{to{stroke-dashoffset:-28px}}@keyframes ff-rise{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}@keyframes ff-slide-in{0%{opacity:0;transform:translate(16px)}to{opacity:1;transform:none}}@keyframes ff-stripes{to{background-position:28px 0}}.pulse{animation:ff-pulse 1.6s var(--ease) infinite}.heartbeat{animation:1.8s ease-in-out infinite ff-heartbeat}.rise{animation:ff-rise var(--t-slow) var(--ease) both}.rise-1{animation-delay:40ms}.rise-2{animation-delay:90ms}.rise-3{animation-delay:.14s}.rise-4{animation-delay:.19s}.slide-in{animation:ff-slide-in var(--t-med) var(--ease) both}.flowing{stroke-dasharray:6 8;animation:.9s linear infinite ff-flow}.running-stripes{background-image:repeating-linear-gradient(-45deg,#ffffff2e 0 7px,#0000 7px 14px);background-size:28px 28px;animation:.8s linear infinite ff-stripes}.skeleton{background:linear-gradient(90deg, var(--surface-2) 0, color-mix(in srgb, var(--line) 70%, var(--surface)) 120px, var(--surface-2) 240px);background-size:480px 100%;border-radius:8px;min-height:14px;animation:1.3s linear infinite ff-shimmer}::view-transition-old(root){animation-duration:var(--t-med);animation-timing-function:var(--ease)}::view-transition-new(root){animation-duration:var(--t-med);animation-timing-function:var(--ease)}.page-enter{animation:ff-rise var(--t-med) var(--ease) both}@media (prefers-reduced-motion:reduce){*,:before,:after{scroll-behavior:auto!important;transition-duration:1ms!important;animation-duration:1ms!important;animation-iteration-count:1!important}.pulse,.heartbeat,.flowing,.running-stripes,.skeleton{animation:none!important}::view-transition-old(root){animation:none!important}::view-transition-new(root){animation:none!important}}.ca-grid{grid-template-columns:minmax(280px,380px) 1fr;align-items:start;gap:20px;margin-top:20px;display:grid}.ca-right{gap:22px;min-width:0;display:grid}.ca-label{font:600 12px/1.2 var(--mono);letter-spacing:.08em;text-transform:uppercase;color:var(--muted);align-items:center;gap:8px;margin:0 0 12px;display:flex}.ca-label span{color:var(--fg);text-transform:none;letter-spacing:0}.ca-label .ca-live{color:var(--teal);text-transform:none;letter-spacing:0;margin-left:auto}.ca-live:before{content:"";background:var(--teal);border-radius:50%;width:7px;height:7px;margin-right:6px;display:inline-block}.ca-setup{padding:18px}.ca-panel code,.ca-cards code,.ca-calls code,.ca-note code{font-family:var(--mono);font-size:.92em}.ca-agents{gap:8px;margin-bottom:14px;display:grid}.ca-agent{border-radius:var(--r-md);border:1.5px solid var(--line);background:var(--surface-2);width:100%;color:var(--fg);text-align:left;cursor:pointer;font:inherit;align-items:center;gap:12px;padding:10px 12px;display:flex}.ca-agent:hover{border-color:var(--line-2)}.ca-agent[aria-selected=true]{border-color:var(--teal);background:color-mix(in srgb, var(--teal) 8%, var(--surface))}.ca-agent span{gap:1px;display:grid}.ca-agent small{color:var(--muted);font-size:12.5px}.ca-tick{background:var(--teal);width:22px;height:22px;color:var(--on-teal);border-radius:50%;place-items:center;margin-left:auto;display:grid}.ca-copy{justify-content:center;width:100%;padding:11px 16px;font-size:15px}.ca-said{min-height:20px;color:var(--teal);text-align:center;margin-top:4px;font-size:13.5px;font-weight:600;display:block}.ca-show summary{cursor:pointer;color:var(--muted);font-size:13.5px}.ca-show pre{border:1px solid var(--line);background:var(--surface-2);font:12px/1.6 var(--mono);white-space:pre-wrap;overflow-wrap:anywhere;border-radius:10px;margin:8px 0;padding:10px 12px}.ca-or{color:var(--muted);overflow-wrap:anywhere;margin:10px 0 0;font-size:13.5px}.ca-steps{gap:8px;margin:14px 0 0;padding:0;font-size:14px;list-style:none;display:grid}.ca-steps li{align-items:baseline;gap:10px;display:flex}.ca-steps b{background:var(--teal-bg);width:22px;height:22px;color:var(--teal-ink);font:650 12px var(--mono);border-radius:50%;flex:none;place-items:center;display:inline-grid}.ca-steps span{overflow-wrap:anywhere}.ca-note{color:var(--muted);overflow-wrap:anywhere;align-items:center;gap:6px;margin:10px 0 0;font-size:13.5px;display:flex}.ca-last{border-radius:var(--r-md);border:1px dashed var(--line-2);color:var(--muted);align-items:center;gap:10px;margin-top:16px;padding:10px 12px;font-size:14px;display:flex}.ca-last i{background:var(--line-2);border-radius:50%;flex:none;width:10px;height:10px}.ca-last.on{color:var(--fg);border-style:solid;border-color:color-mix(in srgb, var(--teal) 45%, var(--line));background:var(--teal-bg)}.ca-last.on i{background:var(--teal);box-shadow:0 0 0 4px color-mix(in srgb, var(--teal) 22%, transparent)}.ca-cards{grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;margin:0;padding:0;list-style:none;display:grid}.ca-card{border-radius:var(--r-md);border:1px solid var(--line);background:var(--surface);gap:4px;padding:14px 16px;display:grid;position:relative}.ca-card:last-child:nth-child(odd){grid-column:1/-1}.ca-ask{color:var(--muted);align-items:center;gap:6px;padding-right:92px;font-size:13.5px;display:flex}.ca-card strong{letter-spacing:-.01em;font-size:22px;line-height:1.25}.ca-card.tone-bad strong{color:var(--coral)}.ca-card.tone-warn strong{color:var(--amber)}.ca-card.tone-ok strong{color:var(--green)}.ca-sub{color:var(--muted);font-size:13.5px}.ca-card>code{color:var(--faint);font-size:11.5px;position:absolute;top:14px;right:16px}.ca-calls{margin:0;padding:4px 16px;list-style:none}.ca-calls li{border-top:1px solid var(--line);grid-template-columns:52px 150px 1fr;align-items:center;gap:12px;padding:10px 0;font-size:14px;display:grid}.ca-calls li:first-child{border-top:0}.ca-calls time{font:12.5px var(--mono);color:var(--muted)}.ca-tool{color:var(--teal-ink);align-items:center;gap:6px;display:flex}.ca-got{overflow-wrap:anywhere}.ca-safe{color:var(--muted);align-items:center;gap:8px;margin:22px 0 0;font-size:13.5px;display:flex}@media (width<=860px){.ca-grid{grid-template-columns:1fr}}@media (width<=560px){.ca-cards{grid-template-columns:1fr}.ca-calls li{grid-template-columns:44px 1fr}.ca-got{grid-column:2}.ca-ask{padding-right:0}.ca-card>code{position:static}}.hsq-strip{flex-wrap:wrap;align-items:center;gap:3px;display:inline-flex}.hsq-strip .sq{background:var(--h-none);border-radius:3px;width:10px;height:10px}.hsq-strip.big{gap:5px}.hsq-strip.big .sq{border-radius:8px;width:28px;height:28px}.hsq-strip.tall .sq{border-radius:2px;width:9px;height:14px}.sq.up{background:var(--h-up)}.sq.warn{background:var(--h-warn)}.sq.down{background:var(--h-down)}.sq.checking{background:var(--h-run);animation:1.2s ease-in-out infinite hpulse}.hdot{background:var(--h-none);border-radius:50%;flex:none;width:9px;height:9px;display:inline-block}.hdot.up{background:var(--h-up)}.hdot.warn{background:var(--h-warn)}.hdot.down{background:var(--h-down)}.hdot.checking{background:var(--h-run);animation:1.2s ease-in-out infinite hpulse}@keyframes hpulse{50%{opacity:.35}}@media (prefers-reduced-motion:reduce){.sq.checking,.hdot.checking{animation:none}}.hc-confirm{z-index:5;background:var(--surface);border-bottom:1px solid var(--line);box-shadow:var(--shadow-3);padding:18px 20px 20px;position:relative}.hc-confirm h3{letter-spacing:-.01em;font-size:17px}.hc-confirm p{color:var(--muted);max-width:86ch;margin:6px 0 0}.hc-cmds{border:1px solid var(--line);border-radius:var(--r-md);grid-template-columns:auto minmax(0,1fr) auto auto;max-width:1100px;margin-top:14px;display:grid;overflow:hidden}.hc-cmd{display:contents}.hc-cmd>*{border-top:1px solid var(--line);align-items:center;min-width:0;padding:10px 14px;display:flex}.hc-cmd:first-child>*{border-top:0}.hc-cmd code{font:500 13px/1.3 var(--mono);overflow-wrap:anywhere}.hc-from{white-space:nowrap;color:var(--muted);border-radius:var(--r-pill);background:var(--surface-2);border:1px solid var(--line);align-self:center;margin:7px 0;padding:3px 8px;font-size:12.5px}.hc-from.repo{background:var(--amber-bg);color:var(--amber);border-color:color-mix(in srgb, var(--amber) 35%, transparent)}.hc-src{font:500 12px/1 var(--mono);color:var(--muted)}.hc-promise{color:var(--muted);flex-wrap:wrap;gap:8px 22px;margin:14px 0 0;padding:0;font-size:13px;list-style:none;display:flex}.hc-promise li{align-items:center;gap:7px;display:inline-flex}.hc-promise svg{color:var(--teal)}.hc-actions{flex-wrap:wrap;gap:8px;margin-top:16px;display:flex}.fm-health{z-index:5;background:var(--surface);border-bottom:1px solid var(--line);color:var(--muted);flex-wrap:wrap;align-items:center;gap:8px 12px;padding:8px 16px;font-size:13px;display:flex;position:relative}.fm-health b{color:var(--fg);font-weight:600}.fm-health .sep{background:var(--line);width:1px;height:16px}.fm-health .bad{color:var(--coral)}.ck{flex-direction:column;gap:18px;display:flex}.ck-overview{border-radius:var(--r-lg);background:var(--surface);border:1px solid var(--line);flex-wrap:wrap;align-items:center;gap:14px 22px;padding:18px 20px;display:flex}.ck-counts{flex-wrap:wrap;gap:6px 22px;font-size:15px;display:flex}.ck-counts span{align-items:baseline;gap:8px;display:inline-flex}.ck-counts b{font:650 22px/1 var(--display)}.ck-when{font:500 12.5px/1.2 var(--mono);color:var(--muted);margin-left:auto}.ck-split{grid-template-columns:minmax(0,1fr) 380px;align-items:start;gap:18px;display:grid}.ck-table-wrap{border-radius:var(--r-lg);background:var(--surface);border:1px solid var(--line);overflow:hidden}.ck-bar{border-bottom:1px solid var(--line);flex-wrap:wrap;justify-content:space-between;align-items:center;gap:8px;padding:12px 16px;display:flex}.ck-bar small{color:var(--muted);font-size:13px}.ck table{border-collapse:collapse;width:100%}.ck th,.ck td{border-bottom:1px solid var(--line);text-align:left;vertical-align:middle;padding:10px 16px}.ck thead th{font:600 11px/1 var(--mono);letter-spacing:.06em;text-transform:uppercase;color:var(--muted);background:var(--surface-2);padding:9px 16px}.ck tbody tr:last-child>*{border-bottom:0}.ck tbody tr.sel>*{background:color-mix(in srgb, var(--teal) 8%, transparent)}.ck-name{text-align:left;cursor:pointer;width:100%;font:inherit;color:inherit;background:0 0;border:0;align-items:center;gap:10px;padding:0;display:flex}.ck-name b{font-weight:600;display:block}.ck-name small{font:500 10.5px/1.3 var(--mono);color:var(--muted);display:block}.ck-res{color:var(--muted);max-width:52ch}.ck-res.down{color:var(--coral)}.ck-res.warn{color:var(--amber)}.ck-lat{font:500 13px/1 var(--mono);white-space:nowrap;text-align:right!important}.ck-at{font:500 12px/1 var(--mono);color:var(--muted);white-space:nowrap}.ck-side{border-radius:var(--r-lg);background:var(--surface);border:1px solid var(--line);position:sticky;top:16px;overflow:hidden}.ck-side header{border-bottom:1px solid var(--line);justify-content:space-between;align-items:center;gap:10px;padding:12px 16px;display:flex}.ck-side header b{align-items:center;gap:10px;display:flex}.ck-tl{max-height:420px;margin:0;padding:6px 0;list-style:none;overflow:auto}.ck-tl li{grid-template-columns:14px 1fr auto;align-items:start;gap:10px;padding:10px 16px;display:grid}.ck-tl li .hdot{margin-top:5px}.ck-tl li p{font:400 12px/1.4 var(--mono);color:var(--muted);overflow-wrap:anywhere;margin:3px 0 0}.ck-tl time{font:500 12px/1.2 var(--mono);color:var(--muted);white-space:nowrap}.hc-fix{border-radius:var(--r-md);border:1px dashed var(--line-2);margin:0;padding:10px 12px;font-size:13px}.hc-fix span{font:600 11px/1 var(--mono);letter-spacing:.06em;text-transform:uppercase;color:var(--muted);margin-bottom:4px;display:block}.ck-side .hc-fix{margin:0 16px 16px}.ck-foot{color:var(--muted);flex-wrap:wrap;justify-content:space-between;gap:8px;font-size:13px;display:flex}.ck-foot a{color:var(--fg)}@media (width<=1100px){.ck-split{grid-template-columns:1fr}.ck-side{position:static}}@media (width<=700px){.ck thead{display:none}.ck table,.ck tbody,.ck tr,.ck th,.ck td{display:block}.ck tbody tr{border-bottom:1px solid var(--line);padding:12px 16px}.ck th,.ck td{border:0;padding:3px 0}.ck-lat{text-align:left!important}.ck td.none{display:none}.ck-when{margin-left:0}.hc-cmds{grid-template-columns:1fr}.hc-cmd{border-top:1px solid var(--line);padding:8px 0;display:block}.hc-cmd:first-child{border-top:0}.hc-cmd>*{border:0;padding:2px 14px}}.hc-net{color:var(--muted);align-items:center;gap:7px;margin:10px 0 0;font-size:13px;display:flex}.hc-net svg{color:var(--teal);flex:none}.ck-side .hc-net{margin:0 0 16px}.sec-chip-wrap{position:relative}.sec-chip{height:36px;font:600 13.5px var(--sans,inherit);cursor:pointer;border:1px solid #0000;border-radius:99px;align-items:center;gap:6px;padding:0 12px;display:inline-flex}.sec-chip.lv-high{background:var(--coral-bg);color:var(--coral);border-color:color-mix(in srgb, var(--coral) 35%, transparent)}.sec-chip.lv-medium{background:var(--amber-bg);color:var(--amber);border-color:color-mix(in srgb, var(--amber) 35%, transparent)}.sec-chip.lv-low{background:var(--blue-bg);color:var(--blue)}.sec-pop{z-index:30;border-radius:var(--r-md);border:1px solid var(--line);background:var(--surface);width:min(520px,100vw - 32px);box-shadow:var(--shadow-3);padding:8px;position:absolute;top:calc(100% + 8px);right:0}.sec-pop ul{margin:0;padding:0;list-style:none;display:grid}.sec-pop li{border-top:1px solid var(--line);grid-template-columns:auto 1fr auto;align-items:center;gap:10px;padding:10px 8px;display:grid}.sec-pop li:first-child{border-top:0}.sec-dot{border-radius:50%;width:9px;height:9px}.sec-dot.lv-high{background:var(--coral)}.sec-dot.lv-medium{background:var(--amber)}.sec-dot.lv-low{background:var(--blue)}.sec-what{gap:2px;min-width:0;font-size:13.5px;display:grid}.sec-what code{font:12px var(--mono);color:var(--muted);overflow-wrap:anywhere}.sec-btns{gap:6px;display:flex}.btn.sm{gap:5px;height:30px;padding:0 10px;font-size:12.5px}.sec-note{color:var(--muted);margin:4px 8px;font-size:12px}.sec-level{font:600 11px/1.4 var(--mono);letter-spacing:.05em;text-transform:uppercase;border-radius:99px;align-items:center;gap:6px;padding:2px 8px;display:inline-flex}.sec-level.lv-high{background:var(--coral-bg);color:var(--coral)}.sec-level.lv-medium{background:var(--amber-bg);color:var(--amber)}.sec-level.lv-low{background:var(--blue-bg);color:var(--blue)}@media (width<=560px){.sec-pop li{grid-template-columns:auto 1fr}.sec-btns{grid-column:2}}.fm{background:var(--bg);flex-direction:column;height:100%;min-height:0;display:flex}.fm-top{z-index:6;background:var(--surface);border-bottom:1px solid var(--line);flex-wrap:wrap;align-items:center;gap:10px 14px;padding:10px 16px;display:flex;position:relative}.fm-proj{flex-direction:column;gap:4px;min-width:0;margin-right:auto;display:flex}.fm-proj h1{letter-spacing:-.015em;font-size:18px;line-height:1.15}.fm-proj small{font:500 12px/1 var(--mono);color:var(--muted);flex-wrap:wrap;align-items:center;gap:8px;display:flex}.fm-planner{background:var(--violet-bg);border:1px solid color-mix(in srgb, var(--violet) 40%, transparent);min-height:46px;color:var(--fg);border-radius:999px;align-items:center;gap:10px;padding:5px 16px 5px 5px;text-decoration:none;display:inline-flex}.fm-planner:hover{border-color:var(--violet);color:var(--fg)}.fm-spark{background:var(--violet);width:36px;height:36px;color:var(--on-violet);border-radius:50%;place-items:center;display:grid}.fm-planner .k{font:600 10px/1 var(--mono);letter-spacing:.08em;text-transform:uppercase;color:var(--violet);align-items:center;gap:6px;display:flex}.fm-planner .v{font:650 13.5px/1.1 var(--body);white-space:nowrap;margin-top:4px;display:block}.fm-planner .v span{font:500 11.5px/1 var(--mono);color:var(--muted);margin-left:6px}.fm-live{background:var(--violet);width:7px;height:7px;box-shadow:0 0 0 3px color-mix(in srgb, var(--violet) 25%, transparent);border-radius:50%}.fm-actions{flex-wrap:wrap;align-items:center;gap:8px;display:flex}.fm-actions .btn{min-height:40px;padding:0 14px;font-size:14px}.btn.ai{color:var(--violet);border-color:color-mix(in srgb, var(--violet) 45%, transparent);background:0 0}.btn.ai:hover{background:var(--violet-bg);border-color:var(--violet);color:var(--violet)}.btn.warn{background:var(--amber-strong);border-color:var(--amber-strong);color:#2a1e05}.seg{background:var(--surface-2);border:1px solid var(--line);border-radius:12px;padding:3px;display:inline-flex}.seg button{min-height:36px;color:var(--muted);font:600 13px/1 var(--body);cursor:pointer;background:0 0;border:0;border-radius:9px;align-items:center;gap:6px;padding:0 12px;display:inline-flex}.seg button[aria-pressed=true]{background:var(--surface);color:var(--fg);box-shadow:var(--shadow-1)}.seg .n{background:var(--fg);min-width:18px;height:18px;color:var(--bg);font:600 10.5px/18px var(--mono);text-align:center;border-radius:9px;padding:0 5px}.fm-stage{flex:1;min-height:0;display:flex;position:relative}.fm-canvas{background:var(--canvas);flex:1;min-width:0;position:relative}.fm-canvas .react-flow{background:0 0}.fm-canvas .react-flow__pane{cursor:grab}.fm-canvas .react-flow__pane.dragging{cursor:grabbing}.react-flow__node{cursor:pointer}.react-flow__node:focus-visible{outline:none}.react-flow__node:focus-visible .ff-focus{outline:3px solid var(--blue);outline-offset:5px}.react-flow__handle.ff-handle{opacity:0;pointer-events:none;border:0;width:6px;min-width:0;height:6px;min-height:0}.react-flow__minimap{background:var(--surface);border:1px solid var(--line);box-shadow:var(--shadow-2);border-radius:14px;overflow:hidden}.react-flow__minimap-mask{fill:color-mix(in srgb, var(--canvas) 70%, transparent)}.react-flow__attribution{display:none}.ff-block{color:var(--fg);font-family:var(--body);animation:ff-pop .6s var(--ease) backwards;transition:opacity .3s;position:relative}.ff-block.miss{opacity:.22}.ff-block.st-skipped{opacity:.32}.ff-card{background:var(--raised);border:1px solid var(--line-2);box-shadow:var(--shadow-2);border-radius:14px;align-items:center;gap:10px;padding:0 12px 0 10px;transition:border-color .25s,box-shadow .3s,background .3s;display:flex;position:absolute;inset:0}.ff-block:hover .ff-card,.ff-block:hover .ff-pill{border-color:var(--muted)}.ff-icon{border-radius:10px;flex:none;place-items:center;width:36px;height:36px;display:grid}.ff-icon.code,.ff-icon.flag{background:var(--slate-bg);color:var(--fg)}.ff-icon.lock{background:var(--amber-strong);color:#2a1e05}.ff-text{flex-direction:column;flex:1;gap:5px;min-width:0;display:flex}.ff-title{font:600 14px/1.1 var(--body);letter-spacing:-.012em;white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.ff-sub{font:500 11.5px/1.1 var(--mono);color:var(--muted);white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.ff-tag{background:var(--surface-2);border:1px solid var(--line);color:var(--muted);font:600 9.5px/1.25 var(--mono);letter-spacing:.07em;text-transform:uppercase;border-radius:6px;padding:2px 6px;position:absolute;top:-9px;left:12px}.ff-tag.llm{background:var(--violet-bg);border-color:color-mix(in srgb, var(--violet) 35%, transparent);color:var(--violet)}.ff-tag.gate{background:var(--amber-strong);border-color:var(--amber-strong);color:#2a1e05}.kind-gate .ff-card{background:var(--amber-bg);border:1.5px dashed var(--amber-strong)}.unconf .ff-card{border:1.5px dashed var(--line-2);box-shadow:none;background:0 0}.unconf .ff-text,.unconf .ff-icon,.unconf .brand-slot{opacity:.55}.ff-pill{background:var(--raised);border:1px solid var(--line-2);box-shadow:var(--shadow-2);border-radius:999px;align-items:center;gap:9px;padding:0 16px 0 7px;transition:border-color .25s,box-shadow .3s;display:flex;position:absolute;inset:0}.ff-pill .ff-icon{border-radius:999px;width:34px;height:34px}.ff-pill .ff-title{font-size:14px}.ff-pill .ff-sub{font-size:10.5px}.ff-dia{clip-path:polygon(50% 0,100% 50%,50% 100%,0 50%);background:var(--line-2);transition:background .3s;position:absolute;inset:0}.ff-dia-in{clip-path:polygon(50% 0,100% 50%,50% 100%,0 50%);background:var(--raised);position:absolute;inset:2px}.kind-decision{filter:drop-shadow(0 6px 10px #00000024)}.ff-dtext{z-index:1;text-align:center;font:600 12.5px/1.2 var(--body);place-items:center;padding:0 28px;display:grid;position:absolute;inset:0}.ff-bar{background:var(--fg);border-radius:6px;transition:background .3s,box-shadow .3s;position:absolute;inset:0}.ff-barlabel{font:600 10px/1 var(--mono);letter-spacing:.08em;text-transform:uppercase;color:var(--muted);white-space:nowrap;margin-bottom:10px;position:absolute;bottom:100%;left:50%;transform:translate(-50%)}.ff-cap{font:500 10.5px/1 var(--mono);color:var(--muted);white-space:nowrap;pointer-events:none;align-items:center;gap:5px;display:flex;position:absolute;top:calc(100% + 7px);left:4px}.kind-decision .ff-cap{left:50%;transform:translate(-50%)}.ff-cap.running,.ff-cap.retry{color:var(--blue)}.ff-cap.ok,.ff-cap.cached{color:var(--teal-ink)}.ff-cap.failed{color:var(--coral)}.ff-cap.waiting{color:var(--amber)}.ff-cap.skipped{color:var(--faint)}.ff-flag{font:600 10px/1.4 var(--body);white-space:nowrap;border-radius:999px;align-items:center;gap:4px;padding:2px 8px;display:inline-flex;position:absolute;top:-11px;right:18px}.ff-flag.yours{background:var(--fg);color:var(--bg);font-family:var(--mono);letter-spacing:.06em;text-transform:uppercase;font-size:9.5px}.ff-flag.tip{background:var(--violet);color:var(--on-violet);top:auto;bottom:-11px}.ff-st{min-width:22px;height:22px;font:700 10px/1 var(--body);box-shadow:0 0 0 3px var(--canvas);border-radius:11px;justify-content:center;align-items:center;gap:4px;padding:0 6px;display:inline-flex;position:absolute;top:-10px;right:-10px}.ff-st.ok{background:var(--teal);color:var(--on-teal)}.ff-st.failed{background:var(--coral);color:#2a0d08}.ff-st.waiting{background:var(--amber-strong);color:#2a1e05}.ff-st.cached{background:var(--teal-bg);color:var(--teal-ink);border:1px solid var(--teal)}.ff-st.retry{background:var(--blue);color:var(--surface)}.ff-retry{background:var(--surface);border:1px solid var(--line-2);color:var(--muted);font:600 10px/1.4 var(--mono);border-radius:6px;align-items:center;gap:3px;padding:1px 6px;display:inline-flex;position:absolute;bottom:-9px;right:12px}.ff-focus{pointer-events:none;border-radius:14px;position:absolute;inset:0}.kind-start .ff-focus,.kind-end .ff-focus{border-radius:999px}.selected .ff-card,.selected .ff-pill{outline:2px solid var(--fg);outline-offset:3px}.selected.kind-decision .ff-dia{background:var(--fg)}.selected .ff-bar{box-shadow:0 0 0 3px var(--canvas), 0 0 0 5px var(--fg)}.hit .ff-card,.hit .ff-pill{outline:2px dashed var(--violet);outline-offset:4px}.cp .ff-card,.cp .ff-pill{box-shadow:var(--shadow-2), 0 0 0 4px color-mix(in srgb, var(--fg) 14%, transparent)}.st-running .ff-card,.st-running .ff-pill,.st-retry .ff-card{border-color:var(--blue);box-shadow:0 0 0 1px var(--blue), 0 0 30px -4px var(--blue)}.st-running:after,.st-retry:after{content:"";border:2px solid var(--blue);opacity:0;pointer-events:none;border-radius:20px;animation:1.25s ease-out infinite ff-ring;position:absolute;inset:-7px}.kind-start.st-running:after,.kind-end.st-running:after{border-radius:999px}.kind-decision.st-running:after,.kind-fork.st-running:after,.kind-join.st-running:after{display:none}.st-ok .ff-card,.st-ok .ff-pill,.st-cached .ff-card{border-color:var(--teal);box-shadow:0 0 0 1px var(--teal), 0 0 22px -8px var(--teal)}.st-failed .ff-card{border-color:var(--coral);box-shadow:0 0 0 1px var(--coral), 0 0 22px -8px var(--coral)}.st-waiting .ff-card{border-style:solid;border-color:var(--amber-strong);animation:1.6s ease-in-out infinite ff-breathe}.kind-decision.st-running .ff-dia{background:var(--blue)}.kind-decision.st-ok .ff-dia{background:var(--teal)}.kind-fork.st-running .ff-bar,.kind-join.st-running .ff-bar{background:var(--blue);box-shadow:0 0 16px var(--blue)}.kind-fork.st-ok .ff-bar,.kind-join.st-ok .ff-bar{background:var(--teal)}.ff-line{fill:none;stroke:var(--edge);stroke-width:2px;stroke-linecap:round;transition:stroke .3s,opacity .3s}.ff-under{fill:none;stroke:#0000;stroke-width:14px;stroke-linecap:round}.ff-edge.cp .ff-under{stroke:color-mix(in srgb, var(--fg) 12%, transparent)}.ff-edge.cp .ff-line{stroke:var(--fg)}.ff-edge.fb .ff-line{stroke:var(--coral);stroke-dasharray:7 6}.ff-edge.unc .ff-line{stroke:var(--faint);stroke-dasharray:2 6}.ff-edge.loop .ff-line{stroke:var(--muted);stroke-dasharray:4 4}.ff-edge.active .ff-line{stroke:var(--blue);stroke-width:2.6px;filter:drop-shadow(0 0 5px var(--blue))}.ff-edge.active .ff-under{stroke:color-mix(in srgb, var(--blue) 18%, transparent)}.ff-edge.done .ff-line{stroke:var(--teal);stroke-width:2.4px}.ff-edge.skipped .ff-line{opacity:.28;stroke-dasharray:3 6;filter:none}.ff-edge.dim{opacity:.25}.ff-dot{fill:var(--blue);display:none}.ff-dot-glow{fill:color-mix(in srgb, var(--blue) 30%, transparent);display:none}.ff-edge.active .ff-dot,.ff-edge.active .ff-dot-glow{display:inline}.ff-elabel{background:var(--surface);border:1px solid var(--line-2);color:var(--muted);font:600 11px/1.2 var(--body);white-space:nowrap;pointer-events:none;border-radius:999px;align-items:center;gap:5px;padding:3px 8px;display:inline-flex;position:absolute;transform:translate(-50%,-50%)}.ff-elabel.br{color:var(--fg);font-family:var(--mono);letter-spacing:.04em;font-size:10.5px}.ff-elabel.fb{color:var(--coral);border-color:color-mix(in srgb, var(--coral) 45%, transparent)}.ff-elabel.unc{border-style:dashed}.ff-elabel.guard{width:24px;height:24px;color:var(--teal);border-color:color-mix(in srgb, var(--teal) 50%, transparent);justify-content:center;padding:0}.ff-elabel.off{opacity:.3}.fm-float{z-index:5;background:var(--surface);border:1px solid var(--line);box-shadow:var(--shadow-2);border-radius:14px;position:absolute}.fm-tl{z-index:5;flex-direction:column;align-items:flex-start;gap:8px;max-width:calc(100% - 300px);display:flex;position:absolute;top:14px;left:14px}.fm-tools{flex-wrap:wrap;align-items:center;gap:2px;padding:4px;display:flex;position:static}.fm-ib{width:40px;height:40px;color:var(--fg);cursor:pointer;background:0 0;border:0;border-radius:10px;place-items:center;display:grid}.fm-ib:hover{background:var(--surface-2)}.fm-zoom{text-align:center;min-width:48px;font:600 12px/1 var(--mono);color:var(--muted)}.fm-sep{background:var(--line);width:1px;height:24px;margin:0 4px}.fm-tbtn{height:40px;color:var(--fg);font:600 13px/1 var(--body);white-space:nowrap;cursor:pointer;background:0 0;border:0;border-radius:10px;align-items:center;gap:7px;padding:0 12px;display:inline-flex}.fm-tbtn:hover{background:var(--surface-2)}.fm-tbtn[aria-pressed=true]{background:var(--slate-bg)}.fm-note{background:var(--surface);border:1px solid var(--line);min-height:36px;box-shadow:var(--shadow-1);color:var(--fg);font:600 13px/1 var(--body);cursor:pointer;border-radius:999px;align-items:center;gap:8px;padding:0 13px;display:inline-flex}.fm-note.unc{border:1.5px dashed var(--line-2)}.fm-note.static{cursor:default}.fm-note .m{font:500 11.5px/1 var(--mono);color:var(--muted)}.fm-search{width:262px;height:48px;color:var(--muted);align-items:center;gap:8px;padding:0 6px 0 14px;display:flex;top:14px;right:14px}.fm-search input{min-width:0;height:100%;color:var(--fg);font:500 14px/1 var(--body);background:0 0;border:0;outline:none;flex:1}.fm-search input::placeholder{color:var(--muted)}.fm-search .c{font:600 11px/1 var(--mono);white-space:nowrap;padding-right:8px}.fm-search:focus-within{outline:3px solid var(--blue);outline-offset:2px}.fm-legend{width:248px;padding:6px 6px 10px;bottom:14px;left:14px}.fm-lh{width:100%;height:36px;font:600 10.5px/1 var(--mono);letter-spacing:.08em;text-transform:uppercase;color:var(--muted);cursor:pointer;background:0 0;border:0;justify-content:space-between;align-items:center;padding:0 8px;display:flex}.fm-lrow{font:500 13px/1.25 var(--body);align-items:center;gap:10px;padding:4px 10px;display:flex}.fm-lg{flex:0 0 28px;place-items:center;display:grid}.lg-card{border:1.5px solid var(--line-2);background:var(--raised);border-radius:4px;width:22px;height:13px}.lg-llm{border-color:var(--violet);background:var(--violet-bg)}.lg-dia{border:1.5px solid var(--line-2);background:var(--raised);width:13px;height:13px;transform:rotate(45deg)}.lg-bar{background:var(--fg);border-radius:2px;width:5px;height:16px}.lg-gate{border:1.5px dashed var(--amber-strong);background:var(--amber-bg)}.lg-unc{border:1.5px dashed var(--line-2);background:0 0}.fm-ldiv{background:var(--line);height:1px;margin:6px 10px}.fm-ldots{font:500 12px/1 var(--body);color:var(--muted);flex-wrap:wrap;gap:6px 10px;padding:4px 10px;display:flex}.fm-ldots span{align-items:center;gap:5px;display:inline-flex}.fm-ldots i{border-radius:50%;width:8px;height:8px;display:inline-block}.fm-lhint{font:500 11px/1.35 var(--mono);color:var(--muted);padding:6px 10px 0}.fm-hud{width:auto;max-width:max-content;animation:fm-up .35s var(--ease) backwards;flex-wrap:wrap;align-items:center;gap:10px 14px;margin:0 auto;padding:8px 8px 8px 16px;display:flex;bottom:14px;left:276px;right:238px}.fm-hud .s{font:650 14px/1.2 var(--body);white-space:nowrap;align-items:center;gap:8px;display:flex}.fm-hud .d{border-radius:50%;width:10px;height:10px}.fm-hud .m{font:500 12px/1.3 var(--mono);color:var(--muted);white-space:nowrap}.fm-prog{background:var(--surface-2);border:1px solid var(--line);border-radius:3px;width:120px;height:6px;overflow:hidden}.fm-prog span{background:var(--teal);height:100%;transition:width .35s var(--ease);display:block}.fm-hud .btn{min-height:40px;padding:0 14px;font-size:14px}.fm-empty{place-items:center;padding:24px;display:grid;position:absolute;inset:0}.sp{background:var(--surface);border-left:1px solid var(--line);z-index:7;width:404px;max-width:100%;animation:fm-slide .35s var(--ease) backwards;flex-direction:column;flex:0 0 404px;display:flex;overflow-y:auto}.sp-head{z-index:2;background:var(--surface);border-bottom:1px solid var(--line);align-items:flex-start;gap:12px;padding:16px 12px 14px 16px;display:flex;position:sticky;top:0}.sp-head h2{letter-spacing:-.018em;margin-top:6px;font-size:19px;line-height:1.2}.sp-kind{background:var(--slate-bg);color:var(--slate);font:600 10.5px/1.3 var(--mono);letter-spacing:.07em;text-transform:uppercase;border-radius:7px;align-items:center;gap:6px;padding:3px 8px;display:inline-flex}.sp-kind.llm{background:var(--violet-bg);color:var(--violet)}.sp-kind.gate{background:var(--amber-bg);color:var(--amber)}.sp-sec{border-bottom:1px solid var(--line);flex-direction:column;gap:10px;padding:16px;display:flex}.sp-sh{font:600 10.5px/1 var(--mono);letter-spacing:.09em;text-transform:uppercase;color:var(--muted)}.sp-what{font:450 15px/1.45 var(--body)}.sp-chips{flex-wrap:wrap;gap:6px;display:flex}.sp-chip{border:1px solid var(--line-2);font:600 12px/1.2 var(--body);color:var(--muted);border-radius:999px;align-items:center;gap:5px;padding:4px 9px;display:inline-flex}.sp-chip.cp{color:var(--fg)}.sp-chip.side{color:var(--amber);border-color:color-mix(in srgb, var(--amber-strong) 60%, transparent)}.sp-chip.yours{background:var(--fg);border-color:var(--fg);color:var(--bg)}.sp-run{font:600 13.5px/1.3 var(--body);border-bottom:1px solid var(--line);align-items:center;gap:8px;padding:10px 16px;display:flex}.sp-run.running,.sp-run.retry{background:var(--blue-bg);color:var(--blue)}.sp-run.ok,.sp-run.cached{background:var(--teal-bg);color:var(--teal-ink)}.sp-run.failed{background:var(--coral-bg);color:var(--coral)}.sp-run.waiting{background:var(--amber-bg);color:var(--amber)}.sp-run.skipped{background:var(--surface-2);color:var(--muted)}.sp-conn{background:var(--surface-2);border:1px solid var(--line);border-radius:12px;align-items:center;gap:12px;padding:10px 12px;display:flex}.sp-conn b{font:650 14.5px/1.2 var(--body);display:block}.sp-conn small{font:500 12px/1 var(--mono);color:var(--muted);align-items:center;gap:6px;margin-top:4px;display:flex}.sp-tip{background:var(--violet-bg);border:1px solid color-mix(in srgb, var(--violet) 35%, transparent);border-radius:12px;flex-direction:column;gap:10px;padding:14px;display:flex}.sp-tip .h{font:650 13.5px/1 var(--body);color:var(--violet);align-items:center;gap:8px;display:flex}.sp-ev{border:1px solid var(--line);background:var(--surface-2);border-radius:12px;overflow:hidden}.sp-evh{border-bottom:1px solid var(--line);font:600 12px/1 var(--mono);align-items:center;gap:8px;padding:9px 12px;display:flex}.sp-evh em{font:500 10.5px/1 var(--mono);color:var(--violet);margin-left:auto;font-style:normal}.sp-code{font:500 12px/1.7 var(--mono);padding:7px 0;overflow-x:auto}.sp-cl{white-space:pre;gap:12px;padding:0 12px;display:flex}.sp-cl b{text-align:right;color:var(--muted);flex:0 0 22px;font-weight:500}.sp-cl.hl{background:color-mix(in srgb, var(--violet) 16%, transparent)}.sp-evl{border:1px solid var(--line);background:var(--surface-2);font:500 13.5px/1.4 var(--body);border-radius:12px;align-items:flex-start;gap:9px;padding:10px 12px;display:flex}.sp-evl svg{color:var(--muted);flex:none;margin-top:1px}.sp-evl.policy{border-color:color-mix(in srgb, var(--amber-strong) 55%, transparent)}.sp-evl.missing{border-style:dashed}.sp-bars{align-items:flex-end;gap:4px;height:48px;display:flex}.sp-bars span{background:var(--teal);opacity:.85;border-radius:3px 3px 1px 1px;flex:1}.sp-bars span.fail{background:var(--coral)}.sp-note{font:500 12.5px/1.4 var(--mono);color:var(--muted)}.sp-lock{background:var(--amber-bg);border:1.5px dashed var(--amber-strong);font:500 14px/1.45 var(--body);border-radius:12px;gap:10px;padding:12px;display:flex}.sp-lock svg{color:var(--amber);flex:none;margin-top:1px}.sp-unc{border:1.5px dashed var(--line-2);font:500 14px/1.45 var(--body);border-radius:12px;gap:10px;padding:12px;display:flex}.sp-br{background:var(--surface-2);border:1px solid var(--line);font:500 14px/1.3 var(--body);border-radius:10px;align-items:center;gap:10px;padding:9px 12px;display:flex}.sp-br code{min-width:30px;font:600 11px/1 var(--mono);text-transform:uppercase;letter-spacing:.05em;color:var(--muted)}.sp-cond{background:var(--surface-2);border:1px solid var(--line);font:500 12.5px/1.5 var(--mono);white-space:pre-wrap;border-radius:10px;padding:9px 12px}.sp-row{flex-wrap:wrap;gap:8px;display:flex}.sp .btn{min-height:40px;padding:0 14px;font-size:14px}.sp .field input,.sp .field select{font-size:15px}@keyframes ff-pop{0%{opacity:0;transform:translateY(10px)scale(.94)}to{opacity:1;transform:none}}@keyframes ff-ring{0%{opacity:.75;transform:scale(1)}to{opacity:0;transform:scale(1.1)}}@keyframes ff-breathe{0%,to{box-shadow:0 0 0 1px var(--amber-strong), 0 0 0 0 color-mix(in srgb, var(--amber-strong) 0%, transparent)}50%{box-shadow:0 0 0 1px var(--amber-strong), 0 0 0 8px color-mix(in srgb, var(--amber-strong) 26%, transparent)}}@keyframes fm-slide{0%{opacity:0;transform:translate(26px)}to{opacity:1;transform:none}}@keyframes fm-up{0%{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}@media (prefers-reduced-motion:reduce){.ff-block,.sp,.fm-hud{animation:none!important}.st-running:after,.st-retry:after{display:none}.st-waiting .ff-card{animation:none!important}.ff-dot,.ff-dot-glow{display:none!important}}@media (width<=900px){.fm-legend,.react-flow__minimap{display:none}.fm-hud{left:14px;right:14px}}@media (width<=760px){.fm{min-height:calc(100vh - 68px)}.fm-stage{min-height:70vh}.fm-tl{max-width:none;right:14px}.fm-search{width:auto;inset:auto 14px 14px}.fm-hud{bottom:72px}.sp{border-left:0;border-top:1px solid var(--line);width:auto;max-height:66%;box-shadow:var(--shadow-3);border-radius:18px 18px 0 0;position:absolute;bottom:0;left:0;right:0}}.scan-form{flex-direction:column;gap:12px;width:min(100%,520px);display:flex}.scan-form .btn{align-self:flex-start}.scan-form small{color:var(--muted);font-size:13px}.scan-form code{border-radius:var(--r-md);background:var(--surface-2);overflow-wrap:anywhere;padding:8px 10px}.fm-scan{z-index:5;background:var(--surface);border-bottom:1px solid var(--line);padding:14px 16px;position:relative}.ff-hdot{margin-top:-4.5px;position:absolute;top:50%;right:11px}.ff-block[class*=\ h-] .ff-card{padding-right:26px}.ff-block.h-up .ff-card{box-shadow:inset 3px 0 0 var(--h-up), var(--shadow-2)}.ff-block.h-warn .ff-card{box-shadow:inset 3px 0 0 var(--h-warn), var(--shadow-2)}.ff-block.h-down .ff-card{box-shadow:inset 3px 0 0 var(--h-down), var(--shadow-2);border-color:color-mix(in srgb, var(--coral) 55%, var(--line))}.ff-block.h-checking .ff-card{box-shadow:inset 3px 0 0 var(--h-run), var(--shadow-2)}.ff-h{color:var(--fg);font-style:normal}.ff-h.down{color:var(--coral)}.ff-h.warn{color:var(--amber)}.ff-h.checking{color:var(--blue)}.sp-verdict{font:600 16px/1.3 var(--display);align-items:flex-start;gap:10px;display:flex}.sp-verdict .hdot{margin-top:5px}.sp-verdict small{font:400 12px/1.3 var(--mono);color:var(--muted);margin-top:3px;display:block}.sp-reason{border-radius:var(--r-md);background:var(--slate-bg);font:500 12.5px/1.45 var(--mono);overflow-wrap:anywhere;white-space:pre-wrap;margin:12px 0 0;padding:10px 12px}.sp-reason.down{background:var(--coral-bg)}.sp-reason.warn{background:var(--amber-bg)}.sp-sec .hc-fix{margin-top:10px}.sp-bars{align-items:flex-end;gap:4px;height:36px;margin-top:14px;display:flex}.sp-bars i{background:var(--h-none);border-radius:4px 4px 2px 2px;flex:0 0 22px;height:30%}.sp-bars i.up{background:var(--h-up)}.sp-bars i.warn{background:var(--h-warn)}.sp-bars i.down{background:var(--h-down);height:22%}.fx{overflow:auto}.fx-h{font:650 19px/1.2 var(--display);margin:0}.fx-h small{font:400 13px/1.4 var(--body);color:var(--muted);margin-top:4px;display:block}.fx-times{grid-template-columns:82px 1fr;align-items:center;gap:6px 10px;margin-top:14px;display:grid}.fx-times>span{color:var(--muted);font-size:12.5px}.fx-times>span b{font:650 15px/1.1 var(--display);color:var(--fg);display:block}.fx-lanes{gap:3px;display:grid}.fx-lane{background:var(--surface-2);border-radius:4px;height:14px;position:relative}.fx-seg{border:1px solid var(--surface);border-radius:3px;position:absolute;top:0;bottom:0}.fx-seg.api{background:var(--blue)}.fx-seg.mcp{background:var(--green)}.fx-seg.llm{background:var(--violet)}.fx-seg.local{background:var(--slate)}.fx-seg.est{background-image:repeating-linear-gradient(135deg,#0000 0 3px,#ffffff73 3px 5px)}.fx-saving{border-radius:var(--r-md);background:var(--teal-bg);align-items:baseline;gap:8px;margin:14px 0 0;padding:10px 12px;font-size:13.5px;display:flex}.fx-saving b{font:650 20px/1 var(--display);color:var(--teal-ink,var(--teal))}.fx-advice+.fx-advice{margin-top:10px}.fx-card{border-radius:var(--r-md);border:1px solid var(--line);background:var(--surface);width:100%;color:var(--fg);text-align:left;font:inherit;cursor:default;flex-direction:column;gap:6px;padding:12px 14px;display:flex}.fx-card:hover,.fx-card:focus-visible{border-color:var(--teal);box-shadow:0 0 0 3px color-mix(in srgb, var(--teal) 18%, transparent);outline:none}.fx-title{justify-content:space-between;gap:10px;font-weight:600;display:flex}.fx-title em{font:600 12.5px/1.3 var(--mono);color:var(--teal-ink,var(--teal));flex:none;font-style:normal}.fx-text{color:var(--muted);font-size:13px}.fx-chips{flex-wrap:wrap;gap:5px;display:flex}.fx-chips i{border-radius:var(--r-pill);background:var(--surface-2);border:1px solid var(--line);font-style:normal;font:500 11.5px/1.5 var(--mono);padding:2px 8px}.fx-refs{font:500 11.5px var(--mono);color:var(--muted)}.fx-do{flex-wrap:wrap;align-items:center;gap:8px;margin-top:8px;display:flex}.fx-btn{border:1px solid var(--line);background:var(--surface);min-height:36px;color:var(--fg);font:550 13px var(--sans);cursor:pointer;border-radius:9px;align-items:center;gap:6px;padding:0 12px;display:inline-flex}.fx-btn:hover,.fx-btn:focus-visible{border-color:var(--teal);outline:none}.fx-said{color:var(--teal);font-size:13px;font-weight:600}.fx-change{border-radius:var(--r-md);border:1px solid var(--line);background:var(--surface-2);gap:6px;margin-top:8px;padding:12px;display:grid}.fx-ch-head{font:600 12.5px var(--mono);justify-content:space-between;gap:8px;display:flex}.fx-ch-head em{color:var(--teal);font-style:normal}.fx-ch-label{font:600 11px/1 var(--mono);letter-spacing:.08em;text-transform:uppercase;color:var(--muted);margin-top:4px}.fx-code{font:12px/1.55 var(--mono);background:var(--surface);white-space:pre-wrap;overflow-wrap:anywhere;border-radius:8px;margin:0;padding:8px 10px}.fx-code>span{text-indent:calc(-3ch - 10px);padding-left:calc(3ch + 10px);display:block}.fx-code.could>span{text-indent:0;padding-left:0}.fx-code.now{border-left:3px solid var(--coral)}.fx-code.could{border-left:3px solid var(--teal)}.fx-code b{width:3ch;color:var(--muted);text-align:right;-webkit-user-select:none;user-select:none;margin-right:10px;font-weight:500;display:inline-block}.fx-note{color:var(--muted);margin:0;font-size:12.5px}.fx-note ul{margin:4px 0 0;padding-left:18px}.fx-note code{font-family:var(--mono)}.fx-caveat{border-radius:var(--r-md);border:1px dashed var(--line-2);color:var(--muted);margin:8px 0 0;padding:10px 12px;font-size:13px}.fx-limits{color:var(--muted);margin:0;padding:10px 16px 14px;font-size:12px}.fx-cp{color:var(--muted);margin:0;font-size:13px}.fx-cp b{color:var(--fg)}.fm-theme{position:relative}.fm-theme-menu{z-index:20;border-radius:var(--r-md);background:var(--surface);border:1px solid var(--line);width:250px;box-shadow:var(--shadow-3);gap:2px;padding:6px;display:grid;position:absolute;top:calc(100% + 6px);left:0}.fm-theme-menu button{color:var(--fg);text-align:left;font:inherit;cursor:pointer;background:0 0;border:0;border-radius:8px;align-items:center;gap:10px;padding:8px 10px;display:flex}.fm-theme-menu button:hover,.fm-theme-menu button:focus-visible{background:var(--surface-2);outline:none}.fm-theme-menu button[aria-checked=true]{background:var(--teal-bg)}.fm-theme-menu b{font-weight:600;display:block}.fm-theme-menu small{color:var(--muted);font-size:12px;display:block}.fm-swatch{border:1px solid var(--line);border-radius:6px;flex:none;width:30px;height:22px}.sw-studio{background:linear-gradient(90deg, var(--surface) 60%, var(--teal) 60%)}.sw-boxed{background:var(--surface-2);box-shadow:inset 0 0 0 4px var(--surface), inset 0 0 0 5px var(--line-2)}.sw-blueprint{background:var(--blue) repeating-linear-gradient(0deg, transparent 0 5px, #ffffff2e 5px 6px)}.sw-metro{background:linear-gradient(transparent 40%, var(--blue) 40% 60%, transparent 60%), var(--surface)}.sw-soft{background:linear-gradient(90deg, var(--blue-bg) 33%, var(--green-bg) 33% 66%, var(--violet-bg) 66%)}.react-flow__viewport-portal{z-index:-1}.ff-box{background:color-mix(in srgb, var(--teal) 6%, var(--surface-2));border:1px solid color-mix(in srgb, var(--teal) 20%, var(--line));pointer-events:none;border-radius:18px;position:absolute;top:0;left:0}.ff-box-label{font:650 13px/1 var(--display);color:var(--fg);position:absolute;top:10px;left:14px}.ff-box-note{font:500 11px/1 var(--mono);color:var(--muted);position:absolute;top:27px;left:14px}.fm[data-graph=boxed] .ff-card{box-shadow:none;border-color:var(--line)}.fm[data-graph=blueprint] .fm-canvas{background-color:var(--blue-bg)!important;background-image:linear-gradient(var(--bp-grid) 1px, transparent 1px), linear-gradient(90deg, var(--bp-grid) 1px, transparent 1px)!important;background-size:24px 24px!important}.fm[data-graph=blueprint]{--bp-ink:var(--blue);--bp-muted:color-mix(in srgb, var(--blue) 65%, var(--muted));--bp-grid:color-mix(in srgb, var(--blue) 16%, transparent)}.fm[data-graph=blueprint] .ff-card,.fm[data-graph=blueprint] .ff-pill{border:1.4px solid var(--bp-ink);box-shadow:none;background:0 0;border-radius:3px}.fm[data-graph=blueprint] .ff-title{color:var(--bp-ink);font-family:var(--mono);font-size:13px}.fm[data-graph=blueprint] .ff-sub,.fm[data-graph=blueprint] .ff-cap{color:var(--bp-muted)}.fm[data-graph=blueprint] .ff-cap{border-top:1px solid var(--bp-muted);padding-top:3px}.fm[data-graph=blueprint] .ff-line{stroke:var(--bp-ink);stroke-width:1.2px;opacity:.8}.fm[data-graph=blueprint] .ff-edge.cp .ff-line{stroke-width:2.6px;opacity:1}.fm[data-graph=blueprint] .brand-slot{filter:grayscale()contrast(1.2);opacity:.8}.ff-metro{grid-template-rows:1fr auto 1fr;place-items:center;display:grid;position:absolute;inset:0}.ff-metro .ff-title{align-self:end;max-width:100%;padding:0 6px 4px;font-size:13.5px}.ff-metro .ff-sub{align-self:start;padding-top:4px;font-size:11px}.ff-track{background:var(--k,var(--edge));border-radius:4px;width:100%;height:8px;position:relative}.ff-station{background:var(--surface);border:4px solid var(--fg);border-radius:50%;width:22px;height:22px;margin:-11px 0 0 -11px;position:absolute;top:50%;left:50%}.kind-api{--k:var(--blue)}.kind-mcp{--k:var(--green)}.kind-llm{--k:var(--violet)}.kind-local{--k:var(--slate)}.fm[data-graph=metro] .ff-line{stroke-width:7px;marker-end:none;stroke-linejoin:round}.fm[data-graph=metro] .ff-edge.to-api .ff-line{stroke:var(--blue)}.fm[data-graph=metro] .ff-edge.to-mcp .ff-line{stroke:var(--green)}.fm[data-graph=metro] .ff-edge.to-llm .ff-line{stroke:var(--violet)}.fm[data-graph=metro] .ff-edge.to-local .ff-line{stroke:var(--slate)}.fm[data-graph=metro] .ff-edge.cp .ff-line{stroke:var(--fg);stroke-width:11px}.fm[data-graph=metro] .cp .ff-track{background:var(--fg)}.fm[data-graph=metro] .selected .ff-station{border-color:var(--teal)}.fm[data-graph=metro] .ff-block.h-down .ff-station{border-color:var(--h-down)}.fm[data-graph=metro] .ff-block.h-warn .ff-station{border-color:var(--h-warn)}.fm[data-graph=soft] .ff-card{box-shadow:none;border:0;border-radius:20px}.fm[data-graph=soft] .kind-api .ff-card{background:color-mix(in srgb, var(--blue) 13%, var(--surface))}.fm[data-graph=soft] .kind-mcp .ff-card{background:color-mix(in srgb, var(--green) 14%, var(--surface))}.fm[data-graph=soft] .kind-llm .ff-card{background:color-mix(in srgb, var(--violet) 14%, var(--surface))}.fm[data-graph=soft] .kind-local .ff-card{background:color-mix(in srgb, var(--slate) 14%, var(--surface))}.fm[data-graph=soft] .ff-line{stroke-width:2.4px}.fm[data-graph=soft] .ff-edge:not(.cp):not(.fb) .ff-line{stroke-dasharray:1 6}.fm[data-graph=soft] .cp .ff-card{box-shadow:0 0 0 2px var(--fg)}.fm.drawing .ff-edge:not(.fb):not(.unc):not(.loop) .ff-line{stroke-dasharray:2400;stroke-dashoffset:2400px;animation:1s cubic-bezier(.2,.7,.2,1) forwards ff-draw;animation-delay:var(--draw-delay,0s)}@keyframes ff-draw{to{stroke-dashoffset:0}}@media (prefers-reduced-motion:reduce){.fm.drawing .ff-edge .ff-line{stroke-dasharray:none;stroke-dashoffset:0;animation:none}}.ff-risk{z-index:2;border:2px solid var(--canvas);width:20px;height:20px;font:800 12px/1 var(--sans,inherit);border-radius:50%;place-items:center;display:grid;position:absolute;top:-8px;right:-8px}.ff-risk.lv-high{background:var(--coral);color:#2a0d08}.ff-risk.lv-medium{background:var(--amber);color:#2a1d02}.ff-risk.lv-low{background:var(--blue);color:#0b1733}.sp-security ul{gap:8px;margin:6px 0 0;padding:0;list-style:none;display:grid}.sp-security li{grid-template-columns:auto 1fr;align-items:start;gap:8px;font-size:13.5px;display:grid}.sp-security code{font:12px var(--mono);color:var(--muted)}.fm-proj{flex-direction:row;align-items:center;gap:10px;margin-right:6px}.fm-ex{padding:2px 8px;font-size:11px}.fm-actions{flex-wrap:nowrap;margin-left:auto}.fm-action{color:var(--muted);align-items:center;gap:8px;font-size:13px;display:inline-flex}.fm-action select{border:1px solid var(--line);background:var(--surface);max-width:260px;height:38px;color:var(--fg);font:600 13.5px var(--body);border-radius:10px;padding:0 10px}.fm-tools{z-index:5;flex-flow:column;padding:3px;position:absolute;bottom:14px;left:14px}.fm-search{width:220px;height:40px}.fm-legend{left:64px}.fm-hud{left:70px}.mm{position:relative}.mm-btn{letter-spacing:1px;justify-content:center;min-width:40px;padding:0 10px;font-size:18px}.mm-menu{z-index:40;border-radius:var(--r-md);border:1px solid var(--line);background:var(--surface);width:270px;max-height:min(70vh,640px);box-shadow:var(--shadow-3);padding:6px;display:grid;position:absolute;top:calc(100% + 8px);right:0;overflow:auto}.mm-head{font:600 11px/1 var(--mono);letter-spacing:.08em;text-transform:uppercase;color:var(--muted);padding:10px 10px 4px}.mm-item{width:100%;min-height:36px;color:var(--fg);font:500 14px/1.25 var(--body);text-align:left;cursor:pointer;background:0 0;border:0;border-radius:8px;align-items:center;gap:10px;padding:6px 10px;text-decoration:none;display:flex}.mm-item:hover,.mm-item:focus-visible{background:var(--surface-2)}.mm-item:disabled{opacity:.5;cursor:default}.mm-item small{color:var(--muted);font-size:12px;display:block}.mm-check{width:16px;color:var(--teal);place-items:center;display:inline-grid}.mm-item .fm-swatch{flex:none}.ff-block.kind-decision.compact .ff-dtext{display:none}.ff-block.kind-decision.compact .ff-dia-in{inset:3px}.fx-big{font:650 28px/1 var(--display);align-items:baseline;gap:10px;margin:10px 0 2px;display:flex}.fx-big span{color:var(--muted);font-size:20px}.fx-big .could{color:var(--teal-ink,var(--teal))}.fx-sub{color:var(--muted);margin-bottom:12px;font-size:12.5px;display:block}.fx-watch{margin-top:12px}.fx-why{color:var(--muted);margin:6px 0 0;font-size:13px}.fx-why summary,.fx-more summary{cursor:pointer;color:var(--muted);font-size:13px}.fx-more{border-top:1px solid var(--line);padding:12px 16px 16px}.fx-more summary{align-items:center;gap:6px;display:flex}.fx-more .fx-limits{padding:8px 0 0}.fx-more .fx-cp{margin-top:8px}.sp-head .sp-what{color:var(--muted);overflow-wrap:anywhere;margin:4px 0 0;font-size:13px}.sp-fold>summary{cursor:pointer;color:var(--muted);font:500 13.5px var(--body);align-items:center;gap:6px;display:flex}.sp-fold[open]>summary{margin-bottom:10px}.sp-security li{grid-template-columns:auto 1fr}.sp-fix{color:var(--muted);margin:4px 0 8px;font-size:13px;display:block}.sp-said{color:var(--teal);margin-left:8px;font-size:12.5px;font-weight:600}@media (width<=700px){.fm-tools{display:none}}.mm-btn{letter-spacing:0;gap:6px;min-width:0;font-size:14px}.mm-caret{color:var(--muted);display:inline-flex}.fm-actions .btn,.sec-chip{white-space:nowrap}@media (width<=760px){.fm-actions{flex-wrap:wrap;margin-left:0}}.how{grid-template-columns:minmax(0,1fr) minmax(300px,380px);align-items:start;gap:16px;display:grid}.how-stage{justify-content:center;min-height:420px;position:relative}.how-files{grid-template-columns:repeat(auto-fill,minmax(min(200px,100%),1fr));gap:10px;display:grid}.how-file{border:1px solid var(--line);background:var(--surface);font:500 12.5px/1.2 var(--mono);color:var(--muted);border-radius:10px;align-items:center;gap:8px;padding:10px 12px;transition:border-color .3s,color .3s,box-shadow .3s;display:flex}.how-file.lit{border-color:color-mix(in srgb, var(--violet) 60%, transparent);color:var(--fg);box-shadow:0 0 0 3px color-mix(in srgb, var(--violet) 14%, transparent)}.how-box{flex-direction:column;gap:14px;max-width:520px;display:flex}.how-apps{grid-template-columns:repeat(auto-fill,minmax(min(160px,100%),1fr));gap:12px;display:grid}.how-app{border:1px solid var(--line);background:var(--surface);box-shadow:var(--shadow-1);animation:ff-rise .4s var(--ease) both;border-radius:14px;flex-direction:column;gap:8px;padding:14px;display:flex}.how-app b{font:600 14px/1.2 var(--body)}.how-app .n{font:600 24px/1 var(--mono);letter-spacing:-.02em;font-variant-numeric:tabular-nums}.how-app .m{font:500 11.5px/1.2 var(--mono);color:var(--muted)}.how-app.none{box-shadow:none;border-style:dashed}.how-app.none .n{color:var(--muted)}.how-draft{flex-direction:column;gap:16px;display:flex}.how-chips{flex-wrap:wrap;gap:8px;display:flex}.how-chip{border:1px solid var(--line-2);background:var(--raised);font:600 13.5px/1.2 var(--body);animation:ff-pop .45s var(--ease) both;border-radius:10px;padding:8px 12px}.how-chip.k-llm{border-color:color-mix(in srgb, var(--violet) 55%, transparent)}.how-chip.k-gate{background:var(--amber-bg);border:1.5px dashed var(--amber-strong)}.how-chip.k-decision{border-radius:4px;transform:none}.how-chip.k-start,.how-chip.k-end{border-radius:999px}.how-chip.k-fork,.how-chip.k-join{background:var(--fg);color:var(--bg)}.how-chip.unc{color:var(--muted);background:0 0;border-style:dashed}.how-chip.dropped{border:1.5px dashed var(--coral);color:var(--coral);background:var(--coral-bg);text-decoration:line-through}.how-checks{background:var(--surface-2);border:1px solid var(--line);border-radius:14px;flex-direction:column;gap:6px;margin:0;padding:12px 14px;list-style:none;display:flex}.how-checks li{align-items:center;gap:8px;font-size:14px;display:flex}.how-checks i{width:20px;height:20px;font:700 11px/1 var(--body);border-radius:50%;flex:none;place-items:center;font-style:normal;display:grid}.how-checks .ok i{background:var(--teal);color:var(--on-teal)}.how-checks .drop i{background:var(--coral);color:#2a0d08}.how-checks .unc i{border:1.5px dashed var(--line-2);color:var(--muted)}.how-checks .gate i{background:var(--amber-strong);color:#2a1e05}.how-ready{border:1px solid color-mix(in srgb, var(--teal) 50%, transparent);background:var(--surface);box-shadow:var(--shadow-2);animation:ff-rise .45s var(--ease) both;border-radius:16px;flex-wrap:wrap;align-items:center;gap:14px;margin-top:16px;padding:12px 12px 12px 18px;display:flex}.how-side{flex-direction:column;gap:16px;display:flex}.how-steps{flex-direction:column;gap:2px;margin:0;padding:0;list-style:none;display:flex}.how-steps li{grid-template-columns:28px minmax(0,1fr);gap:10px;padding:8px 0;display:grid}.how-steps .d{border:1.5px solid var(--line-2);width:28px;height:28px;color:var(--muted);font:600 11px/1 var(--mono);border-radius:50%;place-items:center;display:grid}.how-steps .done .d{background:var(--teal);border-color:var(--teal);color:var(--on-teal)}.how-steps .doing .d{border-color:var(--violet);color:var(--violet);box-shadow:0 0 0 4px color-mix(in srgb, var(--violet) 18%, transparent)}.how-steps b{font:600 14px/1.25 var(--body);display:block}.how-steps .todo b{color:var(--muted)}.how-steps small{font:500 12px/1.4 var(--mono);color:var(--muted);margin-top:3px;display:block}.how-steps .doing small{color:var(--violet)}.how-log{background:var(--surface-2);border:1px solid var(--line);min-height:220px;font:500 12px/1.5 var(--mono);border-radius:12px;flex-direction:column;gap:3px;margin:0;padding:12px;display:flex}.how-log>div{animation:ff-rise .3s var(--ease) both;gap:8px;display:flex}.how-log b{text-transform:uppercase;letter-spacing:.04em;flex:0 0 46px;font-weight:600}.how-log span{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}.how-log .read b{color:var(--muted)}.how-log .run b{color:var(--blue)}.how-log .trace b{color:var(--teal-ink)}.how-log .draft b{color:var(--violet)}.how-log .check b{color:var(--amber)}.how-log .done b{color:var(--teal-ink)}.how-priv{background:var(--teal-bg);border-radius:12px;align-items:flex-start;gap:10px;padding:12px;font-size:14px;line-height:1.45;display:flex}.how-priv svg{color:var(--teal-ink);flex:none;margin-top:2px}.rc-banner{background:var(--violet-bg);border:1px solid color-mix(in srgb, var(--violet) 35%, transparent);border-radius:16px;flex-wrap:wrap;align-items:center;gap:12px 18px;padding:14px 16px;display:flex}.rc-banner h2{font-size:19px}.rc-banner p{font:500 12.5px/1.3 var(--mono);color:var(--muted);margin-top:4px}.rc-counts{flex-wrap:wrap;gap:6px;margin-left:auto;display:flex}.rc-cnt{background:var(--surface);border:1px solid var(--line);font:600 12.5px/1 var(--body);border-radius:999px;align-items:center;gap:6px;padding:5px 10px;display:inline-flex}.rc-cnt i{border-radius:3px;width:9px;height:9px;display:inline-block}.rc-map{border:1px solid var(--line);background-color:var(--canvas);background-image:radial-gradient(var(--dot) 1.1px, transparent 1.4px);background-size:22px 22px;border-radius:18px;height:480px;position:relative;overflow:hidden}.rc-tools{z-index:5;position:absolute;top:12px;right:12px}.rc-changes{grid-template-columns:repeat(auto-fit,minmax(min(300px,100%),1fr));gap:12px;display:grid}.rc-change{background:var(--surface);border:1px solid var(--line);box-shadow:var(--shadow-1);border-radius:14px;flex-direction:column;gap:10px;padding:14px;transition:border-color .2s,box-shadow .2s;display:flex}.rc-change.sel{border-color:var(--fg);box-shadow:0 0 0 1px var(--fg), var(--shadow-1)}.rc-type{font:600 10.5px/1.3 var(--mono);letter-spacing:.06em;text-transform:uppercase;border-radius:7px;align-self:flex-start;align-items:center;padding:3px 8px;display:inline-flex}.rc-type.add{background:var(--teal-bg);color:var(--teal-ink)}.rc-type.change{background:var(--violet-bg);color:var(--violet)}.rc-type.remove{background:var(--coral-bg);color:var(--coral)}.rc-type.conflict{background:var(--amber-bg);color:var(--amber)}.rc-type.kept{background:var(--slate-bg);color:var(--fg)}.rc-change b{font:650 15px/1.3 var(--body)}.rc-change p{font-size:14px;line-height:1.45}.rc-ev{font:500 12px/1.3 var(--mono);color:var(--muted)}.rc-foot{z-index:5;background:var(--surface);border:1px solid var(--line);box-shadow:var(--shadow-2);border-radius:16px;flex-wrap:wrap;align-items:center;gap:10px 16px;padding:12px 16px;display:flex;position:sticky;bottom:0}.rc-foot span{color:var(--muted);margin-right:auto;font-size:14px}.diff-add .ff-card,.diff-add .ff-pill{border:1.5px solid var(--teal);box-shadow:0 0 0 4px color-mix(in srgb, var(--teal) 16%, transparent), var(--shadow-2)}.diff-change .ff-card{border:1.5px solid var(--violet);box-shadow:0 0 0 4px color-mix(in srgb, var(--violet) 14%, transparent), var(--shadow-2)}.diff-change.kind-decision .ff-dia{background:var(--violet)}.diff-remove .ff-card{border:1.5px dashed var(--coral);background:var(--coral-bg);box-shadow:none}.diff-remove .ff-title{text-decoration:line-through}.diff-conflict .ff-card{border:1.5px solid var(--amber-strong);box-shadow:0 0 0 4px color-mix(in srgb, var(--amber-strong) 20%, transparent), var(--shadow-2)}.diff-off{opacity:.4}.ff-dtag{font:600 9.5px/1.3 var(--mono);letter-spacing:.05em;text-transform:uppercase;white-space:nowrap;z-index:2;border-radius:6px;padding:2px 7px;position:absolute;top:-11px;right:10px}.ff-dtag.add{background:var(--teal);color:var(--on-teal)}.ff-dtag.change{background:var(--violet);color:var(--on-violet)}.ff-dtag.remove{background:var(--coral);color:#2a0d08}.ff-dtag.conflict{background:var(--amber-strong);color:#2a1e05}.ff-dtag.kept{background:var(--fg);color:var(--bg)}.ff-dtag.off{background:var(--surface);color:var(--muted);border:1px solid var(--line-2)}@media (width<=960px){.how{grid-template-columns:minmax(0,1fr)}}.mm-actions{flex-wrap:wrap;align-items:center;gap:10px;margin:20px 0 16px;display:flex}.mm-actions .btn small{color:var(--muted);font:500 12px var(--mono)}.mm-actions .btn.primary small{color:inherit;opacity:.8}.mm-said{color:var(--teal);min-height:1em;font-weight:600}.mm-frame{border:1px solid var(--line);box-shadow:var(--shadow-1);background:#fff;border-radius:16px;overflow-x:auto}.mm-frame svg{width:100%;min-width:860px;height:auto;display:block}.mm-mermaid{margin-top:20px}.mm-mermaid summary{cursor:pointer;align-items:center;min-height:44px;font-weight:600;display:flex}.mm-mermaid pre{background:var(--surface-2);border:1px solid var(--line);font:12.5px/1.6 var(--mono);border-radius:12px;margin:8px 0 0;padding:16px;overflow-x:auto}.mm-rules{color:var(--muted);margin-top:12px;font-size:14px}@media print{@page{size:A4 landscape;margin:10mm}body *{visibility:hidden}.mm-print,.mm-print *{visibility:visible}.mm-print{width:100%;box-shadow:none;border:0;position:absolute;inset:0 auto auto 0;overflow:visible}.mm-print svg{min-width:0}}.cat-hero{border-radius:var(--r-lg);background:var(--surface);border:1px solid color-mix(in srgb, var(--violet) 35%, transparent);box-shadow:var(--shadow-1);grid-template-columns:auto minmax(0,1fr);align-items:start;gap:14px 16px;padding:18px;display:grid}.cat-hero p{max-width:70ch;margin-top:6px;font-size:15px}.cat-strips{flex-direction:column;grid-column:1/-1;gap:10px;display:flex}.cat-strip{flex-wrap:wrap;align-items:center;gap:8px;display:flex}.cat-strip .lbl{font:600 10.5px/1 var(--mono);letter-spacing:.08em;text-transform:uppercase;color:var(--muted);min-width:200px;margin-right:6px}.cat-pt{background:var(--surface-2);border:1px solid var(--line);min-height:36px;color:var(--fg);font:600 13px/1 var(--body);border-radius:999px;align-items:center;gap:8px;padding:4px 10px 4px 4px;text-decoration:none;display:inline-flex}.cat-pt:hover{color:var(--fg);border-color:var(--idle)}.cat-pt>span{border-radius:999px!important}.cat-pt i{background:var(--teal);border-radius:50%;width:7px;height:7px;display:inline-block}.cat-pt.idle{color:var(--muted);background:0 0;border-style:dashed}.cat-pt.idle i{border:1.5px solid var(--muted);background:0 0}.cat-none{color:var(--muted);font-size:13px}.cat-controls{z-index:4;background:var(--bg);flex-wrap:wrap;align-items:center;gap:10px;padding:10px 0;display:flex;position:sticky;top:0}.cat-search{background:var(--surface);border:1px solid var(--idle);min-height:46px;color:var(--muted);border-radius:12px;flex:320px;align-items:center;gap:10px;padding:0 14px;display:flex}.cat-search:focus-within{border-color:var(--teal);box-shadow:var(--glow)}.cat-search input{min-width:0;height:44px;color:var(--fg);background:0 0;border:0;outline:none;flex:1;font-size:15px}.cat-chips{flex-wrap:wrap;gap:6px;display:flex}.cat-chips .n{font:600 11px/1 var(--mono);color:var(--muted);margin-left:6px}.cat-chips .filter[aria-pressed=true] .n{color:inherit}.cat-sec{flex-direction:column;gap:12px;display:flex}.cat-sech{align-items:baseline;gap:10px;display:flex}.cat-sech h2{font-size:19px}.cat-sech span{font:500 12.5px/1 var(--mono);color:var(--muted)}.cat-grid{grid-template-columns:repeat(auto-fill,minmax(min(272px,100%),1fr));gap:12px;display:grid}.cat-card{border-radius:var(--r-lg);background:var(--surface);border:1px solid var(--line);box-shadow:var(--shadow-1);transition:transform var(--t-fast) var(--ease), box-shadow var(--t-fast), border-color var(--t-fast);flex-direction:column;gap:10px;padding:14px;display:flex}.cat-card:hover{box-shadow:var(--shadow-2);border-color:var(--idle);transform:translateY(-2px)}.cat-head{align-items:center;gap:12px;display:flex}.cat-name{flex:1;min-width:0}.cat-name b{font:650 15px/1.2 var(--body);display:block}.cat-name small{font:500 11.5px/1 var(--mono);color:var(--muted);margin-top:3px;display:block}.cat-card p{font-size:14px;line-height:1.45}.cat-meta{font:500 12px/1.3 var(--mono);color:var(--muted)}.cat-actions{align-items:center;gap:8px;margin-top:auto;display:flex}.cat-add{margin-left:auto}.cat-state{min-height:36px;font:600 13px/1 var(--body);color:var(--teal-ink);align-items:center;gap:6px;margin-left:auto;text-decoration:none;display:inline-flex}.cat-state i{background:var(--teal);border-radius:50%;width:7px;height:7px;display:inline-block}.cat-state.idle{color:var(--muted)}.cat-state.idle i{border:1.5px solid var(--muted);background:0 0}.cat-badge{font:600 11.5px/1.2 var(--body);white-space:nowrap;border-radius:999px;align-items:center;gap:5px;padding:3px 8px;display:inline-flex}.cat-badge i{background:currentColor;border-radius:50%;width:6px;height:6px;display:inline-block}.cat-badge.live{background:var(--teal-bg);color:var(--teal-ink)}.cat-badge.demo{background:var(--slate-bg);color:var(--slate)}.cat-scrim{z-index:30;background:#060c0f73;position:fixed;inset:0}.cat-drawer{z-index:31;background:var(--surface);border-left:1px solid var(--line);width:440px;max-width:100%;box-shadow:var(--shadow-3);animation:fm-slide .35s var(--ease) backwards;flex-direction:column;display:flex;position:fixed;top:0;bottom:0;right:0;overflow-y:auto}.cat-dhead{border-bottom:1px solid var(--line);align-items:flex-start;gap:12px;padding:18px 14px 16px 18px;display:flex}.cat-dhead h2{margin-top:6px;font-size:20px}.cat-dsec{border-bottom:1px solid var(--line);flex-direction:column;gap:10px;padding:16px 18px;display:flex}.cat-row{flex-flow:wrap;gap:8px}.cat-mode{border-radius:12px;align-items:flex-start;gap:9px;padding:11px 12px;font-size:14px;line-height:1.45;display:flex}.cat-mode.live{background:var(--teal-bg)}.cat-mode.demo{background:var(--slate-bg)}.cat-mode svg{flex:none;margin-top:1px}.cat-steps{flex-direction:column;gap:4px;margin:0;padding:0;list-style:none;display:flex}.cat-steps li{grid-template-columns:26px minmax(0,1fr);gap:10px;padding:6px 0;display:grid}.cat-steps .d{border:1.5px solid var(--line-2);border-radius:50%;place-items:center;width:26px;height:26px;display:grid}.cat-steps li.done .d{background:var(--teal);border-color:var(--teal);color:var(--on-teal)}.cat-steps li.doing .d{border-color:var(--blue);color:var(--blue)}.cat-steps b{font:600 14px/1.3 var(--body);display:block}.cat-steps code{font:500 12.5px/1.45 var(--mono);color:var(--muted);white-space:pre-wrap;word-break:break-word;margin-top:3px;display:block}.cat-learn{font:500 13px/1.3 var(--mono);flex-direction:column;gap:6px;margin:0;padding:0;list-style:none;display:flex}.cat-learn li{align-items:center;gap:8px;display:flex}.cat-learn li:before{content:"";background:var(--violet);border-radius:2px;flex:none;width:6px;height:6px}@media (width<=760px){.cat-strip .lbl{width:100%;min-width:0}.cat-drawer{border-left:0;border-top:1px solid var(--line);border-radius:18px 18px 0 0;width:auto;max-height:82%;top:auto;left:0}}@media (prefers-reduced-motion:reduce){.cat-drawer{animation:none}.cat-card:hover{transform:none}}.gantt{flex-direction:column;gap:8px;min-width:560px;display:flex}.gantt-row{grid-template-columns:minmax(170px,230px) 1fr;align-items:center;gap:12px;display:grid}.gantt-label{border-radius:var(--r-sm);min-height:44px;color:var(--fg);text-align:left;cursor:pointer;background:0 0;border:1px solid #0000;align-items:center;gap:8px;min-width:0;padding:0 8px;display:flex}.gantt-label:hover{background:var(--surface-2)}.is-selected .gantt-label{background:var(--teal-bg);border-color:color-mix(in srgb, var(--teal) 40%, transparent)}.gantt-n{font:500 13px/1 var(--mono);color:var(--muted);flex:none;width:18px}.gantt-title{white-space:nowrap;text-overflow:ellipsis;flex:1;min-width:0;font-size:14px;overflow:hidden}.gantt-track{background:var(--surface-2);cursor:pointer;border:1px solid var(--line);border-radius:7px;height:30px;position:relative}.gantt-bar{background:var(--tone,var(--teal));border-radius:5px;justify-content:flex-end;align-items:center;transition:width .14s linear,left .14s linear;display:flex;position:absolute;top:3px;bottom:3px;overflow:hidden}.gantt-bar.state-succeeded{background:var(--teal)}.gantt-bar.state-running{background:var(--blue)}.gantt-bar.state-failed{background:var(--coral)}.gantt-bar.is-cache{background:color-mix(in srgb, var(--teal) 45%, var(--surface))}.gantt-bar.is-expected{border:2px dashed var(--idle);background:0 0}.gantt-bar.is-critical{outline:3px solid var(--fg);outline-offset:1px}.gantt-bar.is-expected.is-critical{border-color:var(--fg);outline:none}.gantt-chip{font:500 11px/1 var(--mono);color:var(--fg);padding:0 6px}.gantt-skip{font:500 12px/1 var(--mono);color:var(--muted);position:absolute;top:50%;left:8px;transform:translateY(-50%)}.gantt-axis{min-height:18px}.gantt-ticks{font:500 12px/1 var(--mono);color:var(--muted);justify-content:space-between;display:flex;position:relative}.gantt-now{background:var(--blue);border-radius:2px;width:2px;height:14px;position:absolute;top:-10px;transform:translate(-1px)}.legend{color:var(--muted);flex-wrap:wrap;gap:8px 16px;font-size:13px;display:flex}.legend i{vertical-align:-1px;border-radius:3px;width:12px;height:12px;margin-right:6px;display:inline-block}