nuxt-devtools-observatory 0.1.26 → 0.1.30
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 +50 -11
- package/client/dist/assets/index-BCaKoHBH.js +17 -0
- package/client/dist/assets/index-BmGW_M3W.css +1 -0
- package/client/dist/index.html +2 -2
- package/client/src/App.vue +2 -6
- package/client/src/composables/useResizablePane.ts +65 -0
- package/client/src/stores/observatory.ts +162 -218
- package/client/src/style.css +203 -28
- package/client/src/views/ComposableTracker.vue +327 -294
- package/client/src/views/FetchDashboard.vue +104 -132
- package/client/src/views/ProvideInjectGraph.vue +101 -118
- package/client/src/views/RenderHeatmap.vue +192 -157
- package/client/src/views/TransitionTimeline.vue +166 -130
- package/client/tsconfig.json +3 -1
- package/client/vite.config.ts +12 -1
- package/dist/module.d.mts +6 -1
- package/dist/module.json +1 -1
- package/dist/module.mjs +238 -186
- package/dist/runtime/composables/fetch-registry.js +3 -0
- package/dist/runtime/plugin.js +89 -66
- package/package.json +12 -3
- package/client/dist/assets/index-1-H6UMCK.css +0 -1
- package/client/dist/assets/index-eSUuhYQ0.js +0 -17
package/dist/runtime/plugin.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { defineNuxtPlugin, useNuxtApp, useRuntimeConfig, useRouter } from "#app";
|
|
2
2
|
import { nextTick } from "vue";
|
|
3
|
+
import { setupComposableRegistry } from "./composables/composable-registry.js";
|
|
3
4
|
import { setupFetchRegistry } from "./composables/fetch-registry.js";
|
|
4
5
|
import { setupProvideInjectRegistry } from "./composables/provide-inject-registry.js";
|
|
5
|
-
import { setupComposableRegistry } from "./composables/composable-registry.js";
|
|
6
6
|
import { setupRenderRegistry } from "./composables/render-registry.js";
|
|
7
7
|
import { setupTransitionRegistry } from "./composables/transition-registry.js";
|
|
8
8
|
export default defineNuxtPlugin(() => {
|
|
@@ -11,7 +11,15 @@ export default defineNuxtPlugin(() => {
|
|
|
11
11
|
}
|
|
12
12
|
const nuxtApp = useNuxtApp();
|
|
13
13
|
const config = useRuntimeConfig().public.observatory;
|
|
14
|
+
const debugRpc = config.debugRpc === true;
|
|
15
|
+
const debugLog = (...args) => {
|
|
16
|
+
if (debugRpc) {
|
|
17
|
+
console.info("[observatory][rpc][host]", ...args);
|
|
18
|
+
}
|
|
19
|
+
};
|
|
14
20
|
let composableNavigationMode = config.composableNavigationMode === "session" ? "session" : "route";
|
|
21
|
+
let heartbeatId = null;
|
|
22
|
+
let lastSnapshotSignature = "";
|
|
15
23
|
if (config.renderHeatmap) {
|
|
16
24
|
nuxtApp.vueApp.config.performance = true;
|
|
17
25
|
}
|
|
@@ -36,21 +44,24 @@ export default defineNuxtPlugin(() => {
|
|
|
36
44
|
if (import.meta.client) {
|
|
37
45
|
delete window.__observatory__;
|
|
38
46
|
window.__observatory__ = registries;
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
47
|
+
const composableRegistry = registries.composable;
|
|
48
|
+
if (composableRegistry && composableRegistry.onComposableChange) {
|
|
49
|
+
composableRegistry.onComposableChange(() => {
|
|
50
|
+
broadcastAll("composable:onChange");
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
import.meta.hot?.on("observatory:command", (rawPayload) => {
|
|
54
|
+
if (!rawPayload || typeof rawPayload !== "object") {
|
|
43
55
|
return;
|
|
44
56
|
}
|
|
45
|
-
const
|
|
46
|
-
if (
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
const source = event.source;
|
|
50
|
-
source?.postMessage({ type: "observatory:snapshot", data: buildSnapshot() }, event.origin);
|
|
57
|
+
const payload = rawPayload;
|
|
58
|
+
if (payload.cmd === "request-snapshot") {
|
|
59
|
+
debugLog("received command: request-snapshot");
|
|
60
|
+
broadcastAll("command:request-snapshot");
|
|
51
61
|
return;
|
|
52
62
|
}
|
|
53
|
-
if (
|
|
63
|
+
if (payload.cmd === "clear-composables") {
|
|
64
|
+
debugLog("received command: clear-composables");
|
|
54
65
|
if (composableRegistry) {
|
|
55
66
|
if (composableNavigationMode === "session") {
|
|
56
67
|
composableRegistry.clearNonLayout();
|
|
@@ -58,57 +69,55 @@ export default defineNuxtPlugin(() => {
|
|
|
58
69
|
composableRegistry.clear();
|
|
59
70
|
}
|
|
60
71
|
}
|
|
61
|
-
|
|
62
|
-
source?.postMessage({ type: "observatory:snapshot", data: buildSnapshot() }, event.origin);
|
|
72
|
+
broadcastAll("command:clear-composables");
|
|
63
73
|
return;
|
|
64
74
|
}
|
|
65
|
-
if (
|
|
66
|
-
|
|
67
|
-
if (mode === "route" || mode === "session") {
|
|
68
|
-
composableNavigationMode = mode;
|
|
69
|
-
}
|
|
70
|
-
const source = event.source;
|
|
71
|
-
source?.postMessage({ type: "observatory:snapshot", data: buildSnapshot() }, event.origin);
|
|
72
|
-
}
|
|
73
|
-
if (type === "observatory:edit-composable") {
|
|
74
|
-
const { id, key, value } = event.data;
|
|
75
|
-
if (composableRegistry) {
|
|
76
|
-
composableRegistry.editValue(id, key, value);
|
|
75
|
+
if (payload.cmd === "set-mode") {
|
|
76
|
+
debugLog("received command: set-mode", payload.mode);
|
|
77
|
+
if (payload.mode === "route" || payload.mode === "session") {
|
|
78
|
+
composableNavigationMode = payload.mode;
|
|
77
79
|
}
|
|
80
|
+
broadcastAll("command:set-mode");
|
|
81
|
+
return;
|
|
78
82
|
}
|
|
79
|
-
if (
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
const cleaned = file.replace(/^\/@fs/, "").replace(/\?.*$/, "");
|
|
83
|
-
fetch(`/__open-in-editor?file=${encodeURIComponent(cleaned)}`).catch(() => {
|
|
84
|
-
});
|
|
85
|
-
}
|
|
83
|
+
if (payload.cmd === "edit-composable") {
|
|
84
|
+
debugLog("received command: edit-composable", { id: payload.id, key: payload.key });
|
|
85
|
+
composableRegistry?.editValue(payload.id, payload.key, payload.value);
|
|
86
86
|
}
|
|
87
|
-
};
|
|
88
|
-
window.addEventListener("message", messageHandler);
|
|
87
|
+
});
|
|
89
88
|
nuxtApp.hook("app:beforeUnmount", () => {
|
|
90
|
-
|
|
91
|
-
|
|
89
|
+
import.meta.hot?.off("observatory:command");
|
|
90
|
+
if (heartbeatId !== null) {
|
|
91
|
+
window.clearInterval(heartbeatId);
|
|
92
|
+
heartbeatId = null;
|
|
93
|
+
}
|
|
92
94
|
});
|
|
93
|
-
const composableRegistry = registries.composable;
|
|
94
|
-
if (composableRegistry && composableRegistry.onComposableChange) {
|
|
95
|
-
composableRegistry.onComposableChange(() => {
|
|
96
|
-
const lastMessageSource = lastMessageSourceRef?.deref();
|
|
97
|
-
if (!lastMessageSource || !lastMessageOrigin) {
|
|
98
|
-
return;
|
|
99
|
-
}
|
|
100
|
-
lastMessageSource.postMessage(
|
|
101
|
-
{
|
|
102
|
-
type: "observatory:snapshot",
|
|
103
|
-
data: buildSnapshot()
|
|
104
|
-
},
|
|
105
|
-
lastMessageOrigin
|
|
106
|
-
);
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
95
|
}
|
|
110
96
|
nuxtApp.hook("app:mounted", () => {
|
|
111
|
-
broadcastAll();
|
|
97
|
+
broadcastAll("app:mounted");
|
|
98
|
+
nextTick(() => {
|
|
99
|
+
broadcastAll("app:mounted:nextTick");
|
|
100
|
+
});
|
|
101
|
+
setTimeout(() => {
|
|
102
|
+
broadcastAll("app:mounted:50ms");
|
|
103
|
+
}, 50);
|
|
104
|
+
setTimeout(() => {
|
|
105
|
+
broadcastAll("app:mounted:250ms");
|
|
106
|
+
}, 250);
|
|
107
|
+
if (import.meta.client && heartbeatId === null) {
|
|
108
|
+
heartbeatId = window.setInterval(() => {
|
|
109
|
+
const snapshot = buildSnapshot();
|
|
110
|
+
const signature = JSON.stringify(snapshot);
|
|
111
|
+
if (signature !== lastSnapshotSignature) {
|
|
112
|
+
lastSnapshotSignature = signature;
|
|
113
|
+
debugLog("heartbeat detected snapshot change");
|
|
114
|
+
import.meta.hot?.send("observatory:snapshot", snapshot);
|
|
115
|
+
}
|
|
116
|
+
}, 400);
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
nuxtApp.hook("page:finish", () => {
|
|
120
|
+
broadcastAll("page:finish");
|
|
112
121
|
});
|
|
113
122
|
if (import.meta.client) {
|
|
114
123
|
const router = useRouter();
|
|
@@ -118,16 +127,25 @@ export default defineNuxtPlugin(() => {
|
|
|
118
127
|
return;
|
|
119
128
|
}
|
|
120
129
|
const render = registries.render;
|
|
121
|
-
if (render && typeof render.reset === "function")
|
|
130
|
+
if (render && typeof render.reset === "function") {
|
|
131
|
+
;
|
|
132
|
+
render.reset();
|
|
133
|
+
}
|
|
122
134
|
const provideInject = registries.provideInject;
|
|
123
|
-
if (provideInject && typeof provideInject.clear === "function")
|
|
135
|
+
if (provideInject && typeof provideInject.clear === "function") {
|
|
136
|
+
;
|
|
124
137
|
provideInject.clear();
|
|
138
|
+
}
|
|
125
139
|
const composable = registries.composable;
|
|
126
|
-
if (composableNavigationMode === "route" && composable && typeof composable.clearNonLayout === "function")
|
|
140
|
+
if (composableNavigationMode === "route" && composable && typeof composable.clearNonLayout === "function") {
|
|
141
|
+
;
|
|
127
142
|
composable.clearNonLayout();
|
|
143
|
+
}
|
|
128
144
|
const transition = registries.transition;
|
|
129
|
-
if (transition && typeof transition.clear === "function")
|
|
145
|
+
if (transition && typeof transition.clear === "function") {
|
|
146
|
+
;
|
|
130
147
|
transition.clear();
|
|
148
|
+
}
|
|
131
149
|
}
|
|
132
150
|
);
|
|
133
151
|
router.afterEach((to) => {
|
|
@@ -141,18 +159,26 @@ export default defineNuxtPlugin(() => {
|
|
|
141
159
|
;
|
|
142
160
|
render.setRoute(to.path ?? "/");
|
|
143
161
|
}
|
|
144
|
-
nextTick(() => broadcastAll());
|
|
162
|
+
nextTick(() => broadcastAll("router:afterEach"));
|
|
145
163
|
});
|
|
146
164
|
}
|
|
147
|
-
function broadcastAll() {
|
|
165
|
+
function broadcastAll(reason = "unknown") {
|
|
148
166
|
if (!import.meta.client) {
|
|
149
167
|
return;
|
|
150
168
|
}
|
|
151
|
-
|
|
152
|
-
if (!channel) {
|
|
169
|
+
if (!import.meta.hot) {
|
|
153
170
|
return;
|
|
154
171
|
}
|
|
155
|
-
|
|
172
|
+
const snapshot = buildSnapshot();
|
|
173
|
+
debugLog("push snapshot", {
|
|
174
|
+
reason,
|
|
175
|
+
fetch: Array.isArray(snapshot.fetch) ? snapshot.fetch.length : 0,
|
|
176
|
+
composables: Array.isArray(snapshot.composables) ? snapshot.composables.length : 0,
|
|
177
|
+
renders: Array.isArray(snapshot.renders) ? snapshot.renders.length : 0,
|
|
178
|
+
transitions: Array.isArray(snapshot.transitions) ? snapshot.transitions.length : 0
|
|
179
|
+
});
|
|
180
|
+
lastSnapshotSignature = JSON.stringify(snapshot);
|
|
181
|
+
import.meta.hot.send("observatory:snapshot", snapshot);
|
|
156
182
|
}
|
|
157
183
|
function buildSnapshot() {
|
|
158
184
|
function safeParse(val, fallback) {
|
|
@@ -191,7 +217,4 @@ export default defineNuxtPlugin(() => {
|
|
|
191
217
|
};
|
|
192
218
|
return snapshot;
|
|
193
219
|
}
|
|
194
|
-
function getDevtoolsChannel() {
|
|
195
|
-
return window.__nuxt_devtools__?.channel ?? null;
|
|
196
|
-
}
|
|
197
220
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nuxt-devtools-observatory",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.30",
|
|
4
4
|
"description": "Nuxt DevTools: useFetch Dashboard, provide/inject Graph, Composable Tracker, Render Heatmap",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -34,12 +34,18 @@
|
|
|
34
34
|
"client"
|
|
35
35
|
],
|
|
36
36
|
"scripts": {
|
|
37
|
-
"dev": "nuxi dev playground",
|
|
37
|
+
"dev": "concurrently -r -n client,nuxt \"pnpm dev:client\" \"nuxi dev playground\"",
|
|
38
|
+
"dev:client": "vite build --watch --config client/vite.config.ts",
|
|
39
|
+
"docs:clean": "rm -rf docs/.nuxt docs/.output",
|
|
40
|
+
"docs:dev": "pnpm docs:clean && pnpm --dir docs dev",
|
|
41
|
+
"docs:build": "pnpm docs:clean && pnpm --dir docs build",
|
|
42
|
+
"docs:generate": "pnpm docs:clean && pnpm --dir docs generate",
|
|
43
|
+
"docs:preview": "pnpm --dir docs preview",
|
|
38
44
|
"build:client": "vite build --config client/vite.config.ts",
|
|
39
45
|
"build": "npm run build:client && nuxt-module-build build",
|
|
40
46
|
"prepack": "npm run build",
|
|
41
47
|
"lint": "eslint .",
|
|
42
|
-
"format": "prettier --write '**/*.{ts,vue,js,json}' --ignore-path .prettierignore && stylelint '**/*.{css,vue}' --ignore-pattern '
|
|
48
|
+
"format": "prettier --write '**/*.{ts,vue,js,json}' --ignore-path .prettierignore && stylelint '**/*.{css,vue}' --ignore-pattern '**/.nuxt/**' --ignore-pattern '**/.output/**' --ignore-pattern 'coverage/**' --ignore-pattern 'client/dist/**' --ignore-pattern 'scripts/**' --fix && eslint --fix '**/*.{ts,vue,js}' --ignore-pattern '**/.nuxt/**' --ignore-pattern '**/.output/**' --ignore-pattern 'coverage/**' --ignore-pattern 'client/dist/**' --ignore-pattern 'scripts/**' --ignore-pattern 'docs/dist/**'",
|
|
43
49
|
"typecheck": "vue-tsc --noEmit",
|
|
44
50
|
"test": "vitest run",
|
|
45
51
|
"test:watch": "vitest",
|
|
@@ -56,6 +62,7 @@
|
|
|
56
62
|
},
|
|
57
63
|
"devDependencies": {
|
|
58
64
|
"@eslint/js": "^9.39.2",
|
|
65
|
+
"@nuxt/devtools-kit": "4.0.0-alpha.3",
|
|
59
66
|
"@nuxt/eslint": "^1.13.0",
|
|
60
67
|
"@nuxt/kit": "^3.0.0",
|
|
61
68
|
"@nuxt/module-builder": "^1.0.2",
|
|
@@ -67,6 +74,7 @@
|
|
|
67
74
|
"@types/node": "^25.5.0",
|
|
68
75
|
"@vitejs/plugin-vue": "^6.0.0",
|
|
69
76
|
"@vitest/coverage-v8": "^4.1.0",
|
|
77
|
+
"concurrently": "^9.2.1",
|
|
70
78
|
"eslint": "^9.39.2",
|
|
71
79
|
"eslint-config-prettier": "^10.1.8",
|
|
72
80
|
"eslint-plugin-jsdoc": "^62.5.0",
|
|
@@ -80,6 +88,7 @@
|
|
|
80
88
|
"playwright": "^1.58.2",
|
|
81
89
|
"postcss-html": "^1.8.1",
|
|
82
90
|
"prettier": "^3.8.1",
|
|
91
|
+
"sirv": "^3.0.2",
|
|
83
92
|
"stylelint": "^17.4.0",
|
|
84
93
|
"stylelint-config-standard": "^40.0.0",
|
|
85
94
|
"stylelint-config-standard-vue": "^1.0.0",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
.view[data-v-4f9bcc52]{display:flex;flex-direction:column;height:100%;overflow:hidden;padding:12px;gap:10px}.stats-row[data-v-4f9bcc52]{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:8px;flex-shrink:0}.toolbar[data-v-4f9bcc52]{display:flex;align-items:center;gap:6px;flex-shrink:0;flex-wrap:wrap}.split[data-v-4f9bcc52]{display:flex;gap:12px;flex:1;overflow:hidden;min-height:0}.table-wrap[data-v-4f9bcc52]{flex:1;overflow:auto;border:.5px solid var(--border);border-radius:var(--radius-lg)}.detail-panel[data-v-4f9bcc52]{width:280px;flex-shrink:0;display:flex;flex-direction:column;gap:8px;overflow:auto;border:.5px solid var(--border);border-radius:var(--radius-lg);padding:12px;background:var(--bg3)}.detail-empty[data-v-4f9bcc52]{width:280px;flex-shrink:0;display:flex;align-items:center;justify-content:center;color:var(--text3);font-size:12px;border:.5px dashed var(--border);border-radius:var(--radius-lg)}.detail-header[data-v-4f9bcc52]{display:flex;align-items:center;justify-content:space-between}.meta-grid[data-v-4f9bcc52]{display:grid;grid-template-columns:auto 1fr;gap:4px 12px;font-size:11px}.section-label[data-v-4f9bcc52]{font-size:10px;font-weight:500;text-transform:uppercase;letter-spacing:.4px;color:var(--text3);margin-top:6px;min-height:fit-content}.payload-box[data-v-4f9bcc52]{font-family:var(--mono);font-size:11px;color:var(--text2);background:var(--bg2);border-radius:var(--radius);padding:8px 10px;overflow:auto;white-space:pre;max-height:160px}.waterfall[data-v-4f9bcc52]{flex-shrink:0;background:var(--bg3);border:.5px solid var(--border);border-radius:var(--radius-lg);padding:10px 12px}.waterfall-header[data-v-4f9bcc52]{display:flex;align-items:center;justify-content:space-between;gap:8px}.waterfall-body[data-v-4f9bcc52]{margin-top:6px}.wf-row[data-v-4f9bcc52]{display:flex;align-items:center;gap:8px;margin-bottom:4px}.wf-track[data-v-4f9bcc52]{flex:1;position:relative;height:8px;background:var(--bg2);border-radius:2px;overflow:hidden}.wf-bar[data-v-4f9bcc52]{position:absolute;top:0;height:100%;border-radius:2px;opacity:.8}.view[data-v-0c07531b]{display:flex;flex-direction:column;height:100%;overflow:hidden;padding:12px;gap:10px}.toolbar[data-v-0c07531b]{display:flex;align-items:center;gap:6px;flex-shrink:0;flex-wrap:wrap}.split[data-v-0c07531b]{display:flex;gap:12px;flex:1;overflow:hidden;min-height:0}.graph-area[data-v-0c07531b]{flex:1;overflow:auto;border:.5px solid var(--border);border-radius:var(--radius-lg);padding:12px;background:var(--bg3)}.legend[data-v-0c07531b]{display:flex;align-items:center;gap:12px;font-size:11px;color:var(--text2);margin-bottom:12px}.canvas-stage[data-v-0c07531b]{display:flex;justify-content:center;align-items:flex-start;min-width:100%}.dot[data-v-0c07531b]{width:8px;height:8px;border-radius:50%;display:inline-block;margin-right:2px}.canvas-wrap[data-v-0c07531b]{position:relative}.edges-svg[data-v-0c07531b]{position:absolute;top:0;left:0;pointer-events:none}.edge[data-v-0c07531b]{stroke:var(--border);stroke-width:1.5}.graph-node[data-v-0c07531b]{position:absolute;display:flex;align-items:center;gap:7px;padding:0 10px;height:32px;border-radius:var(--radius);border:.5px solid var(--border);background:var(--bg3);cursor:pointer;transition:border-color .12s,background .12s;overflow:hidden;box-sizing:border-box;white-space:nowrap}.graph-node[data-v-0c07531b]:hover{border-color:var(--text3)}.graph-node.is-selected[data-v-0c07531b]{border-color:var(--node-color);background:color-mix(in srgb,var(--node-color) 8%,transparent)}.node-dot[data-v-0c07531b]{width:7px;height:7px;border-radius:50%;flex-shrink:0}.node-label[data-v-0c07531b]{font-size:11px;flex:1;overflow:hidden;text-overflow:ellipsis}.badge-xs[data-v-0c07531b]{font-size:9px;padding:1px 4px}.detail-panel[data-v-0c07531b]{width:280px;flex-shrink:0;overflow:auto;border:.5px solid var(--border);border-radius:var(--radius-lg);padding:12px;background:var(--bg3);display:flex;flex-direction:column;gap:4px;min-height:0}.detail-empty[data-v-0c07531b]{width:280px;display:flex;align-items:center;justify-content:center;color:var(--text3);font-size:12px;border:.5px dashed var(--border);border-radius:var(--radius-lg);flex-shrink:0}.graph-empty[data-v-0c07531b]{display:flex;align-items:center;justify-content:center;min-height:180px;color:var(--text3);font-size:12px}.detail-header[data-v-0c07531b]{display:flex;align-items:center;justify-content:space-between;margin-bottom:6px}.section-label[data-v-0c07531b]{font-size:10px;font-weight:500;text-transform:uppercase;letter-spacing:.4px;color:var(--text3);margin:8px 0 5px}.detail-section[data-v-0c07531b]{display:flex;flex-direction:column;min-height:0}.detail-list[data-v-0c07531b]{display:flex;flex-direction:column;gap:3px;overflow:auto;max-height:220px;padding-right:2px}.provide-row[data-v-0c07531b]{display:flex;flex-direction:column;gap:4px;padding:5px 8px;background:var(--bg2);border-radius:var(--radius);margin-bottom:3px}.row-warning[data-v-0c07531b]{font-size:11px;color:var(--amber);padding:2px 0}.row-consumers[data-v-0c07531b]{display:flex;flex-wrap:wrap;align-items:center;gap:4px;padding:2px 0}.consumer-chip[data-v-0c07531b]{font-size:10px;padding:1px 6px;border-radius:4px;background:color-mix(in srgb,var(--blue) 10%,var(--bg3));border:.5px solid color-mix(in srgb,var(--blue) 30%,var(--border));color:var(--text2)}.scope-badge[data-v-0c07531b]{font-size:10px;padding:1px 6px;border-radius:4px}.scope-global[data-v-0c07531b]{background:color-mix(in srgb,var(--amber) 15%,transparent);border:.5px solid color-mix(in srgb,var(--amber) 40%,var(--border));color:color-mix(in srgb,var(--amber) 80%,var(--text))}.scope-layout[data-v-0c07531b]{background:color-mix(in srgb,var(--purple) 15%,transparent);border:.5px solid color-mix(in srgb,var(--purple) 40%,var(--border));color:color-mix(in srgb,var(--purple) 80%,var(--text))}.scope-component[data-v-0c07531b]{background:var(--bg3);border:.5px solid var(--border);color:var(--text3)}.row-main[data-v-0c07531b]{display:flex;align-items:center;gap:8px;min-width:0}.row-key[data-v-0c07531b]{min-width:100px;color:var(--text2);flex-shrink:0}.row-value-preview[data-v-0c07531b]{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.row-toggle[data-v-0c07531b]{padding:2px 8px;font-size:10px}.value-box[data-v-0c07531b]{font-family:var(--mono);font-size:11px;color:var(--text2);background:#0000001a;border-radius:var(--radius);padding:8px 10px;white-space:pre-wrap;word-break:break-word;overflow:auto;max-height:180px}.inject-row[data-v-0c07531b]{display:flex;align-items:center;gap:8px;padding:5px 8px;background:var(--bg2);border-radius:var(--radius);margin-bottom:3px}.row-from[data-v-0c07531b]{margin-left:auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.inject-miss[data-v-0c07531b]{background:#e24b4a14}.jump-btn[data-v-0c07531b]{font-size:10px;padding:1px 6px;border:.5px solid var(--border);border-radius:var(--radius);background:transparent;color:var(--text3);cursor:pointer;flex-shrink:0;font-family:var(--mono)}.jump-btn[data-v-0c07531b]:hover{border-color:var(--teal);color:var(--teal);background:color-mix(in srgb,var(--teal) 8%,transparent)}.view[data-v-28f502da]{display:flex;flex-direction:column;height:100%;overflow:hidden;padding:12px;gap:10px}.stats-row[data-v-28f502da]{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:8px;flex-shrink:0}.toolbar[data-v-28f502da]{display:flex;align-items:center;gap:6px;flex-shrink:0;flex-wrap:wrap}.clear-btn[data-v-28f502da]{color:var(--text3);border-color:var(--border);flex-shrink:0}.clear-btn[data-v-28f502da]:hover{color:var(--red);border-color:var(--red);background:transparent}.mode-btn[data-v-28f502da]{border-color:color-mix(in srgb,var(--blue) 40%,var(--border));color:var(--blue)}.mode-btn[data-v-28f502da]:hover{border-color:var(--blue);background:color-mix(in srgb,var(--blue) 12%,transparent)}.list[data-v-28f502da]{flex:1;overflow:auto;display:flex;flex-direction:column;gap:5px;min-height:0}.comp-card[data-v-28f502da]{background:var(--bg3);border:.5px solid var(--border);border-radius:var(--radius-lg);overflow:hidden;cursor:pointer;flex-shrink:0}.comp-card[data-v-28f502da]:hover{border-color:var(--text3)}.comp-card.leak[data-v-28f502da]{border-left:2px solid var(--red);border-radius:0 var(--radius-lg) var(--radius-lg) 0}.comp-card.expanded[data-v-28f502da]{border-color:var(--purple)}.comp-header[data-v-28f502da]{display:flex;align-items:center;justify-content:space-between;padding:8px 12px;gap:8px}.comp-identity[data-v-28f502da]{display:flex;align-items:baseline;gap:6px;min-width:0;flex:1}.comp-name[data-v-28f502da]{font-size:12px;font-weight:500;color:var(--text);flex-shrink:0}.comp-file[data-v-28f502da]{font-size:11px;color:var(--text3);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.comp-meta[data-v-28f502da]{display:flex;align-items:center;gap:5px;flex-shrink:0}.refs-preview[data-v-28f502da]{display:flex;flex-wrap:wrap;gap:4px;padding:0 12px 8px;align-items:center}.ref-chip[data-v-28f502da]{display:inline-flex;align-items:center;gap:4px;padding:2px 7px;border-radius:4px;background:var(--bg2);border:.5px solid var(--border);font-size:11px;font-family:var(--mono);max-width:220px;overflow:hidden}.ref-chip--reactive[data-v-28f502da]{border-color:color-mix(in srgb,var(--purple) 40%,var(--border));background:color-mix(in srgb,var(--purple) 8%,var(--bg2))}.ref-chip--computed[data-v-28f502da]{border-color:color-mix(in srgb,var(--blue) 40%,var(--border));background:color-mix(in srgb,var(--blue) 8%,var(--bg2))}.ref-chip-key[data-v-28f502da]{color:var(--text2);flex-shrink:0}.ref-chip-val[data-v-28f502da]{color:var(--teal);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.comp-detail[data-v-28f502da]{padding:4px 12px 12px;border-top:.5px solid var(--border);display:flex;flex-direction:column;gap:3px}.leak-banner[data-v-28f502da]{background:color-mix(in srgb,var(--red) 12%,transparent);border:.5px solid color-mix(in srgb,var(--red) 40%,var(--border));border-radius:var(--radius);padding:6px 10px;font-size:11px;color:var(--red);margin-bottom:6px;font-family:var(--mono)}.section-label[data-v-28f502da]{font-size:10px;font-weight:500;text-transform:uppercase;letter-spacing:.4px;color:var(--text3);margin-top:6px;margin-bottom:3px}.ref-row[data-v-28f502da]{display:flex;align-items:flex-start;gap:8px;padding:3px 0}.ref-key[data-v-28f502da]{min-width:90px;color:var(--text2);flex-shrink:0}.ref-val[data-v-28f502da]{flex:1;color:var(--teal);min-width:0}.ref-val--collapsed[data-v-28f502da]{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ref-val--full[data-v-28f502da]{white-space:pre-wrap;word-break:break-all;line-height:1.5}.ref-row-actions[data-v-28f502da]{display:flex;align-items:center;gap:4px;flex-shrink:0}.expand-btn[data-v-28f502da]{font-size:9px;padding:1px 5px;border-radius:4px;border:.5px solid var(--border);background:var(--bg2);color:var(--text3);cursor:pointer;line-height:1.4;flex-shrink:0}.expand-btn[data-v-28f502da]:hover{border-color:var(--text3);color:var(--text)}.lc-row[data-v-28f502da]{display:flex;align-items:center;gap:8px;padding:2px 0}.lc-dot[data-v-28f502da]{width:6px;height:6px;border-radius:50%;flex-shrink:0}.ref-chip--shared[data-v-28f502da]{border-color:color-mix(in srgb,var(--amber) 50%,var(--border));background:color-mix(in srgb,var(--amber) 10%,var(--bg2))}.ref-chip-shared-dot[data-v-28f502da]{display:inline-block;width:5px;height:5px;border-radius:50%;background:var(--amber);flex-shrink:0;margin-left:1px}.global-banner[data-v-28f502da]{display:flex;align-items:flex-start;gap:8px;background:color-mix(in srgb,var(--amber) 10%,transparent);border:.5px solid color-mix(in srgb,var(--amber) 40%,var(--border));border-radius:var(--radius);padding:7px 10px;font-size:11px;color:var(--text2);margin-bottom:6px}.global-dot[data-v-28f502da]{display:inline-block;width:6px;height:6px;border-radius:50%;background:var(--amber);flex-shrink:0;margin-top:3px}.badge-amber[data-v-28f502da]{background:color-mix(in srgb,var(--amber) 15%,transparent);color:color-mix(in srgb,var(--amber) 80%,var(--text));border:.5px solid color-mix(in srgb,var(--amber) 40%,var(--border))}.history-list[data-v-28f502da]{display:flex;flex-direction:column;gap:1px;background:var(--bg2);border-radius:var(--radius);padding:4px 8px;max-height:180px;overflow-y:auto}.history-row[data-v-28f502da]{display:flex;align-items:center;gap:8px;padding:2px 0;font-size:11px;font-family:var(--mono);border-bottom:.5px solid var(--border)}.history-row[data-v-28f502da]:last-child{border-bottom:none}.history-time[data-v-28f502da]{min-width:52px;color:var(--text3);flex-shrink:0}.history-key[data-v-28f502da]{min-width:80px;color:var(--text2);flex-shrink:0}.history-val[data-v-28f502da]{color:var(--amber);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1}.stat-card[data-v-28f502da]{background:var(--bg3);border:.5px solid var(--border);border-radius:var(--radius-lg);padding:10px 14px}.stat-label[data-v-28f502da]{font-size:10px;font-weight:500;text-transform:uppercase;letter-spacing:.4px;color:var(--text3);margin-bottom:4px}.stat-val[data-v-28f502da]{font-size:22px;font-weight:500;line-height:1;color:var(--text)}.ref-key--clickable[data-v-28f502da]{cursor:pointer;text-decoration:underline dotted var(--text3);text-underline-offset:2px}.ref-key--clickable[data-v-28f502da]:hover{color:var(--purple);text-decoration-color:var(--purple)}.edit-btn[data-v-28f502da]{font-size:10px;padding:1px 6px;border-radius:var(--radius);border:.5px solid var(--border);background:transparent;color:var(--text3);cursor:pointer;margin-left:auto;flex-shrink:0;font-family:var(--mono)}.edit-btn[data-v-28f502da]:hover{border-color:var(--purple);color:var(--purple);background:color-mix(in srgb,var(--purple) 8%,transparent)}.lookup-panel[data-v-28f502da]{flex-shrink:0;border:.5px solid var(--border);border-radius:var(--radius-lg);background:var(--bg3);overflow:hidden}.lookup-header[data-v-28f502da]{display:flex;align-items:center;gap:6px;padding:7px 12px;border-bottom:.5px solid var(--border);background:var(--bg2)}.lookup-row[data-v-28f502da]{display:flex;align-items:center;gap:8px;padding:5px 12px;border-bottom:.5px solid var(--border)}.lookup-row[data-v-28f502da]:last-child{border-bottom:none}.edit-overlay[data-v-28f502da]{position:fixed;top:0;right:0;bottom:0;left:0;background:#0006;z-index:100;display:flex;align-items:center;justify-content:center}.edit-dialog[data-v-28f502da]{background:var(--bg1, var(--bg2));border:.5px solid var(--border);border-radius:var(--radius-lg);padding:14px 16px;width:380px;max-width:92vw;display:flex;flex-direction:column;gap:6px;box-shadow:0 8px 32px #0000004d}.edit-dialog-header[data-v-28f502da]{display:flex;align-items:center;gap:6px;font-size:12px;color:var(--text2);margin-bottom:2px}.edit-textarea[data-v-28f502da]{width:100%;font-family:var(--mono);font-size:12px;padding:8px 10px;background:var(--bg2);border:.5px solid var(--border);border-radius:var(--radius);color:var(--text);resize:vertical;outline:none}.edit-textarea[data-v-28f502da]:focus{border-color:var(--purple)}.edit-error[data-v-28f502da]{color:var(--red);font-family:var(--mono)}.edit-actions[data-v-28f502da]{display:flex;gap:6px;padding-top:4px}.slide-enter-active[data-v-28f502da],.slide-leave-active[data-v-28f502da]{transition:opacity .15s,transform .15s}.slide-enter-from[data-v-28f502da],.slide-leave-to[data-v-28f502da]{opacity:0;transform:translateY(6px)}.fade-enter-active[data-v-28f502da],.fade-leave-active[data-v-28f502da]{transition:opacity .15s}.fade-enter-from[data-v-28f502da],.fade-leave-to[data-v-28f502da]{opacity:0}.jump-btn[data-v-28f502da]{font-size:10px;padding:1px 6px;border:.5px solid var(--border);border-radius:var(--radius);background:transparent;color:var(--text3);cursor:pointer;flex-shrink:0;font-family:var(--mono)}.jump-btn[data-v-28f502da]:hover{border-color:var(--teal);color:var(--teal);background:color-mix(in srgb,var(--teal) 8%,transparent)}.view[data-v-a5a04da1]{display:flex;flex-direction:column;height:100%;overflow:hidden;padding:12px;gap:10px}.controls[data-v-a5a04da1]{display:flex;align-items:center;gap:8px;flex-shrink:0;flex-wrap:wrap}.mode-group[data-v-a5a04da1]{display:flex;gap:2px}.threshold-group[data-v-a5a04da1]{display:flex;align-items:center;gap:6px}.stats-row[data-v-a5a04da1]{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:8px;flex-shrink:0}.stat-sub[data-v-a5a04da1]{margin-top:4px;font-size:11px;color:var(--text3)}.inspector[data-v-a5a04da1]{display:grid;grid-template-columns:minmax(220px,280px) minmax(0,1fr) minmax(260px,320px);gap:12px;flex:1;min-height:0}.roots-panel[data-v-a5a04da1],.tree-panel[data-v-a5a04da1],.detail-panel[data-v-a5a04da1]{border:.5px solid var(--border);border-radius:var(--radius-lg);background:var(--bg3);min-height:0}.roots-panel[data-v-a5a04da1],.detail-panel[data-v-a5a04da1]{display:flex;flex-direction:column;overflow:auto;padding:12px;gap:8px}.panel-title[data-v-a5a04da1]{font-size:10px;font-weight:500;text-transform:uppercase;letter-spacing:.4px;color:var(--text3)}.root-item[data-v-a5a04da1]{display:flex;align-items:center;justify-content:space-between;gap:8px;width:100%;padding:10px 12px;border:1px solid var(--border);border-radius:var(--radius);background:var(--bg2);color:var(--text);text-align:left}.root-item.active[data-v-a5a04da1]{border-color:var(--teal);background:color-mix(in srgb,var(--teal) 16%,var(--bg2))}.root-label[data-v-a5a04da1]{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.root-copy[data-v-a5a04da1]{display:flex;flex-direction:column;min-width:0}.root-sub[data-v-a5a04da1]{font-size:11px}.root-meta[data-v-a5a04da1]{color:var(--text3);font-size:11px}.tree-panel[data-v-a5a04da1]{display:flex;flex-direction:column;overflow:hidden}.tree-toolbar[data-v-a5a04da1]{padding:12px;border-bottom:.5px solid var(--border)}.search-input[data-v-a5a04da1]{width:100%;padding:10px 12px;border:1px solid var(--border);border-radius:var(--radius);background:var(--bg2);color:var(--text)}.tree-frame[data-v-a5a04da1]{flex:1;min-height:0;overflow:auto;padding:12px}[data-v-a5a04da1] .tree-canvas{display:inline-block;min-width:100%;width:max-content}[data-v-a5a04da1] .tree-node{margin-bottom:4px}[data-v-a5a04da1] .tree-row{display:grid;grid-template-columns:8px 18px minmax(0,1fr) auto;align-items:center;gap:6px;min-width:0;width:100%;padding:4px 8px;padding-left:calc(8px + (var(--tree-depth, 0) * 16px));border:1px solid transparent;border-radius:var(--radius);cursor:pointer;white-space:nowrap}[data-v-a5a04da1] .tree-row:hover{background:var(--bg2)}[data-v-a5a04da1] .tree-row.selected{background:color-mix(in srgb,var(--teal) 12%,var(--bg2));border-color:var(--teal)}[data-v-a5a04da1] .tree-row.hot{box-shadow:inset 2px 0 0 var(--red)}[data-v-a5a04da1] .tree-toggle{width:16px;height:16px;border:none;background:transparent;color:var(--text3);padding:0;font-size:14px;display:inline-flex;align-items:center;justify-content:center}[data-v-a5a04da1] .tree-toggle:disabled{cursor:default}[data-v-a5a04da1] .tree-toggle.empty{opacity:0}[data-v-a5a04da1] .tree-rail{display:block;width:2px;height:14px;border-radius:999px;background:color-mix(in srgb,var(--border) 75%,transparent)}[data-v-a5a04da1] .tree-copy{display:flex;align-items:center;min-width:0;gap:6px;overflow:hidden}[data-v-a5a04da1] .tree-name{font-size:12px;color:var(--text);min-width:0;overflow:hidden;text-overflow:ellipsis}[data-v-a5a04da1] .tree-badges{display:flex;gap:6px;flex-shrink:0;overflow:hidden}[data-v-a5a04da1] .tree-badge{border:1px solid var(--border);border-radius:999px;padding:2px 7px;font-size:10px;color:var(--text3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:160px}[data-v-a5a04da1] .tree-metrics{display:flex;align-items:center;min-width:92px;justify-content:flex-end;flex-shrink:0;gap:6px}[data-v-a5a04da1] .tree-metric-pill{display:inline-flex;align-items:center;justify-content:center;min-width:78px;padding:2px 8px;border:1px solid var(--border);border-radius:999px;background:var(--bg2);font-size:10px;color:var(--text3)}[data-v-a5a04da1] .tree-persistent-pill{display:inline-flex;align-items:center;padding:2px 8px;border:1px solid color-mix(in srgb,var(--amber) 55%,var(--border));border-radius:999px;background:color-mix(in srgb,var(--amber) 10%,var(--bg2));font-size:10px;color:color-mix(in srgb,var(--amber) 80%,var(--text))}[data-v-a5a04da1] .tree-hydration-pill{display:inline-flex;align-items:center;padding:2px 8px;border:1px solid color-mix(in srgb,var(--teal) 55%,var(--border));border-radius:999px;background:color-mix(in srgb,var(--teal) 10%,var(--bg2));font-size:10px;color:color-mix(in srgb,var(--teal) 80%,var(--text))}[data-v-a5a04da1] .tree-children{margin-left:7px;padding-left:11px;border-left:1px solid color-mix(in srgb,var(--border) 72%,transparent)}.detail-empty[data-v-a5a04da1]{display:flex;align-items:center;justify-content:center;height:100%;color:var(--text3);font-size:12px}.detail-header[data-v-a5a04da1]{display:flex;align-items:center;justify-content:space-between}.meta-grid[data-v-a5a04da1]{display:grid;grid-template-columns:auto 1fr;gap:4px 12px}.detail-pill-row[data-v-a5a04da1]{display:flex;flex-wrap:wrap;gap:6px}.detail-pill[data-v-a5a04da1]{border:1px solid var(--border);border-radius:999px;padding:4px 8px;background:var(--bg2);font-size:11px}.detail-pill.hot[data-v-a5a04da1]{border-color:color-mix(in srgb,var(--red) 50%,var(--border));color:var(--red)}.detail-pill.persistent[data-v-a5a04da1]{border-color:color-mix(in srgb,var(--amber) 55%,var(--border));color:color-mix(in srgb,var(--amber) 80%,var(--text))}.detail-pill.hydrated[data-v-a5a04da1]{border-color:color-mix(in srgb,var(--teal) 55%,var(--border));color:color-mix(in srgb,var(--teal) 80%,var(--text))}.detail-pill.muted[data-v-a5a04da1]{color:var(--text3);border-color:var(--border)}.section-label[data-v-a5a04da1]{font-size:10px;font-weight:500;text-transform:uppercase;letter-spacing:.4px;color:var(--text3);margin-top:8px;margin-bottom:4px}.trigger-item[data-v-a5a04da1]{background:var(--bg2);border-radius:var(--radius);padding:4px 8px;margin-bottom:3px;color:var(--text2)}[data-v-a5a04da1] .tree-jump-btn{display:none;padding:0 4px;border:none;background:transparent;color:var(--text3);font-size:11px;cursor:pointer;line-height:1;flex-shrink:0}[data-v-a5a04da1] .tree-row:hover .tree-jump-btn,[data-v-a5a04da1] .tree-row.selected .tree-jump-btn{display:inline-flex}[data-v-a5a04da1] .tree-jump-btn:hover{color:var(--teal)}.jump-btn[data-v-a5a04da1]{font-size:10px;padding:1px 6px;border:.5px solid var(--border);border-radius:var(--radius);background:transparent;color:var(--text3);cursor:pointer;flex-shrink:0;font-family:var(--mono)}.jump-btn[data-v-a5a04da1]:hover{border-color:var(--teal);color:var(--teal);background:color-mix(in srgb,var(--teal) 8%,transparent)}.route-select[data-v-a5a04da1]{padding:3px 7px;border:.5px solid var(--border);border-radius:var(--radius);background:var(--bg2);color:var(--text);font-size:11px;cursor:pointer;max-width:140px}.timeline-list[data-v-a5a04da1]{display:flex;flex-direction:column;gap:1px;background:var(--bg2);border-radius:var(--radius);padding:4px 8px;max-height:200px;overflow-y:auto;min-height:fit-content}.timeline-row[data-v-a5a04da1]{display:flex;align-items:center;gap:6px;padding:2px 0;font-size:11px;border-bottom:.5px solid var(--border);min-width:0;min-height:fit-content}.timeline-row[data-v-a5a04da1]:last-child{border-bottom:none}.timeline-kind[data-v-a5a04da1]{flex-shrink:0;font-size:10px;font-weight:500;min-width:40px}.timeline-kind.mount[data-v-a5a04da1]{color:var(--teal)}.timeline-kind.update[data-v-a5a04da1]{color:var(--amber)}.timeline-time[data-v-a5a04da1]{flex-shrink:0;min-width:52px;color:var(--text3)}.timeline-dur[data-v-a5a04da1]{flex-shrink:0;min-width:38px;color:var(--text2)}.timeline-trigger[data-v-a5a04da1]{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--text3);flex:1;min-width:0}.timeline-route[data-v-a5a04da1]{flex-shrink:0;color:var(--text3);font-size:10px}@media(max-width:1180px){.inspector[data-v-a5a04da1]{grid-template-columns:minmax(200px,240px) minmax(0,1fr)}.detail-panel[data-v-a5a04da1]{grid-column:1 / -1;max-height:220px}}.timeline-root[data-v-da869dac]{display:flex;flex-direction:column;height:100%;overflow:hidden}.stats-row[data-v-da869dac]{display:flex;gap:10px;padding:12px 14px 0;flex-shrink:0}.stat-card[data-v-da869dac]{background:var(--bg2);border:.5px solid var(--border);border-radius:var(--radius);padding:8px 14px;min-width:72px;text-align:center}.stat-val[data-v-da869dac]{font-size:20px;font-weight:600;font-family:var(--mono);line-height:1.1}.stat-unit[data-v-da869dac]{font-size:12px;opacity:.6;margin-left:1px}.stat-label[data-v-da869dac]{font-size:10px;color:var(--text3);margin-top:2px;text-transform:uppercase;letter-spacing:.4px}.toolbar[data-v-da869dac]{display:flex;align-items:center;gap:8px;padding:10px 14px;flex-shrink:0;border-bottom:.5px solid var(--border)}.search-input[data-v-da869dac]{flex:1;max-width:260px}.filter-group[data-v-da869dac]{display:flex;gap:4px}.content-area[data-v-da869dac]{display:flex;flex:1;overflow:hidden;min-height:0}.table-pane[data-v-da869dac]{flex:1;overflow:hidden auto;min-width:0}.bar-cell[data-v-da869dac]{width:200px;padding:4px 8px}.bar-track[data-v-da869dac]{position:relative;height:8px;background:var(--bg2);border-radius:4px;overflow:hidden}.bar-fill[data-v-da869dac]{position:absolute;top:0;height:100%;min-width:3px;border-radius:4px;transition:width .15s}.detail-panel[data-v-da869dac]{width:260px;flex-shrink:0;border-left:.5px solid var(--border);overflow-y:auto;background:var(--bg3);padding:0 0 16px}.panel-header[data-v-da869dac]{display:flex;align-items:center;justify-content:space-between;padding:10px 14px 8px;border-bottom:.5px solid var(--border);position:sticky;top:0;background:var(--bg3);z-index:1}.panel-title[data-v-da869dac]{font-family:var(--mono);font-size:13px;font-weight:500}.close-btn[data-v-da869dac]{border:none;background:transparent;color:var(--text3);font-size:11px;padding:2px 6px;cursor:pointer}.panel-section[data-v-da869dac]{padding:10px 14px 6px;border-bottom:.5px solid var(--border)}.panel-section-title[data-v-da869dac]{font-size:10px;font-weight:500;color:var(--text3);text-transform:uppercase;letter-spacing:.4px;margin-bottom:8px}.panel-row[data-v-da869dac]{display:flex;justify-content:space-between;align-items:center;gap:8px;padding:3px 0;font-size:12px}.panel-key[data-v-da869dac]{color:var(--text3);flex-shrink:0}.panel-val[data-v-da869dac]{color:var(--text);text-align:right;word-break:break-all}.cancel-notice[data-v-da869dac],.active-notice[data-v-da869dac]{margin:10px 14px 0;font-size:11px;line-height:1.6;padding:8px 10px;border-radius:var(--radius)}.cancel-notice[data-v-da869dac]{background:#e24b4a1a;color:var(--red);border:.5px solid rgb(226 75 74 / 30%)}.active-notice[data-v-da869dac]{background:#7f77dd1a;color:var(--purple);border:.5px solid rgb(127 119 221 / 30%)}code[data-v-da869dac]{font-family:var(--mono);font-size:10px;background:#00000026;padding:1px 4px;border-radius:3px}.panel-slide-enter-active[data-v-da869dac],.panel-slide-leave-active[data-v-da869dac]{transition:transform .18s ease,opacity .18s ease}.panel-slide-enter-from[data-v-da869dac],.panel-slide-leave-to[data-v-da869dac]{transform:translate(12px);opacity:0}#app-root[data-v-12fe13bc]{display:flex;flex-direction:column;height:100vh;overflow:hidden}.tabbar[data-v-12fe13bc]{display:flex;align-items:center;gap:2px;padding:8px 12px 0;border-bottom:.5px solid var(--border);background:var(--bg3);flex-shrink:0}.tabbar-brand[data-v-12fe13bc]{font-size:11px;font-weight:500;color:var(--purple);letter-spacing:.5px;margin-right:12px;padding-bottom:8px}.tab-btn[data-v-12fe13bc]{border:none;border-bottom:2px solid transparent;border-radius:0;background:transparent;color:var(--text3);font-size:12px;padding:6px 12px 8px;cursor:pointer;transition:color .12s,border-color .12s;display:flex;align-items:center;gap:5px}.tab-btn[data-v-12fe13bc]:hover{color:var(--text);background:transparent}.tab-btn.active[data-v-12fe13bc]{color:var(--purple);border-bottom-color:var(--purple)}.tab-icon[data-v-12fe13bc]{font-size:10px;opacity:.6}.tab-content[data-v-12fe13bc]{flex:1;overflow:hidden;display:flex;flex-direction:column}*{box-sizing:border-box;margin:0;padding:0}body{font-family:var(--font);background:var(--bg);color:var(--text);font-size:13px;line-height:1.5}::-webkit-scrollbar{width:6px;height:6px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:var(--border);border-radius:3px}button{font-family:var(--font);font-size:12px;cursor:pointer;border:.5px solid var(--border);background:transparent;color:var(--text2);padding:4px 10px;border-radius:var(--radius);transition:background .12s}button:hover{background:var(--bg2)}button:active{transform:scale(.98)}button.active{background:#7f77dd26;color:var(--purple);border-color:var(--purple)}button.danger-active{background:#e24b4a1f;color:var(--red);border-color:var(--red)}button.success-active{background:#1d9e751f;color:var(--teal);border-color:var(--teal)}input[type=text],input[type=search]{font-family:var(--font);font-size:12px;border:.5px solid var(--border);background:var(--bg2);color:var(--text);padding:5px 10px;border-radius:var(--radius);outline:none;width:100%}input[type=text]:focus,input[type=search]:focus{border-color:var(--purple);box-shadow:0 0 0 2px #7f77dd33}input[type=range]{accent-color:var(--purple);cursor:pointer}.mono{font-family:var(--mono)}.muted{color:var(--text3)}.text-sm{font-size:11px}.text-xs{font-size:10px}.bold{font-weight:500}.badge{display:inline-block;font-size:10px;font-weight:500;padding:2px 7px;border-radius:99px;white-space:nowrap}.badge-ok{background:#1d9e7526;color:var(--teal)}.badge-err{background:#e24b4a1f;color:var(--red)}.badge-warn{background:#ef9f2726;color:var(--amber)}.badge-info{background:#378add1f;color:var(--blue)}.badge-gray{background:var(--bg2);color:var(--text3);border:.5px solid var(--border)}.badge-purple{background:#7f77dd26;color:var(--purple)}.card{background:var(--bg3);border:.5px solid var(--border);border-radius:var(--radius-lg);padding:12px 14px}.data-table{width:100%;border-collapse:collapse;font-size:12px}.data-table th{text-align:left;font-size:10px;font-weight:500;color:var(--text3);padding:6px 8px;border-bottom:.5px solid var(--border);text-transform:uppercase;letter-spacing:.4px;white-space:nowrap}.data-table td{padding:8px;border-bottom:.5px solid var(--border);color:var(--text);vertical-align:middle}.data-table tr:hover td{background:var(--bg2);cursor:pointer}.data-table tr.selected td{background:#7f77dd14}.stat-card{background:var(--bg2);border-radius:var(--radius);padding:10px 12px}.stat-label{font-size:10px;color:var(--text3);text-transform:uppercase;letter-spacing:.4px;margin-bottom:3px}.stat-val{font-size:20px;font-weight:500}.flex{display:flex}.items-center{align-items:center}.gap-2{gap:8px}.gap-3{gap:12px}.flex-1{flex:1}.overflow-auto{overflow:auto}.p-3{padding:12px}.p-4{padding:16px}.mb-2{margin-bottom:8px}.mb-3{margin-bottom:12px}.mt-2{margin-top:8px}
|