gestalt-mobile 0.16.3 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -9,6 +9,8 @@ import { createPlanMeasurementSnapshot, } from '../../features/plans/application
9
9
  import { canRebindMissingRollout, rebindMissingRollout, } from '../../features/sessions/restore-session/use-case.js';
10
10
  import { gestaltQuizDynamicTool } from '../../../shared/contracts/quiz.js';
11
11
  import { threadPlanName } from './thread-plan-name.js';
12
+ import { WriterAcquisitionError, } from '../../features/sessions/application/writer-acquisition.js';
13
+ import { isCodexThreadWriterBusy, isMissingCodexThreadRollout } from './json-rpc-client.js';
12
14
  /** One private owner for every resource acquired for a live Codex child. */
13
15
  class SessionResource {
14
16
  sessionId;
@@ -65,10 +67,11 @@ export class CodexSessionRuntime {
65
67
  planMeasurementBaseUrl;
66
68
  requestTimeoutMs;
67
69
  maxPendingRequests;
70
+ readerCwd;
68
71
  constructor(launch,
69
72
  // Kept as an ignored compatibility slot while callers migrate from the old
70
73
  // correlated-map constructor shape. Live ownership is `sessions` only.
71
- _legacyProcesses = undefined, onNotification, onServerRequest, onProcessExit, resolveSkills, planStatusSource, onPlanStatus, planMeasurementBaseUrl, requestTimeoutMs = 30_000, maxPendingRequests = 64) {
74
+ _legacyProcesses = undefined, onNotification, onServerRequest, onProcessExit, resolveSkills, planStatusSource, onPlanStatus, planMeasurementBaseUrl, requestTimeoutMs = 30_000, maxPendingRequests = 64, readerCwd) {
72
75
  this.launch = launch;
73
76
  this.onNotification = onNotification;
74
77
  this.onServerRequest = onServerRequest;
@@ -79,9 +82,12 @@ export class CodexSessionRuntime {
79
82
  this.planMeasurementBaseUrl = planMeasurementBaseUrl;
80
83
  this.requestTimeoutMs = requestTimeoutMs;
81
84
  this.maxPendingRequests = maxPendingRequests;
85
+ this.readerCwd = readerCwd;
82
86
  void _legacyProcesses;
83
87
  }
84
88
  sessions = new Map();
89
+ historyReads = new Map();
90
+ writerAcquisitions = new Map();
85
91
  async start(session, now, settings = {}) {
86
92
  const resource = await this.createResource(session);
87
93
  try {
@@ -120,6 +126,12 @@ export class CodexSessionRuntime {
120
126
  for (const resource of [...this.sessions.values()])
121
127
  resource.dispose();
122
128
  }
129
+ /** Keeps a detached session's supervised-plan status observable without launching Codex. */
130
+ async watchPlanStatus(session) {
131
+ if (!this.planStatusSource)
132
+ return;
133
+ await this.planStatusSource.open({ id: session.id, workspacePath: session.workspacePath }, (update) => this.onPlanStatus?.(session.id, update));
134
+ }
123
135
  resolveServerRequest(sessionId, requestId, result) {
124
136
  const resource = this.sessions.get(sessionId);
125
137
  const pending = resource?.pendingRequests.get(requestId);
@@ -142,6 +154,35 @@ export class CodexSessionRuntime {
142
154
  }));
143
155
  return RelaySession.rehydrate(session).startTurn(result, now).snapshot;
144
156
  }
157
+ /** The sole authoritative in-process ownership probe. It never launches a child. */
158
+ ownsWriter(sessionId) {
159
+ return this.sessions.get(sessionId)?.active === true;
160
+ }
161
+ async ensureWriter(session, now) {
162
+ if (this.ownsWriter(session.id))
163
+ return { session, replacementCreated: false };
164
+ const inflight = this.writerAcquisitions.get(session.id);
165
+ if (inflight)
166
+ return inflight;
167
+ const acquisition = this.acquireWriter(session, now);
168
+ this.writerAcquisitions.set(session.id, acquisition);
169
+ try {
170
+ return await acquisition;
171
+ }
172
+ finally {
173
+ if (this.writerAcquisitions.get(session.id) === acquisition)
174
+ this.writerAcquisitions.delete(session.id);
175
+ }
176
+ }
177
+ async acquireWriter(session, now) {
178
+ try {
179
+ const restored = await this.restoreWithOutcome(session, now);
180
+ return { session: restored.session, replacementCreated: restored.replacementCreated };
181
+ }
182
+ catch (error) {
183
+ throw classifyWriterAcquisitionFailure(error);
184
+ }
185
+ }
145
186
  async interruptTurn(session, turnId) {
146
187
  const resource = this.sessions.get(session.id);
147
188
  if (!resource || !session.threadId)
@@ -170,13 +211,44 @@ export class CodexSessionRuntime {
170
211
  return Boolean(token && authorization === `Bearer ${token}`);
171
212
  }
172
213
  async readHistory(session) {
173
- const resource = this.sessions.get(session.id);
174
- if (!resource || !session.threadId)
175
- throw new Error('CODEX_SESSION_NOT_RUNNING');
176
- const result = decodeThreadRead(await resource.process.rpc.request('thread/read', {
177
- threadId: session.threadId,
178
- includeTurns: true,
179
- }));
214
+ if (!session.threadId)
215
+ throw new Error('CODEX_THREAD_ID_MISSING');
216
+ const owned = this.sessions.get(session.id);
217
+ if (owned)
218
+ return this.decodeHistory(owned.process, session.threadId);
219
+ const existing = this.historyReads.get(session.id);
220
+ if (existing)
221
+ return existing;
222
+ const read = this.readDetachedHistory(session);
223
+ this.historyReads.set(session.id, read);
224
+ try {
225
+ return await read;
226
+ }
227
+ finally {
228
+ if (this.historyReads.get(session.id) === read)
229
+ this.historyReads.delete(session.id);
230
+ }
231
+ }
232
+ async readDetachedHistory(session) {
233
+ // A reader is intentionally not a SessionResource: it owns no subscriptions,
234
+ // runtime registration, plan lease, or writer state and is closed on every path.
235
+ const process = this.launch({
236
+ profile: session.profile,
237
+ cwd: this.readerCwd ?? session.workspacePath,
238
+ });
239
+ try {
240
+ await process.rpc.request('initialize', {
241
+ clientInfo: { name: 'gestalt-mobile', version: '0.1.0' },
242
+ capabilities: { experimentalApi: true },
243
+ });
244
+ return await this.decodeHistory(process, session.threadId);
245
+ }
246
+ finally {
247
+ process.close();
248
+ }
249
+ }
250
+ async decodeHistory(process, threadId) {
251
+ const result = decodeThreadRead(await process.rpc.request('thread/read', { threadId, includeTurns: true }));
180
252
  const rawTurns = result;
181
253
  const activeTurn = rawTurns.find((turn) => turn.status === 'inProgress' && typeof turn.id === 'string');
182
254
  return {
@@ -343,6 +415,20 @@ export class CodexSessionRuntime {
343
415
  function isMethodNotFound(error) {
344
416
  return Boolean(error && typeof error === 'object' && error.code === -32601);
345
417
  }
418
+ function classifyWriterAcquisitionFailure(error) {
419
+ if (isCodexThreadWriterBusy(error))
420
+ return new WriterAcquisitionError('writerBusy');
421
+ if (isMissingCodexThreadRollout(error))
422
+ return new WriterAcquisitionError('rolloutMissing');
423
+ if (isMethodNotFound(error))
424
+ return new WriterAcquisitionError('protocolIncompatible');
425
+ const code = error instanceof Error ? error.message : '';
426
+ if (code === 'ENOENT' || code === 'CODEX_THREAD_ID_MISSING')
427
+ return new WriterAcquisitionError('workspaceUnavailable');
428
+ if (/MCP|DEPENDENCY|SKILL/i.test(code))
429
+ return new WriterAcquisitionError('runtimeDependencyFailed');
430
+ return new WriterAcquisitionError('runtimeUnavailable');
431
+ }
346
432
  function rateLimitWindows(value) {
347
433
  const limits = asRecord(value)?.rateLimits;
348
434
  if (!Array.isArray(limits))
@@ -4,86 +4,120 @@
4
4
  * SPDX-License-Identifier: AGPL-3.0-or-later
5
5
  */
6
6
  import { lstat, readdir, readFile, realpath, stat } from 'node:fs/promises';
7
- import { basename, dirname, isAbsolute, join, resolve } from 'node:path';
7
+ import { isAbsolute, join, relative, resolve, sep } from 'node:path';
8
8
  import { parseSupervisedPlan } from '../../features/plans/application/parse-supervised-plan.js';
9
- const maximumPlans = 100;
10
9
  const maximumBytes = 1_048_576;
11
10
  /**
12
- * Bounded, passive access to direct `.gestalt/*.org` children. Every path is
13
- * revalidated after discovery so a workspace cannot escape through symlinks or
14
- * replacement races.
11
+ * Passive access to every regular `.org` file below a workspace. Symlinks are
12
+ * never followed, and every candidate must pass the installed Org Plan helper
13
+ * before it is projected for the browser.
15
14
  */
16
15
  export class FilesystemWorkspacePlanCatalog {
16
+ validator;
17
17
  filesystem;
18
- constructor(filesystem = { lstat, readdir, readFile, realpath, stat }) {
18
+ constructor(validator, filesystem = { lstat, readdir, readFile, realpath, stat }) {
19
+ this.validator = validator;
19
20
  this.filesystem = filesystem;
20
21
  }
21
22
  async list(workspacePath) {
22
- const directory = await this.directory(workspacePath);
23
- if (!directory)
23
+ const workspace = await this.workspace(workspacePath);
24
+ if (!workspace)
24
25
  return [];
25
- let names;
26
- try {
27
- names = (await this.filesystem.readdir(directory, { encoding: 'utf8' }))
28
- .filter((name) => isPlanName(name))
29
- .sort((left, right) => left.localeCompare(right));
30
- }
31
- catch {
32
- return [];
33
- }
26
+ const planNames = await this.discover(workspace);
34
27
  const entries = [];
35
- for (const name of names.slice(0, maximumPlans)) {
36
- const result = await this.readFromDirectory(workspacePath, directory, name);
28
+ for (const planName of planNames) {
29
+ const result = await this.readFromWorkspace(workspace, planName);
37
30
  if (result.kind !== 'available')
38
31
  continue;
39
- entries.push(toEntry(name, result.plan));
32
+ entries.push(toEntry(planName, result.plan));
40
33
  }
41
34
  return entries;
42
35
  }
43
36
  async read(workspacePath, planName) {
44
- if (!isPlanName(planName))
37
+ if (!isPlanPath(planName))
45
38
  return { kind: 'missing' };
46
- const directory = await this.directory(workspacePath);
47
- if (!directory)
39
+ const workspace = await this.workspace(workspacePath);
40
+ if (!workspace)
48
41
  return { kind: 'missing' };
49
- return this.readFromDirectory(workspacePath, directory, planName);
42
+ return this.readFromWorkspace(workspace, planName);
50
43
  }
51
- async directory(workspacePath) {
44
+ async workspace(workspacePath) {
52
45
  if (!isAbsolute(workspacePath))
53
46
  return null;
54
- const workspace = resolve(workspacePath);
55
- const directory = join(workspace, '.gestalt');
56
47
  try {
57
- const metadata = await this.filesystem.lstat(directory);
58
- if (!metadata.isDirectory() || metadata.isSymbolicLink())
59
- return null;
60
- const [canonicalWorkspace, canonicalDirectory] = await Promise.all([
61
- this.filesystem.realpath(workspace),
62
- this.filesystem.realpath(directory),
63
- ]);
64
- return dirname(canonicalDirectory) === canonicalWorkspace ? canonicalDirectory : null;
48
+ const canonical = await this.filesystem.realpath(resolve(workspacePath));
49
+ const metadata = await this.filesystem.stat(canonical);
50
+ return metadata.isDirectory() ? canonical : null;
65
51
  }
66
52
  catch {
67
53
  return null;
68
54
  }
69
55
  }
70
- async readFromDirectory(workspacePath, directory, planName) {
71
- const path = join(directory, planName);
56
+ async discover(workspace) {
57
+ const pending = [workspace];
58
+ const visited = new Set();
59
+ const plans = [];
60
+ while (pending.length > 0) {
61
+ const directory = pending.pop();
62
+ try {
63
+ const before = await this.filesystem.lstat(directory);
64
+ if (!before.isDirectory() || before.isSymbolicLink())
65
+ continue;
66
+ const canonical = await this.filesystem.realpath(directory);
67
+ if (!isWithin(workspace, canonical))
68
+ continue;
69
+ const metadata = await this.filesystem.stat(canonical);
70
+ if (!metadata.isDirectory() || visited.has(canonical))
71
+ continue;
72
+ visited.add(canonical);
73
+ const children = await this.filesystem.readdir(canonical, {
74
+ encoding: 'utf8',
75
+ withFileTypes: true,
76
+ });
77
+ for (const child of children) {
78
+ if (child.isSymbolicLink())
79
+ continue;
80
+ const childPath = join(canonical, child.name);
81
+ if (child.isDirectory())
82
+ pending.push(childPath);
83
+ else if (child.isFile() && isPlanFilename(child.name)) {
84
+ const planName = toPlanName(relative(workspace, childPath));
85
+ if (isPlanPath(planName))
86
+ plans.push(planName);
87
+ }
88
+ }
89
+ }
90
+ catch {
91
+ // A disappearing or unreadable branch does not hide plans elsewhere.
92
+ }
93
+ }
94
+ return plans.sort((left, right) => left.localeCompare(right));
95
+ }
96
+ async readFromWorkspace(workspace, planName) {
97
+ if (!isPlanPath(planName))
98
+ return { kind: 'missing' };
99
+ const path = resolve(workspace, ...planName.split('/'));
100
+ if (!isWithin(workspace, path))
101
+ return { kind: 'missing' };
72
102
  try {
73
103
  const before = await this.filesystem.lstat(path);
74
104
  if (!before.isFile() || before.isSymbolicLink() || before.size > maximumBytes)
75
105
  return { kind: 'unavailable' };
76
106
  const canonical = await this.filesystem.realpath(path);
77
- if (dirname(canonical) !== directory || basename(canonical) !== planName)
107
+ if (!isWithin(workspace, canonical) ||
108
+ toPlanName(relative(workspace, canonical)) !== planName)
78
109
  return { kind: 'unavailable' };
79
110
  const source = await this.filesystem.readFile(canonical, 'utf8');
111
+ if (!(await this.validator.validate(workspace, canonical)))
112
+ return { kind: 'unavailable' };
80
113
  const after = await this.filesystem.stat(canonical);
81
114
  if (!after.isFile() ||
82
115
  after.size !== before.size ||
83
116
  after.ino !== before.ino ||
84
- after.dev !== before.dev)
117
+ after.dev !== before.dev ||
118
+ after.mtimeMs !== before.mtimeMs)
85
119
  return { kind: 'unavailable' };
86
- const parsed = parseSupervisedPlan({ source, planPath: canonical, workspacePath });
120
+ const parsed = parseSupervisedPlan({ source, planPath: canonical, workspacePath: workspace });
87
121
  return parsed.kind === 'available' ? parsed : { kind: 'unavailable' };
88
122
  }
89
123
  catch (error) {
@@ -93,14 +127,24 @@ export class FilesystemWorkspacePlanCatalog {
93
127
  }
94
128
  }
95
129
  }
96
- function isPlanName(value) {
97
- return (value.endsWith('.org') &&
98
- value !== '.org' &&
130
+ function isPlanFilename(value) {
131
+ return value.endsWith('.org') && value !== '.org';
132
+ }
133
+ function isPlanPath(value) {
134
+ return (isPlanFilename(value) &&
99
135
  !isAbsolute(value) &&
100
- basename(value) === value &&
101
136
  !value.includes('\\') &&
102
- value !== '.' &&
103
- value !== '..');
137
+ value.split('/').every((part) => part !== '' && part !== '.' && part !== '..'));
138
+ }
139
+ function toPlanName(path) {
140
+ return sep === '/' ? path : path.split(sep).join('/');
141
+ }
142
+ function isWithin(workspace, candidate) {
143
+ const pathWithinWorkspace = relative(workspace, candidate);
144
+ return (pathWithinWorkspace === '' ||
145
+ (!pathWithinWorkspace.startsWith(`..${sep}`) &&
146
+ pathWithinWorkspace !== '..' &&
147
+ !isAbsolute(pathWithinWorkspace)));
104
148
  }
105
149
  function toEntry(planName, plan) {
106
150
  return {
@@ -0,0 +1,62 @@
1
+ /*
2
+ * Copyright (C) 2026 Dyne.org foundation
3
+ * Designed by Denis Roio <jaromil@dyne.org>
4
+ * SPDX-License-Identifier: AGPL-3.0-or-later
5
+ */
6
+ import { execFile } from 'node:child_process';
7
+ import { dirname, isAbsolute, join, resolve } from 'node:path';
8
+ import { promisify } from 'node:util';
9
+ const execute = promisify(execFile);
10
+ export const ORG_PLAN_VALIDATION_TIMEOUT_MS = 5_000;
11
+ /** Runs the Org Plan skill's own validator without a shell or mutable command text. */
12
+ export class OrgPlanCommandValidator {
13
+ options;
14
+ helpers = new Map();
15
+ constructor(options = {}) {
16
+ this.options = options;
17
+ }
18
+ async validate(workspacePath, planPath) {
19
+ const helper = await this.helper(workspacePath);
20
+ if (!helper)
21
+ return false;
22
+ try {
23
+ await (this.options.execute ?? execute)(helper, ['validate', planPath], {
24
+ shell: false,
25
+ timeout: ORG_PLAN_VALIDATION_TIMEOUT_MS,
26
+ maxBuffer: 64 * 1024,
27
+ });
28
+ return true;
29
+ }
30
+ catch {
31
+ return false;
32
+ }
33
+ }
34
+ async helper(workspacePath) {
35
+ const workspace = resolve(workspacePath);
36
+ const cached = this.helpers.get(workspace);
37
+ if (cached)
38
+ return cached;
39
+ const discovered = this.resolveHelper(workspace);
40
+ this.helpers.set(workspace, discovered);
41
+ const helper = await discovered;
42
+ if (!helper)
43
+ this.helpers.delete(workspace);
44
+ return helper;
45
+ }
46
+ async resolveHelper(workspacePath) {
47
+ if (this.options.helperPath)
48
+ return isAbsolute(this.options.helperPath) ? resolve(this.options.helperPath) : null;
49
+ if (!this.options.discoverSkills)
50
+ return null;
51
+ try {
52
+ const skills = await this.options.discoverSkills(workspacePath);
53
+ const skill = skills.find(({ name }) => name === 'gestalt:org-plan' || name === 'org-plan');
54
+ return skill && isAbsolute(skill.path)
55
+ ? join(dirname(resolve(skill.path)), 'scripts', 'org-plan')
56
+ : null;
57
+ }
58
+ catch {
59
+ return null;
60
+ }
61
+ }
62
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gestalt-mobile",
3
- "version": "0.16.3",
3
+ "version": "0.17.0",
4
4
  "description": "Mobile-first web relay for durable Codex development sessions",
5
5
  "keywords": [
6
6
  "codex",
@@ -1 +0,0 @@
1
- .session-path.svelte-t9laac{text-align:center;text-overflow:ellipsis;white-space:nowrap;min-inline-size:0;margin:0;overflow:hidden}.session-model.svelte-t9laac{color:var(--theme-text-muted);font-family:var(--theme-font-code);margin-inline-start:clamp(.75rem,3vw,2rem)}@media (width<=34rem){.session-model.svelte-t9laac{display:none}}.chat-activity.svelte-thyolt,.live-activity.svelte-thyolt{--activity-gap:.4rem;--activity-type-color:var(--theme-text-muted)}.chat-activity.svelte-thyolt>summary:where(.svelte-thyolt){color:var(--activity-type-color);cursor:pointer;font-size:.875em}.live-activity.svelte-thyolt{margin-block-start:.5rem}.live-activity.svelte-thyolt>strong:where(.svelte-thyolt){color:var(--activity-type-color);font-size:.875em}.activity-list.svelte-thyolt{gap:var(--activity-gap);margin-block:.25rem 0;margin-inline:0;padding:0;list-style:none;display:grid}.activity-row.svelte-thyolt{flex-wrap:wrap;align-items:baseline;gap:.25rem .5rem;display:flex}.activity-row[data-activity-status=failed].svelte-thyolt{border-inline-start:.25rem solid var(--theme-error);padding-inline-start:.375rem}.activity-row[data-activity-status=completed].svelte-thyolt{border-inline-start:.25rem solid var(--theme-success);padding-inline-start:.375rem}.activity-row[data-activity-status].svelte-thyolt:not([data-activity-status=completed]):not([data-activity-status=failed]){border-inline-start:.25rem solid var(--theme-info);padding-inline-start:.375rem}.activity-type.svelte-thyolt{color:var(--activity-type-color);font-size:.75em;line-height:1.2}.activity-content.svelte-thyolt{overflow-wrap:anywhere;white-space:pre-wrap;min-inline-size:0}form.svelte-1264sfg>[role=status]:where(.svelte-1264sfg){text-align:start;margin-block:1rem .35rem}.command-menu.svelte-1264sfg{background:var(--theme-surface);border:1px solid var(--theme-border);border-radius:.375rem;gap:.125rem;max-inline-size:min(100%,32rem);margin:0 0 .35rem;padding:.25rem;list-style:none;display:grid}.command-menu.svelte-1264sfg button:where(.svelte-1264sfg){inline-size:100%;color:var(--theme-text);text-align:start;background:0 0;border:0;border-radius:.25rem;align-items:baseline;gap:.5rem;padding:.25rem .375rem;display:flex}.command-menu.svelte-1264sfg .command-selected:where(.svelte-1264sfg) button:where(.svelte-1264sfg),.command-menu.svelte-1264sfg button:where(.svelte-1264sfg):hover{background:var(--theme-control-hover)}.command-menu.svelte-1264sfg small:where(.svelte-1264sfg){color:var(--theme-text-muted);font-size:.8em}.command-menu.svelte-1264sfg button:where(.svelte-1264sfg):focus-visible{outline:2px solid var(--theme-focus);outline-offset:1px}.prompt-row.svelte-1264sfg{align-items:end;gap:.5rem;display:flex}textarea.svelte-1264sfg{resize:vertical;flex:auto;min-block-size:2.75rem}.prompt-row.svelte-1264sfg button:where(.svelte-1264sfg){flex:none;place-items:center;min-block-size:3rem;inline-size:3rem;padding:0;display:grid}.prompt-row.svelte-1264sfg svg:where(.svelte-1264sfg){fill:none;stroke:currentColor;stroke-width:2px;stroke-linecap:round;stroke-linejoin:round;block-size:1.35rem;inline-size:1.35rem}.block-cursor.svelte-1264sfg{vertical-align:-.1em;background:var(--theme-accent);block-size:1em;inline-size:.55ch;animation:1s steps(2,start) infinite svelte-1264sfg-blink;display:inline-block}@media (prefers-reduced-motion:reduce){.block-cursor.svelte-1264sfg{animation:none}}@keyframes svelte-1264sfg-blink{50%{opacity:0}}.quiz-form.svelte-77f3gb{gap:1rem;display:grid}fieldset.svelte-77f3gb{border:0;min-inline-size:0;margin:0;padding:0}.questions.svelte-77f3gb{gap:1rem;display:grid}legend.svelte-77f3gb{gap:.25rem;max-inline-size:100%;display:grid}.choices.svelte-77f3gb{gap:.5rem;margin-block-start:.5rem;display:grid}.choice.svelte-77f3gb{position:relative}.choice.svelte-77f3gb>input:where(.svelte-77f3gb){opacity:0;cursor:pointer;block-size:100%;inline-size:100%;margin:0;position:absolute;inset:0}.choice.svelte-77f3gb>label:where(.svelte-77f3gb){background:var(--theme-surface);border:2px solid var(--theme-border);border-radius:.5rem;gap:.125rem;min-block-size:44px;padding:.75rem;display:grid}.choice.svelte-77f3gb>input:where(.svelte-77f3gb):checked+label:where(.svelte-77f3gb){border-width:3px;border-color:var(--theme-accent);background:var(--theme-surface-subtle)}.choice.svelte-77f3gb>input:where(.svelte-77f3gb):focus-visible+label:where(.svelte-77f3gb){outline:3px solid var(--theme-focus);outline-offset:2px}label.svelte-77f3gb span:where(.svelte-77f3gb),legend.svelte-77f3gb span:where(.svelte-77f3gb){color:var(--theme-text-muted)}.custom.svelte-77f3gb{margin-block-start:.25rem}.custom.svelte-77f3gb input:where(.svelte-77f3gb){box-sizing:border-box;min-block-size:44px;inline-size:100%;font:inherit;margin-block-start:.375rem}article.svelte-ajsqcq{background:var(--theme-surface-subtle);border-inline-start:.25rem solid var(--theme-info);border-radius:.375rem;margin-block:.75rem;padding:.75rem}.interaction-kind.svelte-ajsqcq,.interaction-submitting.svelte-ajsqcq,.interaction-result.svelte-ajsqcq,.interaction-failed.svelte-ajsqcq{margin-block:0 .5rem}.interaction-result.svelte-ajsqcq{font-weight:600}.command-approval-command.svelte-ajsqcq{white-space:pre-wrap;max-inline-size:100%;font-family:var(--theme-font-code);background:var(--theme-code);border:1px solid var(--theme-border);border-radius:.375rem;margin-block:.5rem .75rem;padding:.625rem;overflow-x:auto}.command-approval-missing.svelte-ajsqcq{margin-block:.5rem .75rem}.file-change-approval-targets.svelte-ajsqcq{overflow-wrap:anywhere;margin-block:.5rem .75rem;padding-inline-start:1.5rem}.file-change-approval-missing.svelte-ajsqcq{margin-block:.5rem .75rem}.approval-actions.svelte-ajsqcq{flex-wrap:wrap;gap:clamp(.5rem,2vw,1rem);display:flex}ol.svelte-1im954t{inline-size:100%;margin:0;padding:0;list-style:none}li.svelte-1im954t{box-sizing:border-box;white-space:pre-wrap;overflow-wrap:anywhere;inline-size:100%;margin-block-end:0}li.svelte-1im954t+li:where(.svelte-1im954t){margin-block-start:1rem}.prompt-turn.svelte-1im954t{background:var(--theme-surface-subtle);border-inline-start:.25rem solid var(--theme-accent);border-radius:.375rem;padding:.5rem .625rem}.answer-turn.svelte-1im954t{border-inline-start:.25rem solid var(--theme-border);padding-inline-start:.625rem}.commentary-turn.svelte-1im954t,.orphan-activity-turn.svelte-1im954t,.progress-turn.svelte-1im954t,.commentary-content.svelte-1im954t{background:var(--theme-surface-subtle);border-inline-start:.25rem solid var(--theme-info);border-radius:.375rem;padding:.5rem .625rem}.live-commentary.svelte-1im954t,.progress-turn.svelte-1im954t{background:0 0}.entry-heading.svelte-1im954t{align-items:baseline;gap:.75rem;display:flex}time.svelte-1im954t{color:var(--theme-text-muted);white-space:nowrap;margin-inline-start:auto;font-size:.875em}.commentary-toggle.svelte-1im954t{min-block-size:1.5rem;color:var(--theme-text-muted);background:0 0;border:0;padding:0 .125rem;font-size:.875em}.answer-history.svelte-1im954t{flex-wrap:wrap;align-items:baseline;gap:.25rem .75rem;margin-block:.2rem .35rem;display:flex}.file-changes.svelte-1im954t{background:var(--theme-surface-subtle);border-inline-start:.25rem solid var(--theme-success);border-radius:.375rem;margin-block:.5rem;padding:.5rem .625rem}.file-changes.svelte-1im954t>strong:where(.svelte-1im954t){font-size:.875em}.file-changes.svelte-1im954t ul:where(.svelte-1im954t){gap:.15rem;margin:.25rem 0 0;padding-inline-start:1.25rem;display:grid}.commentary-content.svelte-1im954t{margin-block:.25rem .5rem}.entry-content.svelte-1im954t{margin-block:.125rem 0;margin-inline:0}pre.svelte-1im954t,code.svelte-1im954t{font-family:var(--theme-font-code)}pre.svelte-1im954t{white-space:pre;background:var(--theme-code);border:1px solid var(--theme-border);border-radius:var(--theme-radius);padding:.625rem;overflow-x:auto}.svelte-1im954t:not(pre)>code:where(.svelte-1im954t){background:var(--theme-code);border-radius:.2rem;padding-inline:.2em}a.svelte-1im954t{color:var(--theme-info)}.table-scroll.svelte-1im954t{margin-block:.75rem;overflow-x:auto}table.svelte-1im954t{border-collapse:collapse;white-space:normal;width:max-content;min-width:100%}th.svelte-1im954t,td.svelte-1im954t{text-align:left;vertical-align:top;border:1px solid var(--theme-border);padding:.25rem .5rem}th.svelte-1im954t{background:var(--theme-surface-subtle);font-weight:600}.toast-viewport.svelte-1a0rutm{z-index:10;pointer-events:none;gap:.5rem;max-block-size:calc(100dvh - 7rem);inline-size:min(24rem,100vw - 1.5rem);display:grid;position:fixed;inset-block-start:calc(1rem + env(safe-area-inset-top));inset-inline-end:max(.75rem, env(safe-area-inset-right));overflow-y:auto}.toast.svelte-1a0rutm{box-sizing:border-box;min-inline-size:0;color:var(--theme-text);background:var(--theme-surface);border:1px solid var(--theme-info);box-shadow:0 .4rem 1.2rem var(--theme-shadow);pointer-events:auto;border-inline-start-width:.35rem;border-radius:.55rem;grid-template-columns:auto minmax(0,1fr) 44px;align-items:start;gap:.6rem;padding:.65rem;display:grid}.toast.error.svelte-1a0rutm{color:var(--theme-error);border-color:var(--theme-error);border-inline-start-style:double}.toast.success.svelte-1a0rutm{color:var(--theme-success);border-color:var(--theme-success);border-inline-start-style:solid}.toast-symbol.svelte-1a0rutm{box-sizing:border-box;border:2px solid;border-radius:50%;place-items:center;block-size:1.6rem;inline-size:1.6rem;font-weight:800;line-height:1;display:grid}.toast-copy.svelte-1a0rutm{overflow-wrap:anywhere;gap:.15rem;min-inline-size:0;padding-block:.1rem;display:grid}.toast-copy.svelte-1a0rutm strong:where(.svelte-1a0rutm){text-transform:capitalize}.toast-copy.svelte-1a0rutm small:where(.svelte-1a0rutm){opacity:.72}button.svelte-1a0rutm{min-block-size:44px;inline-size:44px;color:var(--theme-text);font:inherit;background:0 0;border:0;border-radius:.35rem;place-items:center;padding:0;font-size:1.5rem;display:grid}button.svelte-1a0rutm:hover{background:var(--theme-control-hover)}@media (width<=24rem){.toast.svelte-1a0rutm{grid-template-columns:minmax(0,1fr) 44px;gap:.25rem;max-block-size:5rem;padding:.35rem;overflow-y:auto}.toast-symbol.svelte-1a0rutm{display:none}.toast-copy.svelte-1a0rutm strong:where(.svelte-1a0rutm){clip:rect(0, 0, 0, 0);white-space:nowrap;border:0;block-size:1px;inline-size:1px;padding:0;position:absolute;overflow:hidden}}@media (forced-colors:active){.toast.svelte-1a0rutm,.toast-symbol.svelte-1a0rutm{border-color:canvastext}}.evidence-page.svelte-1j55xyh{box-sizing:border-box;min-block-size:100dvh;inline-size:100%;padding:1rem 1rem 7rem}h1.svelte-1j55xyh{margin-block:0 .5rem}.evidence-composer.svelte-1j55xyh{position:fixed;inset-block-end:2.75rem;inset-inline:1rem}.evidence-prompt.svelte-1j55xyh{box-sizing:border-box;inline-size:100%;margin-block-start:.35rem;display:block}.evidence-nav.svelte-1j55xyh{padding:.5rem 1rem calc(.5rem + env(safe-area-inset-bottom));background:var(--theme-surface);border-block-start:1px solid var(--theme-border);grid-template-columns:repeat(3,minmax(0,1fr));gap:.5rem;display:grid;position:fixed;inset-block-end:0;inset-inline:0}.evidence-nav.svelte-1j55xyh button:where(.svelte-1j55xyh){text-overflow:ellipsis;min-block-size:44px;min-inline-size:0;overflow:hidden}@media (width<=24rem){.evidence-page.svelte-1j55xyh{padding:.5rem .5rem 7rem}.evidence-composer.svelte-1j55xyh{inset-inline:.5rem}}.filesystem-tree.svelte-6z3q4v{inline-size:100%;max-inline-size:100%;display:grid;overflow-x:clip}.tree-row.svelte-6z3q4v{min-inline-size:0;align-items:stretch;padding-inline-start:min(calc(var(--tree-level) * .75rem), 4.5rem);display:flex}.disclosure.svelte-6z3q4v,.disclosure-spacer.svelte-6z3q4v{flex:0 0 44px;min-block-size:44px;inline-size:44px}.disclosure.svelte-6z3q4v{color:inherit;font:inherit;background:0 0;border:0;border-radius:.35rem;place-items:center;padding:0;font-size:1.25rem;font-weight:700;display:grid}.disclosure.svelte-6z3q4v:hover{background:var(--theme-control-hover)}.tree-item.svelte-6z3q4v{min-block-size:44px;min-inline-size:0;color:inherit;font:inherit;text-align:start;background:0 0;border:1px solid #0000;border-radius:.35rem;flex:auto;align-items:center;gap:.5rem;padding:.3rem .5rem;display:flex;overflow:hidden}.tree-item.svelte-6z3q4v:hover{background:var(--theme-control-hover)}.tree-item.selected.svelte-6z3q4v{color:var(--theme-control-pressed-contrast);background:var(--theme-control-pressed);border-color:var(--theme-accent);font-weight:650}.tree-item[aria-disabled=true].svelte-6z3q4v{opacity:.58}.tree-item.repository.svelte-6z3q4v{border-inline-start-width:3px}.selection-mark.svelte-6z3q4v{text-align:center;flex:0 0 1rem;inline-size:1rem}.node-copy.svelte-6z3q4v{flex:auto;min-inline-size:0;display:grid}.node-name.svelte-6z3q4v,.node-path.svelte-6z3q4v{text-overflow:ellipsis;white-space:nowrap;min-inline-size:0;overflow:hidden}.node-path.svelte-6z3q4v{opacity:.72;font-size:.75em;font-weight:400}.repository-badge.svelte-6z3q4v{border:1px solid;border-radius:999px;flex:none;padding:.1rem .35rem;font-size:.72em;font-weight:700;line-height:1.2}@media (width<=24rem){.tree-row.svelte-6z3q4v{padding-inline-start:min(calc(var(--tree-level) * .25rem), 1.5rem)}.tree-item.svelte-6z3q4v{gap:.35rem;padding-inline:.35rem}.repository-badge.svelte-6z3q4v{display:none}}@media (forced-colors:active){.tree-item.selected.svelte-6z3q4v,.tree-item.repository.svelte-6z3q4v,.repository-badge.svelte-6z3q4v{border-color:canvastext}}.evidence-shell.svelte-1d6w4ti{box-sizing:border-box;inline-size:min(100%,48rem);min-inline-size:0;margin-inline:auto;padding:1rem}.eyebrow.svelte-1d6w4ti{letter-spacing:.08em;text-transform:uppercase;margin:0;font-size:.8rem;font-weight:750}h1.svelte-1d6w4ti{margin-block:.25rem .5rem;font-size:clamp(1.35rem,6vw,2rem);line-height:1.15}.instructions.svelte-1d6w4ti{max-inline-size:42rem;margin-block:0 1rem}.tree-panel.svelte-1d6w4ti{border:1px solid var(--theme-border);border-radius:.6rem;min-inline-size:0;padding:.5rem}@media (width<=24rem){.evidence-shell.svelte-1d6w4ti{padding:.5rem}.tree-panel.svelte-1d6w4ti{padding:.25rem}}.git-view.svelte-pudr3t{gap:1.5rem;inline-size:100%;min-inline-size:0;display:grid}.git-tree.svelte-pudr3t,.repository-details.svelte-pudr3t{min-inline-size:0}.section-heading.svelte-pudr3t h3:where(.svelte-pudr3t),.repository-details.svelte-pudr3t h3:where(.svelte-pudr3t){margin-block:0 .35rem}.section-heading.svelte-pudr3t p:where(.svelte-pudr3t){color:var(--theme-text-muted);margin-block:0 .75rem}.clone-form.svelte-pudr3t{gap:.35rem;min-inline-size:0;display:grid}.clone-controls.svelte-pudr3t{grid-template-columns:minmax(10rem,.45fr) minmax(0,1fr) auto;align-items:end;gap:.5rem;display:grid}.clone-field.svelte-pudr3t{gap:.35rem;min-inline-size:0;display:grid}.field-label.svelte-pudr3t{font-weight:600}.clone-destination.svelte-pudr3t output:where(.svelte-pudr3t){overflow-wrap:anywhere;border:1px solid var(--theme-border);border-radius:.35rem;min-block-size:2.75rem;padding:.65rem .75rem}.clone-controls.svelte-pudr3t button:where(.svelte-pudr3t){min-inline-size:5.75rem}.clone-form.svelte-pudr3t p:where(.svelte-pudr3t){color:var(--theme-text-muted);margin:0;font-size:.875rem}.clone-status.svelte-pudr3t{font-weight:600;color:var(--theme-info)!important}.git-overview.svelte-pudr3t{grid-template-columns:minmax(0,1fr) auto;align-items:start;gap:1rem;display:grid}.git-status.svelte-pudr3t p:where(.svelte-pudr3t){margin-block:.5rem}.git-actions.svelte-pudr3t{gap:.5rem;display:grid}.git-actions.svelte-pudr3t button:where(.svelte-pudr3t){min-inline-size:6rem}.commit-history.svelte-pudr3t{margin-block-start:2rem}.commit-history.svelte-pudr3t h3:where(.svelte-pudr3t){margin-block-end:.75rem}.commit-list.svelte-pudr3t{gap:.5rem;margin:0;padding:0;list-style:none;display:grid}.commit-entry.svelte-pudr3t{border-block-end:1px solid var(--theme-border);gap:.35rem;min-inline-size:0;padding:.8rem 0;display:grid}.commit-subject.svelte-pudr3t,.commit-meta.svelte-pudr3t{gap:.65rem;min-inline-size:0;display:flex}.commit-subject.svelte-pudr3t{overflow-wrap:anywhere;align-items:baseline;font-weight:600}.commit-subject.svelte-pudr3t code:where(.svelte-pudr3t){color:var(--theme-text-muted);flex:none;font-size:.875em}.commit-meta.svelte-pudr3t{color:var(--theme-text-muted);flex-wrap:wrap;justify-content:space-between;font-size:.875rem}.commit-meta.svelte-pudr3t time:where(.svelte-pudr3t){overflow-wrap:anywhere;min-inline-size:0;max-inline-size:100%}@media (width<=28rem){.clone-controls.svelte-pudr3t{grid-template-columns:1fr}.clone-controls.svelte-pudr3t button:where(.svelte-pudr3t){inline-size:100%}}.plan.svelte-3rmyvg{overflow-wrap:anywhere;min-inline-size:0}header.svelte-3rmyvg{justify-content:space-between;align-items:start;gap:1rem;display:flex}h2.svelte-3rmyvg,p.svelte-3rmyvg{margin-block:.4rem}progress.svelte-3rmyvg{inline-size:100%}ol.svelte-3rmyvg{padding-inline-start:1.25rem}details.svelte-3rmyvg{margin-block:.5rem}summary.svelte-3rmyvg{cursor:pointer;gap:.2rem;display:grid}.measurement.svelte-3rmyvg{color:var(--muted,currentColor);font-variant-numeric:tabular-nums}.metadata.svelte-3rmyvg{gap:.25rem;display:grid}.metadata.svelte-3rmyvg div:where(.svelte-3rmyvg){gap:.5rem;display:flex}.metadata.svelte-3rmyvg dd:where(.svelte-3rmyvg){margin:0}.close.svelte-3rmyvg{flex:none;block-size:2.75rem;inline-size:2.75rem;font-size:1.5rem}button.svelte-3rmyvg:focus-visible,summary.svelte-3rmyvg:focus-visible{outline-offset:2px;outline:3px solid}@media (prefers-reduced-motion:reduce){.svelte-3rmyvg{scroll-behavior:auto}}.plans.svelte-x2ko9l{overflow-wrap:anywhere;min-inline-size:0}h2.svelte-x2ko9l{margin-block:.4rem}ul.svelte-x2ko9l{gap:.5rem;margin:0;padding:0;list-style:none;display:grid}button.svelte-x2ko9l{text-align:start;gap:.2rem;min-block-size:2.75rem;inline-size:100%;padding:.75rem;display:grid}button.svelte-x2ko9l:focus-visible{outline-offset:2px;outline:3px solid}.session-list.svelte-hxb22h{gap:1rem;inline-size:100%;margin-block:0 1.5rem;padding-inline:0;list-style:none;display:grid}.current-session.svelte-hxb22h{outline:2px solid var(--theme-accent);outline-offset:2px}.session-select.svelte-hxb22h{inline-size:100%;color:inherit;font:inherit;text-align:inherit;cursor:pointer;background:0 0;border:0;padding:0;display:block}.managed-session.svelte-hxb22h{box-sizing:border-box;border:1px solid var(--theme-border);border-radius:.5rem;grid-template-columns:max-content minmax(0,1fr);align-items:start;gap:.75rem;inline-size:100%;padding:.75rem;display:grid}.open-session.svelte-hxb22h{border-inline-start:.3rem solid var(--theme-accent);background:var(--theme-control-hover)}.session-details.svelte-hxb22h{min-inline-size:0}.workspace-path.svelte-hxb22h{overflow-wrap:anywhere}.profile-badge.svelte-hxb22h{background:var(--theme-control-pressed);color:var(--theme-control-pressed-contrast);overflow-wrap:anywhere;border-radius:999px;margin-block-start:.35rem;padding:.15rem .4rem;font-size:.875rem;display:inline-block}.org-plan-metadata.svelte-hxb22h{gap:.125rem;margin-block-start:.35rem;display:grid}.org-plan-title.svelte-hxb22h{font-weight:600}.org-plan-filename.svelte-hxb22h{overflow-wrap:anywhere;color:var(--theme-text-muted)}.session-actions.svelte-hxb22h{flex-wrap:wrap;gap:.5rem;display:flex}@media (width<=30rem){.managed-session.svelte-hxb22h{grid-template-columns:minmax(0,1fr)}}.recent-session.svelte-hxb22h{grid-template-columns:minmax(0,1fr) max-content;align-items:start;gap:.75rem;display:grid}.session-base.svelte-hxb22h{gap:.65rem;min-inline-size:0;margin-block:1rem;display:grid}.session-base-heading.svelte-hxb22h h3:where(.svelte-hxb22h),.session-base-heading.svelte-hxb22h p:where(.svelte-hxb22h){margin:0}.session-base-heading.svelte-hxb22h p:where(.svelte-hxb22h){margin-block-start:.25rem}.tree-panel.svelte-hxb22h{box-sizing:border-box;overscroll-behavior:contain;scrollbar-gutter:stable;border:1px solid var(--theme-border);border-radius:.6rem;max-block-size:min(22rem,48vh);min-inline-size:0;padding:.35rem;overflow-y:auto}.session-settings.svelte-hxb22h{gap:.5rem;min-inline-size:0;margin-block-end:.75rem;display:grid}.session-setting-labels.svelte-hxb22h,.session-setting-controls.svelte-hxb22h{grid-template-columns:repeat(3,minmax(0,1fr));gap:.5rem;min-inline-size:0;display:grid}.session-setting-labels.svelte-hxb22h label:where(.svelte-hxb22h){overflow-wrap:anywhere;min-inline-size:0}.session-setting-controls.svelte-hxb22h select:where(.svelte-hxb22h){text-overflow:ellipsis;inline-size:100%;min-inline-size:0;max-inline-size:100%;overflow:hidden}.session-secondary-actions.svelte-hxb22h,.model-control.svelte-hxb22h{align-items:center;gap:.5rem;min-inline-size:0;display:flex}.session-secondary-actions.svelte-hxb22h{flex-wrap:wrap}.model-control.svelte-hxb22h{margin-inline-start:auto}.skills-profile-error.svelte-hxb22h{color:var(--theme-error);margin:0;font-size:.875rem}.new-session-button.svelte-hxb22h{inline-size:auto;color:var(--theme-accent-contrast);background:var(--theme-accent);border-color:var(--theme-accent);box-shadow:inset 0 .15rem 0 var(--theme-accent-contrast);font-weight:700}@media (width<=28rem){.tree-panel.svelte-hxb22h{padding:.2rem}.model-control.svelte-hxb22h{margin-inline-start:0}}.skills-view.svelte-dg6sjj{min-inline-size:0;padding:1rem max(1rem, env(safe-area-inset-right)) calc(5rem + env(safe-area-inset-bottom)) max(1rem, env(safe-area-inset-left))}.intro.svelte-dg6sjj,.save-intent.svelte-dg6sjj,.summary.svelte-dg6sjj{max-inline-size:70ch}form.svelte-dg6sjj,.field-grid.svelte-dg6sjj{gap:.65rem;display:grid}.field-grid.svelte-dg6sjj{grid-template-columns:minmax(0,1fr)}label.svelte-dg6sjj{font-weight:650}select.svelte-dg6sjj,input.svelte-dg6sjj,button.svelte-dg6sjj{box-sizing:border-box;min-block-size:3rem;inline-size:100%;font:inherit}dialog.svelte-dg6sjj{max-inline-size:min(100% - 2rem,32rem)}.dialog-actions.svelte-dg6sjj{gap:.65rem;display:grid}input.svelte-dg6sjj,select.svelte-dg6sjj{padding-inline:.7rem;font-size:1rem}button.svelte-dg6sjj{padding-inline:1rem}.profile-actions.svelte-dg6sjj{grid-template-columns:repeat(2,minmax(0,1fr));gap:.65rem;display:grid}.skills-toolbar.svelte-dg6sjj{flex-wrap:wrap;align-items:center;gap:.65rem;margin-block:1rem;display:flex}.refresh-skills.svelte-dg6sjj{flex:none;min-block-size:2.25rem;inline-size:auto;padding-inline:.65rem}.refresh-skills.svelte-dg6sjj span:where(.svelte-dg6sjj):first-child{font-size:1.2em;line-height:1}.summary.svelte-dg6sjj{overflow-wrap:anywhere;min-inline-size:0;margin:0}.notice.svelte-dg6sjj{border-inline-start:.3rem solid var(--theme-warning);color:var(--theme-warning);padding-inline-start:.7rem}.error.svelte-dg6sjj{border-inline-start:.3rem solid var(--theme-error);color:var(--theme-error);padding-inline-start:.7rem}.skill-list.svelte-dg6sjj{gap:.75rem;padding:0;list-style:none;display:grid}.skill-card.svelte-dg6sjj{border:1px solid var(--theme-border);border-radius:.5rem;min-inline-size:0;padding:.75rem;scroll-margin-block:1rem}.skill-toggle.svelte-dg6sjj{flex-wrap:wrap;align-items:center;gap:.65rem;min-block-size:3rem;display:flex}.skill-toggle.svelte-dg6sjj>span:where(.svelte-dg6sjj){overflow-wrap:anywhere;min-inline-size:0}.skill-toggle.svelte-dg6sjj input:where(.svelte-dg6sjj){flex:none;min-block-size:1.25rem;inline-size:1.25rem}.state.svelte-dg6sjj{margin-inline-start:auto;font-weight:500}.skill-details.svelte-dg6sjj{overflow-wrap:anywhere;padding-inline-start:1.9rem}.skill-details.svelte-dg6sjj>:where(.svelte-dg6sjj):first-child{margin-block-start:.25rem}.skill-details.svelte-dg6sjj>:where(.svelte-dg6sjj):last-child{margin-block-end:0}dl.svelte-dg6sjj{grid-template-columns:minmax(7rem,auto) minmax(0,1fr);gap:.45rem .75rem;display:grid}dt.svelte-dg6sjj{font-weight:650}dd.svelte-dg6sjj{min-inline-size:0;margin:0}dd.svelte-dg6sjj ul:where(.svelte-dg6sjj){margin:0;padding-inline-start:1.25rem}.path.svelte-dg6sjj{overflow-wrap:anywhere}.svelte-dg6sjj:where(button:where(.svelte-dg6sjj),input:where(.svelte-dg6sjj),select:where(.svelte-dg6sjj)):focus-visible{outline:3px solid var(--theme-focus);outline-offset:2px}@media (width>=42rem){.field-grid.svelte-dg6sjj{grid-template-columns:minmax(10rem,1fr) minmax(0,2fr);align-items:center}}@media (width<=30rem){dl.svelte-dg6sjj{grid-template-columns:1fr;gap:.2rem}}.devices.svelte-1nygetn{max-inline-size:48rem;color:var(--theme-text);margin:auto;padding:1rem}.devices.svelte-1nygetn header:where(.svelte-1nygetn){align-items:center;gap:1rem;display:flex}.devices.svelte-1nygetn h1:where(.svelte-1nygetn),.devices.svelte-1nygetn h2:where(.svelte-1nygetn){font-family:var(--theme-font-display)}.devices.svelte-1nygetn ul:where(.svelte-1nygetn){padding:0;list-style:none}.devices.svelte-1nygetn li:where(.svelte-1nygetn),section.svelte-1nygetn{background:var(--theme-surface);border:1px solid var(--theme-border);border-radius:var(--theme-radius);box-shadow:0 .25rem .75rem var(--theme-shadow);margin-block:1rem;padding:1rem}.devices.svelte-1nygetn form:where(.svelte-1nygetn){gap:.65rem;display:grid}.devices.svelte-1nygetn p:where(.svelte-1nygetn){overflow-wrap:anywhere;margin:0}.devices.svelte-1nygetn input:where(.svelte-1nygetn),.devices.svelte-1nygetn textarea:where(.svelte-1nygetn),.devices.svelte-1nygetn button:where(.svelte-1nygetn){min-block-size:44px;font:inherit}.devices.svelte-1nygetn input:where(.svelte-1nygetn),.devices.svelte-1nygetn textarea:where(.svelte-1nygetn){min-inline-size:0;padding:.45rem}.devices.svelte-1nygetn textarea:where(.svelte-1nygetn){box-sizing:border-box;overflow-wrap:anywhere;resize:vertical;inline-size:100%;font-family:var(--theme-font-code)}.devices.svelte-1nygetn .actions:where(.svelte-1nygetn){flex-wrap:wrap;gap:.5rem;display:flex}.devices.svelte-1nygetn .actions:where(.svelte-1nygetn) button:where(.svelte-1nygetn){flex:11rem}.devices.svelte-1nygetn img:where(.svelte-1nygetn){background:var(--theme-canvas);inline-size:12rem;max-inline-size:100%;margin-block:.75rem;padding:.5rem;display:block}.feedback.svelte-1nygetn{color:var(--theme-error);font-weight:700}dialog.svelte-1nygetn{max-inline-size:min(32rem,100% - 2rem);color:var(--theme-text);background:var(--theme-surface);border:1px solid var(--theme-border);border-radius:var(--theme-radius);box-shadow:0 .5rem 1.5rem var(--theme-shadow)}dialog.svelte-1nygetn h2:where(.svelte-1nygetn){font-family:var(--theme-font-display)}dialog.svelte-1nygetn form:where(.svelte-1nygetn){flex-wrap:wrap;gap:.5rem;display:flex}@media (forced-colors:active){.devices.svelte-1nygetn li:where(.svelte-1nygetn),section.svelte-1nygetn,dialog.svelte-1nygetn{border-color:canvastext}}@media (prefers-reduced-motion:reduce){.svelte-1nygetn{transition-duration:.01ms!important;animation-duration:.01ms!important}}dialog.svelte-eu5bnq{box-sizing:border-box;max-block-size:calc(100dvh - 1rem);inline-size:min(52rem,100vw - 1rem);max-inline-size:none;color:var(--theme-text);background:var(--theme-surface);border:1px solid var(--theme-border);border-radius:var(--theme-radius);box-shadow:0 .75rem 2rem var(--theme-shadow);padding:0}dialog.svelte-eu5bnq::backdrop{background:color-mix(in srgb, var(--theme-canvas) 70%, transparent)}.scratchpad-shell.svelte-eu5bnq{box-sizing:border-box;min-block-size:min(42rem,100dvh - 1rem);max-block-size:calc(100dvh - 1rem);padding:max(1rem, env(safe-area-inset-top)) max(1rem, env(safe-area-inset-right)) max(1rem, env(safe-area-inset-bottom)) max(1rem, env(safe-area-inset-left));grid-template-rows:auto auto minmax(12rem,1fr) auto;gap:.75rem;display:grid}header.svelte-eu5bnq{justify-content:space-between;align-items:flex-start;gap:1rem;display:flex}h2.svelte-eu5bnq,p.svelte-eu5bnq{margin:0}h2.svelte-eu5bnq{font-family:var(--theme-font-display)}header.svelte-eu5bnq p:where(.svelte-eu5bnq){color:var(--theme-text-muted)}label.svelte-eu5bnq{font-weight:700}textarea.svelte-eu5bnq{box-sizing:border-box;resize:none;min-block-size:12rem;inline-size:100%;min-inline-size:0;color:var(--theme-text);background:var(--theme-canvas);border:1px solid var(--theme-border);border-radius:calc(var(--theme-radius) / 2);font:1rem/1.45 var(--theme-font-code);tab-size:2;padding:.75rem}button.svelte-eu5bnq{min-block-size:44px;font:inherit}.close.svelte-eu5bnq{inline-size:44px;color:inherit;background:0 0;border:0;flex:none;padding:0;font-size:2rem;line-height:1}.actions.svelte-eu5bnq{flex-wrap:wrap;gap:.5rem;display:flex}.actions.svelte-eu5bnq button:where(.svelte-eu5bnq){flex:7rem}.danger.svelte-eu5bnq{color:var(--theme-error)}.clear-confirmation.svelte-eu5bnq{border:1px solid var(--theme-error);border-radius:calc(var(--theme-radius) / 2);gap:.5rem;padding:.75rem;display:grid}.feedback.svelte-eu5bnq{color:var(--theme-error);font-weight:700}@media (width<=32rem){dialog.svelte-eu5bnq{border-inline:0;border-radius:0;max-block-size:100dvh;inline-size:100vw}.scratchpad-shell.svelte-eu5bnq{min-block-size:100dvh;max-block-size:100dvh}}@media (forced-colors:active){dialog.svelte-eu5bnq,textarea.svelte-eu5bnq,.clear-confirmation.svelte-eu5bnq{border-color:canvastext}}.chat-view.svelte-1d2e8zz{margin-inline:calc(.25rem - var(--page-inline-padding))}.chat-tail.svelte-1d2e8zz{block-size:1px;scroll-margin-block-end:var(--bottom-navigation-clearance)}.swipe-surface.svelte-1d2e8zz{touch-action:pan-y}.evidence-mode.svelte-1d2e8zz{box-sizing:border-box;inline-size:100%;min-inline-size:0;padding:0}.session-profile-manager-header.svelte-1d2e8zz{box-sizing:border-box;inline-size:100%;min-inline-size:0;padding-inline:max(1rem, env(safe-area-inset-left)) max(1rem, env(safe-area-inset-right));justify-content:space-between;align-items:safe center;gap:1rem;display:flex}.session-profile-manager-header.svelte-1d2e8zz h2:where(.svelte-1d2e8zz){overflow-wrap:anywhere;min-inline-size:0;margin:0}.close-profile-manager.svelte-1d2e8zz{min-block-size:2.5rem;inline-size:2.5rem;color:inherit;background:0 0;border:0;flex:none;padding:0;font-size:2rem;line-height:1}.enrollment.svelte-1c5qcm6{box-sizing:border-box;inline-size:100%;max-inline-size:none;background:var(--theme-page);min-height:100dvh;color:var(--theme-text);place-items:center;margin:0;padding:1rem;display:grid}.card.svelte-1c5qcm6{box-sizing:border-box;background:var(--theme-surface);border:1px solid var(--theme-border);border-radius:calc(var(--theme-radius) * 2);width:min(100%,42rem);box-shadow:0 .5rem 1.5rem var(--theme-shadow);padding:clamp(1.25rem,5vw,3rem)}.brand.svelte-1c5qcm6{color:var(--theme-info);font-family:var(--theme-font-display);letter-spacing:.08em;text-transform:uppercase;font-weight:700}h1.svelte-1c5qcm6{font-family:var(--theme-font-display);margin-block:.25rem 1rem;font-size:clamp(1.8rem,7vw,3rem)}.warning.svelte-1c5qcm6{border-left:.3rem solid var(--theme-warning);background:var(--theme-surface-subtle);padding:1rem}label.svelte-1c5qcm6,input.svelte-1c5qcm6{box-sizing:border-box;width:100%;display:block}label.svelte-1c5qcm6{margin-top:1.5rem;font-weight:700}input.svelte-1c5qcm6,button.svelte-1c5qcm6{min-height:44px;font:inherit}input.svelte-1c5qcm6{margin-top:.4rem;padding:.6rem}button.svelte-1c5qcm6{cursor:pointer;border-radius:.4rem;margin-top:1rem;padding:.55rem 1rem}.authorize.svelte-1c5qcm6{background:var(--theme-accent);width:100%;color:var(--theme-accent-contrast);border-color:var(--theme-accent);font-weight:700}.feedback.svelte-1c5qcm6{color:var(--theme-info);font-weight:700}.error.svelte-1c5qcm6{color:var(--theme-error);font-weight:700}.handoff.svelte-1c5qcm6{border-top:1px solid var(--theme-border);grid-template-columns:minmax(0,1fr);gap:1rem;margin-top:2rem;padding-top:1.5rem;display:grid}.handoff.svelte-1c5qcm6 img:where(.svelte-1c5qcm6){background:var(--theme-canvas);width:12rem;max-width:100%;padding:.5rem}a.svelte-1c5qcm6{color:var(--theme-info);overflow-wrap:anywhere}.copy.svelte-1c5qcm6{display:block}@media (width>=48rem){.handoff.svelte-1c5qcm6{grid-template-columns:12rem minmax(0,1fr);align-items:start}}@media (prefers-reduced-motion:reduce){.svelte-1c5qcm6,.svelte-1c5qcm6:before,.svelte-1c5qcm6:after{scroll-behavior:auto!important;transition-duration:.01ms!important;animation-duration:.01ms!important}}.login.svelte-1byekj9{box-sizing:border-box;inline-size:100%;max-inline-size:none;background:var(--theme-page);min-height:100dvh;color:var(--theme-text);place-items:center;margin:0;padding:1rem;display:grid}.card.svelte-1byekj9{box-sizing:border-box;background:var(--theme-surface);border:1px solid var(--theme-border);border-radius:calc(var(--theme-radius) * 2);width:min(100%,32rem);box-shadow:0 .5rem 1.5rem var(--theme-shadow);padding:clamp(1.25rem,5vw,3rem)}.brand.svelte-1byekj9{color:var(--theme-info);font-family:var(--theme-font-display);letter-spacing:.08em;text-transform:uppercase;font-weight:700}h1.svelte-1byekj9{font-family:var(--theme-font-display);margin-block:.25rem 1rem;font-size:clamp(1.8rem,7vw,3rem)}.sign-in.svelte-1byekj9{border-radius:var(--theme-radius);background:var(--theme-accent);width:100%;min-height:44px;color:var(--theme-accent-contrast);border-color:var(--theme-accent);font:inherit;margin-top:1rem;padding:.55rem 1rem;font-weight:700}.error.svelte-1byekj9{color:var(--theme-error);font-weight:700}@media (prefers-reduced-motion:reduce){.svelte-1byekj9,.svelte-1byekj9:before,.svelte-1byekj9:after{scroll-behavior:auto!important;transition-duration:.01ms!important;animation-duration:.01ms!important}}.auth-gate.svelte-y74n0s{max-width:32rem;color:var(--theme-text);background:var(--theme-surface);border:1px solid var(--theme-border);border-radius:var(--theme-radius);box-shadow:0 .5rem 1.5rem var(--theme-shadow);margin:12vh auto;padding:2rem}.auth-gate.svelte-y74n0s h1:where(.svelte-y74n0s){font-family:var(--theme-font-display)}button.svelte-y74n0s{margin-right:.75rem}@font-face{font-family:Syne;font-style:normal;font-display:swap;font-weight:600;src:url(/assets/syne-greek-600-normal-BpFII5Ja.woff2)format("woff2"),url(/assets/syne-greek-600-normal-BJs4kvyH.woff)format("woff");unicode-range:U+370-377,U+37A-37F,U+384-38A,U+38C,U+38E-3A1,U+3A3-3FF}@font-face{font-family:Syne;font-style:normal;font-display:swap;font-weight:600;src:url(/assets/syne-latin-ext-600-normal-ZnizrDKU.woff2)format("woff2"),url(/assets/syne-latin-ext-600-normal-DEzBMW8B.woff)format("woff");unicode-range:U+100-2BA,U+2BD-2C5,U+2C7-2CC,U+2CE-2D7,U+2DD-2FF,U+304,U+308,U+329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Syne;font-style:normal;font-display:swap;font-weight:600;src:url(/assets/syne-latin-600-normal-BiwQbQXw.woff2)format("woff2"),url(/assets/syne-latin-600-normal-dRu9QuIh.woff)format("woff");unicode-range:U+??,U+131,U+152-153,U+2BB-2BC,U+2C6,U+2DA,U+2DC,U+304,U+308,U+329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:JetBrains Mono;font-style:normal;font-display:swap;font-weight:400;src:url(/assets/jetbrains-mono-cyrillic-ext-400-normal-C_uLvvQ5.woff2)format("woff2"),url(/assets/jetbrains-mono-cyrillic-ext-400-normal-Bh0R7Dhr.woff)format("woff");unicode-range:U+460-52F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:JetBrains Mono;font-style:normal;font-display:swap;font-weight:400;src:url(/assets/jetbrains-mono-cyrillic-400-normal-BEIGL1Tu.woff2)format("woff2"),url(/assets/jetbrains-mono-cyrillic-400-normal-ugxPyKxw.woff)format("woff");unicode-range:U+301,U+400-45F,U+490-491,U+4B0-4B1,U+2116}@font-face{font-family:JetBrains Mono;font-style:normal;font-display:swap;font-weight:400;src:url(/assets/jetbrains-mono-greek-400-normal-C190GLew.woff2)format("woff2"),url(/assets/jetbrains-mono-greek-400-normal-B9oWc5Lo.woff)format("woff");unicode-range:U+370-377,U+37A-37F,U+384-38A,U+38C,U+38E-3A1,U+3A3-3FF}@font-face{font-family:JetBrains Mono;font-style:normal;font-display:swap;font-weight:400;src:url(/assets/jetbrains-mono-vietnamese-400-normal-ByoDsISC.woff2)format("woff2"),url(/assets/jetbrains-mono-vietnamese-400-normal-CqNFfHCs.woff)format("woff");unicode-range:U+102-103,U+110-111,U+128-129,U+168-169,U+1A0-1A1,U+1AF-1B0,U+300-301,U+303-304,U+308-309,U+323,U+329,U+1EA0-1EF9,U+20AB}@font-face{font-family:JetBrains Mono;font-style:normal;font-display:swap;font-weight:400;src:url(/assets/jetbrains-mono-latin-ext-400-normal-Bc8Ftmh3.woff2)format("woff2"),url(/assets/jetbrains-mono-latin-ext-400-normal-fXTG6kC5.woff)format("woff");unicode-range:U+100-2BA,U+2BD-2C5,U+2C7-2CC,U+2CE-2D7,U+2DD-2FF,U+304,U+308,U+329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:JetBrains Mono;font-style:normal;font-display:swap;font-weight:400;src:url(/assets/jetbrains-mono-latin-400-normal-V6pRDFza.woff2)format("woff2"),url(/assets/jetbrains-mono-latin-400-normal-6-qcROiO.woff)format("woff");unicode-range:U+??,U+131,U+152-153,U+2BB-2BC,U+2C6,U+2DA,U+2DC,U+304,U+308,U+329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}:root{--theme-font-body:system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;--theme-font-display:"Syne", var(--theme-font-body);--theme-font-code:"JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;--theme-motion-fast:.12s;--theme-radius:.5rem}:root[data-theme=minimal-light]{--lightningcss-light:initial;--lightningcss-dark: ;color-scheme:light;--theme-page:#fff;--theme-canvas:#fff;--theme-surface:#fff;--theme-surface-subtle:#f3f4f6;--theme-text:#171717;--theme-text-muted:#525252;--theme-border:#525252;--theme-focus:#005fcc;--theme-accent:#171717;--theme-accent-contrast:#fff;--theme-control-hover:#e5e7eb;--theme-control-pressed:#262626;--theme-control-pressed-contrast:#fff;--theme-control-disabled:#737373;--theme-success:#166534;--theme-warning:#854d0e;--theme-error:#b91c1c;--theme-info:#1d4ed8;--theme-code:#f3f4f6;--theme-shadow:#17171740}:root[data-theme=minimal-dark]{--lightningcss-light: ;--lightningcss-dark:initial;color-scheme:dark;--theme-page:#171717;--theme-canvas:#171717;--theme-surface:#262626;--theme-surface-subtle:#404040;--theme-text:#fafafa;--theme-text-muted:#d4d4d4;--theme-border:#a3a3a3;--theme-focus:#93c5fd;--theme-accent:#fafafa;--theme-accent-contrast:#171717;--theme-control-hover:#404040;--theme-control-pressed:#fafafa;--theme-control-pressed-contrast:#171717;--theme-control-disabled:#a3a3a3;--theme-success:#86efac;--theme-warning:#fcd34d;--theme-error:#fca5a5;--theme-info:#93c5fd;--theme-code:#262626;--theme-shadow:#00000080}:root[data-theme=dyne-org]{--lightningcss-light:initial;--lightningcss-dark: ;color-scheme:light;--theme-page:#f4f0e8;--theme-canvas:#fffdf8;--theme-surface:#fffaf1;--theme-surface-subtle:#eee6d8;--theme-text:#171411;--theme-text-muted:#5f564c;--theme-border:#75695b;--theme-focus:#5e2ca5;--theme-accent:#c7460c;--theme-accent-contrast:#fffdf8;--theme-control-hover:#f4ddcf;--theme-control-pressed:#bd3d0d;--theme-control-pressed-contrast:#fffdf8;--theme-control-disabled:#93887b;--theme-success:#287a50;--theme-warning:#9a5a00;--theme-error:#b42318;--theme-info:#5e2ca5;--theme-code:#f1e9db;--theme-shadow:#17141138}:root{--bottom-navigation-clearance:calc(4rem + env(safe-area-inset-bottom));--sticky-header-clearance:calc(5rem + env(safe-area-inset-top));--lightningcss-light:initial;--lightningcss-dark: ;color-scheme:light;font-family:var(--theme-font-body)}body{min-block-size:100dvh;color:var(--theme-text);background:var(--theme-page);accent-color:var(--theme-accent);margin:0}.visually-hidden{clip-path:inset(50%)!important;white-space:nowrap!important;border:0!important;block-size:1px!important;inline-size:1px!important;margin:-1px!important;padding:0!important;position:absolute!important;overflow:hidden!important}main{--page-inline-padding:1rem;box-sizing:border-box;min-block-size:100dvh;max-inline-size:42rem;padding:calc(1rem + env(safe-area-inset-top)) var(--page-inline-padding) calc(var(--bottom-navigation-clearance) + 1rem);margin-inline:auto}@media (width<=24rem){main{--page-inline-padding:.5rem}}.app-header{z-index:1;margin:calc(-1rem - env(safe-area-inset-top)) calc(.25rem - var(--page-inline-padding)) 1.5rem;padding:calc(1rem + env(safe-area-inset-top)) calc(var(--page-inline-padding) - .25rem) .75rem;background:color-mix(in srgb, var(--theme-page) 78%, transparent);-webkit-backdrop-filter:blur(.75rem);backdrop-filter:blur(.75rem);flex-wrap:wrap;justify-content:space-between;align-items:center;gap:1rem;display:flex;position:sticky;inset-block-start:0}.app-header [role=status]{overflow-wrap:anywhere;text-align:end;min-inline-size:0;margin:0}.brand{align-items:center;gap:.4rem;display:flex}.header-actions{flex:none;align-items:center;gap:.25rem;margin-inline-start:auto;display:flex}.weekly-quota{font-variant-numeric:tabular-nums;white-space:nowrap;font-size:.875rem}.menu-trigger{min-block-size:44px;inline-size:44px;color:inherit;background:0 0;border:0;flex:none;place-items:center;padding:0;display:grid}.menu-lines{gap:.25rem;inline-size:1.25rem;display:grid}.menu-lines span{box-sizing:border-box;background:currentColor;block-size:1px;display:block}.menu-lines span:first-child,.menu-lines span:nth-child(2),.menu-lines span:last-child{block-size:2px}@media (width<=28rem){.app-header [role=status]{flex-basis:100%;margin-inline-start:0}}.brand-icon{block-size:2rem;inline-size:2rem}.brand-logotype{block-size:auto;inline-size:6.25rem}.dark-asset,:root[data-logo-tone=light] .light-asset{display:none}:root[data-logo-tone=light] .dark-asset{display:initial}.configuration-panel{box-sizing:border-box;overscroll-behavior:contain;max-block-size:calc(100dvh - 5.5rem);min-inline-size:min(13rem,100vw - 2rem);max-inline-size:calc(100vw - 2rem);color:var(--theme-text);background:var(--theme-surface);border:1px solid var(--theme-border);border-radius:var(--theme-radius);box-shadow:0 .5rem 1.5rem var(--theme-shadow);padding:.75rem;position:fixed;inset:4.5rem 1rem auto auto;overflow-y:auto}.configuration-logo{block-size:auto;inline-size:4.5rem;margin-block-end:.5rem;margin-inline-start:auto;display:block}.appearance-control{align-items:center;gap:.5rem;min-inline-size:0;display:flex}.appearance-control span{font-family:var(--theme-font-display);letter-spacing:-.08em;font-weight:700}.appearance-control select{field-sizing:content;flex:auto;min-block-size:2.25rem;inline-size:auto;min-inline-size:0;max-inline-size:100%;padding-inline:.5rem}.bottom-navigation{padding:.5rem calc(.25rem + env(safe-area-inset-right)) calc(.5rem + env(safe-area-inset-bottom)) calc(.25rem + env(safe-area-inset-left));background:var(--theme-surface);border-block-start:1px solid var(--theme-border);grid-template-columns:repeat(4,minmax(0,1fr));gap:.25rem;display:grid;position:fixed;inset-block-end:0;inset-inline:0}.bottom-navigation button{overflow-wrap:anywhere;word-break:break-word;min-inline-size:0;max-inline-size:100%;transition:color var(--theme-motion-fast) ease, background-color var(--theme-motion-fast) ease, box-shadow var(--theme-motion-fast) ease;padding-inline:0}.bottom-navigation button:hover:not(:disabled){background:var(--theme-control-hover)}.bottom-navigation button:active:not(:disabled){background:var(--theme-control-pressed);color:var(--theme-control-pressed-contrast)}.bottom-navigation button[aria-pressed=true]{color:var(--theme-accent-contrast);background:var(--theme-accent);box-shadow:inset 0 .2rem 0 color-mix(in srgb, var(--theme-accent-contrast) 25%, transparent);font-weight:700}.bottom-navigation button:disabled{color:var(--theme-control-disabled);cursor:not-allowed;opacity:.65}@media (width<=30rem){:root{--bottom-navigation-clearance:calc(10rem + env(safe-area-inset-bottom));--sticky-header-clearance:calc(14rem + env(safe-area-inset-top))}.bottom-navigation{grid-template-columns:repeat(2,minmax(0,1fr))}.bottom-navigation button{text-align:center;padding-inline:.25rem}}button{min-block-size:44px;font:inherit;color:var(--theme-text);background:var(--theme-surface);border:1px solid var(--theme-border);border-radius:var(--theme-radius);cursor:pointer}button:hover:not(:disabled){background:var(--theme-control-hover)}button:active:not(:disabled){background:var(--theme-control-pressed);color:var(--theme-control-pressed-contrast)}button:disabled{color:var(--theme-control-disabled);cursor:not-allowed}.git-view button{scroll-margin-block:var(--sticky-header-clearance) var(--bottom-navigation-clearance)}input,select,textarea{box-sizing:border-box;min-block-size:44px;inline-size:100%;font:inherit;color:var(--theme-text);background:var(--theme-surface);border:1px solid var(--theme-border);border-radius:var(--theme-radius);font-size:max(1rem,16px)}input::placeholder,textarea::placeholder{color:var(--theme-text-muted)}:focus-visible{outline:3px solid var(--theme-focus);outline-offset:3px}@media (prefers-reduced-motion:reduce){*,:before,:after{scroll-behavior:auto!important;transition-duration:.01ms!important;animation-duration:.01ms!important}}@media (forced-colors:active){button,input,select,textarea{border:1px solid canvastext}}