@opencode-trace/viewer 0.0.3 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -2
- package/dist/cli.js +20 -6
- package/dist/cli.js.map +1 -1
- package/dist/cli.test.d.ts +2 -0
- package/dist/cli.test.d.ts.map +1 -0
- package/dist/cli.test.js +110 -0
- package/dist/cli.test.js.map +1 -0
- package/dist/index.test.d.ts +2 -0
- package/dist/index.test.d.ts.map +1 -0
- package/dist/index.test.js +21 -0
- package/dist/index.test.js.map +1 -0
- package/dist/public/assets/index-BAtN_fgH.css +1 -0
- package/dist/public/assets/index-DgiS5drt.js +91 -0
- package/dist/public/index.html +2 -2
- package/dist/server.d.ts +5 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +418 -45
- package/dist/server.js.map +1 -1
- package/dist/server.test.js +1275 -81
- package/dist/server.test.js.map +1 -1
- package/package.json +5 -3
- package/dist/public/assets/index-DoL5ISmB.js +0 -91
- package/dist/public/assets/index-idry_N9R.css +0 -1
package/README.md
CHANGED
|
@@ -27,14 +27,29 @@ opencode-trace-viewer
|
|
|
27
27
|
opencode-trace viewer
|
|
28
28
|
```
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
```bash
|
|
31
|
+
# Start Viewer with custom trace directory
|
|
32
|
+
opencode-trace-viewer --trace-dir /path/to/traces
|
|
33
|
+
|
|
34
|
+
# Start Viewer
|
|
35
|
+
npx @opencode-trace/viewer
|
|
36
|
+
|
|
37
|
+
# Or (if globally installed)
|
|
38
|
+
opencode-trace-viewer
|
|
39
|
+
|
|
40
|
+
# Or (via CLI)
|
|
41
|
+
opencode-trace viewer
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
After starting, browser automatically opens (default http://localhost:3210).
|
|
31
45
|
|
|
32
46
|
### Options
|
|
33
47
|
|
|
34
48
|
| Option | Description |
|
|
35
49
|
|--------|-------------|
|
|
36
|
-
| `--port <num>` | Specify port (default
|
|
50
|
+
| `--port <num>` | Specify port (default 3210) |
|
|
37
51
|
| `--no-open` | Don't auto-open browser |
|
|
52
|
+
| `--trace-dir <path>` | Read trace data from custom directory (default `~/.opencode-trace`) |
|
|
38
53
|
|
|
39
54
|
## Features
|
|
40
55
|
|
package/dist/cli.js
CHANGED
|
@@ -1,16 +1,30 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createViewer } from "./server.js";
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
const rawArgs = process.argv.slice(2);
|
|
4
|
+
let traceDir;
|
|
5
|
+
let openBrowser = true;
|
|
6
|
+
let portArg;
|
|
7
|
+
for (let i = 0; i < rawArgs.length; i++) {
|
|
8
|
+
const a = rawArgs[i];
|
|
9
|
+
if (a === "--trace-dir" && i + 1 < rawArgs.length) {
|
|
10
|
+
traceDir = rawArgs[++i];
|
|
11
|
+
}
|
|
12
|
+
else if (a === "--no-open") {
|
|
13
|
+
openBrowser = false;
|
|
14
|
+
}
|
|
15
|
+
else if (!a.startsWith("--") && portArg === undefined) {
|
|
16
|
+
portArg = a;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
6
19
|
const port = portArg ? parseInt(portArg, 10) : 3210;
|
|
7
20
|
if (isNaN(port)) {
|
|
8
|
-
console.error("Usage: opencode-trace-viewer [port] [--no-open]");
|
|
21
|
+
console.error("Usage: opencode-trace-viewer [port] [--no-open] [--trace-dir <path>]");
|
|
9
22
|
console.error("Default port: 3210");
|
|
10
|
-
console.error(" --no-open
|
|
23
|
+
console.error(" --no-open Don't open browser automatically");
|
|
24
|
+
console.error(" --trace-dir Read trace data from custom path instead of ~/.opencode-trace");
|
|
11
25
|
process.exit(1);
|
|
12
26
|
}
|
|
13
|
-
createViewer({ port, open: openBrowser }).then((instance) => {
|
|
27
|
+
createViewer({ port, open: openBrowser, traceDir }).then((instance) => {
|
|
14
28
|
console.log(`opencode-trace viewer running at ${instance.url}`);
|
|
15
29
|
console.log("Press Ctrl+C to stop");
|
|
16
30
|
process.on("SIGINT", () => {
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,MAAM,
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAEtC,IAAI,QAA4B,CAAC;AACjC,IAAI,WAAW,GAAG,IAAI,CAAC;AACvB,IAAI,OAA2B,CAAC;AAEhC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;IACxC,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACrB,IAAI,CAAC,KAAK,aAAa,IAAI,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;QAClD,QAAQ,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;IAC1B,CAAC;SAAM,IAAI,CAAC,KAAK,WAAW,EAAE,CAAC;QAC7B,WAAW,GAAG,KAAK,CAAC;IACtB,CAAC;SAAM,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QACxD,OAAO,GAAG,CAAC,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAEpD,IAAI,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;IAChB,OAAO,CAAC,KAAK,CAAC,sEAAsE,CAAC,CAAC;IACtF,OAAO,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;IACpC,OAAO,CAAC,KAAK,CAAC,mDAAmD,CAAC,CAAC;IACnE,OAAO,CAAC,KAAK,CAAC,gFAAgF,CAAC,CAAC;IAChG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,YAAY,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE;IACpE,OAAO,CAAC,GAAG,CAAC,oCAAoC,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC;IAChE,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;IAEpC,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;QACxB,QAAQ,CAAC,KAAK,EAAE,CAAC;QACjB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.test.d.ts","sourceRoot":"","sources":["../src/cli.test.ts"],"names":[],"mappings":""}
|
package/dist/cli.test.js
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach, vi } from "vitest";
|
|
2
|
+
const { mockCreateViewer } = vi.hoisted(() => ({
|
|
3
|
+
mockCreateViewer: vi.fn(),
|
|
4
|
+
}));
|
|
5
|
+
vi.mock("./server.js", () => ({
|
|
6
|
+
createViewer: mockCreateViewer,
|
|
7
|
+
}));
|
|
8
|
+
describe("cli", () => {
|
|
9
|
+
let originalArgv;
|
|
10
|
+
let exitSpy;
|
|
11
|
+
let logSpy;
|
|
12
|
+
let errorSpy;
|
|
13
|
+
let onSpy;
|
|
14
|
+
let mockInstance;
|
|
15
|
+
async function loadCliWithArgs(args) {
|
|
16
|
+
vi.resetModules();
|
|
17
|
+
process.argv = ["node", "cli.js", ...args];
|
|
18
|
+
await import("./cli.js");
|
|
19
|
+
await new Promise((resolve) => setImmediate(resolve));
|
|
20
|
+
}
|
|
21
|
+
beforeEach(() => {
|
|
22
|
+
originalArgv = process.argv;
|
|
23
|
+
mockInstance = {
|
|
24
|
+
url: "http://localhost:3210",
|
|
25
|
+
close: vi.fn().mockResolvedValue(undefined),
|
|
26
|
+
};
|
|
27
|
+
mockCreateViewer.mockReset();
|
|
28
|
+
mockCreateViewer.mockResolvedValue(mockInstance);
|
|
29
|
+
exitSpy = vi.spyOn(process, "exit").mockImplementation(((code) => {
|
|
30
|
+
throw new Error(`exit_${code}`);
|
|
31
|
+
}));
|
|
32
|
+
logSpy = vi.spyOn(console, "log").mockImplementation(() => { });
|
|
33
|
+
errorSpy = vi.spyOn(console, "error").mockImplementation(() => { });
|
|
34
|
+
onSpy = vi.spyOn(process, "on");
|
|
35
|
+
});
|
|
36
|
+
afterEach(() => {
|
|
37
|
+
process.argv = originalArgv;
|
|
38
|
+
exitSpy.mockRestore();
|
|
39
|
+
logSpy.mockRestore();
|
|
40
|
+
errorSpy.mockRestore();
|
|
41
|
+
onSpy.mockRestore();
|
|
42
|
+
vi.resetModules();
|
|
43
|
+
});
|
|
44
|
+
it("uses defaults (port 3210, open=true, no traceDir) when no args", async () => {
|
|
45
|
+
await loadCliWithArgs([]);
|
|
46
|
+
expect(mockCreateViewer).toHaveBeenCalledTimes(1);
|
|
47
|
+
expect(mockCreateViewer).toHaveBeenCalledWith({
|
|
48
|
+
port: 3210,
|
|
49
|
+
open: true,
|
|
50
|
+
traceDir: undefined,
|
|
51
|
+
});
|
|
52
|
+
expect(logSpy).toHaveBeenCalledWith("opencode-trace viewer running at http://localhost:3210");
|
|
53
|
+
expect(logSpy).toHaveBeenCalledWith("Press Ctrl+C to stop");
|
|
54
|
+
});
|
|
55
|
+
it("accepts positional port arg", async () => {
|
|
56
|
+
mockInstance.url = "http://localhost:3211";
|
|
57
|
+
await loadCliWithArgs(["3211"]);
|
|
58
|
+
expect(mockCreateViewer).toHaveBeenCalledWith({
|
|
59
|
+
port: 3211,
|
|
60
|
+
open: true,
|
|
61
|
+
traceDir: undefined,
|
|
62
|
+
});
|
|
63
|
+
expect(logSpy).toHaveBeenCalledWith("opencode-trace viewer running at http://localhost:3211");
|
|
64
|
+
});
|
|
65
|
+
it("--no-open disables browser open", async () => {
|
|
66
|
+
await loadCliWithArgs(["--no-open"]);
|
|
67
|
+
expect(mockCreateViewer).toHaveBeenCalledWith({
|
|
68
|
+
port: 3210,
|
|
69
|
+
open: false,
|
|
70
|
+
traceDir: undefined,
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
it("--trace-dir sets traceDir", async () => {
|
|
74
|
+
await loadCliWithArgs(["--trace-dir", "/tmp/x"]);
|
|
75
|
+
expect(mockCreateViewer).toHaveBeenCalledWith({
|
|
76
|
+
port: 3210,
|
|
77
|
+
open: true,
|
|
78
|
+
traceDir: "/tmp/x",
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
it("combines port, --no-open and --trace-dir", async () => {
|
|
82
|
+
mockInstance.url = "http://localhost:3211";
|
|
83
|
+
await loadCliWithArgs(["3211", "--no-open", "--trace-dir", "/tmp/x"]);
|
|
84
|
+
expect(mockCreateViewer).toHaveBeenCalledWith({
|
|
85
|
+
port: 3211,
|
|
86
|
+
open: false,
|
|
87
|
+
traceDir: "/tmp/x",
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
it("invalid port prints usage and exits with code 1", async () => {
|
|
91
|
+
vi.resetModules();
|
|
92
|
+
process.argv = ["node", "cli.js", "abc"];
|
|
93
|
+
await expect(import("./cli.js")).rejects.toThrow("exit_1");
|
|
94
|
+
expect(errorSpy).toHaveBeenCalledWith("Usage: opencode-trace-viewer [port] [--no-open] [--trace-dir <path>]");
|
|
95
|
+
expect(errorSpy).toHaveBeenCalledWith("Default port: 3210");
|
|
96
|
+
expect(errorSpy).toHaveBeenCalledWith(" --no-open Don't open browser automatically");
|
|
97
|
+
expect(errorSpy).toHaveBeenCalledWith(" --trace-dir Read trace data from custom path instead of ~/.opencode-trace");
|
|
98
|
+
expect(mockCreateViewer).not.toHaveBeenCalled();
|
|
99
|
+
});
|
|
100
|
+
it("registers SIGINT handler that closes instance and exits 0", async () => {
|
|
101
|
+
await loadCliWithArgs([]);
|
|
102
|
+
const sigintCall = onSpy.mock.calls.find((c) => c[0] === "SIGINT");
|
|
103
|
+
expect(sigintCall).toBeDefined();
|
|
104
|
+
const handler = sigintCall[1];
|
|
105
|
+
expect(() => handler()).toThrow("exit_0");
|
|
106
|
+
expect(mockInstance.close).toHaveBeenCalledTimes(1);
|
|
107
|
+
expect(exitSpy).toHaveBeenCalledWith(0);
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
//# sourceMappingURL=cli.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.test.js","sourceRoot":"","sources":["../src/cli.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../src/index.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
describe("index (barrel)", () => {
|
|
3
|
+
it("re-exports createViewer from ./server.js", async () => {
|
|
4
|
+
const indexExports = await import("./index.js");
|
|
5
|
+
expect(indexExports.createViewer).toBeDefined();
|
|
6
|
+
expect(typeof indexExports.createViewer).toBe("function");
|
|
7
|
+
});
|
|
8
|
+
it("createViewer reference equals the one exported from server.js", async () => {
|
|
9
|
+
const indexExports = await import("./index.js");
|
|
10
|
+
const serverExports = await import("./server.js");
|
|
11
|
+
expect(indexExports.createViewer).toBe(serverExports.createViewer);
|
|
12
|
+
});
|
|
13
|
+
it("exposes only runtime symbols (types are erased)", async () => {
|
|
14
|
+
const indexExports = await import("./index.js");
|
|
15
|
+
const runtimeKeys = Object.keys(indexExports).sort();
|
|
16
|
+
// ViewerOptions and ViewerInstance are type-only re-exports
|
|
17
|
+
// so only createViewer is present at runtime.
|
|
18
|
+
expect(runtimeKeys).toEqual(["createViewer"]);
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
//# sourceMappingURL=index.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.test.js","sourceRoot":"","sources":["../src/index.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAE9C,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;IAC9B,EAAE,CAAC,0CAA0C,EAAE,KAAK,IAAI,EAAE;QACxD,MAAM,YAAY,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC;QAChD,MAAM,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC,WAAW,EAAE,CAAC;QAChD,MAAM,CAAC,OAAO,YAAY,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+DAA+D,EAAE,KAAK,IAAI,EAAE;QAC7E,MAAM,YAAY,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC;QAChD,MAAM,aAAa,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;QAClD,MAAM,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;IACrE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iDAAiD,EAAE,KAAK,IAAI,EAAE;QAC/D,MAAM,YAAY,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC;QAChD,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,IAAI,EAAE,CAAC;QACrD,4DAA4D;QAC5D,8CAA8C;QAC9C,MAAM,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
header[data-v-dac32c4f]{display:flex;align-items:center;justify-content:space-between;padding:12px 24px;background:var(--bg-primary);border-bottom:1px solid var(--border);flex-shrink:0;min-height:48px}header h1[data-v-dac32c4f]{font-size:16px;font-weight:700;display:flex;align-items:center;gap:8px;line-height:1}.header-actions[data-v-dac32c4f]{display:flex;align-items:center;gap:12px}.dropdown[data-v-dac32c4f]{position:relative}.dropdown-toggle[data-v-dac32c4f]{padding:8px;border-radius:var(--radius);display:flex;align-items:center;justify-content:center;transition:background .1s}.dropdown-toggle[data-v-dac32c4f]:hover{background:var(--bg-hover)}.dropdown-menu[data-v-dac32c4f]{position:absolute;right:0;top:100%;margin-top:4px;background:var(--bg-secondary);border:1px solid var(--border);border-radius:var(--radius);min-width:200px;z-index:100;padding:4px}.dropdown-item[data-v-dac32c4f]{display:flex;align-items:center;gap:8px;width:100%;padding:8px 12px;font-size:14px;font-weight:500;border-radius:var(--radius);transition:background .1s;text-align:left}.dropdown-item[data-v-dac32c4f]:hover{background:var(--bg-hover)}.dropdown-item.danger[data-v-dac32c4f]{color:var(--danger)}.dropdown-divider[data-v-dac32c4f]{height:1px;background:var(--border);margin:4px 0}.breadcrumb[data-v-1dcd01d0]{display:flex;align-items:center;gap:6px;font-size:13px;color:var(--text-secondary);padding:8px 24px;background:var(--bg-primary);border-bottom:1px solid var(--border);flex-shrink:0;flex-wrap:wrap}.breadcrumb a[data-v-1dcd01d0]{color:var(--text-secondary);text-decoration:none}.breadcrumb a[data-v-1dcd01d0]:hover{color:var(--accent);text-decoration:underline}.sep[data-v-1dcd01d0]{color:var(--text-tertiary);margin:0 2px}.current[data-v-1dcd01d0]{color:var(--text-primary);font-weight:500}.fab-container[data-v-05bb3e02]{position:fixed;bottom:24px;right:24px;display:flex;flex-direction:column;gap:8px;z-index:50}.fab-scroll[data-v-05bb3e02]{width:40px;height:40px;border-radius:var(--radius);background:var(--bg-secondary);border:1px solid var(--border);display:flex;align-items:center;justify-content:center;transition:background .1s}.fab-scroll[data-v-05bb3e02]:hover{background:var(--bg-hover)}.toast-container[data-v-c0d5f9b8]{position:fixed;bottom:24px;left:50%;transform:translate(-50%);display:flex;flex-direction:column;gap:8px;z-index:200;pointer-events:none}.toast[data-v-c0d5f9b8]{display:flex;align-items:center;gap:12px;padding:10px 16px;border-radius:var(--radius);font-size:14px;font-weight:500;pointer-events:auto;animation:toast-in-c0d5f9b8 .2s ease-out;border:1px solid}.toast.success[data-v-c0d5f9b8]{background:#30d1581f;border-color:var(--success);color:var(--success)}.toast.error[data-v-c0d5f9b8]{background:#ff3b301f;border-color:var(--danger);color:var(--danger)}.toast.info[data-v-c0d5f9b8]{background:var(--bg-secondary);border-color:var(--border);color:var(--text-primary)}.toast.warning[data-v-c0d5f9b8]{background:#ff9f0a1f;border-color:var(--warning);color:var(--warning)}.toast-action[data-v-c0d5f9b8]{padding:4px 10px;border-radius:var(--radius);font-size:12px;font-weight:700;background:var(--bg-tertiary);white-space:nowrap}@keyframes toast-in-c0d5f9b8{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}.confirm-overlay[data-v-d7ee27c7]{position:fixed;top:0;right:0;bottom:0;left:0;background:#00000080;display:flex;align-items:center;justify-content:center;z-index:300}.confirm-dialog[data-v-d7ee27c7]{background:var(--bg-primary);border:1px solid var(--border);border-radius:var(--radius);padding:24px;max-width:420px;width:90%}.confirm-title[data-v-d7ee27c7]{font-size:16px;font-weight:700;margin-bottom:8px}.confirm-message[data-v-d7ee27c7]{font-size:14px;color:var(--text-secondary);margin-bottom:20px;line-height:1.5}.confirm-actions[data-v-d7ee27c7]{display:flex;gap:8px;justify-content:flex-end}.confirm-btn[data-v-d7ee27c7]{padding:8px 20px;border-radius:var(--radius);font-size:14px;font-weight:500;transition:background .1s}.confirm-btn.cancel[data-v-d7ee27c7]{background:var(--bg-tertiary);color:var(--text-primary)}.confirm-btn.cancel[data-v-d7ee27c7]:hover{background:var(--bg-hover)}.confirm-btn.danger[data-v-d7ee27c7]{background:var(--danger);color:var(--oc-light)}.confirm-btn.danger[data-v-d7ee27c7]:hover{background:var(--danger-hover)}.keyboard-help-overlay[data-v-3d1cdec0]{position:fixed;top:0;right:0;bottom:0;left:0;background:#00000080;display:flex;align-items:center;justify-content:center;z-index:300}.keyboard-help[data-v-3d1cdec0]{background:var(--bg-primary);border:1px solid var(--border);border-radius:var(--radius);padding:24px;max-width:380px;width:90%}.keyboard-help h3[data-v-3d1cdec0]{font-size:16px;font-weight:700;margin-bottom:16px}.shortcut-list[data-v-3d1cdec0]{display:flex;flex-direction:column;gap:10px;margin-bottom:20px}.shortcut[data-v-3d1cdec0]{display:flex;align-items:center;gap:10px;font-size:14px;color:var(--text-secondary)}.help-close[data-v-3d1cdec0]{width:100%;padding:8px 20px;border-radius:var(--radius);font-size:14px;font-weight:500;background:var(--bg-tertiary);transition:background .1s}.help-close[data-v-3d1cdec0]:hover{background:var(--bg-hover)}.modal-overlay[data-v-3bdf94c5]{position:fixed;top:0;right:0;bottom:0;left:0;background:#00000080;display:flex;align-items:center;justify-content:center;z-index:300}.modal-content[data-v-3bdf94c5]{background:var(--bg-primary);border:1px solid var(--border);border-radius:var(--radius);max-width:480px;width:90%}.modal-header[data-v-3bdf94c5]{display:flex;align-items:center;justify-content:space-between;padding:16px 20px;border-bottom:1px solid var(--border)}.modal-header h3[data-v-3bdf94c5]{font-size:16px;font-weight:700}.modal-close[data-v-3bdf94c5]{font-size:20px;padding:4px 8px;border-radius:var(--radius)}.modal-close[data-v-3bdf94c5]:hover{background:var(--bg-hover)}.modal-body[data-v-3bdf94c5]{padding:20px}.file-label[data-v-3bdf94c5]{display:flex;flex-direction:column;gap:8px;margin-bottom:16px}.file-label-text[data-v-3bdf94c5]{font-size:14px;font-weight:500}.file-input-wrapper[data-v-3bdf94c5]{position:relative;display:inline-block}.file-input-native[data-v-3bdf94c5]{position:absolute;top:0;left:0;width:100%;height:100%;opacity:0;cursor:pointer}.file-input-button[data-v-3bdf94c5]{display:inline-block;padding:10px 18px;background:var(--bg-tertiary);color:var(--text-primary);border-radius:var(--radius);font-size:14px;font-weight:500;cursor:pointer;transition:background .1s;border:1px solid var(--border)}.file-input-button[data-v-3bdf94c5]:hover{background:var(--bg-hover)}.file-input-native:focus-visible+.file-input-button[data-v-3bdf94c5]{outline:2px solid var(--accent);outline-offset:2px}.import-status[data-v-3bdf94c5]{min-height:24px}.status-msg[data-v-3bdf94c5]{font-size:14px;padding:8px 12px;border-radius:var(--radius)}.status-msg.success[data-v-3bdf94c5]{background:#30d1581f;color:var(--success)}.status-msg.error[data-v-3bdf94c5]{background:#ff3b301f;color:var(--danger)}.status-msg.warning[data-v-3bdf94c5]{background:#ff9f0a1f;color:var(--warning)}.conflict-panel[data-v-3bdf94c5]{margin-top:16px}.conflict-panel h4[data-v-3bdf94c5]{font-size:14px;font-weight:700;margin-bottom:8px}.conflict-list[data-v-3bdf94c5]{display:flex;flex-direction:column;gap:4px;margin-bottom:12px;max-height:200px;overflow-y:auto}.conflict-item[data-v-3bdf94c5]{display:flex;gap:8px;padding:6px 10px;background:var(--bg-tertiary);border-radius:var(--radius);font-size:13px}.conflict-id[data-v-3bdf94c5]{font-weight:500;color:var(--text-primary)}.conflict-title[data-v-3bdf94c5]{color:var(--text-secondary)}.conflict-actions[data-v-3bdf94c5]{display:flex;gap:8px}.conflict-actions button[data-v-3bdf94c5]{padding:6px 14px;border-radius:var(--radius);font-size:13px;font-weight:500}.action-rename[data-v-3bdf94c5]{background:var(--accent);color:var(--oc-light)}.action-rename[data-v-3bdf94c5]:hover{background:var(--accent-hover)}.action-skip[data-v-3bdf94c5]{background:var(--bg-tertiary)}.action-skip[data-v-3bdf94c5]:hover{background:var(--bg-hover)}.action-cancel[data-v-3bdf94c5]{background:var(--bg-tertiary)}.action-cancel[data-v-3bdf94c5]:hover{background:var(--bg-hover)}.sessions-controls-bar[data-v-15c5be0c]{margin-top:16px;margin-bottom:16px}.view-controls[data-v-15c5be0c]{display:flex;align-items:center;justify-content:flex-end;gap:12px;flex-wrap:wrap}.search-input-container[data-v-15c5be0c]{position:relative;display:flex;align-items:center}.search-icon[data-v-15c5be0c]{position:absolute;left:12px;color:var(--text-tertiary);pointer-events:none;display:flex}.search-input[data-v-15c5be0c]{padding:8px 36px;border:1px solid var(--border);border-radius:var(--radius-input);background:var(--bg-tertiary);color:var(--text-primary);font-family:var(--font-family);font-size:14px;width:240px;outline:none;transition:border-color .1s}.search-input[data-v-15c5be0c]:focus{border-color:var(--accent)}.search-clear[data-v-15c5be0c]{position:absolute;right:4px;padding:4px;border-radius:2px;display:flex;align-items:center}.search-clear[data-v-15c5be0c]:hover{background:var(--bg-hover)}.sort-label[data-v-15c5be0c]{display:flex;align-items:center;gap:6px;font-size:13px;color:var(--text-secondary)}.sort-select[data-v-15c5be0c]{padding:6px 32px 6px 12px;border:1px solid var(--border);border-radius:var(--radius);background:var(--bg-tertiary);color:var(--text-primary);font-family:var(--font-family);font-size:13px;outline:none;-webkit-appearance:none;-moz-appearance:none;appearance:none;cursor:pointer;position:relative}.sort-select[data-v-15c5be0c]:after{content:"";position:absolute;right:10px;top:50%;transform:translateY(-50%);width:12px;height:12px;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:center;color:var(--text-secondary);pointer-events:none}.sort-select option[data-v-15c5be0c]{background:var(--bg-primary);color:var(--text-primary)}.folder-groups[data-v-15c5be0c]{display:flex;flex-direction:column;gap:24px}.folder-group[data-v-15c5be0c]{border:1px solid var(--border);border-radius:var(--radius);overflow:hidden}.folder-header[data-v-15c5be0c]{display:flex;align-items:center;gap:12px;padding:12px 16px;background:var(--bg-tertiary);border-bottom:1px solid var(--border);flex-wrap:wrap}.folder-title[data-v-15c5be0c]{font-size:14px;font-weight:700}.folder-path[data-v-15c5be0c]{font-size:12px;color:var(--text-tertiary);flex:1}.folder-sessions[data-v-15c5be0c]{padding:8px;display:flex;flex-direction:column;gap:4px}.session-card[data-v-15c5be0c]{padding:12px 16px}.session-card-header[data-v-15c5be0c]{display:flex;align-items:center;justify-content:space-between}.session-title-row[data-v-15c5be0c]{flex:1;min-width:0}.session-card-content[data-v-15c5be0c]{display:flex;flex-direction:column;gap:4px}.session-title[data-v-15c5be0c]{font-size:14px;font-weight:700;word-break:break-word}.session-id[data-v-15c5be0c]{font-size:12px;color:var(--text-tertiary);word-break:break-all}.session-meta[data-v-15c5be0c]{display:flex;gap:6px;flex-wrap:wrap;margin-top:4px}.session-card-actions[data-v-15c5be0c]{flex-shrink:0;margin-left:12px}.session-card-more[data-v-15c5be0c]{position:relative}.session-more-btn[data-v-15c5be0c]{padding:4px 8px;border-radius:var(--radius);font-size:16px;line-height:1}.session-more-btn[data-v-15c5be0c]:hover{background:var(--bg-hover)}.session-more-menu[data-v-15c5be0c]{position:absolute;right:0;top:100%;margin-top:4px;background:var(--bg-secondary);border:1px solid var(--border);border-radius:var(--radius);min-width:200px;z-index:50;padding:4px}.session-more-menu .dropdown-item[data-v-15c5be0c]{display:flex;align-items:center;gap:8px;width:100%;padding:8px 12px;font-size:13px;font-weight:500;border-radius:var(--radius);text-align:left}.session-more-menu .dropdown-item[data-v-15c5be0c]:hover{background:var(--bg-hover)}.session-more-menu .dropdown-item.danger[data-v-15c5be0c]{color:var(--danger)}.subsession-arrow[data-v-15c5be0c]{transition:transform .2s ease}.subsession-arrow.rotated[data-v-15c5be0c]{transform:rotate(180deg)}.children-container[data-v-15c5be0c]{margin-left:24px;margin-top:4px;margin-bottom:4px;display:flex;flex-direction:column;gap:4px}.child-card[data-v-15c5be0c]{padding:10px 14px}.batch-toggle-btn[data-v-15c5be0c]{display:flex;align-items:center;gap:6px;padding:6px 14px;border:1px solid var(--border);border-radius:var(--radius);background:var(--bg-tertiary);color:var(--text-primary);font-family:var(--font-family);font-size:13px;font-weight:500;cursor:pointer;transition:background .1s,border-color .1s}.batch-toggle-btn[data-v-15c5be0c]:hover{background:var(--bg-hover)}.batch-toggle-btn.active[data-v-15c5be0c]{background:var(--accent);border-color:var(--accent);color:#fff}.batch-delete-btn[data-v-15c5be0c]{display:flex;align-items:center;gap:6px;padding:6px 14px;border:1px solid var(--danger);border-radius:var(--radius);background:var(--danger);color:#fff;font-family:var(--font-family);font-size:13px;font-weight:500;cursor:pointer;transition:opacity .1s}.batch-delete-btn[data-v-15c5be0c]:hover{opacity:.85}.batch-checkbox[data-v-15c5be0c]{display:flex;align-items:center;flex-shrink:0;margin-right:8px;cursor:pointer}.batch-checkbox input[type=checkbox][data-v-15c5be0c]{width:16px;height:16px;accent-color:var(--accent);cursor:pointer}.folder-checkbox[data-v-15c5be0c]{margin-right:12px}.cs-group{display:inline-flex;align-items:center;gap:4px;margin-right:8px}.cs-label{font-size:11px;font-weight:700;padding:1px 5px;border-radius:2px}.cs-label.sys{background:#8b5cf626;color:var(--sys-color)}.cs-label.tool{background:#ff9f0a26;color:var(--warning)}.cs-label.msg{background:#3d8bff26;color:var(--accent)}.cs-types{display:inline-flex;gap:3px}.cs-type{font-size:11px;font-weight:500;color:var(--text-secondary)}.cs-plus{color:var(--success);margin-left:2px}.cs-minus{color:var(--danger);margin-left:2px}.metadata-header[data-v-1868ccb6]{padding:12px 16px;background:var(--bg-tertiary);font-size:12px;font-weight:700;color:var(--text-tertiary);text-transform:uppercase;letter-spacing:.8px}.metadata-body[data-v-1868ccb6]{padding:16px}.stat-section[data-v-1868ccb6]{margin-bottom:12px}.stat-section[data-v-1868ccb6]:last-child{margin-bottom:0}.stat-section-title[data-v-1868ccb6]{font-size:11px;color:var(--text-tertiary);font-weight:600;margin-bottom:6px;text-transform:uppercase;letter-spacing:.5px}.stat-row-inline[data-v-1868ccb6]{display:flex;gap:12px;flex-wrap:wrap}.stat-item[data-v-1868ccb6]{display:flex;align-items:center;gap:4px;font-size:12px;padding:4px 10px;background:var(--bg-tertiary);border-radius:var(--radius)}.stat-key[data-v-1868ccb6]{color:var(--text-tertiary);font-weight:500;font-size:10px;text-transform:uppercase;letter-spacing:.4px}.stat-key[data-v-1868ccb6]:after{content:":"}.stat-val[data-v-1868ccb6]{color:var(--text-primary);font-weight:600;font-family:var(--font-family);font-size:12px}.stat-item.highlight .stat-val[data-v-1868ccb6]{color:var(--accent)}.stat-item.warning .stat-val[data-v-1868ccb6]{color:var(--warning)}.stat-item.danger .stat-val[data-v-1868ccb6]{color:var(--danger)}.stat-item.success .stat-val[data-v-1868ccb6]{color:var(--success)}.stat-grid[data-v-1868ccb6]{display:grid;grid-template-columns:repeat(auto-fill,minmax(140px,1fr));gap:8px}.stat-grid .stat-item[data-v-1868ccb6]{flex-direction:column;align-items:flex-start;gap:2px;padding:8px;background:var(--bg-tertiary);border-radius:var(--radius)}.stat-grid .stat-key[data-v-1868ccb6]{font-size:10px;text-transform:uppercase;letter-spacing:.5px}.stat-grid .stat-val[data-v-1868ccb6]{font-size:14px}.stat-link[data-v-1868ccb6]{color:var(--accent);text-decoration:underline;font-weight:500}.stat-link[data-v-1868ccb6]:hover{color:var(--accent-hover)}.timeline-controls[data-v-08b9d9bb]{display:flex;justify-content:flex-end;margin-top:16px;margin-bottom:16px}.sort-label[data-v-08b9d9bb]{display:flex;align-items:center;gap:6px;font-size:13px;color:var(--text-secondary)}.sort-select[data-v-08b9d9bb]{padding:6px 32px 6px 12px;border:1px solid var(--border);border-radius:var(--radius);background:var(--bg-tertiary);color:var(--text-primary);font-family:var(--font-family);font-size:13px;outline:none;-webkit-appearance:none;-moz-appearance:none;appearance:none;cursor:pointer;position:relative}.sort-select[data-v-08b9d9bb]:after{content:"";position:absolute;right:10px;top:50%;transform:translateY(-50%);width:12px;height:12px;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:center;color:var(--text-secondary);pointer-events:none}.sort-select option[data-v-08b9d9bb]{background:var(--bg-primary);color:var(--text-primary)}.timeline[data-v-08b9d9bb]{display:flex;flex-direction:column;gap:4px}.timeline-item[data-v-08b9d9bb]{margin-bottom:4px}.timeline-card[data-v-08b9d9bb]{padding:12px 16px}.timeline-card-header[data-v-08b9d9bb]{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap}.timeline-card-header .left[data-v-08b9d9bb]{display:flex;align-items:center;gap:8px;flex-wrap:wrap;flex:1;min-width:0}.timeline-card-header .right[data-v-08b9d9bb]{display:flex;align-items:center;gap:6px;flex-shrink:0}.req-num[data-v-08b9d9bb]{font-weight:700;font-size:14px;color:var(--text-primary)}.call-type[data-v-08b9d9bb]{font-size:11px;font-weight:700;padding:1px 6px;border-radius:2px}.call-type.user[data-v-08b9d9bb]{background:#3d8bff26;color:var(--accent)}.call-type.agent[data-v-08b9d9bb]{background:#8b5cf626;color:var(--sys-color)}.url[data-v-08b9d9bb]{font-size:13px;color:var(--text-secondary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:300px}.time-badge[data-v-08b9d9bb]{font-size:12px;font-weight:500;padding:2px 8px;border-radius:var(--radius);white-space:nowrap}.time-badge.dur[data-v-08b9d9bb]{background:#3d8bff1a;color:var(--accent)}.time-badge.gap[data-v-08b9d9bb]{background:#ff9f0a1a;color:var(--warning)}.time-badge.model[data-v-08b9d9bb]{background:#30d1581a;color:var(--success)}.time-badge.provider[data-v-08b9d9bb]{background:var(--bg-tertiary);color:var(--text-secondary)}.block-item[data-v-f15798cd]{margin-bottom:8px}.block-type-bar[data-v-f15798cd]{display:flex;align-items:center;justify-content:space-between;padding:6px 10px;background:var(--bg-tertiary);border-radius:var(--radius) var(--radius) 0 0;border:1px solid var(--border);border-bottom:none}.block-type-left[data-v-f15798cd]{display:flex;align-items:center;gap:8px;font-size:12px}.block-type-right[data-v-f15798cd]{display:flex;align-items:center;gap:4px}.block-type-tag[data-v-f15798cd]{font-weight:700;font-size:11px;padding:1px 6px;border-radius:2px}.block-type-tag.text[data-v-f15798cd]{background:#3d8bff26;color:var(--accent)}.block-type-tag.thinking[data-v-f15798cd]{background:#8b5cf626;color:var(--sys-color)}.block-type-tag.td[data-v-f15798cd]{background:#ff9f0a26;color:var(--warning)}.block-type-tag.tc[data-v-f15798cd],.block-type-tag.tr[data-v-f15798cd]{background:#30d15826;color:var(--success)}.block-type-tag.image[data-v-f15798cd]{background:#9a989826;color:var(--text-secondary)}.block-type-tag.json[data-v-f15798cd]{background:#a78bfa26;color:var(--json-key-color)}.block-type-tag.xml[data-v-f15798cd]{background:#ff9f0a26;color:var(--warning)}.block-type-tag.status[data-v-f15798cd]{background:#9a989826;color:var(--text-secondary)}.tool-meta-name[data-v-f15798cd]{font-weight:500;color:var(--text-primary)}.tool-meta-id[data-v-f15798cd]{color:var(--text-secondary)}.toggle-btn[data-v-f15798cd]{font-size:11px;font-weight:700;padding:2px 6px;border-radius:2px;color:var(--text-tertiary);transition:color .1s,background .1s}.toggle-btn[data-v-f15798cd]:hover,.toggle-btn.active[data-v-f15798cd]{color:var(--accent);background:#3d8bff1a}.block-content[data-v-f15798cd]{padding:10px 12px;background:var(--bg-primary);border:1px solid var(--border);border-radius:0 0 var(--radius) var(--radius);font-size:13px;line-height:1.6;overflow-x:auto;position:relative}.block-content.empty[data-v-f15798cd]{display:none}.block-content.raw[data-v-f15798cd]{white-space:pre-wrap;word-break:break-word}.copy-btn[data-v-f15798cd]{position:absolute;top:6px;right:6px;padding:4px;border-radius:2px;opacity:0;transition:opacity .1s;z-index:1}.block-content:hover .copy-btn[data-v-f15798cd]{opacity:1}.copy-btn[data-v-f15798cd]:hover{background:var(--bg-hover)}.content-muted[data-v-f15798cd]{color:var(--text-tertiary);font-style:italic}.tool-def-desc[data-v-f15798cd]{margin-bottom:8px;color:var(--text-secondary)}.tool-def-params[data-v-f15798cd]{margin-top:4px}.section-content[data-v-6a06d44d]{margin-bottom:16px}.change-card[data-v-6a06d44d]{border:1px solid var(--border);border-radius:var(--radius);margin-bottom:8px;overflow:hidden}.change-card.added[data-v-6a06d44d]{border-left:3px solid var(--success)}.change-card.removed[data-v-6a06d44d]{border-left:3px solid var(--danger)}.change-card-header[data-v-6a06d44d]{display:flex;align-items:center;gap:8px;padding:8px 12px;background:var(--bg-tertiary);border-bottom:1px solid var(--border)}.change-card-body[data-v-6a06d44d]{padding:8px}.cat-tag[data-v-6a06d44d]{font-size:11px;font-weight:700;padding:1px 6px;border-radius:2px}.cat-tag.sys[data-v-6a06d44d]{background:#8b5cf626;color:var(--sys-color)}.cat-tag.tool[data-v-6a06d44d]{background:#ff9f0a26;color:var(--warning)}.cat-tag.msg[data-v-6a06d44d]{background:#3d8bff26;color:var(--accent)}.action-tag[data-v-6a06d44d]{font-size:11px;font-weight:700;padding:1px 6px;border-radius:2px}.action-tag.new[data-v-6a06d44d]{background:#30d15826;color:var(--success)}.action-tag.del[data-v-6a06d44d]{background:#ff3b3026;color:var(--danger)}.section-content[data-v-c5e69052]{margin-bottom:16px}.msg[data-v-c5e69052]{border:1px solid var(--border);border-radius:var(--radius);margin-bottom:8px;overflow:hidden}.msg-header[data-v-c5e69052]{display:flex;align-items:center;gap:8px;padding:8px 12px;background:var(--bg-tertiary);border-bottom:1px solid var(--border)}.msg-body[data-v-c5e69052]{padding:8px}.cat-tag[data-v-c5e69052]{font-size:11px;font-weight:700;padding:1px 6px;border-radius:2px}.cat-tag.sys[data-v-c5e69052]{background:#8b5cf626;color:var(--sys-color)}.cat-tag.tool[data-v-c5e69052]{background:#ff9f0a26;color:var(--warning)}.cat-tag.msg[data-v-c5e69052]{background:#3d8bff26;color:var(--accent)}.role-tag[data-v-c5e69052]{font-size:12px;font-weight:500;color:var(--text-secondary)}.json-container[data-v-4b06a711]{position:relative;background:var(--bg-primary);font-size:13px;line-height:1.6}.copy-btn[data-v-4b06a711]{position:absolute;top:6px;right:6px;padding:4px;border-radius:2px;opacity:0;transition:opacity .1s;z-index:1}.json-container:hover .copy-btn[data-v-4b06a711]{opacity:1}.copy-btn[data-v-4b06a711]:hover{background:var(--bg-hover)}.json-line[data-v-4b06a711]{display:flex;padding:0 12px;min-height:22px}.json-line[data-v-4b06a711]:hover{background:var(--bg-hover)}.json-num[data-v-4b06a711]{flex-shrink:0;width:40px;text-align:right;padding-right:12px;color:var(--text-tertiary);-webkit-user-select:none;user-select:none}.section-content[data-v-880e4b46]{margin-bottom:16px}.json-block[data-v-880e4b46]{border:1px solid var(--border);border-radius:var(--radius);overflow:hidden}.section-content[data-v-7107da38]{margin-bottom:16px}.json-block[data-v-7107da38]{border:1px solid var(--border);border-radius:var(--radius);overflow:hidden}.view-toggle[data-v-57d357ff]{display:flex;gap:4px;margin-top:16px;margin-bottom:16px;padding:4px;background:var(--bg-tertiary);border-radius:var(--radius);width:fit-content}.view-toggle button[data-v-57d357ff]{padding:6px 16px;border-radius:var(--radius);font-size:13px;font-weight:500;color:var(--text-secondary);transition:background .1s,color .1s}.view-toggle button[data-v-57d357ff]:hover{color:var(--text-primary)}.view-toggle button.active[data-v-57d357ff]{background:var(--bg-primary);color:var(--text-primary);font-weight:700}.record-view-content[data-v-57d357ff]{margin-top:8px}*,*:before,*:after{box-sizing:border-box;margin:0;padding:0}:root{--oc-dark: #201d1d;--oc-light: #fdfcfc;--oc-mid: #9a9898;--oc-dark-surface: #302c2c;--oc-border-gray: #646262;--oc-light-surface: #f1eeee;--accent: #3d8bff;--accent-hover: #1a6fff;--accent-active: #0056b3;--danger: #ff3b30;--danger-hover: #d70015;--danger-active: #a50011;--success: #30d158;--warning: #ff9f0a;--warning-hover: #cc7f08;--warning-active: #995f06;--sys-color: #8b5cf6;--json-key-color: #a78bfa;--text-muted: #6e6e73;--text-secondary-light: #424245;--border-warm: rgba(15, 0, 0, .12);--border-tab: #9a9898;--border-outline: #646262;--input-bg: #f8f7f7;--bg-primary: var(--oc-dark);--bg-secondary: var(--oc-dark-surface);--bg-tertiary: rgba(253, 252, 252, .04);--bg-hover: rgba(253, 252, 252, .08);--text-primary: var(--oc-light);--text-secondary: var(--oc-mid);--text-tertiary: var(--text-muted);--border: rgba(100, 98, 98, .25);--added-bg: rgba(48, 209, 88, .08);--added-border: var(--success);--removed-bg: rgba(255, 59, 48, .08);--removed-border: var(--danger);--radius: 4px;--radius-input: 6px;--font-family: "Berkeley Mono", "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace}[data-theme=light]{--bg-primary: var(--oc-light);--bg-secondary: var(--oc-light-surface);--bg-tertiary: rgba(32, 29, 29, .04);--bg-hover: rgba(32, 29, 29, .06);--text-primary: var(--oc-dark);--text-secondary: var(--text-secondary-light);--text-tertiary: var(--oc-mid);--border: var(--border-warm);--added-bg: rgba(48, 209, 88, .06);--added-border: #1a8a3d;--removed-bg: rgba(255, 59, 48, .06);--removed-border: #c41e3a}html,body{height:100%;font-family:var(--font-family);background:var(--bg-primary);color:var(--text-primary);line-height:1.5;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}a{color:var(--accent);text-decoration:underline;font-weight:500;transition:color .1s}a:hover{color:var(--accent-hover)}button{font-family:inherit;cursor:pointer;border:none;background:none;color:inherit;font-size:inherit}.skip-link{position:absolute;top:-100px;left:50%;transform:translate(-50%);padding:8px 16px;background:var(--accent);color:var(--oc-light);font-weight:500;border-radius:var(--radius);z-index:1000;transition:top .2s}.skip-link:focus{top:8px}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}#app{display:flex;flex-direction:column;height:100vh;overflow:hidden}main{flex:1;overflow-y:auto;padding:24px;-webkit-overflow-scrolling:touch}.container{max-width:1200px;margin:0 auto}.spinner{width:20px;height:20px;border:2px solid var(--border);border-top-color:var(--accent);border-radius:50%;animation:spin .6s linear infinite;display:inline-block;vertical-align:middle;margin-right:8px}@keyframes spin{to{transform:rotate(360deg)}}.loading{display:flex;align-items:center;justify-content:center;padding:48px;color:var(--text-secondary);font-size:14px}.empty-state{text-align:center;padding:64px 24px;color:var(--text-secondary)}.empty-state .icon{font-size:48px;margin-bottom:16px}.empty-state p{font-size:16px;margin-bottom:8px}.error-banner{padding:16px 20px;background:var(--removed-bg);border:1px solid var(--removed-border);border-radius:var(--radius);color:var(--danger);font-size:14px}.page-title{font-size:38px;font-weight:700;line-height:1.5;margin-bottom:24px;display:flex;align-items:baseline;gap:12px;flex-wrap:wrap}.page-title .count{font-size:16px;font-weight:500;color:var(--text-secondary)}.page-title .subtitle{font-size:16px;font-weight:400;color:var(--text-tertiary)}.card{background:var(--bg-secondary);border:1px solid var(--border);border-radius:var(--radius)}.card-interactive{cursor:pointer;transition:background .1s,border-color .1s}.card-interactive:hover{background:var(--bg-hover)}.card-interactive:focus-visible{outline:2px solid var(--accent);outline-offset:2px}.badge{display:inline-flex;align-items:center;padding:2px 8px;font-size:12px;font-weight:500;color:var(--text-secondary);background:var(--bg-tertiary);border-radius:var(--radius);white-space:nowrap}code{background:var(--bg-tertiary);padding:2px 6px;border-radius:var(--radius);font-family:var(--font-family);font-size:13px}kbd{display:inline-block;padding:2px 8px;font-size:12px;font-family:var(--font-family);background:var(--bg-tertiary);border:1px solid var(--border);border-radius:var(--radius);min-width:24px;text-align:center}.section-title{display:flex;align-items:center;gap:8px;font-size:13px;font-weight:700;padding:8px 12px;background:var(--bg-tertiary);border-radius:var(--radius);margin-bottom:8px;cursor:pointer;-webkit-user-select:none;user-select:none;transition:background .1s}.section-title:hover{background:var(--bg-hover)}.section-arrow{transition:transform .2s ease;color:var(--text-secondary)}.section-title.expanded .section-arrow{transform:rotate(0)}.section-title:not(.expanded) .section-arrow{transform:rotate(-90deg)}
|