@doquflow/cli 1.2.1 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/review.js +331 -0
- package/dist/index.js +16 -0
- package/package.json +2 -2
- package/ui-dist/assets/index-3-icxZEZ.css +1 -0
- package/ui-dist/assets/index-BWcDlOkO.css +1 -0
- package/ui-dist/assets/index-CRwiGLWM.js +44 -0
- package/ui-dist/assets/index-Wb1LwUpP.js +45 -0
- package/ui-dist/index.html +2 -2
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* docuflow review
|
|
4
|
+
*
|
|
5
|
+
* Review git changes and surface deterministic findings plus actionable
|
|
6
|
+
* improvements. Optional --ai mode appends Copilot analysis.
|
|
7
|
+
*/
|
|
8
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
9
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.getChangedFiles = getChangedFiles;
|
|
13
|
+
exports.getDiffText = getDiffText;
|
|
14
|
+
exports.buildDeterministicReview = buildDeterministicReview;
|
|
15
|
+
exports.runCopilotReview = runCopilotReview;
|
|
16
|
+
exports.run = run;
|
|
17
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
18
|
+
const node_child_process_1 = require("node:child_process");
|
|
19
|
+
const DIFF_CAP_BYTES = 200 * 1024;
|
|
20
|
+
const AI_DIFF_CAP_CHARS = 40_000;
|
|
21
|
+
const c = {
|
|
22
|
+
green: (s) => `\x1b[32m${s}\x1b[0m`,
|
|
23
|
+
yellow: (s) => `\x1b[33m${s}\x1b[0m`,
|
|
24
|
+
red: (s) => `\x1b[31m${s}\x1b[0m`,
|
|
25
|
+
cyan: (s) => `\x1b[36m${s}\x1b[0m`,
|
|
26
|
+
bold: (s) => `\x1b[1m${s}\x1b[0m`,
|
|
27
|
+
dim: (s) => `\x1b[2m${s}\x1b[0m`,
|
|
28
|
+
};
|
|
29
|
+
function runGit(projectPath, args) {
|
|
30
|
+
const result = (0, node_child_process_1.spawnSync)("git", args, { cwd: projectPath, encoding: "utf8" });
|
|
31
|
+
if (result.status !== 0) {
|
|
32
|
+
const stderr = (result.stderr ?? "").trim();
|
|
33
|
+
const badRef = /bad revision|unknown revision|ambiguous argument/i.test(stderr);
|
|
34
|
+
if (badRef) {
|
|
35
|
+
throw new Error(`Invalid git ref: ${args.join(" ")}`);
|
|
36
|
+
}
|
|
37
|
+
throw new Error(stderr || `git ${args.join(" ")} failed`);
|
|
38
|
+
}
|
|
39
|
+
return (result.stdout ?? "").trim();
|
|
40
|
+
}
|
|
41
|
+
function runGitAllowStatuses(projectPath, args, allowedStatuses) {
|
|
42
|
+
const result = (0, node_child_process_1.spawnSync)("git", args, { cwd: projectPath, encoding: "utf8" });
|
|
43
|
+
if (result.status === null || !allowedStatuses.includes(result.status)) {
|
|
44
|
+
const stderr = (result.stderr ?? "").trim();
|
|
45
|
+
const badRef = /bad revision|unknown revision|ambiguous argument/i.test(stderr);
|
|
46
|
+
if (badRef) {
|
|
47
|
+
throw new Error(`Invalid git ref: ${args.join(" ")}`);
|
|
48
|
+
}
|
|
49
|
+
throw new Error(stderr || `git ${args.join(" ")} failed`);
|
|
50
|
+
}
|
|
51
|
+
return (result.stdout ?? "").trim();
|
|
52
|
+
}
|
|
53
|
+
function ensureGitRepo(projectPath) {
|
|
54
|
+
try {
|
|
55
|
+
const out = runGit(projectPath, ["rev-parse", "--is-inside-work-tree"]);
|
|
56
|
+
if (out !== "true") {
|
|
57
|
+
throw new Error("not a git repository");
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
throw new Error(`No git repository detected at ${projectPath}`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
function parsePorcelainPaths(porcelain) {
|
|
65
|
+
const out = new Set();
|
|
66
|
+
for (const line of porcelain.split("\n")) {
|
|
67
|
+
const trimmed = line.trim();
|
|
68
|
+
if (!trimmed)
|
|
69
|
+
continue;
|
|
70
|
+
const payload = line.replace(/^[ MARCUD?!]{1,2}\s+/, "").trim();
|
|
71
|
+
if (!payload)
|
|
72
|
+
continue;
|
|
73
|
+
if (payload.includes(" -> ")) {
|
|
74
|
+
const parts = payload.split(" -> ");
|
|
75
|
+
out.add(parts[parts.length - 1].trim());
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
out.add(payload);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return Array.from(out).sort((a, b) => a.localeCompare(b));
|
|
82
|
+
}
|
|
83
|
+
function capDiff(diffText) {
|
|
84
|
+
const bytes = Buffer.byteLength(diffText, "utf8");
|
|
85
|
+
if (bytes <= DIFF_CAP_BYTES)
|
|
86
|
+
return diffText;
|
|
87
|
+
const truncated = Buffer.from(diffText, "utf8").subarray(0, DIFF_CAP_BYTES).toString("utf8");
|
|
88
|
+
return `${truncated}\n\n[DOCUFLOW_DIFF_TRUNCATED: analyzed first ${DIFF_CAP_BYTES} bytes of ${bytes} bytes]\n`;
|
|
89
|
+
}
|
|
90
|
+
function pushUnique(arr, item) {
|
|
91
|
+
if (!arr.includes(item))
|
|
92
|
+
arr.push(item);
|
|
93
|
+
}
|
|
94
|
+
function getChangedFiles(projectPath, staged, sinceCommit) {
|
|
95
|
+
if (sinceCommit) {
|
|
96
|
+
const output = runGit(projectPath, ["diff", "--name-only", sinceCommit, "HEAD"]);
|
|
97
|
+
return output ? output.split("\n").filter(Boolean) : [];
|
|
98
|
+
}
|
|
99
|
+
if (staged) {
|
|
100
|
+
const output = runGit(projectPath, ["diff", "--name-only", "--cached"]);
|
|
101
|
+
return output ? output.split("\n").filter(Boolean) : [];
|
|
102
|
+
}
|
|
103
|
+
return parsePorcelainPaths(runGit(projectPath, ["status", "--porcelain"]));
|
|
104
|
+
}
|
|
105
|
+
function getDiffText(projectPath, staged, sinceCommit) {
|
|
106
|
+
if (sinceCommit) {
|
|
107
|
+
return capDiff(runGit(projectPath, ["diff", sinceCommit, "HEAD"]));
|
|
108
|
+
}
|
|
109
|
+
if (staged) {
|
|
110
|
+
return capDiff(runGit(projectPath, ["diff", "--cached"]));
|
|
111
|
+
}
|
|
112
|
+
const untracked = runGit(projectPath, ["ls-files", "--others", "--exclude-standard"])
|
|
113
|
+
.split("\n")
|
|
114
|
+
.map(line => line.trim())
|
|
115
|
+
.filter(Boolean);
|
|
116
|
+
const untrackedPatches = [];
|
|
117
|
+
for (const file of untracked) {
|
|
118
|
+
const patch = runGitAllowStatuses(projectPath, ["diff", "--no-index", "--", "/dev/null", file], [0, 1]);
|
|
119
|
+
if (patch) {
|
|
120
|
+
untrackedPatches.push(patch);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
const stagedDiff = runGit(projectPath, ["diff", "--cached"]);
|
|
124
|
+
const workingDiff = runGit(projectPath, ["diff"]);
|
|
125
|
+
const joined = [
|
|
126
|
+
"=== STAGED DIFF ===",
|
|
127
|
+
stagedDiff,
|
|
128
|
+
"",
|
|
129
|
+
"=== WORKING TREE DIFF ===",
|
|
130
|
+
workingDiff,
|
|
131
|
+
"",
|
|
132
|
+
"=== UNTRACKED FILE DIFF ===",
|
|
133
|
+
untrackedPatches.join("\n"),
|
|
134
|
+
].join("\n");
|
|
135
|
+
return capDiff(joined);
|
|
136
|
+
}
|
|
137
|
+
function buildDeterministicReview(changedFiles, diffText) {
|
|
138
|
+
const summary = [];
|
|
139
|
+
const critical = [];
|
|
140
|
+
const warnings = [];
|
|
141
|
+
const improvements = [];
|
|
142
|
+
summary.push(`Changed files: ${changedFiles.length}`);
|
|
143
|
+
for (const f of changedFiles.slice(0, 10)) {
|
|
144
|
+
summary.push(f);
|
|
145
|
+
}
|
|
146
|
+
if (changedFiles.length > 10) {
|
|
147
|
+
summary.push(`...and ${changedFiles.length - 10} more`);
|
|
148
|
+
}
|
|
149
|
+
const truncated = diffText.includes("[DOCUFLOW_DIFF_TRUNCATED:");
|
|
150
|
+
if (truncated) {
|
|
151
|
+
warnings.push("Large diff detected; review is partial due to diff size cap.");
|
|
152
|
+
improvements.push("Run focused reviews per file or per commit range for full coverage.");
|
|
153
|
+
}
|
|
154
|
+
const addedLines = diffText
|
|
155
|
+
.split("\n")
|
|
156
|
+
.filter(line => line.startsWith("+") && !line.startsWith("+++"))
|
|
157
|
+
.map(line => line.slice(1));
|
|
158
|
+
if (changedFiles.length > 0 && addedLines.length === 0) {
|
|
159
|
+
summary.push("Textual diff is empty (likely binary/rename-only changes).");
|
|
160
|
+
improvements.push("Manually review binary assets and metadata changes before commit.");
|
|
161
|
+
return { summary, critical, warnings, improvements };
|
|
162
|
+
}
|
|
163
|
+
const addedText = addedLines.join("\n");
|
|
164
|
+
if (/(AKIA[0-9A-Z]{16}|ghp_[A-Za-z0-9]{30,}|sk-[A-Za-z0-9]{20,}|-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----)/.test(addedText)) {
|
|
165
|
+
critical.push("Potential secret/key material detected in added lines.");
|
|
166
|
+
improvements.push("Remove credentials from code and load secrets via environment variables.");
|
|
167
|
+
}
|
|
168
|
+
if (/(password|token|secret)\s*[:=]\s*["'][^"']{4,}["']/i.test(addedText)) {
|
|
169
|
+
critical.push("Hardcoded credential-like value detected.");
|
|
170
|
+
}
|
|
171
|
+
if (/\b(eval|new Function)\s*\(/.test(addedText)) {
|
|
172
|
+
critical.push("Dynamic code execution (`eval`/`new Function`) detected.");
|
|
173
|
+
improvements.push("Replace dynamic execution with explicit parsing or whitelisted dispatch.");
|
|
174
|
+
}
|
|
175
|
+
if (/\bchild_process\.(exec|execSync)\s*\(/.test(addedText)) {
|
|
176
|
+
warnings.push("Shell execution added via child_process.exec/execSync.");
|
|
177
|
+
improvements.push("Prefer spawn/spawnSync with argument arrays and explicit input validation.");
|
|
178
|
+
}
|
|
179
|
+
if (/\bTODO\b|\bFIXME\b|\bHACK\b/.test(addedText)) {
|
|
180
|
+
warnings.push("TODO/FIXME/HACK markers found in added code.");
|
|
181
|
+
improvements.push("Resolve or ticket these markers before merge to avoid hidden follow-up work.");
|
|
182
|
+
}
|
|
183
|
+
if (/console\.log\s*\(/.test(addedText)) {
|
|
184
|
+
warnings.push("console.log statements found in added lines.");
|
|
185
|
+
improvements.push("Use structured logger patterns or remove debug logging before merge.");
|
|
186
|
+
}
|
|
187
|
+
if (/\bas any\b|:\s*any\b/.test(addedText)) {
|
|
188
|
+
warnings.push("Type safety weakened with `any` usage.");
|
|
189
|
+
improvements.push("Tighten types with explicit interfaces or narrow unions.");
|
|
190
|
+
}
|
|
191
|
+
if (/@ts-ignore/.test(addedText)) {
|
|
192
|
+
warnings.push("@ts-ignore found in added lines.");
|
|
193
|
+
improvements.push("Replace @ts-ignore with proper typing or guarded runtime checks.");
|
|
194
|
+
}
|
|
195
|
+
if (/catch\s*(\([^)]*\))?\s*\{\s*\}/.test(addedText)) {
|
|
196
|
+
warnings.push("Empty catch block detected.");
|
|
197
|
+
improvements.push("Handle caught errors explicitly and emit actionable context.");
|
|
198
|
+
}
|
|
199
|
+
const longLines = addedLines.filter(line => line.length > 160).length;
|
|
200
|
+
if (longLines > 0) {
|
|
201
|
+
warnings.push(`${longLines} long added line(s) (>160 chars) may hurt readability.`);
|
|
202
|
+
}
|
|
203
|
+
const hasTestFile = changedFiles.some(f => /(^|\/)(test|tests|__tests__)\/|\.test\.[a-z]+$|\.spec\.[a-z]+$/i.test(f));
|
|
204
|
+
if (!hasTestFile) {
|
|
205
|
+
improvements.push("Consider adding or updating tests for changed behavior.");
|
|
206
|
+
}
|
|
207
|
+
if (critical.length === 0 && warnings.length === 0) {
|
|
208
|
+
summary.push("No deterministic critical/warning findings detected.");
|
|
209
|
+
improvements.push("Quick manual pass for architecture consistency and naming is still recommended.");
|
|
210
|
+
}
|
|
211
|
+
return { summary, critical, warnings, improvements };
|
|
212
|
+
}
|
|
213
|
+
function buildCopilotPrompt(projectPath, changedFiles, diffText) {
|
|
214
|
+
const diffForPrompt = diffText.slice(0, AI_DIFF_CAP_CHARS);
|
|
215
|
+
return [
|
|
216
|
+
`Review these git changes for project: ${projectPath}`,
|
|
217
|
+
``,
|
|
218
|
+
`Changed files:`,
|
|
219
|
+
changedFiles.slice(0, 40).map(f => `- ${f}`).join("\n") || "(none)",
|
|
220
|
+
``,
|
|
221
|
+
`Diff:`,
|
|
222
|
+
diffForPrompt || "(no textual diff)",
|
|
223
|
+
``,
|
|
224
|
+
`Return concise markdown with sections:`,
|
|
225
|
+
`1) Critical issues`,
|
|
226
|
+
`2) Warnings`,
|
|
227
|
+
`3) Concrete improvements`,
|
|
228
|
+
`Focus on correctness, security, and maintainability.`,
|
|
229
|
+
].join("\n");
|
|
230
|
+
}
|
|
231
|
+
function runCopilotReview(prompt) {
|
|
232
|
+
const result = (0, node_child_process_1.spawnSync)("copilot", [
|
|
233
|
+
"--prompt", prompt,
|
|
234
|
+
"--allow-all-tools",
|
|
235
|
+
"--allow-all-paths",
|
|
236
|
+
"--no-ask-user",
|
|
237
|
+
"--output-format", "json"
|
|
238
|
+
], { encoding: "utf8", timeout: 180_000 });
|
|
239
|
+
if (result.error || result.status !== 0)
|
|
240
|
+
return null;
|
|
241
|
+
let lastMessage = null;
|
|
242
|
+
for (const line of (result.stdout ?? "").split("\n")) {
|
|
243
|
+
const trimmed = line.trim();
|
|
244
|
+
if (!trimmed)
|
|
245
|
+
continue;
|
|
246
|
+
try {
|
|
247
|
+
const obj = JSON.parse(trimmed);
|
|
248
|
+
if (obj.type === "assistant.message" && obj.data?.content) {
|
|
249
|
+
lastMessage = obj.data.content;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
catch {
|
|
253
|
+
// ignore malformed json lines
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
return lastMessage;
|
|
257
|
+
}
|
|
258
|
+
function printSection(title, lines, quiet) {
|
|
259
|
+
const label = quiet ? title : c.bold(title);
|
|
260
|
+
console.log(`\n${label}`);
|
|
261
|
+
if (lines.length === 0) {
|
|
262
|
+
console.log(" - none");
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
for (const line of lines) {
|
|
266
|
+
console.log(` - ${line}`);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
async function run(options = {}) {
|
|
270
|
+
const projectPath = node_path_1.default.resolve(options.projectPath ?? process.cwd());
|
|
271
|
+
const staged = !!options.staged;
|
|
272
|
+
const sinceCommit = options.sinceCommit;
|
|
273
|
+
const quiet = !!options.quiet;
|
|
274
|
+
const failOnCritical = !!options.failOnCritical;
|
|
275
|
+
const ai = !!options.ai;
|
|
276
|
+
try {
|
|
277
|
+
ensureGitRepo(projectPath);
|
|
278
|
+
}
|
|
279
|
+
catch (error) {
|
|
280
|
+
console.error(c.red(`✗ ${error.message}`));
|
|
281
|
+
process.exit(2);
|
|
282
|
+
}
|
|
283
|
+
let changedFiles = [];
|
|
284
|
+
let diffText = "";
|
|
285
|
+
try {
|
|
286
|
+
changedFiles = getChangedFiles(projectPath, staged, sinceCommit);
|
|
287
|
+
diffText = getDiffText(projectPath, staged, sinceCommit);
|
|
288
|
+
}
|
|
289
|
+
catch (error) {
|
|
290
|
+
const message = error.message;
|
|
291
|
+
if (message.startsWith("Invalid git ref:")) {
|
|
292
|
+
console.error(c.red(`✗ Invalid --since-commit ref: ${sinceCommit}`));
|
|
293
|
+
process.exit(2);
|
|
294
|
+
}
|
|
295
|
+
console.error(c.red(`✗ ${message}`));
|
|
296
|
+
process.exit(2);
|
|
297
|
+
}
|
|
298
|
+
if (changedFiles.length === 0) {
|
|
299
|
+
console.log(quiet ? "nothing to review" : c.cyan("Nothing to review: no changed files in selected scope."));
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
const modeLabel = sinceCommit
|
|
303
|
+
? `since ${sinceCommit}`
|
|
304
|
+
: staged
|
|
305
|
+
? "staged changes"
|
|
306
|
+
: "working tree (staged + unstaged)";
|
|
307
|
+
if (!quiet) {
|
|
308
|
+
console.log(c.bold("\n🔍 DocuFlow Review\n"));
|
|
309
|
+
console.log(`Scope: ${c.cyan(modeLabel)}`);
|
|
310
|
+
}
|
|
311
|
+
const deterministic = buildDeterministicReview(changedFiles, diffText);
|
|
312
|
+
printSection("Summary", deterministic.summary, quiet);
|
|
313
|
+
printSection("Critical", deterministic.critical, quiet);
|
|
314
|
+
printSection("Warnings", deterministic.warnings, quiet);
|
|
315
|
+
printSection("Improvements", deterministic.improvements, quiet);
|
|
316
|
+
if (ai) {
|
|
317
|
+
const prompt = buildCopilotPrompt(projectPath, changedFiles, diffText);
|
|
318
|
+
const aiResult = runCopilotReview(prompt);
|
|
319
|
+
if (aiResult) {
|
|
320
|
+
const aiLabel = quiet ? "AI Review (Copilot)" : c.bold("\nAI Review (Copilot)");
|
|
321
|
+
console.log(`\n${aiLabel}`);
|
|
322
|
+
console.log(aiResult);
|
|
323
|
+
}
|
|
324
|
+
else {
|
|
325
|
+
deterministic.improvements.push("Copilot AI review unavailable; using deterministic review only");
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
if (failOnCritical && deterministic.critical.length > 0) {
|
|
329
|
+
process.exit(1);
|
|
330
|
+
}
|
|
331
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -113,6 +113,16 @@ else if (cmd === 'sync') {
|
|
|
113
113
|
quiet: hasFlag('--quiet', '-q'),
|
|
114
114
|
allowDangerousPermissions: hasFlag('--allow-dangerous-permissions'),
|
|
115
115
|
}));
|
|
116
|
+
// ── review — git change review & improvement suggestions ───────────────────────
|
|
117
|
+
}
|
|
118
|
+
else if (cmd === 'review') {
|
|
119
|
+
Promise.resolve().then(() => __importStar(require('./commands/review'))).then(m => m.run({
|
|
120
|
+
staged: hasFlag('--staged'),
|
|
121
|
+
sinceCommit: getFlagValue('--since-commit'),
|
|
122
|
+
ai: hasFlag('--ai'),
|
|
123
|
+
failOnCritical: hasFlag('--fail-on-critical'),
|
|
124
|
+
quiet: hasFlag('--quiet', '-q'),
|
|
125
|
+
}));
|
|
116
126
|
}
|
|
117
127
|
else {
|
|
118
128
|
console.log(`DocuFlow v${version}`);
|
|
@@ -148,6 +158,12 @@ else {
|
|
|
148
158
|
console.log(' sync --no-lint Skip health check (faster)');
|
|
149
159
|
console.log(' sync --fail-on-score N Exit 1 if health score < N (default: 70)');
|
|
150
160
|
console.log(' sync --quiet Suppress output (CI mode)');
|
|
161
|
+
console.log(' review Review current git changes and suggest improvements');
|
|
162
|
+
console.log(' review --staged Review staged changes only');
|
|
163
|
+
console.log(' review --since-commit REF Review changes since git ref (e.g. HEAD~1)');
|
|
164
|
+
console.log(' review --ai Append Copilot AI review to deterministic findings');
|
|
165
|
+
console.log(' review --fail-on-critical Exit 1 if critical findings are detected');
|
|
166
|
+
console.log(' review --quiet Compact output for CI/scripting');
|
|
151
167
|
console.log('');
|
|
152
168
|
console.log('Options:');
|
|
153
169
|
console.log(' --version, -v Print version number');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@doquflow/cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "CLI for setting up Docuflow in your project",
|
|
5
5
|
"author": "Docuflow <hello@doquflows.dev>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"build": "tsc && node -e \"const fs=require('fs'),p=require('path'),src=p.join(process.cwd(),'../ui/dist'),dst=p.join(process.cwd(),'ui-dist');if(!fs.existsSync(src)){console.log('Warning: packages/ui/dist not found — run npm run build:ui first');process.exit(0)}fs.mkdirSync(dst,{recursive:true});fs.cpSync(src,dst,{recursive:true,force:true});console.log(' ✓ ui-dist synced from packages/ui/dist ('+(fs.readdirSync(dst).length)+' files at root)')\""
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@doquflow/server": "1.
|
|
34
|
+
"@doquflow/server": "1.3.0",
|
|
35
35
|
"cors": "^2.8.5",
|
|
36
36
|
"express": "^4.19.2"
|
|
37
37
|
},
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
:root{--df-bg: #0a0a0b;--df-surface: #111113;--df-surface-2: #161619;--df-surface-3: #1d1d22;--df-border: #1a1a1f;--df-border-2: #26262c;--df-border-3: #2c2c33;--df-border-hi: #3a3a44;--df-text: #ededee;--df-text-2: #d4d4d8;--df-text-3: #a1a1aa;--df-text-4: #6b6b74;--df-accent: #6366f1;--df-accent-hover: #5558e3;--df-accent-2: #818cf8;--df-accent-text: #a5b4fc;--df-accent-soft: rgba(99,102,241,.14);--df-accent-glow: rgba(99,102,241,.18);--df-accent-ring: rgba(99,102,241,.4);--df-accent-halo: rgba(99,102,241,.08);--df-green: #10b981;--df-green-text: #34d399;--df-green-soft: rgba(16,185,129,.12);--df-green-ring: rgba(16,185,129,.3);--df-amber: #f59e0b;--df-amber-text: #fbbf24;--df-amber-soft: rgba(245,158,11,.12);--df-amber-ring: rgba(245,158,11,.3);--df-red: #ef4444;--df-red-text: #f87171;--df-red-soft: rgba(239,68,68,.12);--df-red-ring: rgba(239,68,68,.3);--df-pink: #ec4899;--df-pink-text: #f472b6;--df-pink-soft: rgba(236,72,153,.12);--df-pink-ring: rgba(236,72,153,.3);--df-font-sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;--df-font-serif: "Source Serif 4", "Iowan Old Style", Georgia, serif;--df-font-mono: "JetBrains Mono", ui-monospace, "SF Mono", Menlo, monospace;--df-r-sm: 4px;--df-r-md: 6px;--df-r-lg: 8px;--df-r-xl: 10px;--df-r-pill: 999px;--df-h-btn: 28px;--df-h-input: 30px;--df-h-bar: 44px;--df-w-rail: 60px;--df-w-rail-detail: 280px;--df-w-tree: 260px;--df-ease: cubic-bezier(.2,.7,.3,1);--df-fast: .12s;--df-base: .2s;--df-slow: .35s;--df-content-max: 720px;--df-content-pad: 56px}*,*:before,*:after{box-sizing:border-box}html,body,#root{height:100%;margin:0}body{background:var(--df-bg);color:var(--df-text);font-family:var(--df-font-sans);font-feature-settings:"cv11","ss01";font-size:13px;line-height:1.5;letter-spacing:-.005em;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}button{font-family:inherit}.df-mono{font-family:var(--df-font-mono);font-feature-settings:"cv01","cv02"}.df-serif{font-family:var(--df-font-serif)}::-webkit-scrollbar{width:8px;height:8px}::-webkit-scrollbar-thumb{background:var(--df-border-2);border-radius:4px}::-webkit-scrollbar-thumb:hover{background:var(--df-border-3)}::-webkit-scrollbar-track{background:transparent}::selection{background:var(--df-accent-soft);color:var(--df-text)}.df-app{width:100vw;height:100vh;display:flex;flex-direction:column;overflow:hidden}.df-app__main{flex:1;display:flex;overflow:hidden;min-height:0}.df-view{flex:1;display:flex;flex-direction:column;overflow:hidden;min-width:0;background:var(--df-bg)}@keyframes df-fade-in{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}@keyframes df-spin{to{transform:rotate(360deg)}}@keyframes df-pulse{0%,to{opacity:.4}50%{opacity:1}}@keyframes df-blink{0%,49%{opacity:1}50%,to{opacity:0}}@keyframes df-shimmer{0%{background-position:-200% 0}to{background-position:200% 0}}@keyframes df-bar-grow{0%{transform:scaleY(0)}to{transform:scaleY(1)}}@keyframes df-page-enter{0%{opacity:0;transform:translate(8px)}to{opacity:1;transform:translate(0)}}.df-anim-fade{animation:df-fade-in var(--df-base) var(--df-ease) both}.df-anim-page{animation:df-page-enter var(--df-slow) var(--df-ease) both}.df-pill{display:inline-flex;align-items:center;gap:5px;padding:2px 7px;border-radius:var(--df-r-sm);font-size:11px;font-weight:500;font-family:var(--df-font-sans);background:var(--df-surface-3);border:1px solid var(--df-border-3);color:var(--df-text-3);white-space:nowrap}.df-pill--accent{background:var(--df-accent-soft);border-color:var(--df-accent-ring);color:var(--df-accent-text)}.df-pill--green{background:var(--df-green-soft);border-color:var(--df-green-ring);color:var(--df-green-text)}.df-pill--amber{background:var(--df-amber-soft);border-color:var(--df-amber-ring);color:var(--df-amber-text)}.df-pill--red{background:var(--df-red-soft);border-color:var(--df-red-ring);color:var(--df-red-text)}.df-pill--pink{background:var(--df-pink-soft);border-color:var(--df-pink-ring);color:var(--df-pink-text)}.df-pill__dot{width:5px;height:5px;border-radius:50%;background:currentColor}.df-btn{display:inline-flex;align-items:center;gap:6px;height:var(--df-h-btn);padding:0 10px;border-radius:var(--df-r-md);background:var(--df-surface-3);border:1px solid var(--df-border-3);color:var(--df-text);font-size:12px;font-weight:500;letter-spacing:-.005em;cursor:pointer;transition:background var(--df-fast),border-color var(--df-fast),color var(--df-fast);white-space:nowrap}.df-btn:hover{background:var(--df-surface-2)}.df-btn--primary{background:var(--df-accent);border-color:var(--df-accent);color:#fff}.df-btn--primary:hover{background:var(--df-accent-hover);border-color:var(--df-accent-hover)}.df-btn--ghost{background:transparent;border-color:transparent;color:var(--df-text-3)}.df-btn--ghost:hover{background:var(--df-surface-3);color:var(--df-text)}.df-btn--active{background:var(--df-surface-2);border-color:var(--df-border-hi)}.df-kbd{display:inline-flex;align-items:center;justify-content:center;min-width:18px;height:18px;padding:0 5px;border-radius:var(--df-r-sm);background:var(--df-surface-3);border:1px solid var(--df-border-3);color:var(--df-text-3);font:11px/1 var(--df-font-mono)}.df-btn--primary .df-kbd{background:#ffffff2e;border:none;color:#fff}.df-card{background:var(--df-surface);border:1px solid var(--df-border);border-radius:var(--df-r-xl)}.df-card--padded{padding:18px}.df-card--rows>*+*{border-top:1px solid var(--df-border)}.df-card__row{display:flex;align-items:center;gap:14px;padding:12px 16px;font-size:12px}.df-eyebrow{font-size:11px;color:var(--df-text-4);text-transform:uppercase;letter-spacing:.08em}.df-h1{margin:0;font-size:24px;font-weight:600;letter-spacing:-.02em;color:var(--df-text)}.df-h1--display{font-size:26px}.df-h1--serif{font-family:var(--df-font-serif);font-weight:400;font-size:32px;letter-spacing:-.02em;line-height:1.15}.df-subtle{color:var(--df-text-4);font-size:13px}.df-topbar{height:var(--df-h-bar);display:flex;align-items:center;gap:12px;padding:0 16px;background:var(--df-bg);border-bottom:1px solid var(--df-border);flex-shrink:0;flex-wrap:nowrap;white-space:nowrap;overflow:hidden;min-width:0}.df-topbar>*{flex-shrink:0}.df-topbar__crumb{display:flex;align-items:center;gap:8px;font-size:13px}.df-topbar__sep{color:var(--df-border-3)}.df-topbar__meta{display:flex;align-items:center;gap:6px;font-size:11px;color:var(--df-text-4);min-width:0;overflow:hidden;text-overflow:ellipsis}.df-topbar__meta>span:last-child{overflow:hidden;text-overflow:ellipsis}.df-topbar__divider{width:1px;height:18px;background:var(--df-border);margin:0 4px}.df-topbar__avatar{width:28px;height:28px;border-radius:50%;background:linear-gradient(135deg,var(--df-pink),var(--df-accent))}.df-rail{width:var(--df-w-rail);background:var(--df-bg);border-right:1px solid var(--df-border);display:flex;flex-direction:column;align-items:center;padding:12px 0;gap:2px;flex-shrink:0}.df-rail__logo{width:32px;height:32px;margin-bottom:14px;border-radius:var(--df-r-lg);background:linear-gradient(135deg,var(--df-accent),#a855f7);display:flex;align-items:center;justify-content:center;color:#fff}.df-rail__item{position:relative;width:40px;height:40px;display:flex;align-items:center;justify-content:center;background:transparent;border:none;border-radius:var(--df-r-lg);color:var(--df-text-4);cursor:pointer;transition:background var(--df-fast),color var(--df-fast)}.df-rail__item:hover{color:var(--df-text-3)}.df-rail__item--active{background:var(--df-surface-3);color:var(--df-text)}.df-rail__item--active:before{content:"";position:absolute;left:-6px;top:10px;bottom:10px;width:2px;border-radius:1px;background:var(--df-accent)}.df-rail__spacer{flex:1}.df-rail__groups{width:100%;padding:0 8px}.df-rail__group{margin-bottom:8px}.df-rail__group-label{font-size:9px;letter-spacing:.12em;color:var(--df-text-5);text-transform:uppercase;text-align:center;margin-bottom:4px}.df-rail__divider{width:20px;height:1px;margin:4px auto;background:var(--df-border-3)}.df-rail__project-picker{width:32px;margin-bottom:4px}.df-rail__project-picker-wrap{position:relative;width:32px;height:32px;border-radius:var(--df-r-lg);background:var(--df-surface-3);display:flex;align-items:center;justify-content:center;cursor:pointer;transition:background var(--df-fast)}.df-rail__project-picker-wrap:hover,.df-rail__project-picker-wrap.open{background:var(--df-surface-2)}.df-rail__project-picker-caret{position:absolute;right:2px;top:50%;transform:translateY(-50%);width:0;height:0;border:3.5px solid var(--df-text-4);border-width:3.5px 0 3.5px 4px;transition:transform var(--df-fast)}.df-rail__project-picker-wrap.open .df-rail__project-picker-caret{transform:translateY(-50%) rotate(-90deg)}.df-rail__project-picker-menu{position:absolute;top:38px;left:0;width:220px;padding:4px;background:var(--df-surface);border:1px solid var(--df-border);border-radius:var(--df-r-lg);box-shadow:var(--df-shadow);z-index:100;display:none}.df-rail__project-picker-wrap.open+.df-rail__project-picker-menu,.df-rail__project-picker-menu--open{display:block}.df-rail__project-picker-search{width:100%;padding:7px 10px;background:var(--df-bg);border:1px solid var(--df-border-2);border-radius:var(--df-r-sm);font-size:12px;color:var(--df-text);margin-bottom:4px}.df-rail__project-picker-list{max-height:180px;overflow-y:auto}.df-rail__project-picker-item{display:flex;align-items:center;gap:8px;padding:7px 8px;font-size:12px;color:var(--df-text-3);cursor:pointer;border-radius:var(--df-r-sm);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.df-rail__project-picker-item:hover,.df-rail__project-picker-item--selected{background:var(--df-accent-halo);color:var(--df-accent-text)}.df-rail__project-picker-icon{width:16px;height:16px;flex-shrink:0}.df-rail__project-picker-item-badge{font-size:10px;padding:1px 6px;border-radius:var(--df-r-pill);background:var(--df-accent-halo);color:var(--df-accent-text);border:1px solid var(--df-accent-ring);white-space:nowrap;flex-shrink:0}.df-rail__project-picker-item-name{flex:1;overflow:hidden;text-overflow:ellipsis}.df-rail__project-picker-form{padding:4px;border-top:1px solid var(--df-border);margin-top:4px}.df-rail__project-picker-name{width:100%;padding:6px 8px;margin-bottom:4px;background:var(--df-bg);border:1px solid var(--df-border-2);border-radius:var(--df-r-sm);font-size:12px;color:var(--df-text);outline:none}.df-rail__project-picker-name:focus{border-color:var(--df-accent-ring);box-shadow:0 0 0 3px var(--df-accent-halo)}.df-rail__project-picker-select{width:100%;padding:6px 8px;margin-bottom:4px;background:var(--df-bg);border:1px solid var(--df-border-2);border-radius:var(--df-r-sm);font-size:12px;color:var(--df-text)}.df-rail__project-picker-create{width:100%;padding:5px;margin-top:4px;background:var(--df-accent);border-radius:var(--df-r-sm);font-size:11px;font-weight:600;color:#fff;cursor:pointer}.df-rail__project-picker-create:hover{opacity:.9}.df-rail__tip{pointer-events:none;position:absolute;left:46px;background:var(--df-surface);border:1px solid var(--df-border);border-radius:var(--df-r-sm);padding:3px 8px;font-size:11px;color:var(--df-text-2);white-space:nowrap;z-index:200;box-shadow:var(--df-shadow);transform:translate(-6px);opacity:0;transition:all var(--df-fast) var(--df-ease)}.df-rail__item:hover .df-rail__tip{transform:translate(0);opacity:1}.df-rail__item:hover .df-rail__tip--lg{left:auto;right:-70px}.df-rail--collapsed{width:64px!important}.df-rail--collapsed .df-rail__groups,.df-rail--collapsed .df-rail__project-picker{display:none}.df-rail--collapsed .df-rail__item:not(.df-rail__project-picker-wrap):hover .df-rail__tip{display:none}.df-field{display:block}.df-field__label{font-size:11px;color:var(--df-text-4);text-transform:uppercase;letter-spacing:.08em;margin-bottom:6px}.df-field__value{padding:10px 12px;background:var(--df-surface);border:1px solid var(--df-border-2);border-radius:var(--df-r-lg);font-size:13px;color:var(--df-text)}.df-field__value--mono{font-family:var(--df-font-mono)}.df-code{background:var(--df-surface-3);border:1px solid var(--df-border-2);padding:1px 6px;border-radius:var(--df-r-sm);font-family:var(--df-font-mono);font-size:.82em;color:var(--df-accent-text)}.df-status-dot{display:inline-block;width:8px;height:8px;border-radius:50%;background:var(--df-text-4)}.df-status-dot--live{background:var(--df-green);animation:df-pulse 1.4s infinite}.df-status-dot--paused{background:var(--df-text-4)}.df-ask{flex:1;display:flex;flex-direction:column;overflow:hidden;background:var(--df-bg)}.df-ask__header{padding:40px var(--df-content-pad) 24px;border-bottom:1px solid var(--df-border)}.df-ask__eyebrow{display:flex;align-items:center;gap:8px;margin-bottom:10px}.df-ask__title-accent{color:var(--df-accent-text)}.df-ask__intro{margin:6px 0 0;color:var(--df-text-4);font-size:13px}.df-ask__box-wrap{margin-top:24px;position:relative}.df-ask__box{display:flex;align-items:center;gap:10px;padding:14px 18px;border-radius:var(--df-r-xl);background:var(--df-surface);border:1px solid var(--df-border-2);transition:all var(--df-base) var(--df-ease)}.df-ask__box--active{border-color:var(--df-accent-ring);box-shadow:0 0 0 4px var(--df-accent-halo)}.df-ask__box-input{flex:1;font-size:15px;color:var(--df-text);min-height:22px}.df-ask__placeholder{color:var(--df-text-4)}.df-ask__caret{display:inline-block;width:2px;height:16px;background:var(--df-accent-text);vertical-align:-2px;margin-left:1px;animation:df-blink .8s infinite}.df-ask__run{height:28px;padding:0 14px;border-radius:var(--df-r-md);background:var(--df-accent);color:#fff;border:none;font-size:12px;font-weight:600;cursor:pointer;display:flex;align-items:center;gap:5px}.df-ask__run:hover{background:var(--df-accent-hover)}.df-ask__reset{padding:4px 10px;border-radius:var(--df-r-md);background:transparent;color:var(--df-text-4);border:1px solid var(--df-border-3);font-size:11px;cursor:pointer}.df-ask__chips{margin-top:12px;display:flex;flex-wrap:wrap;gap:6px}.df-chip{padding:6px 11px;border-radius:var(--df-r-pill);background:transparent;border:1px solid var(--df-border-2);color:var(--df-text-3);font-size:12px;cursor:pointer;font-family:inherit;transition:all var(--df-fast)}.df-chip:hover{background:var(--df-surface-2);border-color:var(--df-border-hi);color:var(--df-text)}.df-ask__body{flex:1;display:flex;overflow:hidden;min-height:0}.df-ask__main{flex:1;padding:28px var(--df-content-pad) 56px;min-width:0;overflow:auto}.df-search__head{display:flex;align-items:center;gap:10px;color:var(--df-accent-text);font-size:13px;margin-bottom:18px}.df-search__spinner{width:14px;height:14px;border:2px solid var(--df-border-3);border-top-color:var(--df-accent);border-radius:50%;animation:df-spin .7s linear infinite}.df-search__stage{display:flex;align-items:center;gap:10px;padding:8px 0;font-size:12px;color:var(--df-text-4)}.df-search__stage--done{color:var(--df-green)}.df-search__skel{margin-top:24px;display:flex;flex-direction:column;gap:10px}.df-search__skel-bar{height:12px;border-radius:var(--df-r-sm);background:linear-gradient(90deg,var(--df-surface-2),var(--df-surface-3),var(--df-surface-2));background-size:200% 100%;animation:df-shimmer 1.4s infinite linear}.df-answer{max-width:var(--df-content-max)}.df-answer__meta{display:flex;align-items:center;gap:10px;margin-bottom:20px}.df-answer__doc{font-family:var(--df-font-serif);border-top:1px solid var(--df-border);border-bottom:1px solid var(--df-border);padding:28px 0 32px}.df-answer__h{margin:0 0 22px;font-size:24px;font-weight:400;color:var(--df-text);letter-spacing:-.01em;line-height:1.25}.df-answer__prose{font-size:16px;line-height:1.72;color:var(--df-text-2)}.df-answer__prose p{margin:0 0 16px}.df-answer__prose strong{color:var(--df-text);font-weight:600}.df-answer__sup{color:var(--df-accent-text);font-weight:600;margin-left:2px;font-family:var(--df-font-sans);font-size:.7em}.df-answer__list{margin:0 0 18px;padding-left:0;list-style:none}.df-answer__li{position:relative;padding:8px 0 8px 22px;margin-left:6px;border-left:1px solid var(--df-border-2)}.df-answer__num{position:absolute;left:-10px;top:11px;width:18px;height:18px;border-radius:50%;background:var(--df-bg);border:1px solid var(--df-border-hi);color:var(--df-accent-text);font-size:10.5px;font-weight:600;display:flex;align-items:center;justify-content:center;font-family:var(--df-font-sans)}.df-cites{margin-top:24px;font-family:var(--df-font-serif)}.df-cites__row{display:flex;gap:14px;padding:12px 0;border-top:1px solid var(--df-border)}.df-cites__row:first-child{border-top:none}.df-cites__num{width:24px;color:var(--df-accent-text);font-weight:600;font-family:var(--df-font-sans);font-size:12px;margin-top:2px}.df-cites__title{font-size:15px;color:var(--df-text)}.df-cites__path{font-family:var(--df-font-mono);font-size:11px;color:var(--df-text-4);margin-top:2px}.df-related{margin-top:28px;padding-top:20px;border-top:1px solid var(--df-border)}.df-related__list{display:flex;flex-direction:column;gap:6px}.df-related__item{display:flex;align-items:center;justify-content:space-between;padding:10px 12px;background:transparent;border:1px solid var(--df-border);border-radius:var(--df-r-md);color:var(--df-text-3);font-size:13px;cursor:pointer;font-family:inherit;text-align:left;transition:border-color var(--df-fast),color var(--df-fast)}.df-related__item:hover{border-color:var(--df-border-3);color:var(--df-text)}.df-actions{margin-top:24px;display:flex;gap:8px}.df-cites-rail{width:300px;border-left:1px solid var(--df-border);padding:28px 20px;background:#0c0c0e;flex-shrink:0;overflow:auto}.df-cites-rail__list{display:flex;flex-direction:column;gap:8px}.df-cites-card{padding:12px;background:var(--df-surface);border:1px solid var(--df-border);border-radius:var(--df-r-lg);cursor:pointer;transition:border-color var(--df-fast)}.df-cites-card:hover{border-color:var(--df-border-3)}.df-cites-card__head{display:flex;align-items:center;gap:6px;margin-bottom:6px}.df-cites-card__num{width:18px;height:18px;border-radius:5px;background:var(--df-accent-soft);color:var(--df-accent-text);font-size:10px;font-weight:600;display:flex;align-items:center;justify-content:center;font-family:var(--df-font-mono)}.df-cites-card__title{font-size:13px;font-weight:500;color:var(--df-text);flex:1}.df-cites-card__path{font-size:11px;color:var(--df-text-4);font-family:var(--df-font-mono);margin-bottom:8px}.df-cites-card__foot{display:flex;align-items:center;gap:6px;font-size:10px}.df-activity__row{display:flex;align-items:center;gap:14px;padding:10px 14px;font-size:12px;border-top:1px solid var(--df-border)}.df-activity__row:first-child{border-top:none}.df-activity__time{width:48px;color:var(--df-text-4);font-size:11px;font-family:var(--df-font-mono)}.df-activity__target{flex:1;color:var(--df-text-3);font-family:var(--df-font-mono)}.df-activity__delta{color:var(--df-text-4)}.df-wiki{flex:1;display:flex;overflow:hidden}.df-tree{width:var(--df-w-tree);border-right:1px solid var(--df-border);padding:14px 10px;overflow:auto;flex-shrink:0}.df-tree__filter{display:flex;align-items:center;gap:6px;padding:6px 8px;margin-bottom:8px;background:var(--df-surface);border:1px solid var(--df-border);border-radius:var(--df-r-md);font-size:12px;color:var(--df-text-4)}.df-tree__heading{font-size:10px;color:var(--df-text-4);text-transform:uppercase;letter-spacing:.08em;padding:8px 8px 4px}.df-tree__row{display:flex;align-items:center;gap:6px;padding:5px 8px;border-radius:var(--df-r-sm);font-size:12px;color:var(--df-text-3);cursor:pointer;transition:background var(--df-fast)}.df-tree__row:hover{background:var(--df-surface-2)}.df-tree__row--active{background:var(--df-accent-soft);color:var(--df-accent-text)}.df-tree__row--active:hover{background:var(--df-accent-soft)}.df-tree__row--stale{color:var(--df-amber-text)}.df-tree__caret{width:11px;display:flex;color:var(--df-text-4)}.df-tree__indicator{width:5px;height:5px;border-radius:50%}.df-tree__indicator--stale{background:var(--df-amber)}.df-tree__indicator--highlight{background:var(--df-accent)}.df-page{flex:1;overflow:auto;padding:40px var(--df-content-pad);max-width:780px;font-family:var(--df-font-serif)}.df-page__crumb{display:flex;align-items:center;gap:8px;font-size:11px;color:var(--df-text-4);margin-bottom:10px;font-family:var(--df-font-sans)}.df-page__crumb-active{color:var(--df-text-3)}.df-page__meta{display:flex;align-items:center;gap:8px;margin:14px 0 28px;font-family:var(--df-font-sans)}.df-page__path{font-size:11px;color:var(--df-text-4);font-family:var(--df-font-mono)}.df-page__prose{font-size:16px;line-height:1.72;color:var(--df-text-2)}.df-page__prose p:first-child{margin-top:0}.df-page__prose ul{padding-left:18px;line-height:1.7}.df-page__prose a{color:var(--df-accent-text);text-decoration:none}.df-page__prose a:hover{text-decoration:underline}.df-page__h3{font-family:var(--df-font-sans);font-size:13px;font-weight:600;color:var(--df-text);margin-top:28px;text-transform:uppercase;letter-spacing:.08em}.df-page__kv-row{display:flex;padding:8px 14px;border-top:1px solid var(--df-border);font-size:13px}.df-page__kv-row:first-child{border-top:none}.df-page__kv-key{width:120px;color:var(--df-accent-text);font-family:var(--df-font-mono)}.df-page__kv-val{color:var(--df-text-3)}.df-graph{flex:1;display:flex;overflow:hidden}.df-graph__canvas{flex:1;position:relative;overflow:hidden}.df-graph__grid{position:absolute;top:0;right:0;bottom:0;left:0;background-image:radial-gradient(circle,var(--df-border) 1px,transparent 1px);background-size:24px 24px;opacity:.5}.df-graph__legend{position:absolute;top:16px;left:16px;background:var(--df-surface);border:1px solid var(--df-border);border-radius:var(--df-r-lg);padding:10px 12px;display:flex;flex-direction:column;gap:6px;font-size:11px;z-index:2}.df-graph__legend-row{display:flex;align-items:center;gap:7px;color:var(--df-text-3);text-transform:capitalize}.df-graph__legend-swatch{width:8px;height:8px;border-radius:50%}.df-graph__controls{position:absolute;top:16px;right:16px;display:flex;gap:6px;z-index:2}.df-graph__svg{position:absolute;top:0;right:0;bottom:0;left:0}.df-graph__detail{width:var(--df-w-rail-detail);border-left:1px solid var(--df-border);padding:24px 20px;flex-shrink:0;overflow:auto}.df-graph__connection{display:flex;align-items:center;gap:8px;padding:7px 8px;border-radius:var(--df-r-sm);cursor:pointer;font-size:12px;color:var(--df-text-3)}.df-graph__connection:hover{background:var(--df-surface-2)}.df-graph__connection-dot{width:6px;height:6px;border-radius:50%}.df-health{flex:1;overflow:auto;padding:40px var(--df-content-pad)}.df-health__grid{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;margin:24px 0 32px}.df-stat{padding:18px;background:var(--df-surface);border:1px solid var(--df-border);border-radius:var(--df-r-xl)}.df-stat__num{font-size:34px;font-weight:600;letter-spacing:-.02em;margin-top:6px}.df-stat__num--green{color:var(--df-green)}.df-stat__num--amber{color:var(--df-amber-text)}.df-stat__num--red{color:var(--df-red)}.df-stat__bar{height:4px;background:var(--df-border);border-radius:2px;margin-top:10px;overflow:hidden}.df-stat__bar-fill{height:100%;background:linear-gradient(90deg,var(--df-green),var(--df-green-text));border-radius:2px}.df-stat__caption{font-size:11px;color:var(--df-text-4);margin-top:10px}.df-trend{background:var(--df-surface);border:1px solid var(--df-border);border-radius:var(--df-r-xl);padding:20px;margin-bottom:24px}.df-trend__head{display:flex;align-items:center;justify-content:space-between;margin-bottom:14px}.df-trend__title{font-size:13px;font-weight:500}.df-trend__bars{display:flex;align-items:flex-end;gap:6px;height:80px}.df-trend__bar{flex:1;border-radius:3px 3px 0 0;opacity:.85;transform-origin:bottom;animation:df-bar-grow .5s var(--df-ease) both}.df-issues__row{display:flex;align-items:center;gap:14px;padding:14px 16px;border-top:1px solid var(--df-border)}.df-issues__row:first-child{border-top:none}.df-issues__page{font-size:13px;font-weight:500;color:var(--df-text)}.df-issues__msg{flex:1;font-size:12px;color:var(--df-text-3)}.df-issues__age{font-size:11px;color:var(--df-text-4);font-family:var(--df-font-mono)}.df-sync{flex:1;overflow:auto;padding:40px var(--df-content-pad)}.df-sync__head{display:flex;align-items:center;justify-content:space-between}.df-sync__cards{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;margin:24px 0 28px}.df-sync-card{padding:16px;background:var(--df-surface);border:1px solid var(--df-border);border-radius:var(--df-r-xl)}.df-sync-card__body{margin-top:8px;font-weight:500;display:flex;align-items:center;gap:8px}.df-sync-card__sub{font-size:11px;color:var(--df-text-4);margin-top:6px;font-family:var(--df-font-mono)}.df-sync-card__sub--green{color:var(--df-green);font-family:inherit}.df-timeline{background:var(--df-surface);border:1px solid var(--df-border);border-radius:var(--df-r-xl);padding:8px 0}.df-timeline__row{display:flex;align-items:center;gap:14px;padding:10px 18px;position:relative}.df-timeline__time{width:48px;font-size:11px;color:var(--df-text-4);font-family:var(--df-font-mono)}.df-timeline__line{position:absolute;left:78px;top:0;bottom:0;width:1px;background:var(--df-border)}.df-timeline__dot{position:relative;width:9px;height:9px;border-radius:50%;background:var(--df-border-3);z-index:1}.df-timeline__dot--commit{background:var(--df-pink)}.df-timeline__dot--sync{background:var(--df-accent)}.df-timeline__dot--done{background:var(--df-green);box-shadow:0 0 0 3px #10b9812e}.df-timeline__msg{flex:1;font-size:13px;color:var(--df-text-2)}.df-timeline__msg--done{color:var(--df-green)}.df-onboard{flex:1;display:flex;flex-direction:column;overflow:auto}.df-onboard__center{flex:1;display:flex;align-items:center;justify-content:center;padding:48px 32px}.df-onboard__inner{width:100%;max-width:640px}.df-onboard__steps{display:flex;align-items:center;gap:8px;margin-bottom:32px;font-size:12px}.df-onboard__step{display:flex;align-items:center;gap:8px;color:var(--df-text-4)}.df-onboard__step--active,.df-onboard__step--done{color:var(--df-text)}.df-onboard__step-num{width:22px;height:22px;border-radius:50%;background:var(--df-surface-3);color:#fff;display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:600}.df-onboard__step--active .df-onboard__step-num{background:var(--df-accent)}.df-onboard__step--done .df-onboard__step-num{background:var(--df-green)}.df-onboard__step-line{flex:1;height:1px;background:var(--df-border)}.df-onboard__step-line--done{background:var(--df-green)}.df-onboard__intro{color:var(--df-text-4);margin:6px 0 24px}.df-domains{display:grid;grid-template-columns:1fr 1fr;gap:10px}.df-domain{text-align:left;padding:18px;border-radius:var(--df-r-xl);background:var(--df-surface);border:1px solid var(--df-border);cursor:pointer;font-family:inherit;color:var(--df-text);transition:all var(--df-fast)}.df-domain--selected{background:var(--df-accent-halo);border-color:var(--df-accent)}.df-domain__icon{width:32px;height:32px;border-radius:var(--df-r-lg);background:var(--df-surface-3);display:flex;align-items:center;justify-content:center;margin-bottom:10px;color:var(--df-text-3)}.df-domain--selected .df-domain__icon{background:var(--df-accent-soft);color:var(--df-accent-text)}.df-domain__label{font-weight:500;font-size:14px}.df-domain__desc{font-size:12px;color:var(--df-text-4);margin-top:4px}.df-onboard__fields{display:flex;flex-direction:column;gap:14px}.df-dropzone{padding:32px;border:1.5px dashed var(--df-border-3);border-radius:12px;text-align:center;background:#0c0c0e}.df-dropzone__title{margin-top:12px;font-size:14px;color:var(--df-text)}.df-dropzone__sub{margin-top:4px;font-size:12px;color:var(--df-text-4)}.df-init-log{background:var(--df-surface);border:1px solid var(--df-border);border-radius:var(--df-r-xl);padding:16px;font-family:var(--df-font-mono);font-size:12px}.df-init-log__line{display:flex;gap:10px;padding:4px 0;color:var(--df-text-3)}.df-init-log__mark--ok{color:var(--df-green)}.df-init-log__mark--run{color:var(--df-accent-text)}.df-onboard__nav{display:flex;justify-content:space-between;margin-top:32px}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
:root{--df-bg: #0a0a0b;--df-surface: #111113;--df-surface-2: #161619;--df-surface-3: #1d1d22;--df-border: #1a1a1f;--df-border-2: #26262c;--df-border-3: #2c2c33;--df-border-hi: #3a3a44;--df-text: #ededee;--df-text-2: #d4d4d8;--df-text-3: #a1a1aa;--df-text-4: #6b6b74;--df-accent: #6366f1;--df-accent-hover: #5558e3;--df-accent-2: #818cf8;--df-accent-text: #a5b4fc;--df-accent-soft: rgba(99,102,241,.14);--df-accent-glow: rgba(99,102,241,.18);--df-accent-ring: rgba(99,102,241,.4);--df-accent-halo: rgba(99,102,241,.08);--df-green: #10b981;--df-green-text: #34d399;--df-green-soft: rgba(16,185,129,.12);--df-green-ring: rgba(16,185,129,.3);--df-amber: #f59e0b;--df-amber-text: #fbbf24;--df-amber-soft: rgba(245,158,11,.12);--df-amber-ring: rgba(245,158,11,.3);--df-red: #ef4444;--df-red-text: #f87171;--df-red-soft: rgba(239,68,68,.12);--df-red-ring: rgba(239,68,68,.3);--df-pink: #ec4899;--df-pink-text: #f472b6;--df-pink-soft: rgba(236,72,153,.12);--df-pink-ring: rgba(236,72,153,.3);--df-font-sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;--df-font-serif: "Source Serif 4", "Iowan Old Style", Georgia, serif;--df-font-mono: "JetBrains Mono", ui-monospace, "SF Mono", Menlo, monospace;--df-r-sm: 4px;--df-r-md: 6px;--df-r-lg: 8px;--df-r-xl: 10px;--df-r-pill: 999px;--df-h-btn: 28px;--df-h-input: 30px;--df-h-bar: 44px;--df-w-rail: 60px;--df-w-rail-detail: 280px;--df-w-tree: 260px;--df-ease: cubic-bezier(.2,.7,.3,1);--df-fast: .12s;--df-base: .2s;--df-slow: .35s;--df-content-max: 720px;--df-content-pad: 56px}*,*:before,*:after{box-sizing:border-box}html,body,#root{height:100%;margin:0}body{background:var(--df-bg);color:var(--df-text);font-family:var(--df-font-sans);font-feature-settings:"cv11","ss01";font-size:13px;line-height:1.5;letter-spacing:-.005em;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}button{font-family:inherit}.df-mono{font-family:var(--df-font-mono);font-feature-settings:"cv01","cv02"}.df-serif{font-family:var(--df-font-serif)}::-webkit-scrollbar{width:8px;height:8px}::-webkit-scrollbar-thumb{background:var(--df-border-2);border-radius:4px}::-webkit-scrollbar-thumb:hover{background:var(--df-border-3)}::-webkit-scrollbar-track{background:transparent}::selection{background:var(--df-accent-soft);color:var(--df-text)}.df-app{width:100vw;height:100vh;display:flex;flex-direction:column;overflow:hidden}.df-app__main{flex:1;display:flex;overflow:hidden;min-height:0}.df-view{flex:1;display:flex;flex-direction:column;overflow:hidden;min-width:0;background:var(--df-bg)}@keyframes df-fade-in{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}@keyframes df-spin{to{transform:rotate(360deg)}}@keyframes df-pulse{0%,to{opacity:.4}50%{opacity:1}}@keyframes df-blink{0%,49%{opacity:1}50%,to{opacity:0}}@keyframes df-shimmer{0%{background-position:-200% 0}to{background-position:200% 0}}@keyframes df-bar-grow{0%{transform:scaleY(0)}to{transform:scaleY(1)}}@keyframes df-page-enter{0%{opacity:0;transform:translate(8px)}to{opacity:1;transform:translate(0)}}.df-anim-fade{animation:df-fade-in var(--df-base) var(--df-ease) both}.df-anim-page{animation:df-page-enter var(--df-slow) var(--df-ease) both}.df-pill{display:inline-flex;align-items:center;gap:5px;padding:2px 7px;border-radius:var(--df-r-sm);font-size:11px;font-weight:500;font-family:var(--df-font-sans);background:var(--df-surface-3);border:1px solid var(--df-border-3);color:var(--df-text-3);white-space:nowrap}.df-pill--accent{background:var(--df-accent-soft);border-color:var(--df-accent-ring);color:var(--df-accent-text)}.df-pill--green{background:var(--df-green-soft);border-color:var(--df-green-ring);color:var(--df-green-text)}.df-pill--amber{background:var(--df-amber-soft);border-color:var(--df-amber-ring);color:var(--df-amber-text)}.df-pill--red{background:var(--df-red-soft);border-color:var(--df-red-ring);color:var(--df-red-text)}.df-pill--pink{background:var(--df-pink-soft);border-color:var(--df-pink-ring);color:var(--df-pink-text)}.df-pill__dot{width:5px;height:5px;border-radius:50%;background:currentColor}.df-btn{display:inline-flex;align-items:center;gap:6px;height:var(--df-h-btn);padding:0 10px;border-radius:var(--df-r-md);background:var(--df-surface-3);border:1px solid var(--df-border-3);color:var(--df-text);font-size:12px;font-weight:500;letter-spacing:-.005em;cursor:pointer;transition:background var(--df-fast),border-color var(--df-fast),color var(--df-fast);white-space:nowrap}.df-btn:hover{background:var(--df-surface-2)}.df-btn--primary{background:var(--df-accent);border-color:var(--df-accent);color:#fff}.df-btn--primary:hover{background:var(--df-accent-hover);border-color:var(--df-accent-hover)}.df-btn--ghost{background:transparent;border-color:transparent;color:var(--df-text-3)}.df-btn--ghost:hover{background:var(--df-surface-3);color:var(--df-text)}.df-btn--active{background:var(--df-surface-2);border-color:var(--df-border-hi)}.df-kbd{display:inline-flex;align-items:center;justify-content:center;min-width:18px;height:18px;padding:0 5px;border-radius:var(--df-r-sm);background:var(--df-surface-3);border:1px solid var(--df-border-3);color:var(--df-text-3);font:11px/1 var(--df-font-mono)}.df-btn--primary .df-kbd{background:#ffffff2e;border:none;color:#fff}.df-card{background:var(--df-surface);border:1px solid var(--df-border);border-radius:var(--df-r-xl)}.df-card--padded{padding:18px}.df-card--rows>*+*{border-top:1px solid var(--df-border)}.df-card__row{display:flex;align-items:center;gap:14px;padding:12px 16px;font-size:12px}.df-eyebrow{font-size:11px;color:var(--df-text-4);text-transform:uppercase;letter-spacing:.08em}.df-h1{margin:0;font-size:24px;font-weight:600;letter-spacing:-.02em;color:var(--df-text)}.df-h1--display{font-size:26px}.df-h1--serif{font-family:var(--df-font-serif);font-weight:400;font-size:32px;letter-spacing:-.02em;line-height:1.15}.df-subtle{color:var(--df-text-4);font-size:13px}.df-topbar{height:var(--df-h-bar);display:flex;align-items:center;gap:12px;padding:0 16px;background:var(--df-bg);border-bottom:1px solid var(--df-border);flex-shrink:0;flex-wrap:nowrap;white-space:nowrap;overflow:hidden;min-width:0}.df-topbar>*{flex-shrink:0}.df-topbar__crumb{display:flex;align-items:center;gap:8px;font-size:13px}.df-topbar__sep{color:var(--df-border-3)}.df-topbar__meta{display:flex;align-items:center;gap:6px;font-size:11px;color:var(--df-text-4);min-width:0;overflow:hidden;text-overflow:ellipsis}.df-topbar__meta>span:last-child{overflow:hidden;text-overflow:ellipsis}.df-topbar__divider{width:1px;height:18px;background:var(--df-border);margin:0 4px}.df-topbar__avatar{width:28px;height:28px;border-radius:50%;background:linear-gradient(135deg,var(--df-pink),var(--df-accent))}.df-rail{width:var(--df-w-rail);background:var(--df-bg);border-right:1px solid var(--df-border);display:flex;flex-direction:column;align-items:center;padding:12px 0;gap:2px;flex-shrink:0}.df-rail__logo{width:32px;height:32px;margin-bottom:14px;border-radius:var(--df-r-lg);background:linear-gradient(135deg,var(--df-accent),#a855f7);display:flex;align-items:center;justify-content:center;color:#fff}.df-rail__item{position:relative;width:40px;height:40px;display:flex;align-items:center;justify-content:center;background:transparent;border:none;border-radius:var(--df-r-lg);color:var(--df-text-4);cursor:pointer;transition:background var(--df-fast),color var(--df-fast)}.df-rail__item:hover{color:var(--df-text-3)}.df-rail__item--active{background:var(--df-surface-3);color:var(--df-text)}.df-rail__item--active:before{content:"";position:absolute;left:-6px;top:10px;bottom:10px;width:2px;border-radius:1px;background:var(--df-accent)}.df-rail__spacer{flex:1}.df-field{display:block}.df-field__label{font-size:11px;color:var(--df-text-4);text-transform:uppercase;letter-spacing:.08em;margin-bottom:6px}.df-field__value{padding:10px 12px;background:var(--df-surface);border:1px solid var(--df-border-2);border-radius:var(--df-r-lg);font-size:13px;color:var(--df-text)}.df-field__value--mono{font-family:var(--df-font-mono)}.df-code{background:var(--df-surface-3);border:1px solid var(--df-border-2);padding:1px 6px;border-radius:var(--df-r-sm);font-family:var(--df-font-mono);font-size:.82em;color:var(--df-accent-text)}.df-status-dot{display:inline-block;width:8px;height:8px;border-radius:50%;background:var(--df-text-4)}.df-status-dot--live{background:var(--df-green);animation:df-pulse 1.4s infinite}.df-status-dot--paused{background:var(--df-text-4)}.df-modal-overlay{position:fixed;top:0;right:0;bottom:0;left:0;background:#0000008c;z-index:300;display:flex;align-items:flex-start;justify-content:center;padding-top:12vh}.df-cmd-palette{width:min(720px,calc(100vw - 48px));border:1px solid var(--df-border-2);border-radius:var(--df-r-xl);background:var(--df-bg);box-shadow:0 18px 48px #00000073;overflow:hidden}.df-cmd-palette__head{display:flex;gap:8px;padding:10px;border-bottom:1px solid var(--df-border)}.df-cmd-palette__input{flex:1;height:36px;padding:0 12px;border-radius:var(--df-r-md);border:1px solid var(--df-border-2);background:var(--df-surface);color:var(--df-text);font-size:13px;font-family:inherit;outline:none}.df-cmd-palette__close{height:36px;padding:0 10px;border-radius:var(--df-r-md);border:1px solid var(--df-border-2);background:var(--df-surface-3);color:var(--df-text-3);font-family:var(--df-font-mono);font-size:11px;cursor:pointer}.df-cmd-palette__list{max-height:56vh;overflow:auto}.df-cmd-palette__empty{padding:16px;color:var(--df-text-4);font-size:12px}.df-cmd-palette__item{width:100%;border:none;border-top:1px solid var(--df-border);background:transparent;color:var(--df-text);text-align:left;padding:12px 14px;cursor:pointer;font-family:inherit}.df-cmd-palette__item:first-child{border-top:none}.df-cmd-palette__item--active,.df-cmd-palette__item:hover{background:var(--df-surface)}.df-cmd-palette__title{font-size:13px;font-weight:600}.df-cmd-palette__meta{margin-top:3px;display:flex;gap:10px;font-size:11px;color:var(--df-text-4);text-transform:uppercase;letter-spacing:.04em}.df-cmd-palette__preview{margin-top:6px;color:var(--df-text-3);font-size:12px}.df-ask{flex:1;display:flex;flex-direction:column;overflow:hidden;background:var(--df-bg)}.df-ask__header{padding:40px var(--df-content-pad) 24px;border-bottom:1px solid var(--df-border)}.df-ask__eyebrow{display:flex;align-items:center;gap:8px;margin-bottom:10px}.df-ask__title-accent{color:var(--df-accent-text)}.df-ask__intro{margin:6px 0 0;color:var(--df-text-4);font-size:13px}.df-ask__box-wrap{margin-top:24px;position:relative}.df-ask__box{display:flex;align-items:center;gap:10px;padding:14px 18px;border-radius:var(--df-r-xl);background:var(--df-surface);border:1px solid var(--df-border-2);transition:all var(--df-base) var(--df-ease)}.df-ask__box--active{border-color:var(--df-accent-ring);box-shadow:0 0 0 4px var(--df-accent-halo)}.df-ask__box-input{flex:1;font-size:15px;color:var(--df-text);min-height:22px}.df-ask__placeholder{color:var(--df-text-4)}.df-ask__caret{display:inline-block;width:2px;height:16px;background:var(--df-accent-text);vertical-align:-2px;margin-left:1px;animation:df-blink .8s infinite}.df-ask__run{height:28px;padding:0 14px;border-radius:var(--df-r-md);background:var(--df-accent);color:#fff;border:none;font-size:12px;font-weight:600;cursor:pointer;display:flex;align-items:center;gap:5px}.df-ask__run:hover{background:var(--df-accent-hover)}.df-ask__reset{padding:4px 10px;border-radius:var(--df-r-md);background:transparent;color:var(--df-text-4);border:1px solid var(--df-border-3);font-size:11px;cursor:pointer}.df-ask__chips{margin-top:12px;display:flex;flex-wrap:wrap;gap:6px}.df-chip{padding:6px 11px;border-radius:var(--df-r-pill);background:transparent;border:1px solid var(--df-border-2);color:var(--df-text-3);font-size:12px;cursor:pointer;font-family:inherit;transition:all var(--df-fast)}.df-chip:hover{background:var(--df-surface-2);border-color:var(--df-border-hi);color:var(--df-text)}.df-ask__body{flex:1;display:flex;overflow:hidden;min-height:0}.df-ask__main{flex:1;padding:28px var(--df-content-pad) 56px;min-width:0;overflow:auto}.df-search__head{display:flex;align-items:center;gap:10px;color:var(--df-accent-text);font-size:13px;margin-bottom:18px}.df-search__spinner{width:14px;height:14px;border:2px solid var(--df-border-3);border-top-color:var(--df-accent);border-radius:50%;animation:df-spin .7s linear infinite}.df-search__stage{display:flex;align-items:center;gap:10px;padding:8px 0;font-size:12px;color:var(--df-text-4)}.df-search__stage--done{color:var(--df-green)}.df-search__skel{margin-top:24px;display:flex;flex-direction:column;gap:10px}.df-search__skel-bar{height:12px;border-radius:var(--df-r-sm);background:linear-gradient(90deg,var(--df-surface-2),var(--df-surface-3),var(--df-surface-2));background-size:200% 100%;animation:df-shimmer 1.4s infinite linear}.df-answer{max-width:var(--df-content-max)}.df-answer__meta{display:flex;align-items:center;gap:10px;margin-bottom:20px}.df-answer__doc{font-family:var(--df-font-serif);border-top:1px solid var(--df-border);border-bottom:1px solid var(--df-border);padding:28px 0 32px}.df-answer__h{margin:0 0 22px;font-size:24px;font-weight:400;color:var(--df-text);letter-spacing:-.01em;line-height:1.25}.df-answer__prose{font-size:16px;line-height:1.72;color:var(--df-text-2)}.df-answer__prose p{margin:0 0 16px}.df-answer__prose strong{color:var(--df-text);font-weight:600}.df-answer__sup{color:var(--df-accent-text);font-weight:600;margin-left:2px;font-family:var(--df-font-sans);font-size:.7em}.df-answer__list{margin:0 0 18px;padding-left:0;list-style:none}.df-answer__li{position:relative;padding:8px 0 8px 22px;margin-left:6px;border-left:1px solid var(--df-border-2)}.df-answer__num{position:absolute;left:-10px;top:11px;width:18px;height:18px;border-radius:50%;background:var(--df-bg);border:1px solid var(--df-border-hi);color:var(--df-accent-text);font-size:10.5px;font-weight:600;display:flex;align-items:center;justify-content:center;font-family:var(--df-font-sans)}.df-cites{margin-top:24px;font-family:var(--df-font-serif)}.df-cites__row{display:flex;gap:14px;padding:12px 0;border-top:1px solid var(--df-border)}.df-cites__row:first-child{border-top:none}.df-cites__num{width:24px;color:var(--df-accent-text);font-weight:600;font-family:var(--df-font-sans);font-size:12px;margin-top:2px}.df-cites__title{font-size:15px;color:var(--df-text)}.df-cites__path{font-family:var(--df-font-mono);font-size:11px;color:var(--df-text-4);margin-top:2px}.df-related{margin-top:28px;padding-top:20px;border-top:1px solid var(--df-border)}.df-related__list{display:flex;flex-direction:column;gap:6px}.df-related__item{display:flex;align-items:center;justify-content:space-between;padding:10px 12px;background:transparent;border:1px solid var(--df-border);border-radius:var(--df-r-md);color:var(--df-text-3);font-size:13px;cursor:pointer;font-family:inherit;text-align:left;transition:border-color var(--df-fast),color var(--df-fast)}.df-related__item:hover{border-color:var(--df-border-3);color:var(--df-text)}.df-actions{margin-top:24px;display:flex;gap:8px}.df-cites-rail{width:300px;border-left:1px solid var(--df-border);padding:28px 20px;background:#0c0c0e;flex-shrink:0;overflow:auto}.df-cites-rail__list{display:flex;flex-direction:column;gap:8px}.df-cites-card{padding:12px;background:var(--df-surface);border:1px solid var(--df-border);border-radius:var(--df-r-lg);cursor:pointer;transition:border-color var(--df-fast)}.df-cites-card:hover{border-color:var(--df-border-3)}.df-cites-card__head{display:flex;align-items:center;gap:6px;margin-bottom:6px}.df-cites-card__num{width:18px;height:18px;border-radius:5px;background:var(--df-accent-soft);color:var(--df-accent-text);font-size:10px;font-weight:600;display:flex;align-items:center;justify-content:center;font-family:var(--df-font-mono)}.df-cites-card__title{font-size:13px;font-weight:500;color:var(--df-text);flex:1}.df-cites-card__path{font-size:11px;color:var(--df-text-4);font-family:var(--df-font-mono);margin-bottom:8px}.df-cites-card__foot{display:flex;align-items:center;gap:6px;font-size:10px}.df-activity__row{display:flex;align-items:center;gap:14px;padding:10px 14px;font-size:12px;border-top:1px solid var(--df-border)}.df-activity__row:first-child{border-top:none}.df-activity__time{width:48px;color:var(--df-text-4);font-size:11px;font-family:var(--df-font-mono)}.df-activity__target{flex:1;color:var(--df-text-3);font-family:var(--df-font-mono)}.df-activity__delta{color:var(--df-text-4)}.df-wiki{flex:1;display:flex;overflow:hidden}.df-tree{width:var(--df-w-tree);border-right:1px solid var(--df-border);padding:14px 10px;overflow:auto;flex-shrink:0}.df-tree__filter{display:flex;align-items:center;gap:6px;padding:6px 8px;margin-bottom:8px;background:var(--df-surface);border:1px solid var(--df-border);border-radius:var(--df-r-md);font-size:12px;color:var(--df-text-4)}.df-tree__heading{font-size:10px;color:var(--df-text-4);text-transform:uppercase;letter-spacing:.08em;padding:8px 8px 4px}.df-tree__row{display:flex;align-items:center;gap:6px;padding:5px 8px;border-radius:var(--df-r-sm);font-size:12px;color:var(--df-text-3);cursor:pointer;transition:background var(--df-fast)}.df-tree__row:hover{background:var(--df-surface-2)}.df-tree__row--active{background:var(--df-accent-soft);color:var(--df-accent-text)}.df-tree__row--active:hover{background:var(--df-accent-soft)}.df-tree__row--stale{color:var(--df-amber-text)}.df-tree__caret{width:11px;display:flex;color:var(--df-text-4)}.df-tree__indicator{width:5px;height:5px;border-radius:50%}.df-tree__indicator--stale{background:var(--df-amber)}.df-tree__indicator--highlight{background:var(--df-accent)}.df-page{flex:1;overflow:auto;padding:40px var(--df-content-pad);max-width:780px;font-family:var(--df-font-serif)}.df-page__crumb{display:flex;align-items:center;gap:8px;font-size:11px;color:var(--df-text-4);margin-bottom:10px;font-family:var(--df-font-sans)}.df-page__crumb-active{color:var(--df-text-3)}.df-page__meta{display:flex;align-items:center;gap:8px;margin:14px 0 28px;font-family:var(--df-font-sans)}.df-page__path{font-size:11px;color:var(--df-text-4);font-family:var(--df-font-mono)}.df-page__prose{font-size:16px;line-height:1.72;color:var(--df-text-2)}.df-page__prose p:first-child{margin-top:0}.df-page__prose ul{padding-left:18px;line-height:1.7}.df-page__prose a{color:var(--df-accent-text);text-decoration:none}.df-page__prose a:hover{text-decoration:underline}.df-page__h3{font-family:var(--df-font-sans);font-size:13px;font-weight:600;color:var(--df-text);margin-top:28px;text-transform:uppercase;letter-spacing:.08em}.df-page__kv-row{display:flex;padding:8px 14px;border-top:1px solid var(--df-border);font-size:13px}.df-page__kv-row:first-child{border-top:none}.df-page__kv-key{width:120px;color:var(--df-accent-text);font-family:var(--df-font-mono)}.df-page__kv-val{color:var(--df-text-3)}.df-graph{flex:1;display:flex;overflow:hidden}.df-graph__canvas{flex:1;position:relative;overflow:hidden}.df-graph__grid{position:absolute;top:0;right:0;bottom:0;left:0;background-image:radial-gradient(circle,var(--df-border) 1px,transparent 1px);background-size:24px 24px;opacity:.5}.df-graph__legend{position:absolute;top:16px;left:16px;background:var(--df-surface);border:1px solid var(--df-border);border-radius:var(--df-r-lg);padding:10px 12px;display:flex;flex-direction:column;gap:6px;font-size:11px;z-index:2}.df-graph__legend-row{display:flex;align-items:center;gap:7px;color:var(--df-text-3);text-transform:capitalize}.df-graph__legend-swatch{width:8px;height:8px;border-radius:50%}.df-graph__controls{position:absolute;top:16px;right:16px;display:flex;gap:6px;z-index:2}.df-graph__svg{position:absolute;top:0;right:0;bottom:0;left:0}.df-graph__detail{width:var(--df-w-rail-detail);border-left:1px solid var(--df-border);padding:24px 20px;flex-shrink:0;overflow:auto}.df-graph__connection{display:flex;align-items:center;gap:8px;padding:7px 8px;border-radius:var(--df-r-sm);cursor:pointer;font-size:12px;color:var(--df-text-3)}.df-graph__connection:hover{background:var(--df-surface-2)}.df-graph__connection-dot{width:6px;height:6px;border-radius:50%}.df-health{flex:1;overflow:auto;padding:40px var(--df-content-pad)}.df-health__grid{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;margin:24px 0 32px}.df-stat{padding:18px;background:var(--df-surface);border:1px solid var(--df-border);border-radius:var(--df-r-xl)}.df-stat__num{font-size:34px;font-weight:600;letter-spacing:-.02em;margin-top:6px}.df-stat__num--green{color:var(--df-green)}.df-stat__num--amber{color:var(--df-amber-text)}.df-stat__num--red{color:var(--df-red)}.df-stat__bar{height:4px;background:var(--df-border);border-radius:2px;margin-top:10px;overflow:hidden}.df-stat__bar-fill{height:100%;background:linear-gradient(90deg,var(--df-green),var(--df-green-text));border-radius:2px}.df-stat__caption{font-size:11px;color:var(--df-text-4);margin-top:10px}.df-trend{background:var(--df-surface);border:1px solid var(--df-border);border-radius:var(--df-r-xl);padding:20px;margin-bottom:24px}.df-trend__head{display:flex;align-items:center;justify-content:space-between;margin-bottom:14px}.df-trend__title{font-size:13px;font-weight:500}.df-trend__bars{display:flex;align-items:flex-end;gap:6px;height:80px}.df-trend__bar{flex:1;border-radius:3px 3px 0 0;opacity:.85;transform-origin:bottom;animation:df-bar-grow .5s var(--df-ease) both}.df-issues__row{display:flex;align-items:center;gap:14px;padding:14px 16px;border-top:1px solid var(--df-border)}.df-issues__row:first-child{border-top:none}.df-issues__page{font-size:13px;font-weight:500;color:var(--df-text)}.df-issues__msg{flex:1;font-size:12px;color:var(--df-text-3)}.df-issues__age{font-size:11px;color:var(--df-text-4);font-family:var(--df-font-mono)}.df-sync{flex:1;overflow:auto;padding:40px var(--df-content-pad)}.df-sync__head{display:flex;align-items:center;justify-content:space-between}.df-sync__cards{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;margin:24px 0 28px}.df-sync-card{padding:16px;background:var(--df-surface);border:1px solid var(--df-border);border-radius:var(--df-r-xl)}.df-sync-card__body{margin-top:8px;font-weight:500;display:flex;align-items:center;gap:8px}.df-sync-card__sub{font-size:11px;color:var(--df-text-4);margin-top:6px;font-family:var(--df-font-mono)}.df-sync-card__sub--green{color:var(--df-green);font-family:inherit}.df-timeline{background:var(--df-surface);border:1px solid var(--df-border);border-radius:var(--df-r-xl);padding:8px 0}.df-timeline__row{display:flex;align-items:center;gap:14px;padding:10px 18px;position:relative}.df-timeline__time{width:48px;font-size:11px;color:var(--df-text-4);font-family:var(--df-font-mono)}.df-timeline__line{position:absolute;left:78px;top:0;bottom:0;width:1px;background:var(--df-border)}.df-timeline__dot{position:relative;width:9px;height:9px;border-radius:50%;background:var(--df-border-3);z-index:1}.df-timeline__dot--commit{background:var(--df-pink)}.df-timeline__dot--sync{background:var(--df-accent)}.df-timeline__dot--done{background:var(--df-green);box-shadow:0 0 0 3px #10b9812e}.df-timeline__msg{flex:1;font-size:13px;color:var(--df-text-2)}.df-timeline__msg--done{color:var(--df-green)}.df-onboard{flex:1;display:flex;flex-direction:column;overflow:auto}.df-onboard__center{flex:1;display:flex;align-items:center;justify-content:center;padding:48px 32px}.df-onboard__inner{width:100%;max-width:640px}.df-onboard__steps{display:flex;align-items:center;gap:8px;margin-bottom:32px;font-size:12px}.df-onboard__step{display:flex;align-items:center;gap:8px;color:var(--df-text-4)}.df-onboard__step--active,.df-onboard__step--done{color:var(--df-text)}.df-onboard__step-num{width:22px;height:22px;border-radius:50%;background:var(--df-surface-3);color:#fff;display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:600}.df-onboard__step--active .df-onboard__step-num{background:var(--df-accent)}.df-onboard__step--done .df-onboard__step-num{background:var(--df-green)}.df-onboard__step-line{flex:1;height:1px;background:var(--df-border)}.df-onboard__step-line--done{background:var(--df-green)}.df-onboard__intro{color:var(--df-text-4);margin:6px 0 24px}.df-domains{display:grid;grid-template-columns:1fr 1fr;gap:10px}.df-domain{text-align:left;padding:18px;border-radius:var(--df-r-xl);background:var(--df-surface);border:1px solid var(--df-border);cursor:pointer;font-family:inherit;color:var(--df-text);transition:all var(--df-fast)}.df-domain--selected{background:var(--df-accent-halo);border-color:var(--df-accent)}.df-domain__icon{width:32px;height:32px;border-radius:var(--df-r-lg);background:var(--df-surface-3);display:flex;align-items:center;justify-content:center;margin-bottom:10px;color:var(--df-text-3)}.df-domain--selected .df-domain__icon{background:var(--df-accent-soft);color:var(--df-accent-text)}.df-domain__label{font-weight:500;font-size:14px}.df-domain__desc{font-size:12px;color:var(--df-text-4);margin-top:4px}.df-onboard__fields{display:flex;flex-direction:column;gap:14px}.df-onboard__input{width:100%;height:38px;padding:0 12px;border-radius:var(--df-r-lg);border:1px solid var(--df-border-2);background:var(--df-surface);color:var(--df-text);font-family:inherit;font-size:13px;outline:none}.df-onboard__input--mono{font-family:var(--df-font-mono)}.df-dropzone{padding:32px;border:1.5px dashed var(--df-border-3);border-radius:12px;text-align:center;background:#0c0c0e}.df-dropzone__title{margin-top:12px;font-size:14px;color:var(--df-text)}.df-dropzone__sub{margin-top:4px;font-size:12px;color:var(--df-text-4)}.df-init-log{background:var(--df-surface);border:1px solid var(--df-border);border-radius:var(--df-r-xl);padding:16px;font-family:var(--df-font-mono);font-size:12px}.df-init-log__line{display:flex;gap:10px;padding:4px 0;color:var(--df-text-3)}.df-init-log__mark--ok{color:var(--df-green)}.df-init-log__mark--run{color:var(--df-accent-text)}.df-onboard__nav{display:flex;justify-content:space-between;margin-top:32px}.df-settings{flex:1;overflow:auto;padding:40px var(--df-content-pad) 56px;max-width:980px}.df-settings__section{margin-top:20px;background:var(--df-surface);border:1px solid var(--df-border);border-radius:var(--df-r-xl);padding:16px}.df-settings__head{display:flex;align-items:center;justify-content:space-between;gap:12px}.df-settings__title{font-size:13px;color:var(--df-text);font-weight:600}.df-settings__kv{margin-top:8px;display:grid;grid-template-columns:120px 1fr;gap:10px;align-items:center;font-size:12px}.df-settings__kv>span{color:var(--df-text-4)}.df-settings__kv>code{color:var(--df-text-2);background:var(--df-surface-2);border:1px solid var(--df-border-2);border-radius:var(--df-r-sm);padding:4px 8px;font-family:var(--df-font-mono);overflow-wrap:anywhere}.df-settings__schema{margin-top:10px;width:100%;min-height:240px;border-radius:var(--df-r-md);border:1px solid var(--df-border-2);background:#0b0b0d;color:var(--df-text);padding:12px;font-size:12px;line-height:1.5;font-family:var(--df-font-mono);resize:vertical}.df-settings__bridge-row{margin:10px 0 12px;display:flex;flex-wrap:wrap;gap:8px}.df-settings__bridge{border:1px solid var(--df-border-2);background:transparent;color:var(--df-text-3);border-radius:var(--df-r-pill);font-size:12px;padding:6px 12px;cursor:pointer;font-family:inherit}.df-settings__bridge--active{background:var(--df-accent-soft);border-color:var(--df-accent-ring);color:var(--df-accent-text)}.df-settings__danger{border-color:var(--df-red-ring)}.df-settings__status{margin-top:12px;color:var(--df-accent-text);font-size:12px}
|