buddy-workbench 0.1.26 → 0.1.27

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "buddy-workbench",
3
- "version": "0.1.26",
3
+ "version": "0.1.27",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "bin": {
@@ -23,6 +23,25 @@
23
23
  "prepublishOnly": "npm run build",
24
24
  "version": "node -e \"const v=process.env.npm_package_version; const fs=require('fs'); ['ui/package.json', 'ui/package-lock.json'].forEach(p=>{if(fs.existsSync(p)){const j=JSON.parse(fs.readFileSync(p)); j.version=v; if(j.packages&&j.packages['']){j.packages[''].version=v;} fs.writeFileSync(p, JSON.stringify(j,null,2)+'\\n');}});\" && git add ui/package.json ui/package-lock.json"
25
25
  },
26
+ "devbuddyChangelog": [
27
+ {
28
+ "version": "0.1.27",
29
+ "name": "Data backups and settings refinements",
30
+ "notes": [
31
+ "Added data directory size statistics and secure .tar.gz backup import and export.",
32
+ "Refined the Static Pages action column header alignment."
33
+ ]
34
+ },
35
+ {
36
+ "version": "0.1.26",
37
+ "name": "Light theme and update center",
38
+ "notes": [
39
+ "Added a switchable light theme with persistent appearance settings.",
40
+ "Refined the light theme window color, primary actions, and navigation styling.",
41
+ "Added an npm-based update indicator and in-app Change Log."
42
+ ]
43
+ }
44
+ ],
26
45
  "dependencies": {
27
46
  "@jsquash/jpeg": "1.6.0",
28
47
  "axios": "1.7.9",
@@ -0,0 +1,285 @@
1
+ import { createReadStream, createWriteStream, existsSync } from 'node:fs';
2
+ import { copyFile, lstat, mkdir, mkdtemp, open, readdir, rm, stat, writeFile } from 'node:fs/promises';
3
+ import { tmpdir } from 'node:os';
4
+ import { dirname, join, posix, resolve, sep } from 'node:path';
5
+ import { Transform } from 'node:stream';
6
+ import { pipeline } from 'node:stream/promises';
7
+ import { createGunzip, createGzip } from 'node:zlib';
8
+ import { once } from 'node:events';
9
+ import { Router } from 'express';
10
+ import { paths } from '../config.js';
11
+
12
+ const router = Router();
13
+ const TAR_BLOCK_SIZE = 512;
14
+ const MAX_COMPRESSED_BYTES = 512 * 1024 * 1024;
15
+ const MAX_EXPANDED_BYTES = 2 * 1024 * 1024 * 1024;
16
+ const MAX_IMPORTED_FILES = 100000;
17
+
18
+ async function collectFiles(directory, relativeDirectory = '') {
19
+ if (!existsSync(directory)) return [];
20
+ const entries = await readdir(directory, { withFileTypes: true });
21
+ const files = [];
22
+
23
+ for (const entry of entries) {
24
+ const absolutePath = join(directory, entry.name);
25
+ const relativePath = relativeDirectory ? `${relativeDirectory}/${entry.name}` : entry.name;
26
+ if (entry.isDirectory()) {
27
+ files.push(...await collectFiles(absolutePath, relativePath));
28
+ } else if (entry.isFile()) {
29
+ const fileStat = await lstat(absolutePath);
30
+ files.push({
31
+ absolutePath,
32
+ relativePath: relativePath.replaceAll('\\', '/'),
33
+ size: fileStat.size,
34
+ mtime: fileStat.mtime
35
+ });
36
+ }
37
+ }
38
+
39
+ return files;
40
+ }
41
+
42
+ async function dataDirectoryStats() {
43
+ const files = await collectFiles(paths.dataDir);
44
+ return {
45
+ sizeBytes: files.reduce((total, file) => total + file.size, 0),
46
+ fileCount: files.length
47
+ };
48
+ }
49
+
50
+ function splitTarPath(relativePath) {
51
+ if (Buffer.byteLength(relativePath) <= 100) return { name: relativePath, prefix: '' };
52
+ const separators = [...relativePath.matchAll(/\//g)].map((match) => match.index).reverse();
53
+ for (const index of separators) {
54
+ const prefix = relativePath.slice(0, index);
55
+ const name = relativePath.slice(index + 1);
56
+ if (Buffer.byteLength(prefix) <= 155 && Buffer.byteLength(name) <= 100) {
57
+ return { name, prefix };
58
+ }
59
+ }
60
+ throw new Error(`Backup path is too long: ${relativePath}`);
61
+ }
62
+
63
+ function writeString(buffer, value, offset, length) {
64
+ const encoded = Buffer.from(String(value));
65
+ if (encoded.length > length) throw new Error(`Tar field exceeds ${length} bytes.`);
66
+ encoded.copy(buffer, offset);
67
+ }
68
+
69
+ function writeOctal(buffer, value, offset, length) {
70
+ writeString(buffer, Math.max(0, value).toString(8).padStart(length - 1, '0'), offset, length - 1);
71
+ }
72
+
73
+ function createTarHeader(file) {
74
+ const header = Buffer.alloc(TAR_BLOCK_SIZE);
75
+ const { name, prefix } = splitTarPath(file.relativePath);
76
+ writeString(header, name, 0, 100);
77
+ writeOctal(header, 0o600, 100, 8);
78
+ writeOctal(header, 0, 108, 8);
79
+ writeOctal(header, 0, 116, 8);
80
+ writeOctal(header, file.size, 124, 12);
81
+ writeOctal(header, Math.floor(file.mtime.getTime() / 1000), 136, 12);
82
+ header.fill(0x20, 148, 156);
83
+ writeString(header, '0', 156, 1);
84
+ writeString(header, 'ustar', 257, 6);
85
+ writeString(header, '00', 263, 2);
86
+ writeString(header, 'devbuddy', 265, 32);
87
+ writeString(header, 'devbuddy', 297, 32);
88
+ if (prefix) writeString(header, prefix, 345, 155);
89
+
90
+ const checksum = header.reduce((total, byte) => total + byte, 0);
91
+ writeString(header, checksum.toString(8).padStart(6, '0'), 148, 6);
92
+ header[154] = 0;
93
+ header[155] = 0x20;
94
+ return header;
95
+ }
96
+
97
+ async function writeWithBackpressure(stream, chunk) {
98
+ if (!stream.write(chunk)) await once(stream, 'drain');
99
+ }
100
+
101
+ function nullTerminatedString(buffer, offset, length) {
102
+ const field = buffer.subarray(offset, offset + length);
103
+ const nullIndex = field.indexOf(0);
104
+ return field.subarray(0, nullIndex === -1 ? field.length : nullIndex).toString('utf8').trim();
105
+ }
106
+
107
+ function parseOctal(buffer, offset, length) {
108
+ const value = nullTerminatedString(buffer, offset, length).trim();
109
+ if (!value) return 0;
110
+ const parsed = Number.parseInt(value, 8);
111
+ if (!Number.isFinite(parsed) || parsed < 0) throw new Error('Backup contains an invalid tar size.');
112
+ return parsed;
113
+ }
114
+
115
+ function verifyTarHeader(header) {
116
+ const expected = parseOctal(header, 148, 8);
117
+ const copy = Buffer.from(header);
118
+ copy.fill(0x20, 148, 156);
119
+ const actual = copy.reduce((total, byte) => total + byte, 0);
120
+ if (expected !== actual) throw new Error('Backup archive checksum is invalid.');
121
+ }
122
+
123
+ function safeArchiveTarget(stagingDirectory, archivePath) {
124
+ const normalizedInput = archivePath.replaceAll('\\', '/');
125
+ const normalized = posix.normalize(normalizedInput);
126
+ if (
127
+ !normalized ||
128
+ normalized === '.' ||
129
+ normalized === '..' ||
130
+ normalized.startsWith('../') ||
131
+ normalized.startsWith('/') ||
132
+ /^[a-zA-Z]:/.test(normalized)
133
+ ) {
134
+ throw new Error(`Backup contains an unsafe path: ${archivePath}`);
135
+ }
136
+ const target = resolve(stagingDirectory, ...normalized.split('/'));
137
+ const stagingRoot = resolve(stagingDirectory);
138
+ if (target !== stagingRoot && !target.startsWith(`${stagingRoot}${sep}`)) {
139
+ throw new Error(`Backup path escapes the data directory: ${archivePath}`);
140
+ }
141
+ return target;
142
+ }
143
+
144
+ function byteLimit(limit, label) {
145
+ let total = 0;
146
+ return new Transform({
147
+ transform(chunk, _encoding, callback) {
148
+ total += chunk.length;
149
+ if (total > limit) {
150
+ callback(new Error(`${label} exceeds the supported size limit.`));
151
+ } else {
152
+ callback(null, chunk);
153
+ }
154
+ }
155
+ });
156
+ }
157
+
158
+ async function extractTar(tarPath, stagingDirectory) {
159
+ const archiveStat = await stat(tarPath);
160
+ const archive = await open(tarPath, 'r');
161
+ let offset = 0;
162
+ let importedFiles = 0;
163
+
164
+ try {
165
+ while (offset + TAR_BLOCK_SIZE <= archiveStat.size) {
166
+ const header = Buffer.alloc(TAR_BLOCK_SIZE);
167
+ const { bytesRead } = await archive.read(header, 0, TAR_BLOCK_SIZE, offset);
168
+ if (bytesRead !== TAR_BLOCK_SIZE) throw new Error('Backup archive ended unexpectedly.');
169
+ if (header.every((byte) => byte === 0)) break;
170
+ verifyTarHeader(header);
171
+
172
+ const name = nullTerminatedString(header, 0, 100);
173
+ const prefix = nullTerminatedString(header, 345, 155);
174
+ const archivePath = prefix ? `${prefix}/${name}` : name;
175
+ const type = String.fromCharCode(header[156] || 48);
176
+ const size = parseOctal(header, 124, 12);
177
+ const dataStart = offset + TAR_BLOCK_SIZE;
178
+ const dataEnd = dataStart + size;
179
+ if (dataEnd > archiveStat.size) throw new Error('Backup file data exceeds the archive size.');
180
+
181
+ const target = safeArchiveTarget(stagingDirectory, archivePath);
182
+ if (type === '5') {
183
+ await mkdir(target, { recursive: true });
184
+ } else if (type === '0') {
185
+ importedFiles += 1;
186
+ if (importedFiles > MAX_IMPORTED_FILES) throw new Error('Backup contains too many files.');
187
+ await mkdir(dirname(target), { recursive: true });
188
+ if (size === 0) {
189
+ await writeFile(target, Buffer.alloc(0), { mode: 0o600 });
190
+ } else {
191
+ await pipeline(
192
+ createReadStream(tarPath, { start: dataStart, end: dataEnd - 1 }),
193
+ createWriteStream(target, { mode: 0o600 })
194
+ );
195
+ }
196
+ } else {
197
+ throw new Error('Backup contains an unsupported link or special file.');
198
+ }
199
+
200
+ offset = dataStart + Math.ceil(size / TAR_BLOCK_SIZE) * TAR_BLOCK_SIZE;
201
+ }
202
+ } finally {
203
+ await archive.close();
204
+ }
205
+
206
+ return importedFiles;
207
+ }
208
+
209
+ async function mergeDirectory(source, destination) {
210
+ await mkdir(destination, { recursive: true });
211
+ const entries = await readdir(source, { withFileTypes: true });
212
+ for (const entry of entries) {
213
+ const sourcePath = join(source, entry.name);
214
+ const destinationPath = join(destination, entry.name);
215
+ if (entry.isDirectory()) {
216
+ await mergeDirectory(sourcePath, destinationPath);
217
+ } else if (entry.isFile()) {
218
+ await mkdir(dirname(destinationPath), { recursive: true });
219
+ await copyFile(sourcePath, destinationPath);
220
+ }
221
+ }
222
+ }
223
+
224
+ router.get('/stats', async (_req, res, next) => {
225
+ try {
226
+ res.json(await dataDirectoryStats());
227
+ } catch (error) {
228
+ next(error);
229
+ }
230
+ });
231
+
232
+ router.get('/export', async (_req, res, next) => {
233
+ try {
234
+ const files = await collectFiles(paths.dataDir);
235
+ const date = new Date().toISOString().slice(0, 10);
236
+ res.setHeader('Content-Type', 'application/gzip');
237
+ res.setHeader('Content-Disposition', `attachment; filename="devbuddy-data-${date}.tar.gz"`);
238
+
239
+ const gzip = createGzip({ level: 6 });
240
+ gzip.pipe(res);
241
+ for (const file of files) {
242
+ await writeWithBackpressure(gzip, createTarHeader(file));
243
+ const readOptions = file.size > 0 ? { end: file.size - 1 } : undefined;
244
+ for await (const chunk of createReadStream(file.absolutePath, readOptions)) {
245
+ await writeWithBackpressure(gzip, chunk);
246
+ }
247
+ const padding = (TAR_BLOCK_SIZE - (file.size % TAR_BLOCK_SIZE)) % TAR_BLOCK_SIZE;
248
+ if (padding) await writeWithBackpressure(gzip, Buffer.alloc(padding));
249
+ }
250
+ await writeWithBackpressure(gzip, Buffer.alloc(TAR_BLOCK_SIZE * 2));
251
+ gzip.end();
252
+ } catch (error) {
253
+ if (!res.headersSent) next(error);
254
+ else res.destroy(error);
255
+ }
256
+ });
257
+
258
+ router.post('/import', async (req, res, next) => {
259
+ const temporaryDirectory = await mkdtemp(join(tmpdir(), 'devbuddy-backup-'));
260
+ const tarPath = join(temporaryDirectory, 'backup.tar');
261
+ const stagingDirectory = join(temporaryDirectory, 'data');
262
+
263
+ try {
264
+ await mkdir(stagingDirectory, { recursive: true });
265
+ await pipeline(
266
+ req,
267
+ byteLimit(MAX_COMPRESSED_BYTES, 'Compressed backup'),
268
+ createGunzip(),
269
+ byteLimit(MAX_EXPANDED_BYTES, 'Expanded backup'),
270
+ createWriteStream(tarPath, { mode: 0o600 })
271
+ );
272
+ const importedFiles = await extractTar(tarPath, stagingDirectory);
273
+ await mergeDirectory(stagingDirectory, paths.dataDir);
274
+ res.json({
275
+ importedFiles,
276
+ ...(await dataDirectoryStats())
277
+ });
278
+ } catch (error) {
279
+ next(error);
280
+ } finally {
281
+ await rm(temporaryDirectory, { recursive: true, force: true }).catch(() => {});
282
+ }
283
+ });
284
+
285
+ export default router;
@@ -0,0 +1,140 @@
1
+ import { execFile } from 'node:child_process';
2
+ import { readFileSync } from 'node:fs';
3
+ import { join } from 'node:path';
4
+ import { promisify } from 'node:util';
5
+ import { Router } from 'express';
6
+ import { root } from '../config.js';
7
+
8
+ const router = Router();
9
+ const execFileAsync = promisify(execFile);
10
+ const packageJson = JSON.parse(readFileSync(join(root, 'package.json'), 'utf8'));
11
+ const PACKAGE_NAME = packageJson.name;
12
+ const CURRENT_VERSION = packageJson.version;
13
+ const CACHE_TTL_MS = 15 * 60 * 1000;
14
+
15
+ let cachedResult = null;
16
+ let cachedAt = 0;
17
+
18
+ function versionParts(version) {
19
+ return String(version || '')
20
+ .trim()
21
+ .replace(/^v/i, '')
22
+ .split('-')[0]
23
+ .split('.')
24
+ .map((part) => Number.parseInt(part, 10) || 0);
25
+ }
26
+
27
+ function compareVersions(left, right) {
28
+ const a = versionParts(left);
29
+ const b = versionParts(right);
30
+ const length = Math.max(a.length, b.length);
31
+ for (let index = 0; index < length; index += 1) {
32
+ const difference = (a[index] || 0) - (b[index] || 0);
33
+ if (difference !== 0) return difference;
34
+ }
35
+ return 0;
36
+ }
37
+
38
+ function normalizeChangelogEntry(entry) {
39
+ if (!entry || typeof entry !== 'object' || !entry.version) return null;
40
+ return {
41
+ version: String(entry.version).replace(/^v/i, ''),
42
+ name: entry.name || 'Release',
43
+ notes: Array.isArray(entry.notes) ? entry.notes.map((note) => `• ${note}`).join('\n') : String(entry.notes || ''),
44
+ publishedAt: entry.publishedAt || null
45
+ };
46
+ }
47
+
48
+ function buildReleaseList(metadata) {
49
+ const localEntries = Array.isArray(packageJson.devbuddyChangelog)
50
+ ? packageJson.devbuddyChangelog.map(normalizeChangelogEntry).filter(Boolean)
51
+ : [];
52
+ const remoteEntries = Array.isArray(metadata.devbuddyChangelog)
53
+ ? metadata.devbuddyChangelog.map(normalizeChangelogEntry).filter(Boolean)
54
+ : [];
55
+ const entriesByVersion = new Map();
56
+
57
+ [...remoteEntries, ...localEntries].forEach((entry) => {
58
+ if (!entriesByVersion.has(entry.version)) entriesByVersion.set(entry.version, entry);
59
+ });
60
+
61
+ if (metadata.time && typeof metadata.time === 'object') {
62
+ Object.entries(metadata.time).forEach(([version, publishedAt]) => {
63
+ if (['created', 'modified'].includes(version) || !/^\d+\.\d+\.\d+/.test(version)) return;
64
+ const existing = entriesByVersion.get(version);
65
+ if (existing) {
66
+ if (!existing.publishedAt) existing.publishedAt = publishedAt;
67
+ } else {
68
+ entriesByVersion.set(version, {
69
+ version,
70
+ name: 'Release',
71
+ notes: 'Published to the configured npm registry.',
72
+ publishedAt
73
+ });
74
+ }
75
+ });
76
+ }
77
+
78
+ return [...entriesByVersion.values()]
79
+ .sort((left, right) => compareVersions(right.version, left.version))
80
+ .slice(0, 10);
81
+ }
82
+
83
+ async function readNpmPackageMetadata() {
84
+ const npmCommand = process.platform === 'win32' ? 'npm.cmd' : 'npm';
85
+ const { stdout } = await execFileAsync(
86
+ npmCommand,
87
+ ['view', `${PACKAGE_NAME}@latest`, 'version', 'time', 'devbuddyChangelog', '--json'],
88
+ {
89
+ timeout: 8000,
90
+ maxBuffer: 1024 * 1024,
91
+ windowsHide: true
92
+ }
93
+ );
94
+ const metadata = JSON.parse(stdout);
95
+ if (!metadata || typeof metadata !== 'object' || !metadata.version) {
96
+ throw new Error('The configured npm registry did not return package version metadata.');
97
+ }
98
+ return metadata;
99
+ }
100
+
101
+ async function checkForUpdates() {
102
+ const metadata = await readNpmPackageMetadata();
103
+ const latestVersion = String(metadata.version).replace(/^v/i, '');
104
+ return {
105
+ currentVersion: CURRENT_VERSION,
106
+ latestVersion,
107
+ updateAvailable: compareVersions(latestVersion, CURRENT_VERSION) > 0,
108
+ checkedAt: new Date().toISOString(),
109
+ releases: buildReleaseList(metadata),
110
+ sourceUnavailable: false
111
+ };
112
+ }
113
+
114
+ function unavailableResult() {
115
+ return {
116
+ currentVersion: CURRENT_VERSION,
117
+ latestVersion: CURRENT_VERSION,
118
+ updateAvailable: false,
119
+ checkedAt: new Date().toISOString(),
120
+ releases: buildReleaseList({}),
121
+ sourceUnavailable: true
122
+ };
123
+ }
124
+
125
+ router.get('/', async (req, res) => {
126
+ const forceRefresh = req.query.refresh === '1';
127
+ if (!forceRefresh && cachedResult && Date.now() - cachedAt < CACHE_TTL_MS) {
128
+ return res.json(cachedResult);
129
+ }
130
+
131
+ try {
132
+ cachedResult = await checkForUpdates();
133
+ } catch {
134
+ cachedResult = unavailableResult();
135
+ }
136
+ cachedAt = Date.now();
137
+ return res.json(cachedResult);
138
+ });
139
+
140
+ export default router;
package/server.js CHANGED
@@ -21,6 +21,8 @@ import postmanRoutes from './server/routes/postman.js';
21
21
  import bookmarkSyncRoutes from './server/routes/bookmark-sync.js';
22
22
  import fileOrganizerRoutes from './server/routes/file-organizer.js';
23
23
  import branchSyncRoutes from './server/routes/branch-sync.js';
24
+ import updateRoutes from './server/routes/updates.js';
25
+ import dataBackupRoutes from './server/routes/data-backup.js';
24
26
  import { addErrorRecord } from './server/repositories/errors.js';
25
27
  import { startClipboardCapture } from './server/services/clipboard-history.js';
26
28
 
@@ -77,6 +79,8 @@ app.use('/api/postman', postmanRoutes);
77
79
  app.use('/api/bookmark-sync', bookmarkSyncRoutes);
78
80
  app.use('/api/file-organizer', fileOrganizerRoutes);
79
81
  app.use('/api/branch-sync', branchSyncRoutes);
82
+ app.use('/api/updates', updateRoutes);
83
+ app.use('/api/data-backup', dataBackupRoutes);
80
84
 
81
85
  app.use((err, req, res, _next) => {
82
86
  addErrorRecord({
@@ -0,0 +1 @@
1
+ html,body{width:100%;height:100%}input::-ms-clear,input::-ms-reveal{display:none}*,*:before,*:after{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;-ms-overflow-style:scrollbar;-webkit-tap-highlight-color:rgba(0,0,0,0)}@-ms-viewport{width:device-width}body{margin:0}[tabindex="-1"]:focus{outline:none}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5em;font-weight:500}p{margin-top:0;margin-bottom:1em}abbr[title],abbr[data-original-title]{-webkit-text-decoration:underline dotted;text-decoration:underline dotted;border-bottom:0;cursor:help}address{margin-bottom:1em;font-style:normal;line-height:inherit}input[type=text],input[type=password],input[type=number],textarea{-webkit-appearance:none}ol,ul,dl{margin-top:0;margin-bottom:1em}ol ol,ul ul,ol ul,ul ol{margin-bottom:0}dt{font-weight:500}dd{margin-bottom:.5em;margin-left:0}blockquote{margin:0 0 1em}dfn{font-style:italic}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}pre,code,kbd,samp{font-size:1em;font-family:SFMono-Regular,Consolas,Liberation Mono,Menlo,Courier,monospace}pre{margin-top:0;margin-bottom:1em;overflow:auto}figure{margin:0 0 1em}img{vertical-align:middle;border-style:none}a,area,button,[role=button],input:not([type=range]),label,select,summary,textarea{touch-action:manipulation}table{border-collapse:collapse}caption{padding-top:.75em;padding-bottom:.3em;text-align:left;caption-side:bottom}input,button,select,optgroup,textarea{margin:0;color:inherit;font-size:inherit;font-family:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}button,html [type=button],[type=reset],[type=submit]{-webkit-appearance:button}button::-moz-focus-inner,[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner{padding:0;border-style:none}input[type=radio],input[type=checkbox]{box-sizing:border-box;padding:0}input[type=date],input[type=time],input[type=datetime-local],input[type=month]{-webkit-appearance:listbox}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;margin:0;padding:0;border:0}legend{display:block;width:100%;max-width:100%;margin-bottom:.5em;padding:0;color:inherit;font-size:1.5em;line-height:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item}template{display:none}[hidden]{display:none!important}mark{padding:.2em;background-color:#feffe6}:root{--db-brand: #6555e8;--db-brand-strong: #5143c2;--db-brand-soft: #eeecff;--db-primary: #6555e8;--db-primary-hover: #7669ee;--db-bg: #f4f5fa;--db-surface: #fff;--db-surface-subtle: #f8f9fc;--db-text: #172033;--db-text-secondary: #5f6b82;--db-border: #e3e6ef;--db-sidebar: #171c2b;--db-sidebar-muted: #a6afc3;--db-success: #247a3d;--db-warning: #9a5b08;--db-danger: #cf3038;--db-radius: 12px;--db-shadow-sm: 0 4px 16px rgba(31, 42, 68, .06);--db-shadow-md: 0 18px 44px rgba(31, 42, 68, .1);font-family:Inter,ui-sans-serif,system-ui,-apple-system,PingFang SC,sans-serif;color:var(--db-text);background:var(--db-bg)}:root[data-theme=light]{--db-primary: #6e68d6;--db-primary-hover: #7c76e1;--db-bg: #f7f8fc;--db-surface: #fff;--db-surface-subtle: #fafbfe;--db-text: #172033;--db-text-secondary: #667085;--db-border: #e5e8f0;--db-sidebar: #fff;--db-sidebar-muted: #687187;--db-shadow-sm: 0 4px 16px rgba(31, 42, 68, .055);--db-shadow-md: 0 18px 44px rgba(31, 42, 68, .085)}html,body{height:100vh;overflow:hidden}body{margin:0;background:var(--db-bg)}.workbench{height:100vh;overflow:hidden;background:var(--db-bg)}.sidebar{position:sticky!important;top:0;height:100vh;overflow:hidden;background:var(--db-sidebar)!important}.sidebar .ant-layout-sider-children{display:flex;flex-direction:column;min-height:0}.sidebar .ant-menu-title-content{-webkit-user-select:none;user-select:none}.brand{display:block;flex:none;padding:25px 22px 18px;overflow:hidden;color:#fff;font-size:20px;font-weight:750;letter-spacing:-.4px;text-decoration:none;white-space:nowrap;transition:background .16s ease,color .16s ease}.brand:hover{background:#ffffff09;color:#fff}.brand:active{background:#ffffff0f}.brand:focus-visible{outline-offset:-4px}.brand-mark{color:#a99fff}.brand-name{margin-left:8px}.brand-version{margin-left:7px;color:var(--db-sidebar-muted);font-size:11px;font-weight:500;letter-spacing:normal;vertical-align:middle}.sidebar-nav{flex:1;min-height:0;overflow-x:hidden;overflow-y:auto;padding:0 12px 16px;border-inline-end:0;border-right:0;color-scheme:dark;scrollbar-width:thin;scrollbar-color:rgba(166,175,195,.3) transparent}.sidebar-nav::-webkit-scrollbar{width:8px;border:0;outline:0;background:transparent;box-shadow:none;-webkit-appearance:none}.sidebar-nav::-webkit-scrollbar-track,.sidebar-nav::-webkit-scrollbar-track-piece,.sidebar-nav::-webkit-scrollbar-corner{border:0;border-right:0;border-left:0;outline:0;background:transparent;box-shadow:none;-webkit-appearance:none}.sidebar-nav::-webkit-scrollbar-thumb{border:2px solid transparent;border-radius:999px;background:#a6afc34d;background-clip:padding-box;box-shadow:none;-webkit-appearance:none}.sidebar-nav::-webkit-scrollbar-thumb:hover{background:#c4cbda75;background-clip:padding-box}.sidebar .ant-menu{background:transparent}.sidebar .ant-menu.ant-menu-root.ant-menu-inline{border-inline-end:0!important;border-right:0!important}.sidebar .ant-menu:focus,.sidebar .ant-menu:focus-visible{outline:none;box-shadow:none}.sidebar .ant-menu-item-group-title{padding:17px 16px 7px;color:#8791aa;font-size:10px;font-weight:700;letter-spacing:.1em;text-transform:uppercase}.sidebar .ant-menu-item{margin-block:3px}.sidebar .ant-menu-item-selected{box-shadow:inset 0 0 0 1px #a99fff38}.sidebar-bottom{flex:none;padding:12px;border-top:1px solid rgba(255,255,255,.08);background:var(--db-sidebar)}.sidebar-footer{padding:14px 12px 0;color:var(--db-sidebar-muted);font-size:12px}.sidebar.ant-layout-sider-collapsed .brand{padding-inline:0;text-align:center}.sidebar.ant-layout-sider-collapsed .brand-name,.sidebar.ant-layout-sider-collapsed .brand-version,.sidebar.ant-layout-sider-collapsed .ant-menu-item-group-title{display:none}.sidebar.ant-layout-sider-collapsed .sidebar-nav,.sidebar.ant-layout-sider-collapsed .sidebar-bottom{padding-inline:8px}.sidebar .ant-layout-sider-trigger{position:static!important;width:100%!important;flex:none;border-top:1px solid rgba(255,255,255,.08);background:#121725;color:var(--db-sidebar-muted)}:root[data-theme=light] .sidebar{border-inline-end:1px solid var(--db-border);box-shadow:8px 0 30px #1f2a4409}:root[data-theme=light] .brand{color:var(--db-text)}:root[data-theme=light] .brand:hover{background:#f8f9fc;color:var(--db-text)}:root[data-theme=light] .brand:active{background:#f2f3f8}:root[data-theme=light] .brand-mark{color:var(--db-brand)}:root[data-theme=light] .sidebar-nav{color-scheme:light;scrollbar-color:rgba(95,107,130,.22) transparent}:root[data-theme=light] .sidebar-nav::-webkit-scrollbar-thumb{background:#5f6b8238;background-clip:padding-box}:root[data-theme=light] .sidebar-nav::-webkit-scrollbar-thumb:hover{background:#5f6b8257;background-clip:padding-box}:root[data-theme=light] .sidebar .ant-menu-item-group-title{color:#8992a7}:root[data-theme=light] .sidebar .ant-menu-item-selected{box-shadow:inset 0 0 0 1px #6555e81f}:root[data-theme=light] .sidebar-bottom{border-top-color:var(--db-border)}:root[data-theme=light] .sidebar .ant-layout-sider-trigger{border-top-color:var(--db-border);background:#f8f9fc}.page{height:100vh;overflow-y:auto;padding:clamp(20px,3.5vw,40px)}.page-header{display:flex;justify-content:space-between;align-items:flex-start;gap:24px;margin-bottom:28px}.page-header .ant-typography{margin:0}.page-header h2.ant-typography{margin-top:3px}.page-header .ant-typography-secondary{color:var(--db-text-secondary)}.launcher-data-notice{margin-bottom:20px}.platform-unavailable-card{max-width:500px;margin:60px auto;border-color:var(--db-border);border-radius:var(--db-radius);text-align:center;box-shadow:var(--db-shadow-sm)}.overview-page{width:100%;max-width:1440px;margin:0 auto;padding-bottom:40px}.overview-data-warning{margin-bottom:18px}.overview-hero{position:relative;display:flex;align-items:flex-end;justify-content:space-between;gap:36px;min-height:264px;padding:clamp(28px,4vw,46px);overflow:hidden;border:1px solid rgba(255,255,255,.1);border-radius:20px;background:radial-gradient(circle at 82% 18%,rgba(149,137,255,.34),transparent 30%),linear-gradient(135deg,#171c2b,#25284a 58%,#433b94);box-shadow:var(--db-shadow-md);color:#fff}.overview-hero:after{position:absolute;right:-90px;bottom:-150px;width:340px;height:340px;border:1px solid rgba(255,255,255,.12);border-radius:50%;box-shadow:0 0 0 42px #ffffff06,0 0 0 84px #ffffff05;content:"";pointer-events:none}.overview-hero-content{position:relative;z-index:1;max-width:720px}.overview-eyebrow{display:block;margin-bottom:12px;color:#c8c2ff;font-size:11px;font-weight:750;letter-spacing:.13em;text-transform:uppercase}.overview-hero h1.ant-typography,.overview-hero h2.ant-typography{max-width:680px;margin:0;color:#fff;font-size:clamp(30px,4vw,48px);line-height:1.08;letter-spacing:-.035em}.overview-hero-description,.overview-hero-copy,.overview-hero .ant-typography-secondary{display:block;max-width:620px;margin:16px 0 0;color:#c9cede;font-size:15px;line-height:1.65}.overview-actions,.overview-hero-actions{position:relative;z-index:1;display:flex;flex-wrap:wrap;gap:10px;flex:none}.overview-hero-actions{margin-top:20px}.overview-hero .ant-btn{height:42px;padding-inline:18px;border-radius:10px;font-weight:650}.overview-hero .ant-btn-primary{border-color:#fff;background:#fff;color:#3f348f;box-shadow:0 8px 22px #00000029}.overview-hero .ant-btn-primary:hover{border-color:#f1efff!important;background:#f1efff!important;color:#342a7c!important}.overview-hero .ant-btn-default{border-color:#ffffff47;background:#ffffff14;color:#fff}.overview-hero .ant-btn-default:hover{border-color:#ffffff7a!important;background:#ffffff26!important;color:#fff!important}.overview-hero .ant-skeleton-element .ant-skeleton-button{height:42px;border-radius:10px;background:#ffffff26!important}.overview-hero .ant-skeleton-element .ant-skeleton-button:after{background:linear-gradient(90deg,transparent,rgba(255,255,255,.22),transparent)!important}.overview-hero-mark{position:relative;z-index:1;display:grid;width:112px;height:112px;flex:none;border:1px solid rgba(255,255,255,.16);border-radius:30px;background:#ffffff14;color:#dcd8ff;font-size:42px;transform:rotate(-7deg);place-items:center}:root[data-theme=light] .overview-hero{border-color:#dedafc;background:radial-gradient(circle at 82% 18%,rgba(101,85,232,.15),transparent 30%),linear-gradient(135deg,#fff,#f5f3ff 58%,#e8e4ff);color:var(--db-text)}:root[data-theme=light] .overview-hero:after{border-color:#6555e81f;box-shadow:0 0 0 42px #6555e806,0 0 0 84px #6555e805}:root[data-theme=light] .overview-eyebrow{color:var(--db-brand-strong)}:root[data-theme=light] .overview-hero h1.ant-typography,:root[data-theme=light] .overview-hero h2.ant-typography{color:var(--db-text)}:root[data-theme=light] .overview-hero-description,:root[data-theme=light] .overview-hero-copy,:root[data-theme=light] .overview-hero .ant-typography-secondary{color:var(--db-text-secondary)}:root[data-theme=light] .overview-hero .ant-btn-primary{border-color:var(--db-primary);background:var(--db-primary);color:#fff}:root[data-theme=light] .overview-hero .ant-btn-primary:hover{border-color:var(--db-primary-hover)!important;background:var(--db-primary-hover)!important;color:#fff!important}:root[data-theme=light] .overview-hero .ant-btn-default{border-color:#d7d3f3;background:#ffffffb8;color:var(--db-brand-strong)}:root[data-theme=light] .overview-hero .ant-btn-default:hover{border-color:var(--db-brand)!important;background:#fff!important;color:var(--db-brand-strong)!important}:root[data-theme=light] .overview-hero-mark{border-color:#6555e829;background:#ffffffad;color:var(--db-brand)}.overview-metrics{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:14px;margin-top:18px}.overview-metric-card{min-width:0;border:1px solid var(--db-border);border-radius:var(--db-radius);background:var(--db-surface);box-shadow:var(--db-shadow-sm)}.overview-metric-card .ant-card-body{display:flex;align-items:center;gap:14px;padding:18px 20px}.overview-metric{display:flex;align-items:center;gap:14px;width:100%;min-width:0}.overview-metric-content{min-width:0}.overview-metric-icon{display:grid;width:42px;height:42px;flex:none;border-radius:12px;background:var(--db-brand-soft);color:var(--db-brand);font-size:18px;place-items:center}.overview-metric-card.is-success .overview-metric-icon{background:#eaf7ee;color:var(--db-success)}.overview-metric-card.is-danger .overview-metric-icon{background:#fff0f1;color:var(--db-danger)}.overview-metric-card.is-neutral .overview-metric-icon{background:#edf1f7;color:#526078}.overview-metric-copy{min-width:0}.overview-metric-label{display:block;color:var(--db-text-secondary);font-size:12px;font-weight:600}.overview-metric-value{display:block;margin-top:1px;color:var(--db-text);font-size:25px;font-weight:740;line-height:1.2;letter-spacing:-.025em}.overview-metric-note{display:block;overflow:hidden;margin-top:3px;color:var(--db-text-secondary)!important;font-size:11px;text-overflow:ellipsis;white-space:nowrap}.overview-grid,.overview-content-grid{display:grid;grid-template-columns:minmax(0,1.3fr) minmax(320px,.7fr);gap:18px;margin-top:18px}.overview-panel{min-width:0;border:1px solid var(--db-border);border-radius:16px;background:var(--db-surface);box-shadow:var(--db-shadow-sm)}.overview-panel .ant-card-head{min-height:60px;padding-inline:22px;border-bottom-color:#edf0f5}.overview-panel .ant-card-head-title{padding-block:16px}.overview-panel .ant-card-body{padding:20px 22px}.overview-section-header{display:flex;align-items:flex-start;justify-content:space-between;gap:16px}.overview-section-title{display:block;color:var(--db-text);font-size:15px;font-weight:700}.overview-section-title.ant-typography{margin:0}.overview-section-description{display:block;margin-top:2px;color:var(--db-text-secondary);font-size:12px;font-weight:450}.overview-service-list{display:grid;gap:4px;margin-top:12px}.overview-service-row{display:flex;align-items:center;gap:14px;min-height:58px;padding:9px 10px;border-radius:10px;transition:background .16s ease,border-color .16s ease,box-shadow .16s ease}.overview-service-status{width:9px;height:9px;flex:none;border-radius:50%;background:#a8b0bf;box-shadow:0 0 0 4px #f0f2f6}.overview-service-status.is-running{background:#38a457;box-shadow:0 0 0 4px #e8f7ed}.overview-service-status.is-error{background:#e2464d;box-shadow:0 0 0 4px #fff0f1}.overview-service-meta{min-width:0;flex:1}.overview-service-name{display:block;overflow:hidden;color:var(--db-text);font-weight:650;text-overflow:ellipsis;white-space:nowrap}.overview-service-detail{display:block;overflow:hidden;margin-top:2px;color:var(--db-text-secondary);font-size:12px;text-overflow:ellipsis;white-space:nowrap}.overview-service-row .ant-btn{flex:none}.overview-quick-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}.overview-quick-card{display:flex;align-items:center;gap:12px;min-width:0;min-height:66px;padding:13px 14px;border:1px solid var(--db-border);border-radius:12px;background:var(--db-surface);color:var(--db-text);cursor:pointer;text-align:left;transition:border-color .16s ease,box-shadow .16s ease,transform .16s ease}.overview-quick-card:hover{border-color:#b9b2fa;box-shadow:0 8px 20px #5143c21a;transform:translateY(-1px)}.overview-quick-card-icon{display:grid;width:36px;height:36px;flex:none;border-radius:10px;background:var(--db-brand-soft);color:var(--db-brand);place-items:center}.overview-quick-card-copy{min-width:0}.overview-quick-card-title{display:block;overflow:hidden;font-weight:650;text-overflow:ellipsis;white-space:nowrap}.overview-quick-card-description{display:block;overflow:hidden;margin-top:1px;color:var(--db-text-secondary);font-size:11px;text-overflow:ellipsis;white-space:nowrap}.overview-checklist{display:grid;gap:12px}.overview-checklist-item{display:flex;align-items:flex-start;gap:11px}.overview-checklist-marker{display:grid;width:24px;height:24px;flex:none;border-radius:50%;background:var(--db-brand-soft);color:var(--db-brand);font-size:11px;font-weight:750;place-items:center}.overview-checklist-copy{min-width:0;flex:1}.overview-checklist-title{display:block;color:var(--db-text);font-size:13px;font-weight:650}.overview-checklist-description{display:block;margin-top:1px;color:var(--db-text-secondary);font-size:12px;line-height:1.5}.overview-shortcuts-section{min-width:0;padding:22px;border:1px solid var(--db-border);border-radius:16px;background:var(--db-surface);box-shadow:var(--db-shadow-sm)}.overview-shortcuts{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;margin-top:18px}.overview-shortcut{display:flex;align-items:center;gap:12px;min-width:0;min-height:76px;padding:14px;border:1px solid var(--db-border);border-radius:12px;background:var(--db-surface);color:var(--db-text);cursor:pointer;font:inherit;text-align:left;transition:border-color .16s ease,box-shadow .16s ease,transform .16s ease}.overview-shortcut:hover{border-color:#b9b2fa;box-shadow:0 8px 20px #5143c21a;transform:translateY(-1px)}.overview-shortcut-icon{display:grid;width:38px;height:38px;flex:none;border-radius:10px;background:var(--db-brand-soft);color:var(--db-brand);font-size:16px;place-items:center}.overview-shortcut-copy{min-width:0;flex:1}.overview-shortcut-title{display:block;overflow:hidden;font-size:13px;font-weight:680;text-overflow:ellipsis;white-space:nowrap}.overview-shortcut-description{display:-webkit-box;overflow:hidden;margin-top:3px;color:var(--db-text-secondary);font-size:11px;line-height:1.4;-webkit-box-orient:vertical;-webkit-line-clamp:2}.overview-shortcut-arrow{flex:none;color:#9ba3b2;font-size:11px}.overview-setup-card,.overview-health-card{border:1px solid var(--db-border);border-radius:16px;box-shadow:var(--db-shadow-sm)}.overview-setup-card .ant-card-body{padding:22px}.overview-setup .overview-eyebrow{margin-bottom:5px;color:var(--db-brand)}.overview-setup-progress{flex:none;font-size:12px}.overview-setup-list{display:grid;gap:16px;margin:21px 0 0;padding:0;list-style:none}.overview-setup-step{display:flex;align-items:flex-start;gap:12px}.overview-setup-step-marker{display:grid;width:27px;height:27px;flex:none;border-radius:50%;background:var(--db-brand-soft);color:var(--db-brand);font-size:12px;font-weight:750;place-items:center}.overview-setup-step.is-complete .overview-setup-step-marker{background:#e9f7ee;color:var(--db-success)}.overview-setup-step-copy{min-width:0;flex:1}.overview-setup-step-title{display:block;font-size:13px}.overview-setup-step-description{display:block;margin-top:2px;color:var(--db-text-secondary)!important;font-size:11px;line-height:1.45}.overview-setup-step-action.ant-btn{height:auto;margin-top:3px;padding:0;font-size:12px}.overview-health-card{margin-top:18px}.overview-health-card .ant-card-body{padding:22px}.overview-health .overview-section-header{padding-bottom:16px;border-bottom:1px solid #edf0f5}.overview-section-link.ant-btn{flex:none}.overview-service-row{width:100%;-webkit-appearance:none;-moz-appearance:none;appearance:none;border:1px solid #edf0f5;background:var(--db-surface);color:inherit;cursor:pointer;font:inherit;text-align:left}.overview-service-row.is-idle{border-color:#edf0f5;background:var(--db-surface)}.overview-service-row.is-running{border-color:#dcefe1;background:#f6fbf7}.overview-service-row.is-error{border-color:#f4dfe0;background:#fff7f7}.overview-service-row:hover{border-color:#ded9ff;background:#f8f7ff;box-shadow:0 4px 12px #5143c20f}.overview-service-primary{min-width:0;flex:1}.overview-service-name-line{display:flex;align-items:center;gap:10px;min-width:0}.overview-service-name-line .ant-badge{flex:none}.overview-service-stats{display:flex;align-items:center;gap:16px;flex:none;color:var(--db-text-secondary);font-size:12px}.overview-service-stat{display:inline-flex;align-items:center;gap:5px;white-space:nowrap}.overview-service-stat.has-errors{color:var(--db-danger);font-weight:650}.overview-service-arrow{color:#9ba3b2}.overview-more-services.ant-btn{display:block;margin:10px auto -5px}.overview-empty{padding-block:22px 8px}.overview-footer{display:flex;align-items:center;justify-content:center;gap:8px;margin-top:18px;color:var(--db-text-secondary);font-size:12px}.overview-footer .ant-btn{height:auto;padding-block:0}.launcher-grid{display:grid;gap:7px}.launcher-card{cursor:pointer;border-color:#e3e6ef}.launcher-card .ant-card-body{padding:10px 14px}.service-card{display:flex;align-items:center;justify-content:space-between;gap:16px;min-height:46px}.service-card .ant-typography{display:block;margin:0}.service-card h4.ant-typography{margin:0 0 1px;font-size:15px;line-height:20px}.service-info{min-width:0;flex:1}.service-info>.ant-typography{font-size:12px;line-height:16px}.service-action{display:flex;flex-direction:column;align-items:flex-end;gap:3px;white-space:nowrap}.service-action .ant-badge{font-size:11px;line-height:14px}.launcher-table .ant-table-tbody>tr{cursor:pointer}.start-script-icon{color:#8c8c8c;font-size:12px}.script-add{margin-bottom:10px}.service-config{margin-bottom:10px;margin-top:10px}.service-config .ant-collapse-content-box{padding-bottom:0!important}.service-config .ant-form-item{margin-bottom:14px}.clipboard-picker{min-width:190px}.squoosh-page{position:relative;min-height:calc(100vh - 48px);margin:clamp(-20px,-3.5vw,-40px);padding:clamp(20px,3.5vw,40px);color:#172033}.squoosh-page.is-file-dragging{box-shadow:inset 0 0 0 3px #7667e8}.squoosh-page.is-file-dragging:after{position:absolute;z-index:20;top:12px;right:12px;bottom:12px;left:12px;display:grid;place-items:center;border:2px dashed #7667e8;border-radius:12px;background:#f8f7ffc7;color:#5b4cc4;content:"Drop image to compress";font-size:20px;font-weight:700;pointer-events:none}.squoosh-header{display:flex;align-items:center;justify-content:space-between;gap:20px;padding-bottom:20px;border-bottom:1px solid #e4e7ef}.squoosh-header .ant-typography{margin:0;color:inherit}.squoosh-header>div>.ant-typography:first-child,.settings-heading>.ant-typography:first-child{color:var(--db-brand);font-size:11px;font-weight:750;letter-spacing:.12em}.squoosh-header h2.ant-typography{margin-top:4px;font-size:25px}.squoosh-studio{display:grid;grid-template-columns:minmax(0,1fr) 380px;margin-top:16px;border:1px solid #e1e5ed;border-radius:10px;overflow:hidden;background:#fff;box-shadow:0 12px 32px #1f2a4412}.squoosh-preview-area{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));min-width:0;background:#fbfcfe}.preview-pane{display:grid;grid-template-rows:auto minmax(0,1fr);min-width:0;min-height:570px}.preview-pane+.preview-pane{border-left:1px solid #e1e5ed}.preview-pane>header{display:flex;justify-content:space-between;align-items:center;gap:12px;min-height:58px;padding:0 16px;border-bottom:1px solid #e1e5ed;background:#fff}.preview-pane>header>div{display:grid;gap:1px;min-width:0}.preview-pane>header .ant-typography{color:#27344c;font-weight:650}.preview-pane>header span{overflow:hidden;color:var(--db-text-secondary);font-size:12px;text-overflow:ellipsis;white-space:nowrap}.preview-canvas{position:relative;display:grid;min-width:0;min-height:0;place-items:center;padding:22px;background-color:#f3f5f9;background-image:linear-gradient(45deg,#e9edf4 25%,transparent 25%),linear-gradient(-45deg,#e9edf4 25%,transparent 25%),linear-gradient(45deg,transparent 75%,#e9edf4 75%),linear-gradient(-45deg,transparent 75%,#e9edf4 75%);background-position:0 0,0 12px,12px -12px,-12px 0;background-size:24px 24px}.image-dropzone{width:100%;max-width:420px}.image-dropzone.ant-upload-wrapper .ant-upload-drag{border-color:#cfd6e4;background:#ffffffe0}.image-dropzone.ant-upload-wrapper .ant-upload-drag:hover{border-color:#7667e8}.image-dropzone .ant-upload{padding:76px 18px!important}.image-dropzone .ant-upload-drag-icon .anticon{color:var(--db-brand)}.image-dropzone .ant-upload-text{color:#27344c!important}.image-dropzone .ant-upload-hint{color:var(--db-text-secondary)!important}.image-panel{display:flex;align-items:center;justify-content:center;width:100%;height:100%;min-width:0;min-height:0}.image-panel img{display:block;width:auto;max-width:100%;max-height:min(65vh,650px);object-fit:contain;border-radius:5px;box-shadow:0 10px 30px #00000052}.image-panel-meta{display:grid;gap:3px;min-width:0;text-align:center}.image-panel-meta .ant-typography{min-width:0;color:#46516a}.squoosh-settings{overflow-y:auto;padding:22px 20px;background:#fff}.settings-heading{margin-bottom:21px;padding-bottom:17px;border-bottom:1px solid #e7eaf0}.settings-heading .ant-typography{margin:0;color:#27344c}.settings-heading h4.ant-typography{margin-top:5px}.settings-heading .ant-typography-secondary{margin-top:4px;color:var(--db-text-secondary);font-size:13px}.option-row,.option-switch,.option-select{display:flex;justify-content:space-between;align-items:center;gap:16px}.option-row{margin-bottom:4px}.option-row .ant-typography,.option-switch .ant-typography,.option-select .ant-typography{color:#27344c}.option-row .ant-typography-secondary,.option-switch .ant-typography-secondary,.option-select .ant-typography-secondary{color:var(--db-text-secondary);font-size:12px}.option-switch{padding:15px 0;border-top:1px solid #e7eaf0}.option-select{padding:14px 0;border-top:1px solid #e7eaf0}.option-select .ant-select,.option-select .ant-input-number{flex:0 0 170px;width:170px}.advanced-options{margin:6px -12px 16px}.advanced-options .ant-collapse-header,.advanced-options .ant-collapse-content{color:#46516a!important}.advanced-options .ant-collapse-content{background:transparent}.advanced-options .ant-collapse-content-box{padding-top:0!important}.image-loading{display:grid;min-height:330px;place-items:center}.image-loading .ant-spin-text{color:#46516a}.preview-pane>header button.ant-btn.ant-btn-color-primary{min-width:116px;border-color:var(--db-primary)!important;background:var(--db-primary)!important;color:#fff!important;font-weight:650;text-shadow:none}.preview-pane>header button.ant-btn.ant-btn-color-primary>span,.preview-pane>header button.ant-btn.ant-btn-color-primary .anticon{color:#fff!important}.preview-pane>header button.ant-btn.ant-btn-color-primary:hover{border-color:var(--db-primary-hover)!important;background:var(--db-primary-hover)!important;color:#fff!important}.compression-saving{position:absolute;bottom:24px;left:50%;z-index:1;margin:0;padding:9px 12px;border-radius:4px;background:#fff7e6;color:#ad6800;font-weight:600;text-align:center;transform:translate(-50%);white-space:nowrap}.compression-saving.is-saving{background:#f6ffed;color:#389e0d}.clipboard-tabs{margin:-12px 0 16px}.clipboard-tabs .ant-tabs-nav{margin-bottom:0}.clipboard-list{display:grid;gap:8px}.clipboard-item .ant-card-body{position:relative;display:block;padding:12px 14px}.clipboard-item .ant-card-body>div{width:100%;min-width:0}.clipboard-actions{position:absolute;top:8px;right:8px;display:flex}.clipboard-item pre{width:100%;max-height:160px;overflow:auto;margin:5px 0 0;white-space:pre-wrap;overflow-wrap:anywhere;font:12px/1.5 ui-monospace,SFMono-Regular,Menlo,monospace}.clipboard-original{display:flex;gap:12px;margin-top:8px;font-size:12px}.port-manual-query{margin:-12px 0 16px}.port-query-result{margin-top:12px}.group-task-list{display:grid;gap:8px}.group-task-header{display:flex;align-items:center;justify-content:space-between;gap:16px;margin-bottom:16px}.group-task-empty{margin:16px 0}.group-task-card{display:flex;align-items:center;justify-content:space-between;gap:16px}.group-task-card>div:first-child{display:grid;gap:2px}.group-task-card .ant-space{flex-wrap:nowrap}.group-task-card .ant-btn{width:72px}.group-task-selector{display:grid;gap:8px;width:100%}.group-task-selector .ant-card-body{padding:10px 14px}.group-task-projects{display:grid;gap:8px}.settings-page{width:100%;max-width:none}.settings-page>.ant-typography{margin:0}.settings-page-header{display:flex;align-items:center;justify-content:space-between;gap:16px}.settings-page-header .ant-typography{margin:0}.settings-page-header>.ant-btn{min-width:96px}.settings-card{width:100%;margin-top:20px;border-radius:14px;border:1px solid #e4e8f1;box-shadow:0 2px 12px #1f2a440d}.settings-card h4.ant-typography{margin:0}.settings-icon-wrap{display:flex;align-items:center;justify-content:center;width:40px;height:40px;flex-shrink:0;border-radius:10px;background:linear-gradient(135deg,#ece9fc,#ddd6fe)}.settings-icon{color:var(--db-brand);font-size:18px}.settings-title{display:flex;align-items:center;gap:14px;margin-bottom:24px;padding-bottom:20px;border-bottom:1px solid #eef0f6}.settings-title .ant-typography{margin:0}.settings-title .ant-typography-secondary{font-size:13px;margin-top:2px}.token-settings-form{display:grid;gap:0}.token-row{display:grid;grid-template-columns:200px 1fr;align-items:center;gap:20px;padding:16px 18px;margin:0 -6px;border-radius:10px;border:1px solid transparent;transition:background .18s,border-color .18s}.token-row:hover{background:#f8f9fc;border-color:#eef0f6}.token-row+.token-row{margin-top:2px}.token-row.is-configured{background:#fafbfe}.token-row-info{display:grid;gap:2px;min-width:0}.token-row-name-line{display:flex;align-items:center;gap:8px}.token-row-name{font-size:14px;white-space:nowrap}.token-row-hint{font-size:12px;line-height:1.4}.token-row-tag.ant-tag{margin:0;font-size:11px;line-height:18px;padding-inline:6px;border-radius:4px}.token-row .ant-form-item{margin:0;min-width:0}.token-row .ant-input,.token-row .ant-input-password{border-radius:8px}.script-header{display:flex;align-items:center;gap:16px}.script-header .ant-divider{flex:1;min-width:0;margin:16px 0}.script-header>.ant-btn{flex-shrink:0}.script-editor{margin-bottom:10px}.script-fields{display:grid;grid-template-columns:1fr 1.5fr;gap:12px}.script-fields .ant-form-item{margin-bottom:12px}.log-output{min-height:360px;max-height:58vh;overflow:auto;margin:0;padding:12px 0;border-radius:4px;background:#111827;color:#d1fae5;font:12px/1.55 ui-monospace,SFMono-Regular,Menlo,monospace}.log-line{min-height:19px}.log-line:hover{background:#ffffff0a}.log-line code{padding:0 15px;overflow-wrap:anywhere;color:inherit;white-space:pre-wrap;font:inherit}.log-link{color:#7dd3fc;text-decoration:underline;text-underline-offset:2px}.log-link:hover{color:#bae6fd}.ansi-black{color:#475569}.ansi-red,.log-error{color:#fb7185}.ansi-green,.log-success{color:#86efac}.ansi-yellow,.log-warning{color:#fcd34d}.ansi-blue{color:#93c5fd}.ansi-magenta{color:#f0abfc}.ansi-cyan{color:#67e8f9}.ansi-gray{color:#94a3b8}.ansi-white{color:#f8fafc}@media(max-width:1100px){.squoosh-studio{grid-template-columns:1fr}.squoosh-settings{border-top:1px solid #e1e5ed}.preview-pane{min-height:440px}.overview-metrics{grid-template-columns:repeat(2,minmax(0,1fr))}.overview-grid,.overview-content-grid{grid-template-columns:1fr}}@media(max-width:900px){.overview-hero{align-items:flex-start;flex-direction:column;min-height:0}.overview-hero-mark{position:absolute;right:34px;bottom:30px;width:88px;height:88px;opacity:.55;font-size:34px}.overview-actions,.overview-hero-actions{width:100%}}@media(max-width:650px){.page{padding:16px 16px 28px}.service-card,.page-header{align-items:flex-start;flex-direction:column}.page-header{gap:16px;margin-bottom:22px}.page-header>:last-child,.page-header>:last-child>.ant-space{max-width:100%;flex-wrap:wrap}.script-fields{grid-template-columns:1fr}.token-row{grid-template-columns:1fr;gap:10px;padding:14px 12px}.overview-hero{padding:28px 22px;border-radius:16px}.overview-hero h1.ant-typography,.overview-hero h2.ant-typography{font-size:31px}.overview-hero .ant-btn{flex:1}.overview-metrics{gap:10px;margin-top:12px}.overview-metric-card .ant-card-body{gap:10px;padding:15px}.overview-metric-icon{width:36px;height:36px;border-radius:10px}.overview-metric-value{font-size:21px}.overview-panel .ant-card-head,.overview-panel .ant-card-body{padding-inline:16px}.overview-quick-grid,.overview-shortcuts{grid-template-columns:1fr}.overview-shortcuts-section,.overview-setup-card .ant-card-body,.overview-health-card .ant-card-body{padding:17px}.overview-service-row{align-items:flex-start;flex-wrap:wrap;padding:12px 8px}.overview-service-primary{flex-basis:100%}.overview-service-stats{width:100%;flex-wrap:wrap;gap:9px 14px;padding-left:0}.overview-service-arrow{margin-left:auto}.overview-footer{flex-wrap:wrap}.squoosh-page{min-height:calc(100vh - 40px);margin:-12px -16px -28px;padding:18px 16px 28px}.squoosh-header{align-items:flex-start;flex-direction:column}.squoosh-preview-area{grid-template-columns:1fr}.preview-pane{min-height:360px}.preview-pane+.preview-pane{border-top:1px solid #e1e5ed;border-left:0}.preview-canvas{min-height:300px}}@media(max-width:460px){.overview-metrics,.todo-stats-grid{grid-template-columns:1fr!important}.overview-hero .ant-btn{flex-basis:100%}}@media(hover:none),(pointer:coarse){.overview-quick-card{min-height:72px}.sidebar .ant-menu-item{min-height:44px;line-height:44px}}:where(button,a,[role=button],.ant-menu-item):focus-visible{outline:3px solid rgba(101,85,232,.34);outline-offset:2px}@media(prefers-reduced-motion:reduce){*,*:before,*:after{scroll-behavior:auto!important;animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}}.standalone-log-container{display:flex;flex-direction:column;height:100vh;background:#111827;overflow:hidden}.standalone-log-header{display:flex;justify-content:space-between;align-items:center;padding:12px 24px;background:#1f2937;border-bottom:1px solid #374151;color:#f3f4f6;flex-shrink:0}.standalone-log-body{flex:1;min-height:0;display:flex;flex-direction:column;background:#111827}.standalone-log-body .log-output{flex:1;min-height:0;max-height:none!important;border-radius:0!important;margin:0!important;padding:16px 0}.page.is-static-page{padding:0!important;overflow:hidden}.static-page-container{width:100%;height:100%;overflow:hidden;background:#fff}.static-page-iframe{width:100%;height:100%;border:none;display:block}.sidebar-bottom-inner{display:flex;align-items:center;gap:4px}.sidebar-bottom-inner>nav{flex:1;min-width:0}.sidebar-bottom-inner .ant-menu{flex:1;min-width:0}.sidebar-update-button{width:36px;height:36px;flex:none;color:var(--db-sidebar-muted);font-size:17px}.sidebar-update-button:hover{color:#d9d4ff!important;background:#ffffff14!important}.sidebar-update-button.has-update{color:#ffd166;background:#ffd1661a}.sidebar-update-button.has-update:hover{color:#ffe099!important;background:#ffd16629!important}:root[data-theme=light] .sidebar-update-button:hover{color:var(--db-primary)!important;background:var(--db-brand-soft)!important}:root[data-theme=light] .sidebar-update-button.has-update{color:#b26a00;background:#fff4d6}:root[data-theme=light] .sidebar-update-button.has-update:hover{color:#925600!important;background:#ffedbd!important}.changelog-title{display:flex;align-items:center;gap:10px;font-size:18px;font-weight:650;line-height:1.3}.changelog-bulb{display:grid;width:32px;height:32px;border-radius:9px;background:var(--db-brand-soft);color:var(--db-primary);place-items:center}.changelog-bulb.has-update{background:#fff4d6;color:#b26a00}.changelog-loading{display:grid;min-height:220px;place-items:center}.changelog-version-row{display:flex;align-items:center;gap:28px;margin-top:20px;padding:16px 18px;border:1px solid var(--db-border);border-radius:10px;background:var(--db-surface-subtle)}.changelog-version-row>div{display:grid;gap:2px}.changelog-version-row .ant-tag{margin-inline-start:auto;margin-inline-end:0}.changelog-source-alert{margin-top:14px}.changelog-release-list{max-height:min(52vh,520px);overflow-y:auto;margin-top:18px;padding-right:6px}.changelog-release{padding:0 2px 20px}.changelog-release+.changelog-release{padding-top:20px;border-top:1px solid var(--db-border)}.changelog-release-heading{display:flex;align-items:center;justify-content:space-between;gap:18px;margin-bottom:8px}.changelog-release-title{display:flex;align-items:center;gap:9px;min-width:0}.changelog-release-version.ant-tag{flex:none;margin:0;border-color:#d8d3ff;border-radius:6px;background:var(--db-brand-soft);color:var(--db-brand-strong);font-weight:650}.changelog-release-heading h4.ant-typography{min-width:0;margin:0;font-size:16px;font-weight:650;line-height:1.4}.changelog-release-heading>.ant-typography{flex:none;font-size:12px}.changelog-release-notes{display:block;color:var(--db-text-secondary);line-height:1.65;white-space:pre-wrap}@media(max-width:650px){.changelog-version-row{align-items:flex-start;flex-wrap:wrap;gap:14px 28px}.changelog-version-row .ant-tag{margin-inline-start:0}}.sidebar-error-btn{color:#a6adb4!important;border:none!important;background:transparent!important;display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;border-radius:6px;flex-shrink:0;transition:all .2s}.sidebar-error-btn:hover{color:#ff4d4f!important;background:#ff4d4f26!important}.sidebar-error-btn.is-active{color:#fff!important;background:#ff4d4f!important}.clipboard-page{width:100%;max-width:1440px;margin:0 auto;padding-bottom:40px}.clipboard-controls,.clipboard-settings{display:flex;flex-direction:column;align-items:flex-end}.clipboard-controls{gap:8px}.clipboard-settings{gap:6px}.clipboard-setting-row{display:flex;align-items:center;gap:8px}.clipboard-setting-label.ant-typography{color:var(--db-text-secondary);font-size:12px}.clipboard-deduplicate-select{width:160px}.clipboard-disabled-card{margin-top:24px;padding-block:48px;border-color:var(--db-border);border-radius:var(--db-radius);text-align:center;box-shadow:var(--db-shadow-sm)}.clipboard-disabled-copy{margin-top:8px}.clipboard-disabled-title.ant-typography{display:block;color:var(--db-text);font-size:16px}.clipboard-item{border-color:var(--db-border);border-radius:var(--db-radius);box-shadow:0 3px 12px #1f2a440a}.clipboard-item-meta{display:flex;align-items:center;flex-wrap:wrap;gap:8px}.clipboard-image-wrap,.clipboard-preview{margin-top:8px}.clipboard-image{display:block;max-width:100%;max-height:300px;cursor:pointer;border:1px solid var(--db-border);border-radius:8px}.clipboard-page a{color:var(--db-brand)}.clipboard-page a:hover{color:var(--db-brand-strong)}@media(max-width:650px){.clipboard-controls,.clipboard-settings{width:100%;align-items:stretch}.clipboard-controls>.ant-space{width:100%;flex-wrap:wrap}.clipboard-picker,.clipboard-deduplicate-select{flex:1;min-width:0;width:auto}.clipboard-setting-row{justify-content:space-between}}.launcher-loading{display:grid;min-height:180px;place-items:center}.launcher-service-link{color:var(--db-brand);font-weight:650}.launcher-service-link:hover{color:var(--db-brand-strong)}.launcher-branch.ant-typography{margin:0}.quick-launch-bar{margin-bottom:20px;padding:14px 16px;border:1px solid var(--db-border);border-radius:var(--db-radius);background:var(--db-surface);box-shadow:var(--db-shadow-sm)}.quick-launch-label{color:var(--db-text-secondary);font-size:11px;font-weight:750;letter-spacing:.08em;text-transform:uppercase}.repo-icon-button.ant-btn{display:inline-flex;align-items:center;justify-content:center;width:24px;min-width:24px;height:24px;padding:0;border-radius:6px}.repo-generic-icon{color:var(--db-brand)}.script-running-filter{display:inline-flex;align-items:center;gap:6px;cursor:pointer;-webkit-user-select:none;user-select:none}.script-running-filter-label.ant-typography{font-size:13px}.service-modal-footer{display:flex;align-items:center;justify-content:space-between}.standalone-log-invalid{display:grid;color:#ef4444;place-items:center}.standalone-log-title-row,.standalone-log-actions{display:flex;align-items:center}.standalone-log-title-row{gap:16px}.standalone-log-actions{gap:12px}.standalone-log-title.ant-typography{margin:0;color:#f3f4f6;font-size:16px}.standalone-log-separator,.standalone-log-close.ant-btn{color:#9ca3af}.standalone-log-separator{font-weight:400}@media(max-width:650px){.quick-launch-bar .ant-space{align-items:stretch}.quick-launch-bar .ant-btn{flex:1}.standalone-log-header{align-items:flex-start;gap:10px}.standalone-log-actions{flex-wrap:wrap;justify-content:flex-end}}.port-diagnostic-page{width:100%;max-width:1440px;margin:0 auto;padding-bottom:40px}.port-diagnostic-page .port-manual-query{margin-bottom:18px;border-color:var(--db-border);border-radius:var(--db-radius);background:var(--db-surface);box-shadow:var(--db-shadow-sm)}.port-diagnostic-page .port-manual-query .ant-card-body{padding:16px 18px}.port-diagnostic-page .port-query-result{margin-top:14px;padding-top:14px;border-top:1px solid var(--db-border)}.port-diagnostic-table .ant-table-container{overflow:hidden;border:1px solid var(--db-border);border-radius:var(--db-radius);box-shadow:var(--db-shadow-sm)}.port-diagnostic-table .ant-table-thead>tr>th{background:var(--db-surface-subtle)}@media(max-width:650px){.port-diagnostic-page .port-manual-query .ant-space{width:100%}.port-diagnostic-page .port-manual-query .ant-input-number{flex:1}}.settings-page{max-width:1440px;margin-inline:auto;padding-bottom:40px}.settings-card-spaced{margin-bottom:20px}.settings-app-select{width:min(100%,260px)}.settings-form-item-flush.ant-form-item{margin-bottom:0}.settings-appearance-row{display:flex;align-items:center;justify-content:space-between;gap:24px;padding:18px 20px;border:1px solid var(--db-border);border-radius:10px;background:var(--db-surface-subtle)}.settings-appearance-hint{display:block;margin-top:3px}.settings-appearance-row .ant-segmented{flex:none}.settings-data-path{display:flex;align-items:center;gap:12px;min-width:0}.settings-data-path .ant-input{min-width:0;flex:1;background:var(--db-surface-subtle)}.settings-data-usage,.settings-backup-actions{display:flex;align-items:center;gap:10px;min-width:0}.settings-data-usage>.anticon{color:var(--db-primary);font-size:16px}.settings-data-usage .ant-btn-link{margin-left:auto}.settings-backup-actions{flex-wrap:wrap}.settings-backup-input{display:none}.settings-import-confirm{margin-top:12px}.settings-import-confirm .ant-typography{margin-bottom:8px}.settings-title-actions{margin-bottom:12px;padding-bottom:0;border-bottom:0}.settings-title-copy{min-width:0;flex:1}.settings-page-modal-form{margin-top:16px}.settings-page .ant-table-wrapper{overflow:hidden;border:1px solid var(--db-border);border-radius:10px}.settings-page .ant-table-thead>tr>th{background:var(--db-surface-subtle)}.settings-action-column-title{text-align:center}.settings-page a,.settings-page .ant-btn-link:not(.ant-btn-dangerous){color:var(--db-brand)}.settings-page a:hover,.settings-page .ant-btn-link:not(.ant-btn-dangerous):hover{color:var(--db-brand-strong)}@media(max-width:650px){.settings-appearance-row{align-items:stretch;flex-direction:column}.settings-appearance-row .ant-segmented{width:100%}.settings-appearance-row .ant-segmented-item{flex:1}.settings-data-path{align-items:stretch;flex-direction:column}.settings-data-usage{flex-wrap:wrap}.settings-data-usage .ant-btn-link{margin-left:0}.settings-backup-actions .ant-btn{flex:1 1 150px}.settings-app-select{width:100%}.settings-title-actions{align-items:flex-start;flex-wrap:wrap}.settings-title-actions>.ant-btn{width:100%}}.pr-review-page{width:100%;max-width:1440px;margin:0 auto;padding-bottom:40px}.pr-review-page a,.pr-review-page .ant-btn-link{color:var(--db-brand)}.pr-review-input-card,.pr-review-list-card,.pr-review-info-card,.pr-review-findings-card,.pr-review-metric-card,.pr-review-loading-card{border:1px solid var(--db-border);border-radius:var(--db-radius);box-shadow:var(--db-shadow-sm)}.pr-review-input-card{background:linear-gradient(135deg,var(--db-brand-soft),#fff 62%)}.pr-review-empty{padding:24px 0}.pr-review-form-label{display:flex;width:100%;align-items:center;justify-content:space-between;gap:12px}.pr-review-demo-action{height:auto;padding:0;font-size:12px}.pr-review-inline-action{height:auto;padding:0}.pr-review-inline-divider{margin:0 2px}.pr-review-list{display:grid;gap:10px}.pr-review-list-item{border:1px solid var(--db-border);border-radius:10px;background:var(--db-surface);transition:border-color .18s ease,box-shadow .18s ease,background .18s ease}.pr-review-list-item:hover{border-color:#6555e87a}.pr-review-list-item.is-selected{border-color:var(--db-brand);background:var(--db-brand-soft);box-shadow:0 0 0 2px #6555e81a}.pr-review-list-row,.pr-review-list-primary,.pr-review-list-toolbar,.pr-review-file-header{display:flex;align-items:center}.pr-review-list-row{justify-content:space-between;flex-wrap:wrap;gap:12px}.pr-review-list-primary{min-width:0;flex:1;gap:12px}.pr-review-list-copy{min-width:0;flex:1}.pr-review-list-title{font-size:14px}.pr-review-list-meta{display:flex;align-items:center;flex-wrap:wrap;gap:6px;margin-top:6px;color:var(--db-text-secondary);font-size:12px}.pr-review-list-separator{color:var(--db-border)}.pr-review-list-toolbar{justify-content:space-between;gap:16px;margin-bottom:16px;padding-bottom:12px;border-bottom:1px solid var(--db-border)}.pr-review-list-card{margin-top:16px}.pr-review-selection-count{font-size:13px}.pr-review-loading-card{padding:40px 0;text-align:center}.pr-review-loading-icon{color:var(--db-brand);font-size:32px}.pr-review-results{width:100%;padding-bottom:24px}.pr-review-branch-tag.ant-tag{margin:0;border-color:#6555e83d;background:var(--db-brand-soft);color:var(--db-brand-strong)}.pr-review-detail-label{font-size:12px}.pr-review-metric-card{height:100%;text-align:center}.pr-review-metric-card .ant-statistic-content{color:var(--db-brand-strong)}.pr-review-metric-card.is-muted .ant-statistic-content{color:var(--db-text-secondary)}.pr-review-success{color:var(--db-success);font-size:16px}.pr-review-file-header{width:92%;justify-content:space-between;flex-wrap:wrap;gap:8px}.pr-review-suggestion-badge .ant-badge-count{background:var(--db-brand)}.pr-review-code{margin:4px 0 0;padding:7px 10px;overflow-x:auto;border:1px solid var(--db-border);border-radius:6px;background:var(--db-surface-subtle);color:var(--db-text);font-size:12px}.pr-review-issue-copy{width:100%}.pr-review-ignored-list{max-height:200px;overflow-y:auto}.pr-review-ignored-tag{color:var(--db-text-secondary)}.pr-review-comment-body{margin-top:12px}.pr-review-comment-context{margin-bottom:12px!important;font-size:13px}@media(max-width:650px){.pr-review-form-label,.pr-review-list-toolbar{align-items:flex-start;flex-direction:column}.pr-review-list-toolbar .ant-btn{width:100%}}.jira-filters-page{width:100%;max-width:1440px;margin:0 auto;padding-bottom:40px}.jira-filters-page a,.jira-filter-modal a{color:var(--db-brand)}.jira-filter-tabs-bar{display:flex;width:100%;min-width:0;align-items:center;justify-content:space-between;gap:16px;margin-bottom:16px;padding:4px 14px 0;border:1px solid var(--db-border);border-radius:var(--db-radius);background:var(--db-surface);box-shadow:var(--db-shadow-sm)}.jira-filter-tabs{min-width:0;flex:1;overflow:hidden}.jira-filter-tabs .ant-tabs-nav{margin-bottom:0}.jira-filter-tabs .ant-tabs-tab-active .ant-tabs-tab-btn,.jira-filter-tabs .ant-tabs-tab:hover{color:var(--db-brand)}.jira-filter-tabs .ant-tabs-ink-bar{background:var(--db-brand)}.jira-filter-refresh{flex-shrink:0}.jira-filters-table{overflow:hidden;border:1px solid var(--db-border);border-radius:var(--db-radius);background:var(--db-surface);box-shadow:var(--db-shadow-sm)}.jira-filters-table .ant-table-thead>tr>th{background:var(--db-surface-subtle);color:var(--db-text-secondary);font-size:12px;letter-spacing:.02em}.jira-issue-summary{display:flex;min-width:0;align-items:center;flex-wrap:nowrap;gap:8px}.jira-issue-link{color:var(--db-brand);font-weight:550;overflow-wrap:break-word}.jira-todo-complete{color:var(--db-success)}.jira-todo-pending{color:var(--db-warning)}.jira-filter-loading,.jira-filter-error,.jira-filter-empty{padding:64px 0;text-align:center}.jira-filter-modal .ant-table{margin-top:16px}.jira-filter-external-icon{color:var(--db-brand);cursor:pointer;font-size:11px}@media(max-width:650px){.jira-filter-tabs-bar{align-items:stretch;flex-direction:column;padding:4px 12px 12px}.jira-filter-refresh{width:100%}}.todo-page,.todo-archive-page{width:100%;max-width:1320px;margin:0 auto;padding-bottom:40px}.todo-page-header{margin-bottom:24px;padding-top:2px}.todo-header-copy{max-width:720px}.todo-eyebrow{display:block;margin-bottom:5px;color:var(--db-brand)!important;font-size:11px;font-weight:750;letter-spacing:.14em}.todo-page-title{color:var(--db-text)!important;font-size:30px!important;font-weight:740!important;letter-spacing:-.025em}.todo-page-description{max-width:680px;margin-top:6px!important;font-size:13px;line-height:1.6}.todo-header-actions{display:flex;align-items:flex-end;justify-content:flex-end}.todo-header-button-group{justify-content:flex-end}.todo-header-button-group .ant-btn{min-height:36px}.todo-archive-link.ant-btn{border-color:#6555e83d;color:var(--db-brand-strong)}.todo-archive-link.ant-btn:hover{border-color:var(--db-brand);background:var(--db-brand-soft)}.todo-stats-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px;margin-bottom:18px}.todo-stat-card,.todo-quick-add-card,.todo-filter-card,.todo-item-card,.todo-archive-toolbar,.todo-archive-card{border:1px solid var(--db-border);border-radius:var(--db-radius);box-shadow:var(--db-shadow-sm)}.todo-stat-card .ant-card-body{min-height:92px;padding:15px 17px}.todo-stat-card{overflow:hidden;background:var(--db-surface);transition:border-color .18s ease,box-shadow .18s ease}.todo-stat-card:hover{border-color:#6555e83d;box-shadow:0 8px 22px #1f2a4414}.todo-stat-head,.todo-stat-rate{display:flex;align-items:center;justify-content:space-between;gap:12px}.todo-stat-label{color:var(--db-text-secondary);font-size:12px;font-weight:650;letter-spacing:.03em;text-transform:uppercase}.todo-stat-icon{display:grid;width:28px;height:28px;flex:none;border-radius:8px;background:var(--db-brand-soft);color:var(--db-brand);font-size:13px;place-items:center}.todo-stat-card.is-pending .todo-stat-icon{background:#fff5e6;color:var(--db-warning)}.todo-stat-card.is-completed .todo-stat-icon{background:#eaf7ee;color:var(--db-success)}.todo-stat-value{margin-top:5px;color:var(--db-text);font-size:25px;font-weight:720;line-height:1.15}.todo-stat-value.is-active{color:var(--db-warning)}.todo-stat-value.is-complete{color:var(--db-success)}.todo-stat-warning{display:inline-block;margin-left:7px;color:var(--db-danger);font-size:11px;font-weight:600;vertical-align:middle}.todo-stat-percentage{color:var(--db-brand-strong);font-size:15px}.todo-stat-progress{margin-top:18px}.todo-stat-progress .ant-progress-bg{background:var(--db-brand)!important}.todo-quick-add-card{margin-bottom:18px;border-color:#6555e838;background:linear-gradient(135deg,var(--db-brand-soft),#fff 68%)}.todo-quick-add-card .ant-card-body{padding:17px 18px 18px}.todo-quick-add-header{display:flex;align-items:center;gap:10px;margin-bottom:13px}.todo-quick-add-icon{display:grid;width:30px;height:30px;flex:none;border-radius:9px;background:var(--db-brand);color:#fff;font-size:13px;place-items:center}.todo-quick-add-title,.todo-quick-add-hint{display:block}.todo-quick-add-title{color:var(--db-text);font-size:13px;font-weight:700;line-height:1.35}.todo-quick-add-hint{margin-top:1px;color:var(--db-text-secondary);font-size:11px;line-height:1.4}.todo-quick-add-row{display:grid;grid-template-columns:minmax(240px,1fr) 132px 132px auto;align-items:center;gap:12px}.todo-quick-title{min-width:0}.todo-quick-select{width:130px}.todo-filter-card{margin-bottom:16px;background:var(--db-surface)}.todo-filter-card .ant-card-body{padding:13px 14px}.todo-search-input{width:210px}.todo-filter-select{width:132px}.todo-sort-select{width:138px}.todo-filter-row{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:16px}.todo-status-filter{flex:none}.todo-filter-tools{display:flex;align-items:center;justify-content:flex-end;flex-wrap:wrap;gap:8px}.todo-status-filter .ant-radio-button-wrapper{min-width:84px;text-align:center}.todo-batch-bar{display:flex;align-items:center;justify-content:space-between;gap:16px;margin-bottom:16px;padding:11px 16px;border:1px solid rgba(101,85,232,.28);border-radius:10px;background:var(--db-brand-soft)}.todo-batch-count,.todo-batch-count strong{color:var(--db-brand-strong)}.todo-table-header{display:flex;align-items:center;gap:12px;margin-bottom:7px;padding:8px 17px;border-bottom:1px solid var(--db-border);color:var(--db-text-secondary);font-size:12px}.todo-table-title{flex:1;font-weight:650}.todo-table-filter,.todo-item-meta{display:flex;width:120px;justify-content:center}.todo-table-filter{color:var(--db-text-secondary);font-size:11px;font-weight:700;letter-spacing:.02em}.todo-table-date,.todo-item-date{width:120px;text-align:center}.todo-table-actions,.todo-item-actions{width:120px;text-align:right}.todo-select-mode-icon{cursor:pointer;font-size:15px;transition:color .18s ease}.todo-list-items,.todo-archive-list{display:flex;flex-direction:column;gap:10px}.todo-item-card{overflow:hidden;background:var(--db-surface);transition:border-color .18s ease,box-shadow .18s ease,background-color .18s ease}.todo-item-card:hover{border-color:#6555e852;box-shadow:0 8px 24px #1f2a4414}.todo-archive-card{background:var(--db-surface);transition:border-color .18s ease,box-shadow .18s ease}.todo-archive-card:hover{border-color:#6555e847;box-shadow:0 8px 24px #1f2a4412}.todo-item-card.is-selected{border-color:var(--db-brand);background:linear-gradient(90deg,var(--db-brand-soft),#fff 44%);box-shadow:0 0 0 2px #6555e81c}.todo-item-card.is-completed{border-color:#e8eaf0;background:var(--db-surface-subtle)}.todo-item-card .ant-card-body,.todo-archive-card .ant-card-body{padding:14px 16px}.todo-list-row,.todo-archive-row{display:flex;align-items:center;gap:12px}.todo-item-check{display:flex;width:22px;flex:none;align-items:center;justify-content:center}.todo-item-checkbox{transform:scale(1.08)}.todo-item-copy{min-width:0;flex:1}.todo-item-title{color:var(--db-text);font-size:15px;font-weight:620;line-height:1.45;overflow-wrap:anywhere}.todo-item-card.is-completed .todo-item-title,.todo-archive-card.is-completed .todo-item-title{color:var(--db-text-secondary);text-decoration:line-through}.todo-item-description{margin-top:3px;overflow:hidden;color:var(--db-text-secondary);font-size:11px;line-height:1.5;text-overflow:ellipsis;white-space:nowrap}.todo-item-tag{max-width:100%;margin:0;overflow:hidden;text-overflow:ellipsis;vertical-align:middle}.todo-inline-icon{margin-right:4px}.todo-due-tag.ant-tag{align-items:flex-start;line-height:1.35}.todo-due-tag .todo-inline-icon{margin-top:2px}.todo-due-copy{display:inline-flex;flex-direction:column;align-items:flex-start}.todo-overdue-status{display:block;margin-top:1px;font-size:10px;font-weight:650}.todo-empty-value{font-size:12px}.todo-item-actions .ant-space{justify-content:flex-end}.todo-action-button{color:var(--db-text-secondary)}.todo-action-button.is-archive{color:#b85f09}.todo-item-card:not(:hover):not(.is-selected) .todo-item-actions{opacity:.72}.todo-select-mode-icon{color:var(--db-text-secondary)}.todo-select-mode-icon.is-active,.todo-select-mode-icon:hover,.todo-link,.todo-page a,.todo-archive-page a{color:var(--db-brand)}.todo-archive-toolbar{margin-bottom:16px;background:var(--db-surface)}.todo-archive-toolbar .ant-card-body{padding:13px 15px}.todo-archive-toolbar-row{display:flex;align-items:center;justify-content:space-between;gap:16px}.todo-archive-search{width:240px}.todo-archive-column-meta{display:flex;width:120px;justify-content:center}.todo-archive-column-date{width:140px;text-align:center}.todo-archive-column-actions{width:100px;text-align:right}.todo-loading-state{display:flex;min-height:220px;align-items:center;justify-content:center;flex-direction:column;gap:13px;border:1px dashed var(--db-border);border-radius:var(--db-radius);background:var(--db-surface);text-align:center}.todo-state-card{padding:48px 24px;border:1px dashed var(--db-border);border-radius:var(--db-radius);background:var(--db-surface)}.todo-page-footer{margin-top:24px;text-align:right}.todo-modal-form{margin-top:16px}.todo-modal-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px}.todo-modal-date{width:100%}.todo-brand-text,.todo-restore-icon{color:var(--db-brand)}.todo-title-icon{margin-right:9px}.todo-tone-icon.is-brand,.todo-tone-icon.is-purple{color:var(--db-brand)}.todo-tone-icon.is-danger{color:var(--db-danger)}.todo-tone-icon.is-warning{color:#bd7107}.todo-tone-icon.is-success{color:var(--db-success)}.todo-tone-icon.is-orange{color:#c5680a}.todo-link{font-weight:500;text-decoration:underline;text-underline-offset:2px}.todo-link.is-jira{font-weight:650}@media(max-width:900px){.todo-stats-grid{grid-template-columns:repeat(2,minmax(0,1fr))}.todo-quick-add-row{grid-template-columns:repeat(2,minmax(0,1fr)) auto}.todo-quick-title{grid-column:1 / -1}.todo-quick-select{width:100%}.todo-filter-row{align-items:stretch;flex-direction:column;gap:12px}.todo-filter-tools{display:grid;grid-template-columns:minmax(190px,1fr) repeat(3,minmax(125px,auto));justify-content:stretch}.todo-search-input,.todo-filter-select,.todo-sort-select{width:100%}.todo-table-header,.todo-archive-table-header{display:none}.todo-list-row,.todo-archive-row{align-items:flex-start;flex-wrap:wrap}.todo-list-row>.todo-item-copy{flex-basis:calc(100% - 42px)}.todo-archive-row>.todo-item-copy{flex-basis:100%}.todo-item-meta,.todo-archive-column-meta,.todo-item-date,.todo-archive-column-date{display:flex;width:auto;flex:1 1 150px;align-items:center;justify-content:flex-start;gap:7px;text-align:left}.todo-item-meta:before,.todo-item-date:before,.todo-archive-column-meta:before,.todo-archive-column-date:before{flex:none;color:var(--db-text-secondary);content:attr(data-label);font-size:10px;font-weight:700;letter-spacing:.05em;text-transform:uppercase}.todo-item-actions,.todo-archive-column-actions{width:auto;margin-left:auto;text-align:right}}@media(max-width:650px){.todo-page,.todo-archive-page{padding-bottom:24px}.todo-page-title{font-size:27px!important}.todo-header-actions{width:100%;align-items:stretch}.todo-header-button-group,.todo-archive-header-actions{display:flex;width:100%}.todo-header-button-group .ant-space-item,.todo-archive-header-actions .ant-space-item{display:flex;flex:1 1 140px}.todo-header-button-group .ant-btn,.todo-archive-header-actions .ant-btn{width:100%}.todo-stat-card .ant-card-body{min-height:88px;padding:14px 15px}.todo-quick-add-card .ant-card-body{padding:15px}.todo-quick-add-row{grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}.todo-quick-add-row>.ant-btn{grid-column:1 / -1;width:100%}.todo-quick-add-row .ant-select{width:100%!important}.todo-status-filter{display:flex;width:100%;overflow-x:auto}.todo-status-filter .ant-radio-button-wrapper{min-width:max-content;flex:1;padding-inline:12px;white-space:nowrap}.todo-filter-tools{grid-template-columns:repeat(2,minmax(0,1fr))}.todo-search-input,.todo-sort-select{grid-column:1 / -1}.todo-batch-bar,.todo-archive-toolbar-row{align-items:flex-start;flex-direction:column}.todo-batch-bar>.ant-space{width:100%}.todo-search-input,.todo-filter-select,.todo-sort-select,.todo-archive-search{width:100%}.todo-item-card .ant-card-body,.todo-archive-card .ant-card-body{padding:13px 14px}.todo-item-meta,.todo-archive-column-meta{flex:1 1 calc(50% - 6px)}.todo-item-date,.todo-archive-column-date{flex-basis:100%}.todo-item-actions,.todo-archive-column-actions{width:100%;padding-top:2px;border-top:1px solid var(--db-border)}.todo-item-actions .ant-space,.todo-archive-column-actions .ant-space{width:100%;justify-content:flex-end}.todo-state-card{padding:38px 16px}.todo-page-footer .ant-btn{width:100%}.todo-modal-grid{grid-template-columns:1fr}}.error-logs-page{width:100%}.error-logs-toolbar{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;margin-bottom:16px}.error-logs-search{width:min(280px,100%)}.error-logs-search-icon{color:var(--db-text-secondary)}.error-logs-list{display:grid;gap:10px}.error-log-item{overflow:hidden;border-color:var(--db-border);border-left:4px solid var(--db-danger);border-radius:var(--db-radius);box-shadow:var(--db-shadow-sm)}.error-log-summary{display:flex;align-items:flex-start;justify-content:space-between;gap:12px}.error-log-copy{min-width:0;flex:1}.error-log-meta{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-bottom:4px}.error-log-tag{margin:0}.error-log-timestamp{font-size:12px}.error-log-message{display:block;color:var(--db-text);font-size:14px;overflow-wrap:anywhere}.error-log-actions{flex-shrink:0}.error-log-copy-success,.error-logs-empty-icon{color:var(--db-success)}.error-log-details{margin-top:10px}.error-log-output{min-height:auto;max-height:360px;margin:0;padding:10px;border-radius:8px;font-size:12px}.error-log-output code{color:#fca5a5}.error-logs-empty-card{margin-top:16px;padding-block:48px;border-color:var(--db-border);border-radius:var(--db-radius);text-align:center;box-shadow:var(--db-shadow-sm)}.error-logs-empty-icon{font-size:48px}.error-logs-empty-copy{margin-top:8px}.error-logs-empty-title{display:block;color:var(--db-text);font-size:16px}@media(max-width:650px){.error-logs-toolbar{align-items:stretch}.error-logs-search{width:100%}.error-log-summary{flex-direction:column}.error-log-actions{align-self:flex-end}}.postman-container{display:flex;height:100vh;width:100%;background-color:var(--db-bg);color:var(--db-text);font-family:Inter,ui-sans-serif,system-ui,-apple-system,PingFang SC,sans-serif;overflow:hidden;margin:0}.postman-sidebar{width:290px;min-width:290px;max-width:320px;border-right:1px solid var(--db-border);display:flex;flex-direction:column;background-color:var(--db-surface)}.sidebar-header{padding:14px 16px;border-bottom:1px solid var(--db-border);background-color:var(--db-surface);display:flex;flex-direction:column;gap:10px}.sidebar-title-row{display:flex;justify-content:space-between;align-items:center}.sidebar-toolbar{display:flex;gap:6px;align-items:center}.sidebar-search-row{display:flex;width:100%}.sidebar-content{flex:1;overflow-y:auto;padding:8px 0}.collection-group{margin-bottom:2px}.collection-header{display:flex;justify-content:space-between;align-items:center;padding:6px 12px 6px 16px;cursor:pointer;-webkit-user-select:none;user-select:none;transition:background-color .15s;min-height:36px}.collection-header:hover{background-color:var(--db-surface-subtle)}.collection-title-wrap{display:flex;align-items:center;min-width:0;flex:1;margin-right:8px}.collection-name{min-width:0;flex:0 1 auto}.collection-count{font-size:11px;margin-left:6px;flex-shrink:0}.tree-node-row{display:flex;align-items:center;padding:6px 12px 6px 16px;cursor:pointer;-webkit-user-select:none;user-select:none;font-size:13px;transition:background-color .15s;position:relative;border-left:3px solid transparent;min-height:34px}.tree-node-row:hover{background-color:var(--db-surface-subtle)}.tree-node-row.is-active{background-color:var(--db-brand-soft);border-left-color:var(--db-brand);font-weight:600}.tree-node-row .node-title{flex:1;min-width:0;color:var(--db-text)}.tree-node-row .node-actions,.collection-header .collection-actions{display:flex;align-items:center;flex-shrink:0;opacity:0;visibility:hidden;transition:opacity .15s ease-in-out,visibility .15s ease-in-out}.tree-node-row:hover .node-actions,.collection-header:hover .collection-actions{opacity:1;visibility:visible}.node-icon{margin-right:8px;font-size:14px}.postman-workspace{flex:1;display:flex;flex-direction:column;overflow:hidden;background-color:var(--db-bg)}.request-editor{padding:18px 24px;border-bottom:1px solid var(--db-border);display:flex;flex-direction:column;gap:12px;background-color:var(--db-surface);box-shadow:0 2px 8px #1f2a4408}.request-editor-empty{display:flex;align-items:center;justify-content:center;height:240px;color:var(--db-text-secondary)}.request-name-input{border:none!important;background:transparent!important;box-shadow:none!important;font-size:17px!important;font-weight:700!important;color:var(--db-text)!important;padding-left:0!important;margin-bottom:2px}.request-name-input:focus-visible{border-radius:6px!important;box-shadow:0 0 0 3px #6555e83d!important}.request-url-row{display:flex;gap:8px;align-items:center}.url-input{flex:1;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,monospace}.method-select .ant-select-selector{font-weight:700}.request-tabs-wrap{margin-top:4px}.tab-pane-content{padding:8px 0}.response-panel{flex:1;display:flex;flex-direction:column;overflow:hidden;background-color:var(--db-surface);margin:16px 24px 24px;border:1px solid var(--db-border);border-radius:10px;box-shadow:0 6px 18px #1f2a440d}.response-panel.empty-state,.response-panel.loading-state{align-items:center;justify-content:center}.loading-spinner{display:flex;flex-direction:column;align-items:center}.response-header-bar{display:flex;justify-content:space-between;align-items:center;padding:12px 20px;border-bottom:1px solid var(--db-border);background-color:var(--db-surface-subtle)}.response-status-group{display:flex;align-items:center;gap:16px}.response-meta-item{font-size:13px;color:var(--db-text-secondary);display:flex;align-items:center;gap:4px;font-weight:500}.response-body-wrap{flex:1;overflow:hidden;display:flex;flex-direction:column;padding:0 20px 16px;background-color:var(--db-surface)}.response-body-wrap .ant-tabs{height:100%;display:flex;flex-direction:column}.response-body-wrap .ant-tabs-content-holder{flex:1;overflow-y:auto}.code-viewer{background-color:#1e1e1e;border:1px solid #333333;border-radius:6px;padding:14px;margin:0;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,monospace;font-size:13px;color:#c4b5fd;overflow-x:auto;white-space:pre-wrap;word-break:break-all}.postman-loading{display:grid;min-height:360px;place-items:center}.postman-sidebar-title.ant-typography{color:var(--db-text);font-size:15px}.sidebar-toolbar .postman-toolbar-action{flex:1}.postman-empty{margin-top:40px}.postman-empty-copy{margin-top:4px;color:var(--db-text-secondary);font-size:12px;line-height:1.6}.postman-empty-emphasis.ant-typography{color:var(--db-brand)}.collection-caret{display:inline-flex;align-items:center;margin-right:6px;color:var(--db-text-secondary);font-size:11px}.postman-import-pane{padding-block:16px}.postman-import-pane.is-text{padding-block:12px}.postman-import-icon{color:var(--db-brand);font-size:48px}.postman-field-hint.ant-typography{display:block;margin-bottom:8px}.postman-code-input{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,monospace;font-size:13px}.postman-loading-icon{margin-bottom:12px;color:var(--db-brand);font-size:28px}.response-status-tag.ant-tag{padding:2px 8px;font-size:13px}.response-headers-table{margin-top:8px}.method-select{width:110px}.environment-select{width:160px}.postman-add-row{margin-top:8px}.request-body-mode{margin-bottom:12px}.auth-pane{max-width:520px}.auth-field{display:flex;align-items:center;margin-bottom:12px}.auth-field.is-compact{margin-bottom:6px}.auth-field:last-child{margin-bottom:0}.auth-field-label.ant-typography{width:80px;flex-shrink:0}.auth-field-control{min-width:0;flex:1}.auth-field-stack{width:100%}.postman-rename-input{margin-top:12px}.environment-modal-stack{width:100%}.environment-modal-toolbar,.environment-editor-header{display:flex;align-items:center;gap:12px}.environment-modal-toolbar{flex-wrap:wrap}.environment-active-select{width:220px}.environment-editor{padding:16px;border:1px solid var(--db-border);border-radius:var(--db-radius);background:var(--db-surface-subtle)}.environment-editor-header{justify-content:space-between;margin-bottom:12px}.environment-name-input{width:260px;font-weight:650}.environment-add-variable{margin-top:12px}.environment-empty{padding-block:32px;color:var(--db-text-secondary);text-align:center}.code-viewer.raw{color:#e6e6e6}.postman-container .ant-typography-secondary,.response-meta-item{color:var(--db-text-secondary)}.tree-node-row:focus-visible,.collection-header:focus-visible{outline:3px solid rgba(101,85,232,.28);outline-offset:-3px}.tree-node-row:focus-within .node-actions,.collection-header:focus-within .collection-actions{opacity:1;visibility:visible}@media(max-width:1100px){.postman-sidebar{width:250px;min-width:250px}.request-editor{padding-inline:18px}.response-panel{margin-inline:18px}.request-url-row{flex-wrap:wrap}.request-url-row .url-input{min-width:260px}}@media(max-width:900px){.postman-container{display:flex;flex-direction:column;overflow-y:auto}.postman-sidebar{width:100%;min-width:0;max-width:none;max-height:280px;flex:none;border-right:0;border-bottom:1px solid var(--db-border)}.sidebar-header{padding:12px 14px}.sidebar-content{min-height:110px}.postman-workspace{min-height:650px;flex:none}.request-url-row .url-input{min-width:min(360px,55%)}}@media(max-width:650px){.postman-sidebar{max-height:250px}.request-editor{padding:14px}.request-url-row{align-items:stretch}.request-url-row .method-select{width:calc(35% - 4px)!important}.request-url-row .url-input{min-width:calc(65% - 4px)}.request-url-row>.ant-select:not(.method-select){width:100%!important}.request-url-row .send-btn,.request-url-row>.ant-btn{flex:1}.response-panel{min-height:360px;margin:12px 14px 18px}.response-header-bar{align-items:flex-start;gap:10px;padding:11px 14px}.response-status-group{flex-wrap:wrap;gap:8px 12px}.response-body-wrap{padding-inline:14px}}@media(hover:none),(pointer:coarse){.collection-header,.tree-node-row{min-height:44px}.tree-node-row .node-actions,.collection-header .collection-actions{opacity:1;visibility:visible}}@media(prefers-reduced-motion:reduce){.collection-header,.tree-node-row,.node-actions,.collection-actions{transition:none}}.bookmark-sync-page{width:100%;max-width:1100px;margin:0 auto;padding-bottom:40px}.bookmark-sync-loading{display:grid;min-height:240px;place-items:center}.bookmark-sync-alert,.bookmark-browser-grid,.bookmark-control-card,.bookmark-sync-result{margin-bottom:24px}.bookmark-sync-alert{border-radius:var(--db-radius)}.bookmark-browser-card,.bookmark-control-card{height:100%;border-color:var(--db-border);border-radius:var(--db-radius);box-shadow:var(--db-shadow-sm)}.bookmark-browser-card .ant-card-head,.bookmark-control-card .ant-card-head{border-bottom-color:var(--db-border)}.bookmark-browser-icon{color:var(--db-brand);font-size:18px}.bookmark-browser-icon.is-edge,.bookmark-browser-count.is-edge{color:var(--db-brand-strong)}.bookmark-browser-path.ant-typography{margin-bottom:12px;color:var(--db-text-secondary);font-size:12px}.bookmark-browser-details,.bookmark-control-stack{width:100%}.bookmark-browser-count.ant-typography{color:var(--db-brand);font-size:18px}.bookmark-control-label.ant-typography{display:block;margin-bottom:8px}.bookmark-control-divider.ant-divider{margin-block:8px}.bookmark-control-actions{width:100%}.bookmark-sync-button{min-width:140px}.bookmark-sync-result{border-radius:var(--db-radius)}.bookmark-result-details{margin-top:8px}.bookmark-backup-label.ant-typography,.bookmark-backup-item.ant-list-item{font-size:12px}.bookmark-backup-item.ant-list-item{padding-block:2px}.bookmark-preview-stack{width:100%;margin-top:12px}.bookmark-mode-alert.ant-alert-info{border-color:#d8d3ff;background:var(--db-brand-soft)}.bookmark-mode-alert.ant-alert-info .ant-alert-icon{color:var(--db-brand)}.bookmark-preview-empty{padding-block:30px;color:var(--db-text-secondary);text-align:center}.bookmark-sync-page a{color:var(--db-brand)}.bookmark-sync-page a:hover{color:var(--db-brand-strong)}@media(max-width:650px){.bookmark-control-actions .ant-btn{flex:1 1 150px}.bookmark-control-card .ant-radio-group{display:grid;width:100%}.bookmark-control-card .ant-radio-button-wrapper{width:100%;text-align:center}}.file-organizer-page{width:100%;max-width:1440px;margin:0 auto;padding-bottom:40px}.file-organizer-card{border-color:var(--db-border);border-radius:var(--db-radius);box-shadow:var(--db-shadow-sm)}.file-organizer-setup-card,.file-organizer-stats-card{margin-bottom:16px}.file-organizer-field-label.ant-typography{display:block;margin-bottom:8px}.file-organizer-presets{margin-top:8px}.file-organizer-helper-label.ant-typography{color:var(--db-text-secondary);font-size:12px}.file-organizer-target-mode{margin-bottom:8px}.file-organizer-custom-target{margin-top:4px}.file-organizer-target-preview{margin-top:8px;padding:8px 12px;border:1px solid var(--db-border);border-radius:8px;background:var(--db-surface-subtle)}.file-organizer-target-preview code{color:var(--db-brand-strong)}.file-organizer-inline-label.ant-typography{margin-right:8px}.file-organizer-category-tag.ant-tag{padding:4px 10px;cursor:pointer;border:2px solid transparent;font-size:13px}.file-organizer-category-tag.is-active{border-color:var(--db-brand);box-shadow:0 0 0 2px var(--db-brand-soft)}.file-organizer-confirm-icon{color:var(--db-brand)}.file-organizer-confirm-path{padding:8px 12px;border-radius:6px;background:var(--db-surface-subtle);font-family:ui-monospace,SFMono-Regular,Menlo,monospace;word-break:break-all}.file-organizer-confirm-note{margin-top:12px;color:var(--db-text-secondary);font-size:13px}.file-browser-path-row{margin-bottom:12px}.file-browser-parent-row{margin-bottom:8px}.file-browser-list{max-height:300px;overflow-y:auto;border:1px solid var(--db-border);border-radius:8px}.file-browser-empty{padding:20px 16px;color:var(--db-text-secondary);text-align:center}.file-browser-item{display:flex;align-items:center;justify-content:space-between;min-height:42px;padding:8px 12px;border-bottom:1px solid var(--db-border);cursor:pointer;transition:background .16s ease}.file-browser-item:last-child{border-bottom:0}.file-browser-item:hover{background:var(--db-brand-soft)}.file-browser-icon{margin-right:8px;color:var(--db-brand)}.file-browser-confirm-row{margin-top:12px;text-align:right}@media(max-width:650px){.file-organizer-presets{align-items:stretch}.file-organizer-presets .ant-btn{flex:1}.file-browser-item{min-height:48px}}.branch-sync-page{width:100%;max-width:1280px;margin:0 auto;padding-bottom:40px}.branch-sync-page a,.branch-sync-page .ant-btn-link{color:var(--db-brand)}.branch-sync-warning{margin-bottom:20px;border-radius:10px}.branch-sync-loading-state{padding:80px 0;text-align:center}.branch-sync-empty-state{margin-top:60px}.branch-sync-table-card,.branch-sync-subapps-card,.branch-sync-preview-card{border:1px solid var(--db-border);border-radius:var(--db-radius);box-shadow:var(--db-shadow-sm)}.branch-sync-table-card{overflow:hidden}.branch-sync-table-card>.ant-card-body{padding:0}.branch-sync-table-card .ant-table-thead>tr>th{background:var(--db-surface-subtle);color:var(--db-text-secondary);font-size:12px}.branch-sync-table-card .ant-table-tbody>tr>td,.branch-sync-table-card .ant-table-thead>tr>th,.branch-sync-subapps-wrapper .ant-table-tbody>tr>td{padding:12px 16px!important}.branch-sync-table-card .ant-table-tbody>tr>td:first-child,.branch-sync-table-card .ant-table-thead>tr>th:first-child,.branch-sync-subapps-wrapper .ant-table-tbody>tr>td:first-child{padding-left:16px!important;padding-right:16px!important;width:48px!important;min-width:48px!important;max-width:48px!important}.branch-sync-table-card .ant-table-tbody>tr>td:last-child,.branch-sync-table-card .ant-table-thead>tr>th:last-child,.branch-sync-subapps-wrapper .ant-table-tbody>tr>td:last-child{padding-right:24px!important}.branch-sync-action-cell{display:flex;flex-direction:column;gap:10px;width:100%}.branch-sync-action-cell .ant-btn{white-space:nowrap}.branch-sync-app-name{display:flex;flex-direction:column;align-items:flex-start;gap:4px}.branch-sync-app-subbadge{margin-top:2px}.branch-sync-app-link{color:var(--db-brand)!important;font-size:14px}.branch-sync-count-badge .ant-badge-count{background:var(--db-brand);font-size:10px}.branch-sync-branches-col{display:flex;flex-direction:column;gap:4px}.branch-sync-branch-block{display:flex;flex-direction:column;align-items:flex-start;gap:2px}.branch-sync-tag-row{display:flex;align-items:center;gap:4px}.branch-sync-branch-line{display:flex;align-items:center;gap:4px;font-size:12px}.branch-sync-branch-label{width:48px;display:inline-block;flex-shrink:0;color:var(--db-text-secondary);font-size:11px;font-weight:500}.branch-sync-custom-icon{color:var(--db-brand);font-size:12px;margin-left:2px;cursor:pointer;flex-shrink:0;opacity:.85;transition:opacity .2s,transform .2s}.branch-sync-custom-icon:hover{opacity:1;transform:scale(1.15)}.branch-sync-branch-tag.ant-tag{border-color:#6555e83d;background:var(--db-brand-soft);color:var(--db-brand-strong)}.branch-sync-status-stack{display:flex;width:100%;flex-direction:column;gap:12px}.branch-sync-status-row{display:flex;flex-direction:column;align-items:flex-start;gap:4px;font-size:12px}.branch-sync-status-label{color:var(--db-text-secondary);font-size:11px;font-weight:500}.branch-sync-pair-status{display:flex;flex-direction:column;align-items:flex-start;gap:4px}.branch-sync-open-pr-btn.ant-btn-link{font-size:11px!important;padding:0!important;height:auto!important;line-height:1.4!important}.branch-sync-inline-alert{margin-top:2px;padding:2px 8px;border-radius:5px;font-size:11px}.branch-sync-table-card .ant-table-tbody>tr.ant-table-expanded-row>td{padding:0!important;background:#6555e809!important;border-bottom:1px solid var(--db-border)!important;box-shadow:inset 0 2px 4px #00000005,inset 0 -2px 4px #00000005}.branch-sync-subapps-wrapper{width:100%;background:#6555e809;position:relative}.branch-sync-subapps-wrapper .ant-table{background:transparent!important}.branch-sync-subapps-wrapper .ant-table-tbody>tr>td{background:transparent!important;border-bottom:1px dashed rgba(101,85,232,.12)!important;transition:background .2s ease}.branch-sync-subapps-wrapper .ant-table-tbody>tr:hover>td{background:#6555e811!important}.branch-sync-subapps-wrapper .ant-table-tbody>tr:last-child>td{border-bottom:none!important}.branch-sync-subapp-row:last-child{border-bottom:none}.subapp-col-indent{width:48px;flex-shrink:0}.subapp-col-name{width:320px;flex-shrink:0;padding:0 16px;display:flex;align-items:center;gap:6px}.subapp-col-branches{width:240px;flex-shrink:0;padding:0 16px}.subapp-col-status{width:420px;flex-shrink:0;padding:0 16px}.subapp-col-action{width:180px;flex-shrink:0;padding:0 24px 0 16px}.branch-sync-modal-body,.branch-sync-modal-form{margin-top:16px}.branch-sync-create-preview{margin-top:12px}.branch-sync-create-preview-title{color:var(--db-text-secondary);font-size:13px}.branch-sync-preview-card{margin-top:8px;background:var(--db-surface-subtle)}.branch-sync-preview-repos{display:flex;flex-direction:column;gap:6px;font-size:12px}.branch-sync-preview-subitem{padding-left:12px}.branch-sync-result-list{margin-top:8px}.branch-sync-result-item{display:block!important;padding:10px 12px!important}.branch-sync-result-row{display:flex;align-items:center;justify-content:space-between;gap:12px}.branch-sync-result-name{font-size:13px}.branch-sync-result-repo{font-size:11px}.branch-sync-result-error{margin-top:6px;padding:4px 8px;font-size:12px}@media(max-width:760px){.branch-sync-page .page-header>.ant-space{width:100%}.branch-sync-page .page-header>.ant-space .ant-btn{flex:1}}