castle-web-cli 0.4.170 → 0.4.171

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.
Files changed (51) hide show
  1. package/dist/agent-prompts.d.ts +1 -0
  2. package/dist/agent-prompts.js +3 -0
  3. package/dist/agent.js +47 -11
  4. package/dist/castle-host/host.js +71 -0
  5. package/dist/ide.d.ts +10 -0
  6. package/dist/ide.js +5 -5
  7. package/dist/init.js +1 -1
  8. package/dist/shell/assets/index-6odVZQSZ.css +1 -0
  9. package/dist/shell/assets/index-Ws0WrCbi.js +445 -0
  10. package/dist/shell/index.html +3 -3
  11. package/kits/base/castle.json +1 -1
  12. package/kits/base/sdk/README.md +17 -1
  13. package/kits/base/sdk/commands.d.ts +14 -0
  14. package/kits/base/sdk/user.d.ts +4 -0
  15. package/kits/base/sdk/user.js +36 -1
  16. package/kits/multiplayer-2d/CLAUDE.md +20 -9
  17. package/kits/multiplayer-2d/castle.json +2 -2
  18. package/kits/multiplayer-2d/code/server/players.js +27 -6
  19. package/kits/multiplayer-2d/code/server/world.js +24 -1
  20. package/kits/multiplayer-2d/code/systems/multiplayer.js +45 -4
  21. package/kits/multiplayer-2d/package-lock.json +26 -1
  22. package/kits/multiplayer-2d/package.json +2 -0
  23. package/kits/multiplayer-3d/CLAUDE.md +28 -9
  24. package/kits/multiplayer-3d/castle.json +3 -3
  25. package/kits/multiplayer-3d/code/server/players.js +54 -5
  26. package/kits/multiplayer-3d/code/server/world.js +45 -1
  27. package/kits/multiplayer-3d/code/systems/multiplayer.js +108 -6
  28. package/kits/multiplayer-3d/package-lock.json +26 -1
  29. package/kits/multiplayer-3d/package.json +2 -0
  30. package/kits/physics-2d/castle.json +1 -1
  31. package/kits/physics-2d/editors/PxArtEditor.jsx +2 -2
  32. package/kits/physics-3d/behaviors/Pickup.jsx +5 -3
  33. package/kits/physics-3d/castle.json +1 -1
  34. package/kits/real-time/CLAUDE.md +23 -4
  35. package/kits/real-time/castle.json +1 -1
  36. package/kits/real-time/code/client/connection.js +9 -4
  37. package/kits/real-time/code/client/joinOverlay.js +46 -0
  38. package/kits/real-time/code/client/messages.js +4 -0
  39. package/kits/real-time/code/server/gameHooks.js +4 -0
  40. package/kits/real-time/code/server/persist.js +105 -0
  41. package/kits/real-time/code/server/session.js +289 -19
  42. package/kits/real-time/package-lock.json +1139 -0
  43. package/kits/turn-based/CLAUDE.md +76 -20
  44. package/kits/turn-based/castle.json +1 -1
  45. package/kits/turn-based/code/server/index.js +16 -5
  46. package/kits/turn-based/package.json +2 -1
  47. package/kits/turn-based/room.js +162 -13
  48. package/kits/turn-based/testing.js +276 -92
  49. package/package.json +1 -2
  50. package/dist/shell/assets/index-BvQmVwlO.css +0 -1
  51. package/dist/shell/assets/index-CV5sBby1.js +0 -445
@@ -90,6 +90,7 @@ export declare function userTurnInstruction(opts: {
90
90
  messages: string[];
91
91
  interruptedDraft?: string;
92
92
  attachments?: string[];
93
+ files?: string[];
93
94
  }): string;
94
95
  export declare function buildTaskPrompt(opts: {
95
96
  deckLabel: string;
@@ -882,6 +882,9 @@ export function userTurnInstruction(opts) {
882
882
  // while the CLI backends open the saved files themselves.
883
883
  parts.push(`The user attached image file(s), saved in the deck at: ${opts.attachments.join(", ")}. If the images are not already visible in this message, open them with your read tool. Take them into account; pass the paths along to task agents that need them.`);
884
884
  }
885
+ if (opts.files && opts.files.length > 0) {
886
+ parts.push(`The user pointed at these deck files: ${opts.files.join(", ")}. Read them with your read tool if you need them to reply. When you spawn a task one of these files concerns, name that path in that task's prompt so the agent reads it; do not mention it to tasks it does not concern.`);
887
+ }
885
888
  return parts.join("\n\n");
886
889
  }
887
890
  export function buildTaskPrompt(opts) {
package/dist/agent.js CHANGED
@@ -18,6 +18,7 @@ import { execFileSync, spawn } from 'child_process';
18
18
  import { quickReferenceFor } from './platformDoc.js';
19
19
  import { IMPORTS_DIR } from './imports.js';
20
20
  import { isSameOriginUpgrade } from './wsOrigin.js';
21
+ import { resolveDeckPath } from './ide.js';
21
22
  import * as fs from 'fs';
22
23
  import * as os from 'os';
23
24
  import * as path from 'path';
@@ -616,6 +617,9 @@ const RESULT_SUMMARY_CHARS = 600;
616
617
  // TRANSCRIPT_BYTE_BUDGET in agent-prompts.ts), so this term needs its own bound.
617
618
  const PLAN_BYTE_BUDGET = 8 * 1024;
618
619
  const MAX_ATTACHMENTS = 6;
620
+ // @-mentioned files are path references, so the only cost is instruction bytes
621
+ // -- but a client is not the one to decide how many the router is told about.
622
+ const MAX_MESSAGE_FILES = 12;
619
623
  const MAX_ATTACHMENT_BYTES = 8 * 1024 * 1024;
620
624
  const TERMINAL_STATUSES = ['done', 'failed', 'interrupted'];
621
625
  function nowIso() {
@@ -3010,6 +3014,20 @@ function saveAttachments(attachmentsDir, messageId, images) {
3010
3014
  }
3011
3015
  return saved;
3012
3016
  }
3017
+ // Deck-relative paths a client @-mentioned, keeping only the ones that name a
3018
+ // real place in this deck. Nothing is read here: the paths travel as references
3019
+ // and whoever needs the contents opens them.
3020
+ function validMessageFiles(deckDir, files) {
3021
+ if (!Array.isArray(files))
3022
+ return [];
3023
+ const kept = [];
3024
+ for (const entry of files.slice(0, MAX_MESSAGE_FILES)) {
3025
+ const resolved = resolveDeckPath(deckDir, entry);
3026
+ if (resolved.ok && !kept.includes(resolved.rel))
3027
+ kept.push(resolved.rel);
3028
+ }
3029
+ return kept;
3030
+ }
3013
3031
  // Cap on the failure detail shown in a board row -- just enough for the
3014
3032
  // router to reason about what went wrong, not the full crash dump.
3015
3033
  const ERROR_PREVIEW_CHARS = 200;
@@ -3814,7 +3832,7 @@ function startChildRegistry(registryPath, groups) {
3814
3832
  // messages.json was committed by a prior drain (its turn ran, finished or
3815
3833
  // not -- a logged message is considered handled), so re-queueing it would
3816
3834
  // double-deliver. Order is preserved.
3817
- function loadRecoverableSends(pendingPath, committedIds) {
3835
+ function loadRecoverableSends(deckDir, pendingPath, committedIds) {
3818
3836
  const stored = readJsonFile(pendingPath);
3819
3837
  if (!Array.isArray(stored))
3820
3838
  return [];
@@ -3829,6 +3847,11 @@ function loadRecoverableSends(pendingPath, committedIds) {
3829
3847
  id: item.id,
3830
3848
  text: item.text,
3831
3849
  attachments: item.attachments.filter((a) => typeof a === 'string'),
3850
+ // Re-validated rather than trusted: enqueue is where a path earns its
3851
+ // place, and a mirror on disk is not evidence it ever did. A build that
3852
+ // predates @-mentions wrote no files at all, which is a send worth
3853
+ // recovering for its words, not a malformed one.
3854
+ files: validMessageFiles(deckDir, item.files),
3832
3855
  });
3833
3856
  }
3834
3857
  }
@@ -3918,11 +3941,12 @@ function startRouterTurn(ctx, instruction, attachments = []) {
3918
3941
  }
3919
3942
  // Commit each drained send to the message log (skipping ones already logged
3920
3943
  // -- see PendingSend.logged -- so a re-carried send doesn't double its user
3921
- // bubble) and collect the instruction pieces: message texts and attachment
3922
- // paths, in drain order.
3944
+ // bubble) and collect the instruction pieces: message texts, attachment paths
3945
+ // and @-mentioned file paths, in drain order.
3923
3946
  function commitDrainedSends(drained, log) {
3924
3947
  const texts = [];
3925
3948
  const attachmentPaths = [];
3949
+ const filePaths = [];
3926
3950
  for (const item of drained) {
3927
3951
  if (!item.logged) {
3928
3952
  const message = {
@@ -3934,6 +3958,8 @@ function commitDrainedSends(drained, log) {
3934
3958
  };
3935
3959
  if (item.attachments.length > 0)
3936
3960
  message.attachments = item.attachments;
3961
+ if (item.files.length > 0)
3962
+ message.files = item.files;
3937
3963
  log.add(message);
3938
3964
  }
3939
3965
  if (item.text.trim())
@@ -3941,8 +3967,12 @@ function commitDrainedSends(drained, log) {
3941
3967
  for (const name of item.attachments) {
3942
3968
  attachmentPaths.push(path.join('.castle', 'agent', 'attachments', name));
3943
3969
  }
3970
+ for (const file of item.files) {
3971
+ if (!filePaths.includes(file))
3972
+ filePaths.push(file);
3973
+ }
3944
3974
  }
3945
- return { texts, attachmentPaths };
3975
+ return { texts, attachmentPaths, filePaths };
3946
3976
  }
3947
3977
  // Drain the queue into the log as real user messages and start one follow-up
3948
3978
  // turn addressing them all (a burst batches into a single turn). A pending
@@ -3958,7 +3988,7 @@ function maybeStartRouterQueueTurn(ctx) {
3958
3988
  // Kept so a fold or manual interrupt of THIS turn can hand these sends back
3959
3989
  // to reclaimInFlightSends if it dies before producing anything visible.
3960
3990
  state.inFlightSends = drained;
3961
- const { texts, attachmentPaths } = commitDrainedSends(drained, ctx.log);
3991
+ const { texts, attachmentPaths, filePaths } = commitDrainedSends(drained, ctx.log);
3962
3992
  // The queue is now committed to messages.json; clear its durable mirror.
3963
3993
  persistPendingSends(ctx);
3964
3994
  const draft = state.pendingInterruptedDraft;
@@ -3969,6 +3999,7 @@ function maybeStartRouterQueueTurn(ctx) {
3969
3999
  messages: texts,
3970
4000
  interruptedDraft: draft || undefined,
3971
4001
  attachments: attachmentPaths,
4002
+ files: filePaths,
3972
4003
  }), attachmentPaths);
3973
4004
  }
3974
4005
  // The turn settled: clear the busy flag, broadcast it, then flush anything
@@ -4017,7 +4048,7 @@ function safeClientMessageId(clientId) {
4017
4048
  return null;
4018
4049
  return /^[A-Za-z0-9_-]{1,32}$/.test(clientId) ? clientId : null;
4019
4050
  }
4020
- function handleQueueUserMessage(ctx, text, images, clientId) {
4051
+ function handleQueueUserMessage(ctx, text, images, files, clientId) {
4021
4052
  const { state } = ctx;
4022
4053
  // Mid-run: queue (don't interrupt). It shows as a queued row in the
4023
4054
  // composer and flushes when the current turn settles. Idle: start now.
@@ -4040,7 +4071,12 @@ function handleQueueUserMessage(ctx, text, images, clientId) {
4040
4071
  }
4041
4072
  const id = sentId ?? nanoid(8);
4042
4073
  const attachments = saveAttachments(ctx.attachmentsDir, id, images);
4043
- state.pendingSends.push({ id, text, attachments });
4074
+ state.pendingSends.push({
4075
+ id,
4076
+ text,
4077
+ attachments,
4078
+ files: validMessageFiles(ctx.deckDir, files),
4079
+ });
4044
4080
  persistPendingSends(ctx);
4045
4081
  if (state.routerRunning) {
4046
4082
  // The new send was just pushed above, so folding now (which unshifts the
@@ -4121,11 +4157,11 @@ function createRouterQueue(deps) {
4121
4157
  };
4122
4158
  // Restart recovery: re-enqueue sends that never reached the message log,
4123
4159
  // so an interrupted serve resumes them exactly once instead of losing them.
4124
- ctx.state.pendingSends.push(...loadRecoverableSends(ctx.pendingPath, new Set(deps.messages.map((m) => m.id))));
4160
+ ctx.state.pendingSends.push(...loadRecoverableSends(ctx.deckDir, ctx.pendingPath, new Set(deps.messages.map((m) => m.id))));
4125
4161
  persistPendingSends(ctx);
4126
4162
  maybeStartRouterQueueTurn(ctx);
4127
4163
  return {
4128
- handleUserMessage: (text, images, clientId) => handleQueueUserMessage(ctx, text, images, clientId),
4164
+ handleUserMessage: (text, images, files, clientId) => handleQueueUserMessage(ctx, text, images, files, clientId),
4129
4165
  interruptRouter: () => interruptRouterQueue(ctx),
4130
4166
  cancelQueued: (index) => cancelQueuedSend(ctx, index),
4131
4167
  isRunning: () => ctx.state.routerRunning,
@@ -4318,7 +4354,7 @@ export function createAgentServer(opts) {
4318
4354
  broadcast({ type: 'message-picker', id, pickerAnswers: msg.pickerAnswers });
4319
4355
  }
4320
4356
  if (text.trim())
4321
- routerQueue.handleUserMessage(text.trim(), undefined);
4357
+ routerQueue.handleUserMessage(text.trim(), undefined, undefined);
4322
4358
  }
4323
4359
  function handleTaskAck(id, rejected) {
4324
4360
  taskStore.acknowledge(id, rejected);
@@ -4404,7 +4440,7 @@ export function createAgentServer(opts) {
4404
4440
  if (!duplicate) {
4405
4441
  if (clientId !== null)
4406
4442
  rememberClientId(clientId);
4407
- routerQueue.handleUserMessage(typeof msg.text === 'string' ? msg.text.trim() : '', msg.images, clientId ?? undefined);
4443
+ routerQueue.handleUserMessage(typeof msg.text === 'string' ? msg.text.trim() : '', msg.images, msg.files, clientId ?? undefined);
4408
4444
  }
4409
4445
  if (clientId !== null) {
4410
4446
  if (socket.readyState === socket.OPEN) {
@@ -24,6 +24,7 @@ const COMMAND_NAMES = [
24
24
  "leaderboard.save",
25
25
  "leaderboard.show",
26
26
  "user.getCurrent",
27
+ "user.get",
27
28
  "time.getServerTime",
28
29
  "pass.has",
29
30
  "pass.offer",
@@ -120,6 +121,8 @@ function runCommand(ctx, command, params, caps) {
120
121
  return leaderboardShow(ctx, params, caps);
121
122
  case "user.getCurrent":
122
123
  return Promise.resolve(userGetCurrent(ctx));
124
+ case "user.get":
125
+ return userGet(params, gql);
123
126
  case "time.getServerTime":
124
127
  return timeGetServerTime(gql);
125
128
  case "pass.has":
@@ -669,6 +672,56 @@ function userGetCurrent(ctx) {
669
672
  user: { userId: ctx.userId, username: ctx.username, isAnonymous: ctx.isAnonymous === true },
670
673
  };
671
674
  }
675
+ // One user's public profile, or null when there is no such user. The photo and
676
+ // frame are fetched here and handed over as data: urls, since a deck's CSP
677
+ // allows no image host and the host is outside it.
678
+ async function userGet(params, gql) {
679
+ const userId = asString(params.userId, "userId", "user.get");
680
+ const data = await graphql(gql, USER_QUERY, { userId }, "user.get");
681
+ const user = data.user;
682
+ if (!user?.userId || !user.username)
683
+ return { user: null };
684
+ const [photoUrl, frameUrl] = await Promise.all([
685
+ imageDataUrl(user.photo?.avatarUrl),
686
+ imageDataUrl(user.photoFrame?.smallFrameUrl),
687
+ ]);
688
+ return {
689
+ user: {
690
+ userId: user.userId,
691
+ username: user.username,
692
+ isAnonymous: user.isAnonymous === true,
693
+ photoUrl,
694
+ frameUrl,
695
+ color: asOptionalString(user.usernameStyle?.color),
696
+ },
697
+ };
698
+ }
699
+ // An image as a data: url, or null when there is none or the fetch fails. A
700
+ // missing avatar is not an error for the deck.
701
+ async function imageDataUrl(url) {
702
+ if (typeof url !== "string" || url.length === 0 || typeof fetch !== "function") {
703
+ return null;
704
+ }
705
+ try {
706
+ const response = await fetch(url);
707
+ if (!response.ok)
708
+ return null;
709
+ const type = response.headers.get("content-type") ?? "image/png";
710
+ return `data:${type};base64,${base64(new Uint8Array(await response.arrayBuffer()))}`;
711
+ }
712
+ catch {
713
+ return null;
714
+ }
715
+ }
716
+ // `btoa` takes a binary string, built here in chunks small enough for
717
+ // `fromCharCode` to spread.
718
+ function base64(bytes) {
719
+ let binary = "";
720
+ for (let i = 0; i < bytes.length; i += 8192) {
721
+ binary += String.fromCharCode(...bytes.subarray(i, i + 8192));
722
+ }
723
+ return btoa(binary);
724
+ }
672
725
  async function timeGetServerTime(gql) {
673
726
  const data = await graphql(gql, SERVER_TIME_QUERY, {}, "time.getServerTime");
674
727
  return {
@@ -1116,6 +1169,24 @@ const PASSES_FOR_DECK_QUERY = `
1116
1169
  }
1117
1170
  }
1118
1171
  `;
1172
+ const USER_QUERY = `
1173
+ query CastleUserProfile($userId: ID!) {
1174
+ user(userId: $userId) {
1175
+ userId
1176
+ username
1177
+ isAnonymous
1178
+ photo {
1179
+ avatarUrl
1180
+ }
1181
+ photoFrame {
1182
+ smallFrameUrl
1183
+ }
1184
+ usernameStyle {
1185
+ color
1186
+ }
1187
+ }
1188
+ }
1189
+ `;
1119
1190
  const SERVER_TIME_QUERY = `
1120
1191
  query CastleServerTime {
1121
1192
  serverTime {
package/dist/ide.d.ts CHANGED
@@ -9,6 +9,16 @@ export declare const FAVICON_LINK_TAGS: string;
9
9
  export declare const FILES_API_PREFIX = "/__castle/files/";
10
10
  export declare const COVER_API_PATH = "/__castle/cover";
11
11
  export { COVER_FILE };
12
+ export declare function resolveDeckPath(deckDir: string, requestedPath: unknown, opts?: {
13
+ mutation?: boolean;
14
+ }): {
15
+ ok: true;
16
+ abs: string;
17
+ rel: string;
18
+ } | {
19
+ ok: false;
20
+ error: string;
21
+ };
12
22
  export interface IdeServer {
13
23
  /** Serve the IDE page + its static assets. Returns true if it handled the request. */
14
24
  handleHttpRequest(req: http.IncomingMessage, res: http.ServerResponse, reqPath: string): boolean;
package/dist/ide.js CHANGED
@@ -1,7 +1,7 @@
1
- // IDE backend for `castle-web serve`: serves the shell UI (a dockview workspace
2
- // bundled from `src/shell/` into `dist/shell/`) and runs the terminal panel's
3
- // PTY. The deck loads in an iframe inside the shell; an agent CLI can be driven
4
- // in the terminal panel right next to the live deck.
1
+ // IDE backend for `castle-web serve`: serves the shell UI (the flow
2
+ // workbench bundled from `src/shell/` into `dist/shell/`) and runs the
3
+ // terminal panel's PTY. The deck loads in an iframe inside the shell; an
4
+ // agent CLI can be driven in the terminal panel right next to the live deck.
5
5
  //
6
6
  // Backend pattern ported from castle-cli's `ide` branch: @lydell/node-pty for
7
7
  // the PTY, an @xterm/headless screen + @xterm/addon-serialize so a reconnecting
@@ -226,7 +226,7 @@ function isImportPath(rel) {
226
226
  // writeProjectFile guards so the builtin editor can't escape the deck. Callers
227
227
  // that are about to CHANGE the file pass `mutation`, which additionally refuses
228
228
  // anything a dependency owns.
229
- function resolveDeckPath(deckDir, requestedPath, opts = {}) {
229
+ export function resolveDeckPath(deckDir, requestedPath, opts = {}) {
230
230
  if (typeof requestedPath !== 'string' || requestedPath.trim() === '') {
231
231
  return { ok: false, error: 'Missing file path.' };
232
232
  }
package/dist/init.js CHANGED
@@ -55,7 +55,7 @@ if (!(await mountEditorRoute())) startGame(initCard());
55
55
  // Registry version of castle-web-sdk to inject when scaffolding from a
56
56
  // globally-installed castle-web (not from inside the workspace). Bumped
57
57
  // alongside cli/sdk version bumps.
58
- const PUBLISHED_SDK_VERSION = '0.4.27';
58
+ const PUBLISHED_SDK_VERSION = '0.4.28';
59
59
  // Range, not a pin: `castle-web-fonts` is its own package precisely so a tenth
60
60
  // face can ship without a cli release, and a caret range means an existing
61
61
  // deck's next install picks it up. Nothing here has to move when it does.
@@ -0,0 +1 @@
1
+ :root{--castle-font-body:baltomobile, Balto, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;--castle-font-display:Basteleur, Georgia, "Times New Roman", serif;--castle-text-size-small:11px;--castle-text-size-base:13px;--castle-text-size-large:15px;--castle-text-style-smallcaps-size:var(--castle-text-size-small);--castle-text-style-smallcaps-letter-spacing:.05em;--castle-text-style-smallcaps-transform:uppercase;--castle-text-primary:#e6e6e6;--castle-text-secondary:#b3b3b3;--castle-text-muted:#888;--castle-text-dim:#525252;--castle-text-dark:#111;--castle-surface-1:#000;--castle-surface-2:#0c0c0c;--castle-surface-3:#181818;--castle-surface-4:#242424;--castle-surface-5:#303030;--castle-surface-6:#3c3c3c;--castle-surface-light:#e6e6e6;--castle-border-1:#2a2a2a;--castle-border-2:#6a6a6a;--castle-border-3:#3a3a3a;--castle-border-4:#e6e6e6;--castle-danger-text:#e86a73;--castle-danger-surface:#73172d;--castle-danger-surface-hover:#b4202a;--castle-warn-text:#e8b25a;--castle-warn-surface:#5a3d0a;--castle-space-small:3px;--castle-space-base:6px;--castle-space-large:12px;--castle-radius-small:4px;--castle-radius-base:8px;--castle-radius-pill:999px;--castle-button-height:24px;--castle-button-icon-size:16px;--castle-button-height-large:36px;--castle-button-icon-size-large:24px;--castle-icon-size-inline:12px;--castle-panel-header-height:36px;--castle-panel-header-height-mobile:48px}.text-style-smallcaps{font-size:var(--castle-text-style-smallcaps-size);letter-spacing:var(--castle-text-style-smallcaps-letter-spacing);text-transform:var(--castle-text-style-smallcaps-transform)}.icon-inline{flex:0 0 var(--castle-icon-size-inline);width:var(--castle-icon-size-inline);height:var(--castle-icon-size-inline);font-size:var(--castle-icon-size-inline)}.icon-slot{flex:0 0 var(--castle-button-icon-size);width:var(--castle-button-icon-size);height:var(--castle-button-icon-size);justify-content:center;align-items:center;display:flex}.icon-cell{flex:0 0 var(--castle-button-height);width:var(--castle-button-height);height:var(--castle-button-height);color:var(--castle-text-dim);pointer-events:none;justify-content:center;align-items:center;display:inline-flex}.icon-slot svg,.icon-slot iconify-icon,.icon-cell svg,.icon-cell iconify-icon{flex:0 0 var(--castle-button-icon-size);width:var(--castle-button-icon-size);height:var(--castle-button-icon-size);font-size:var(--castle-button-icon-size)}.button{justify-content:center;align-items:center;gap:var(--castle-space-base);max-width:100%;height:var(--castle-button-height);padding:0 var(--castle-space-base);border-radius:var(--castle-radius-small);background:var(--castle-surface-4);color:var(--castle-text-primary);font-family:var(--castle-font-body);font-size:var(--castle-text-size-base);white-space:nowrap;cursor:pointer;border:0;line-height:1.3;display:inline-flex}.button:not(.button-icon){min-width:0}.button>span{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}.button:hover,.button.is-hover{background:var(--castle-surface-5)}.button:active,.button.is-pressed{background:var(--castle-surface-3)}.button:focus-visible,.button.is-focus{outline:1px solid var(--castle-border-2);outline-offset:2px}.button[aria-pressed=true],.button[aria-pressed=true]:hover,.button[aria-pressed=true]:active{background:var(--castle-surface-light);color:var(--castle-text-dark)}.button:disabled{opacity:.4;cursor:default}.button-icon{width:var(--castle-button-height);padding:0}.button-icon-large{width:var(--castle-button-height-large);height:var(--castle-button-height-large)}.button-danger{background:var(--castle-danger-surface);color:var(--castle-text-primary)}.button-danger:hover,.button-danger.is-hover{background:var(--castle-danger-surface-hover)}.button-danger:active,.button-danger.is-pressed{background:var(--castle-danger-surface)}.button-quiet{color:var(--castle-text-dim);background:0 0}.button-quiet:hover,.button-quiet.is-hover{background:var(--castle-surface-5);color:var(--castle-text-primary)}.button-quiet:active,.button-quiet.is-pressed{background:var(--castle-surface-3)}.button-quiet[aria-pressed=true],.button-quiet[aria-pressed=true]:hover,.button-quiet[aria-pressed=true]:active{background:var(--castle-surface-5);color:var(--castle-text-primary)}.button svg,.button iconify-icon{width:var(--castle-button-icon-size);height:var(--castle-button-icon-size);font-size:var(--castle-button-icon-size)}.button-icon-large svg,.button-icon-large iconify-icon{width:var(--castle-button-icon-size-large);height:var(--castle-button-icon-size-large);font-size:var(--castle-button-icon-size-large)}.button-badge{min-width:16px;height:16px;padding:0 var(--castle-space-small);border-radius:var(--castle-radius-pill);background:var(--castle-surface-5);color:var(--castle-text-secondary);font-size:var(--castle-text-size-small);font-variant-numeric:tabular-nums;text-align:center;text-overflow:clip;flex:none;line-height:16px;overflow:hidden}.button>.button-badge{text-overflow:clip;min-width:16px;overflow:hidden}.text-field{min-width:0;height:var(--castle-button-height);padding:0 var(--castle-space-base);border:1px solid var(--castle-border-3);border-radius:var(--castle-radius-small);background:var(--castle-surface-3);color:var(--castle-text-primary);font-family:var(--castle-font-body);font-size:var(--castle-text-size-base);cursor:text;outline:0}.text-field::placeholder{color:var(--castle-text-muted)}.text-field:hover,.text-field.is-hover{background:var(--castle-surface-4)}.text-field:focus,.text-field:focus-visible,.text-field.is-focus{outline:1px solid var(--castle-border-2);outline-offset:2px}.text-field:disabled{opacity:.4;cursor:default}.select{min-width:0;height:var(--castle-button-height);padding:0 var(--castle-space-base);border:1px solid var(--castle-border-3);border-radius:var(--castle-radius-small);background:var(--castle-surface-3);color:var(--castle-text-primary);font-family:var(--castle-font-body);font-size:var(--castle-text-size-base);cursor:pointer;outline:0}.select:hover,.select.is-hover{background:var(--castle-surface-4)}.select:focus,.select:focus-visible,.select.is-focus{outline:1px solid var(--castle-border-2);outline-offset:2px}.select:disabled{opacity:.4;cursor:default}.dock-control{justify-content:center;align-items:center;gap:var(--castle-space-base);max-width:100%;height:var(--castle-panel-header-height);padding:0 var(--castle-space-large);border:1px solid var(--castle-border-1);border-radius:var(--castle-radius-base);background:var(--castle-surface-3);color:var(--castle-text-primary);font-family:var(--castle-font-body);font-size:var(--castle-text-size-base);white-space:nowrap;cursor:pointer;font-weight:600;line-height:1;display:inline-flex}.dock-control:not(.dock-control-icon){min-width:0}.dock-control>span{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}.dock-control-icon{width:var(--castle-panel-header-height);padding:0}.dock-control-quiet{background:0 0;border-color:#0000;justify-content:flex-start;min-width:0}.dock-control-mark{background:var(--castle-surface-1)}.dock-control-group{cursor:default;box-shadow:inset 0 0 0 1px var(--castle-border-1);border:none;justify-content:flex-start;align-items:stretch;gap:0;padding:0;overflow:hidden}button.dock-control:hover,button.dock-control.is-hover{background:var(--castle-surface-4);border-color:var(--castle-border-3)}button.dock-control:active,button.dock-control.is-pressed{background:var(--castle-surface-2)}button.dock-control-quiet:active,button.dock-control-quiet.is-pressed{background:var(--castle-surface-3)}button.dock-control:focus-visible,button.dock-control.is-focus{outline:1px solid var(--castle-border-2);outline-offset:2px}.dock-control:disabled{opacity:.4;cursor:default}button.dock-control:disabled:hover,button.dock-control:disabled.is-hover{background:var(--castle-surface-3);border-color:var(--castle-border-1)}button.dock-control-quiet:disabled:hover,button.dock-control-quiet:disabled.is-hover{background:0 0;border-color:#0000}button.dock-control-mark:disabled:hover,button.dock-control-mark:disabled.is-hover{background:var(--castle-surface-1)}.dock-control svg,.dock-control iconify-icon{width:var(--castle-button-icon-size);height:var(--castle-button-icon-size);font-size:var(--castle-button-icon-size);flex-shrink:0}.dock-control-mark svg,.dock-control-mark img{width:20px;height:20px}.dock-control-mark img{object-fit:contain;display:block}.dock-segment{flex:0 0 var(--castle-panel-header-height);width:var(--castle-panel-header-height);height:var(--castle-panel-header-height);color:var(--castle-text-muted);cursor:pointer;background:0 0;border:none;border-radius:0;justify-content:center;align-items:center;padding:0;display:inline-flex}.dock-segment iconify-icon,.dock-segment svg{width:var(--castle-button-icon-size);height:var(--castle-button-icon-size);font-size:var(--castle-button-icon-size)}@media (hover:hover){.dock-segment:hover:not(.is-active){color:var(--castle-text-primary);background:var(--castle-surface-5)}}.dock-segment.is-hover:not(.is-active){color:var(--castle-text-primary);background:var(--castle-surface-5)}.dock-segment.is-active{color:var(--castle-text-dark);background:var(--castle-surface-light)}.dock-segment.is-drag-origin{opacity:0;pointer-events:none;flex:0 0 0;width:0;min-width:0;max-width:0;padding:0;overflow:hidden}.dock-segment-slot{flex:0 0 var(--castle-panel-header-height);width:var(--castle-panel-header-height);height:var(--castle-panel-header-height);color:var(--castle-text-primary);background:var(--castle-surface-6);pointer-events:none;justify-content:center;align-items:center;display:inline-flex}.dock-segment-slot iconify-icon,.dock-segment-slot svg{width:var(--castle-button-icon-size);height:var(--castle-button-icon-size);font-size:var(--castle-button-icon-size)}.dock-segment-ghost{border-radius:var(--castle-radius-small);pointer-events:none;box-shadow:0 8px 24px #00000073}.dock-segment:has(.dock-badge){position:relative}.dock-segment .dock-badge{top:var(--castle-space-small);right:var(--castle-space-small);z-index:1;background:var(--castle-surface-light);color:var(--castle-text-dark);pointer-events:none;transform-origin:50%;position:absolute}.dock-segment .dock-badge:not(.is-appearing){visibility:hidden;opacity:0;transform:scale(.45)}.dock-segment .dock-badge.is-appearing{visibility:visible;animation:.28s cubic-bezier(.2,.8,.2,1) both dock-badge-appear}@keyframes dock-badge-appear{0%{opacity:0;transform:scale(.45)}70%{opacity:1;transform:scale(1.08)}to{opacity:1;transform:scale(1)}}@media (prefers-reduced-motion:reduce){.dock-segment .dock-badge.is-appearing{animation:none}}.menu{gap:var(--castle-space-small);width:max-content;min-width:144px;padding:var(--castle-space-small);border:1px solid var(--castle-border-3);border-radius:var(--castle-radius-base);background:var(--castle-surface-5);flex-direction:column;display:flex;box-shadow:0 8px 24px #0000008c}.menu-item{align-items:center;gap:var(--castle-space-base);width:100%;height:26px;padding:0 var(--castle-space-base);border-radius:var(--castle-radius-small);color:var(--castle-text-primary);font-family:var(--castle-font-body);font-size:var(--castle-text-size-base);cursor:pointer;background:0 0;border:0;display:flex}.menu-icon{flex:0 0 16px;width:16px;height:16px;font-size:16px}svg.menu-icon,iconify-icon.menu-icon{fill:none;stroke:currentColor;stroke-linecap:round;stroke-linejoin:round;stroke-width:1.5px}.menu-icon svg,.menu-icon iconify-icon{width:16px;height:16px;font-size:16px}.menu-item:hover:not(:disabled),.menu-item.is-hover:not(:disabled){background:var(--castle-surface-6)}.menu-item:disabled{opacity:.4;cursor:default}.menu-item-label{text-overflow:ellipsis;white-space:nowrap;text-align:left;flex:auto;min-width:0;overflow:hidden}.menu-check{color:var(--castle-text-primary);flex:none}.menu-keys{margin-left:var(--castle-space-large);color:var(--castle-text-muted);font-size:var(--castle-text-size-small);white-space:nowrap;flex:none}.menu-item:disabled .menu-keys{color:inherit}.menu-item-danger{color:var(--castle-danger-text)}.menu-separator{height:1px;margin:var(--castle-space-small) 0;background:var(--castle-border-3)}.menu-header{padding:var(--castle-space-small) var(--castle-space-base);color:var(--castle-text-muted);font-size:var(--castle-text-size-small);letter-spacing:.04em;text-transform:uppercase}.menu-confirm{gap:var(--castle-space-base);min-width:180px;padding:var(--castle-space-small) var(--castle-space-base);flex-direction:column;display:flex}.menu-confirm-text{color:var(--castle-text-primary);font-size:var(--castle-text-size-base);margin:0}.menu-confirm-actions{justify-content:flex-end;gap:var(--castle-space-base);display:flex}.menu-error{padding:var(--castle-space-small) var(--castle-space-base);color:var(--castle-danger-text);font-size:var(--castle-text-size-small);margin:0}.feedback-quiet{--castle-feedback-text:var(--castle-text-muted);--castle-feedback-surface:var(--castle-surface-3);--castle-feedback-border:var(--castle-border-3)}.feedback-warn{--castle-feedback-text:var(--castle-warn-text);--castle-feedback-surface:var(--castle-warn-surface);--castle-feedback-surface-hover:color-mix(in srgb, var(--castle-warn-text) 35%, var(--castle-warn-surface));--castle-feedback-border:color-mix(in srgb, var(--castle-warn-text), var(--castle-warn-surface))}.feedback-danger{--castle-feedback-text:var(--castle-danger-text);--castle-feedback-surface:var(--castle-danger-surface);--castle-feedback-surface-hover:var(--castle-danger-surface-hover);--castle-feedback-border:color-mix(in srgb, var(--castle-danger-text), var(--castle-danger-surface))}.feedback-note{color:var(--castle-feedback-text);font-size:var(--castle-text-size-base);margin:0}.feedback-banner{align-items:center;gap:var(--castle-space-base);min-height:var(--castle-panel-header-height);padding:var(--castle-space-base);border-bottom:1px solid var(--castle-feedback-border);background:var(--castle-feedback-surface);color:var(--castle-feedback-text);font-size:var(--castle-text-size-base);display:flex}.feedback-banner>span:not(.icon-cell){flex:auto;min-width:0}.feedback-banner .icon-cell{color:inherit}.feedback-warn .button,.feedback-danger .button{border:1px solid var(--castle-feedback-border);background:var(--castle-feedback-surface);color:var(--castle-text-primary)}.feedback-warn .button:hover,.feedback-warn .button.is-hover,.feedback-danger .button:hover,.feedback-danger .button.is-hover{background:var(--castle-feedback-surface-hover)}.feedback-warn .button:active,.feedback-warn .button.is-pressed,.feedback-danger .button:active,.feedback-danger .button.is-pressed{background:var(--castle-feedback-surface)}.feedback-takeover{padding:calc(var(--castle-space-large) * 2);border:1px solid var(--castle-feedback-border);border-radius:var(--castle-radius-base);background:var(--castle-feedback-surface);color:var(--castle-feedback-text);font-size:var(--castle-text-size-base);text-align:center;justify-content:center;align-items:center;display:flex}.panel{border:1px solid var(--castle-border-1);border-radius:var(--castle-radius-base);background:var(--castle-surface-2);color:var(--castle-text-primary);font-family:var(--castle-font-body);transition:border-color .12s;position:relative;overflow:hidden}@media (hover:hover){.panel:hover{border-color:var(--castle-border-3)}}.panel.is-hover{border-color:var(--castle-border-3)}.panel.is-active,.panel.is-active:hover,.panel.is-active.is-hover{border-color:var(--castle-border-2)}.panel.is-dragging,.panel.is-dragging:hover,.panel.is-dragging.is-hover,.panel.is-dragging.is-active{border-color:var(--castle-border-4)}.panel-header,.panel-tabs-header{height:var(--castle-panel-header-height);padding:0 var(--castle-space-base);border-bottom:1px solid var(--castle-border-1);background:var(--castle-surface-3);align-items:center;display:flex}@media (hover:hover){.panel-header:hover,.panel-tabs-header:hover{background:var(--castle-surface-4);cursor:grab}}.panel-header.is-hover,.panel-tabs-header.is-hover{background:var(--castle-surface-4);cursor:grab}.panel-header:active,.panel-header.is-pressed,.panel-tabs-header:active,.panel-tabs-header.is-pressed{cursor:grabbing}.panel-tabs-header{align-items:stretch;gap:var(--castle-space-base)}.panel-title{align-items:center;gap:var(--castle-space-base);min-width:0;padding:0 var(--castle-space-base);color:var(--castle-text-primary);font-family:var(--castle-font-display);font-size:var(--castle-text-size-base);margin:0 auto 0 0;font-weight:700;line-height:1.5;display:inline-flex}.panel-title svg,.panel-title iconify-icon{width:var(--castle-button-icon-size);height:var(--castle-button-icon-size);font-size:var(--castle-button-icon-size);flex-shrink:0}.panel-header-actions{align-items:center;gap:var(--castle-space-small);margin-left:auto;display:flex}.panel-type-toggle{align-items:center;gap:var(--castle-space-base);min-width:0;max-width:100%;height:var(--castle-button-height);padding:0 var(--castle-space-base);border-radius:var(--castle-radius-small);color:var(--castle-text-primary);font-family:var(--castle-font-display);font-size:var(--castle-text-size-base);white-space:nowrap;cursor:pointer;background:0 0;border:0;align-self:center;font-weight:700;display:inline-flex}.panel-type-toggle:hover,.panel-type-toggle.is-hover,.panel-type-toggle[aria-pressed=true]{background:var(--castle-surface-5)}.panel-type-toggle svg,.panel-type-toggle iconify-icon{width:var(--castle-button-icon-size);height:var(--castle-button-icon-size);font-size:var(--castle-button-icon-size);flex-shrink:0}.panel-tabs{align-items:center;gap:var(--castle-space-base);flex:auto;min-width:0;display:flex}.panel-tab{max-width:160px;height:var(--castle-button-height);padding:var(--castle-space-small) var(--castle-space-base);border-radius:var(--castle-radius-small);color:var(--castle-text-dim);font-family:var(--castle-font-body);font-size:var(--castle-text-size-base);white-space:nowrap;cursor:pointer;background:0 0;border:0;align-items:center;line-height:18px;display:flex;position:relative;overflow:hidden}.panel-tab>span{text-overflow:ellipsis;min-width:0;overflow:hidden}.panel-tab:hover,.panel-tab.is-hover{background:var(--castle-surface-5);color:var(--castle-text-secondary)}.panel-tab.is-active{background:var(--castle-surface-5);color:var(--castle-text-primary)}.panel-tab:hover>span,.panel-tab.is-hover>span{-webkit-mask-image:linear-gradient(to right, #000 calc(100% - (var(--castle-button-icon-size) + var(--castle-space-large))), transparent 100%);mask-image:linear-gradient(to right, #000 calc(100% - (var(--castle-button-icon-size) + var(--castle-space-large))), transparent 100%)}.panel-tab.is-narrow:not(.is-active):hover>span,.panel-tab.is-narrow:not(.is-active).is-hover>span{-webkit-mask-image:none;mask-image:none}.panel-tab-close{z-index:1;top:var(--castle-space-small);right:var(--castle-space-small);width:calc(var(--castle-button-icon-size) + var(--castle-space-large));height:var(--castle-button-icon-size);border-radius:var(--castle-radius-small);background:linear-gradient(to right, transparent, var(--castle-surface-3) 45%);color:currentColor;cursor:pointer;opacity:0;pointer-events:none;border:0;justify-content:flex-end;align-items:center;padding:0;display:inline-flex;position:absolute}.panel-tab-close svg,.panel-tab-close iconify-icon{width:var(--castle-button-icon-size);height:var(--castle-button-icon-size);font-size:var(--castle-button-icon-size)}.panel-tab:hover .panel-tab-close,.panel-tab.is-hover .panel-tab-close,.panel-tab:focus-within .panel-tab-close{opacity:1;pointer-events:auto;background:linear-gradient(to right, transparent, var(--castle-surface-5) 45%)}.panel-tab.is-active .panel-tab-close{background:linear-gradient(to right, transparent, var(--castle-surface-5) 45%)}.panel-tab-close:hover,.panel-tab-close.is-hover{background:linear-gradient(to right, transparent, var(--castle-surface-5) 45%);color:var(--castle-text-primary)}.panel-tab.is-narrow:not(.is-active):hover .panel-tab-close,.panel-tab.is-narrow:not(.is-active).is-hover .panel-tab-close{opacity:0;pointer-events:none}.panel-tab.is-drag-origin{opacity:0;pointer-events:none;border:0;width:0;min-width:0;max-width:0;padding:0}.panel-tab-insert{width:2px;height:var(--castle-button-height);border-radius:var(--castle-radius-pill);background:var(--castle-border-4);pointer-events:none;flex:0 0 2px}.panel-tab-ghost{padding:var(--castle-space-base) var(--castle-space-large);border:1px solid var(--castle-border-1);border-radius:var(--castle-radius-small);background:var(--castle-surface-3);color:var(--castle-text-primary);font-size:var(--castle-text-size-base);pointer-events:none;box-shadow:0 8px 24px #00000073}.panel-mobile-current{justify-content:center;align-self:center;align-items:center;gap:var(--castle-space-base);min-width:0;max-width:100%;height:var(--castle-button-height-large);padding:0 var(--castle-space-base);border-radius:var(--castle-radius-small);color:var(--castle-text-primary);font-family:var(--castle-font-body);font-size:var(--castle-text-size-base);cursor:pointer;background:0 0;border:0;display:inline-flex}.panel-mobile-current:hover,.panel-mobile-current.is-hover{background:var(--castle-surface-5)}.panel-mobile-current-text{align-items:baseline;gap:var(--castle-space-small);min-width:0;display:flex}.panel-mobile-current-label{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}.panel-mobile-current strong,.panel-mobile-current-type{font-family:var(--castle-font-display);flex-shrink:0;font-weight:700}.panel-mobile-current svg,.panel-mobile-current iconify-icon{width:var(--castle-button-icon-size-large);height:var(--castle-button-icon-size-large);font-size:var(--castle-button-icon-size-large);flex:none}:root{--lightningcss-light: ;--lightningcss-dark:initial;color-scheme:dark;--v2-gutter:#000;--v2-surface:#0d0d0d;--v2-raised:#161616;--v2-hover:#1d1d1d;--v2-fg:#e6e6e6;--v2-head:#e8e8e8;--v2-secondary:#b3b3b3;--v2-muted:#888;--v2-dim:#525252;--v2-placeholder:#666;--v2-ink:#111;--v2-white:#fff;--v2-border:#2a2a2a;--v2-accent:#622461;--v2-accent-hover:#855484;--v2-error-bg:#5a2b2b;--v2-warn:#e2c08d;--v2-error:#e08c8c;--v2-overlay-scrim:#00000059;--v2-overlay-code:#00000038;--v2-overlay-code-block:#00000047;--v2-overlay-task:#141414eb;--v2-overlay-feed-code:#7878784d;--v2-overlay-white-subtle:#ffffff0f;--v2-overlay-white-hover:#ffffff14;--v2-overlay-white-border:#ffffff24;--v2-overlay-white-quote:#fff6;--v2-overlay-white-dim:#ffffffd9;--v2-shadow-pop:0 10px 24px -10px #000000e6;--v2-selection:#e6e6e62e;--v2-mono:ui-monospace, SFMono-Regular, Menlo, monospace;--panel-gutter:10px;--panel-chrome-radius:8px}*{box-sizing:border-box}html,body,#root{height:100%;margin:0}body{color:var(--v2-fg);background:var(--v2-surface);font-family:baltomobile,Balto,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif;overflow:hidden}.panel-error{height:100%;color:var(--v2-muted);flex-direction:column;align-items:flex-start;gap:8px;padding:14px 16px;font-size:13px;display:flex;overflow:auto}.panel-error-title{color:var(--v2-fg)}.panel-error-msg{white-space:pre-wrap;word-break:break-word;max-width:100%;color:var(--v2-muted);margin:0;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px}.panel-error-retry{font:inherit;border:1px solid var(--v2-border);background:var(--v2-raised);color:var(--v2-fg);cursor:pointer;border-radius:4px;padding:3px 10px;font-size:12px}.panel-error-retry:hover{background:var(--v2-hover)}.editor-panel-root{flex-direction:column;width:100%;height:100%;min-height:0;display:flex}.editor-shell{flex:auto;min-height:0;display:flex}.editor-panel-body{flex-direction:column;flex:auto;min-width:0;min-height:0;display:flex}.editor-panel-view{flex:auto;min-width:0;min-height:0;position:relative}.editor-import-banner{background:var(--flow-surface,#181818);border-bottom:1px solid var(--v2-border,#2a2a2a);color:var(--v2-muted,#888);flex:none;align-items:center;gap:8px;padding:8px;font:12px ui-sans-serif,system-ui,sans-serif;display:flex}.editor-import-chip{border:1px solid var(--v2-border,#2a2a2a);background:var(--v2-raised,#161616);color:var(--v2-muted,#888);letter-spacing:.02em;border-radius:999px;flex:none;align-items:center;padding:2px 8px;font-size:12px;line-height:1.4;display:inline-flex}.editor-import-banner-text{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}.editor-import-banner-action{border:1px solid var(--v2-border,#2a2a2a);background:var(--v2-raised,#161616);color:var(--v2-text,#ddd);font:inherit;cursor:pointer;border-radius:4px;flex:none;margin-left:auto;padding:2px 10px}.editor-import-banner-action:hover{border-color:var(--v2-muted,#888)}.editor-import-chip.editor-fork-chip{color:var(--v2-text,#ddd)}.editor-fork-modal-scrim{z-index:40;background:#00000080;justify-content:center;align-items:center;display:flex;position:fixed;inset:0}.editor-fork-modal{border:1px solid var(--v2-border,#2a2a2a);background:var(--flow-surface,#181818);max-width:420px;color:var(--v2-text,#ddd);border-radius:6px;padding:16px;font:13px ui-sans-serif,system-ui,sans-serif}.editor-fork-modal-title{margin-bottom:8px;font-weight:600}.editor-fork-modal-body{color:var(--v2-muted,#888);line-height:1.5}.editor-fork-modal-actions{justify-content:flex-end;gap:8px;margin-top:16px;display:flex}.editor-fork-modal-actions button{border:1px solid var(--v2-border,#2a2a2a);background:var(--v2-raised,#161616);color:var(--v2-text,#ddd);font:inherit;cursor:pointer;border-radius:4px;padding:4px 12px}.editor-fork-modal-actions button:hover{border-color:var(--v2-muted,#888)}.editor-contextbar{background:var(--v2-gutter,#0d0d0d);border-bottom:1px solid var(--v2-border,#2a2a2a);flex:none;align-items:center;gap:8px;padding:5px 8px;display:flex}.editor-drawer-toggle{width:26px;height:24px;color:var(--v2-muted,#888);cursor:pointer;background:0 0;border:1px solid #0000;border-radius:6px;flex:none;justify-content:center;align-items:center;display:inline-flex}.editor-drawer-toggle:hover{color:var(--v2-fg,#e7e7ef);background:var(--v2-surface,#1b1b2b)}.editor-drawer-toggle.on{color:var(--v2-fg,#e7e7ef);background:var(--v2-surface,#1b1b2b);border-color:var(--v2-border,#3a3a52)}.editor-drawer{background:var(--v2-gutter,#0d0d0d);border-right:1px solid var(--v2-border,#2a2a2a);flex:none;width:190px;padding:6px 4px;overflow-y:auto}.editor-drawer-folder{letter-spacing:.03em;text-transform:uppercase;color:var(--v2-muted,#888);padding:6px 8px 2px;font:10px ui-sans-serif,system-ui,sans-serif}.editor-drawer-item{width:100%;color:var(--v2-secondary,#b3b3b3);cursor:pointer;text-align:left;text-overflow:ellipsis;white-space:nowrap;background:0 0;border:none;border-radius:6px;padding:5px 8px;font:12px ui-sans-serif,system-ui,sans-serif;display:block;overflow:hidden}.editor-drawer-item:hover{background:var(--v2-surface,#1b1b2b);color:var(--v2-fg,#e7e7ef)}.editor-drawer-item.current{color:var(--v2-fg,#e7e7ef);background:#ffffff1a}.editor-drawer-empty{color:var(--v2-muted,#888);padding:10px 8px;font-size:12px}.editor-view-picker{background:var(--v2-surface,#1b1b2b);color:var(--v2-fg,#e7e7ef);border:1px solid var(--v2-border,#3a3a52);cursor:pointer;border-radius:6px;flex:none;padding:3px 6px;font:12px system-ui,sans-serif}.editor-contextbar-path{text-overflow:ellipsis;white-space:nowrap;color:var(--v2-muted,#888);flex:auto;font:11px ui-monospace,SFMono-Regular,Menlo,monospace;overflow:hidden}.editor-contextbar-reload{width:22px;height:22px;color:var(--v2-muted,#888);cursor:pointer;background:0 0;border:none;border-radius:5px;flex:none;justify-content:center;align-items:center;padding:0;display:inline-flex}.editor-contextbar-reload:hover{color:var(--v2-white,#fff);background:var(--v2-overlay-white-hover,#ffffff14)}.editor-contextbar-reload svg{width:13px;height:13px}.deck-panel{background:var(--v2-surface);width:100%;height:100%}.deck-frame{border:0;width:100%;height:100%;display:block}.play-panel{background:var(--castle-surface-2);flex-direction:column;width:100%;height:100%;display:flex}.play-scene-picker{padding:0 var(--castle-space-large) var(--castle-space-large);flex:none;justify-content:center;align-items:center;display:flex}.play-stage{min-height:0;padding:var(--castle-space-large);flex:auto;justify-content:center;align-items:center;display:flex;container-type:size}.play-stage:has(+.play-scene-picker){padding-bottom:var(--castle-space-base)}.play-frame-shell{aspect-ratio:5/7;border-radius:4%/2.85714%;width:min(100cqw,71.4286cqh);height:min(100cqh,140cqw);position:relative;overflow:hidden}.play-frame-shell .deck-frame{width:100%;height:100%}.play-logs{border-top:1px solid var(--castle-border-1);background:var(--castle-surface-2);color:var(--castle-text-secondary);flex:none;position:relative}.play-logs.is-open{--play-logs-height:160px;flex:0 0 var(--play-logs-height);height:var(--play-logs-height);flex-direction:column;min-height:0;display:flex;overflow:hidden}.play-logs-resize{z-index:2;cursor:row-resize;touch-action:none;height:12px;display:none;position:absolute;top:-6px;left:0;right:0}.play-logs.is-open>.play-logs-resize{display:block}body.play-logs-resizing,body.play-logs-resizing *{cursor:row-resize!important;-webkit-user-select:none!important;user-select:none!important}.play-logs-header{min-height:calc(var(--castle-button-height) + 2 * var(--castle-space-base));padding:var(--castle-space-base);align-items:center;column-gap:var(--castle-space-base);cursor:pointer;flex:none;grid-template-columns:minmax(max-content,1fr) minmax(0,auto) minmax(max-content,1fr);display:grid;position:relative}.play-logs-header:hover{background:var(--castle-surface-3)}.play-logs-expand{z-index:0;cursor:pointer;background:0 0;border:0;padding:0;position:absolute;inset:0}.play-logs-expand:focus{outline:none}.play-logs-expand:focus-visible{outline:2px solid var(--castle-border-2);outline-offset:-2px}.play-logs-label{align-items:center;gap:var(--castle-space-base);min-width:0;color:var(--castle-text-dim);pointer-events:none;justify-self:start;display:inline-flex}.play-logs-header:hover .play-logs-label{color:var(--castle-text-primary)}.play-logs-label svg{flex:0 0 var(--castle-button-icon-size);width:var(--castle-button-icon-size);height:var(--castle-button-icon-size);font-size:var(--castle-button-icon-size)}.play-logs-pending{min-width:0;color:var(--castle-text-muted);font-size:var(--castle-text-size-small);text-overflow:ellipsis;white-space:nowrap;pointer-events:none;grid-column:2;margin:0;line-height:1.4;overflow:hidden}.play-logs-restart{z-index:1;grid-column:3;justify-self:end;min-width:max-content;position:relative}.play-logs-restart.is-pending,.play-logs-restart.is-pending:hover,.play-logs-restart.is-pending:active{color:var(--castle-warn-text)}.play-logs-restart-icon{line-height:1;display:inline-flex}.play-logs-restart-icon.is-spinning{animation:.6s linear infinite play-logs-spin}@keyframes play-logs-spin{to{transform:rotate(360deg)}}.play-logs-toolbar{align-items:center;gap:var(--castle-space-base);padding:var(--castle-space-base);border-top:1px solid var(--castle-border-1);flex-wrap:wrap;flex:none;display:flex}.play-logs-body{min-height:0;padding:var(--castle-space-base) var(--castle-space-large);border-top:1px solid var(--castle-border-1);font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:var(--castle-text-size-small);flex:auto;line-height:1.5;overflow-y:auto}.play-logs-line{white-space:pre-wrap;word-break:break-word}.play-logs-warn{color:var(--castle-warn-text)}.play-logs-error{color:var(--castle-danger-text)}.play-logs-empty{color:var(--castle-text-dim)}.flow-root.is-mobile .play-panel{--castle-text-size-small:14px;--castle-text-size-base:16px;--castle-text-style-smallcaps-size:var(--castle-text-size-small);--castle-button-height:var(--castle-button-height-large)}.flow-root.is-mobile .play-panel .button:not(.button-icon){padding-left:var(--castle-space-large);padding-right:var(--castle-space-large)}.flow-root.is-mobile .play-logs.is-open{--play-logs-height:200px}.flow-root.is-mobile .play-logs-header:hover{background:0 0}.flow-root.is-mobile .play-logs-header:hover .play-logs-label{color:var(--castle-text-dim)}.flow-root.is-mobile .play-stage{padding:var(--castle-space-small)}.term-panel{width:100%;height:100%;position:relative}.term-host{overscroll-behavior:contain;padding:6px;position:absolute;inset:0}.shell-root{--operator-pad:10px;--operator-col-fit:min(var(--operator-col,400px), 100%);--composer-reserve:88px;background:var(--v2-gutter);height:100%;position:relative}#chat-host{width:var(--operator-col-fit);background:var(--v2-gutter);color:var(--v2-fg);z-index:10;flex-direction:column;font-family:Balto,system-ui,-apple-system,sans-serif;display:flex;position:absolute;top:0;bottom:0;left:0}.settings-popover{z-index:2147483000;background:var(--v2-surface);width:390px;max-width:calc(100vw - 24px);max-height:calc(100vh - 16px);color:var(--v2-fg);border:1px solid var(--v2-border);box-shadow:var(--v2-shadow-pop);border-radius:8px;padding:10px 12px;font-size:13px;position:fixed;overflow:hidden auto}.settings-popover .settings-row{flex-wrap:wrap;justify-content:space-between;align-items:center;gap:6px 10px;display:flex}.settings-popover .settings-row+.settings-row{margin-top:8px}.settings-popover .settings-label{white-space:nowrap}.settings-popover .settings-seg{border:1px solid var(--v2-border);border-radius:4px;display:flex;overflow:hidden}.settings-popover .settings-opt{font:inherit;background:var(--v2-surface);color:var(--v2-muted);cursor:pointer;white-space:nowrap;border:0;padding:5px 10px;font-size:13px}.settings-popover .settings-opt+.settings-opt{border-left:1px solid var(--v2-border)}.settings-popover .settings-opt:hover{color:var(--v2-fg)}.settings-popover .settings-opt.active{background:var(--v2-accent);color:var(--v2-white)}.settings-popover .settings-text{min-width:0;font:inherit;background:var(--v2-surface);color:var(--v2-fg);border:1px solid var(--v2-border);border-radius:4px;flex:auto;padding:5px 8px;font-size:13px}.settings-popover .settings-text::placeholder{color:var(--v2-placeholder)}.settings-popover .settings-text:focus{border-color:var(--v2-accent);outline:none}.settings-popover .settings-row-stack{flex-direction:column;align-items:stretch;gap:4px;display:flex}.settings-popover .settings-row-main{flex-wrap:wrap;justify-content:space-between;align-items:center;gap:6px 10px;display:flex}.settings-popover .settings-text-warn{border-color:var(--v2-warn)}.settings-popover .settings-warning{color:var(--v2-warn);text-align:right;font-size:11px;line-height:1.35}.settings-popover .settings-warning-suggest{appearance:none;font:inherit;color:var(--v2-warn);cursor:pointer;background:0 0;border:none;margin:0;padding:0;text-decoration:underline}.settings-popover .settings-warning-suggest:hover{color:var(--v2-fg)}.settings-popover .settings-select{max-width:60%;font:inherit;background:var(--v2-surface);color:var(--v2-fg);border:1px solid var(--v2-border);cursor:pointer;border-radius:4px;flex:0 auto;padding:5px 8px;font-size:13px}.settings-popover .settings-select:focus{border-color:var(--v2-accent);outline:none}.settings-popover .settings-select option{background:var(--v2-surface);color:var(--v2-fg)}.settings-popover .settings-group+.settings-group{border-top:1px solid var(--v2-border);margin-top:12px;padding-top:12px}.settings-popover .settings-usage-text{color:var(--v2-secondary);white-space:nowrap}.settings-popover .settings-usage-subtext{color:var(--v2-muted);text-align:right;margin-top:4px;font-size:11px}.settings-popover .settings-usage-bar{background:var(--v2-border);border-radius:2px;height:4px;margin-top:6px;overflow:hidden}.settings-popover .settings-usage-fill{background:var(--v2-accent-hover);height:100%}.settings-popover .settings-usage-fill.blocked{background:var(--v2-error)}.settings-popover .settings-account-open{width:100%;font:inherit;background:var(--v2-surface);color:var(--v2-muted);border:1px solid var(--v2-border);cursor:pointer;border-radius:4px;margin-top:10px;padding:7px 12px;font-size:13px}.settings-popover .settings-account-open:hover{color:var(--v2-fg)}.settings-popover .settings-usage-actions{gap:8px;margin-top:10px;display:flex}.settings-popover .settings-usage-actions .settings-account-open{flex:1 1 0;width:auto;margin-top:0}.castle-key-heading{margin-bottom:4px;font-weight:600}.castle-key-subtitle{color:#9a9a9a;margin-bottom:14px;font-size:12px;line-height:1.5}.castle-key-tabs{border:1px solid #3a3a3a;border-radius:4px;margin-bottom:12px;display:flex;overflow:hidden}.castle-key-tab{color:#9a9a9a;font:inherit;cursor:pointer;background:#2e2e2e;border:0;flex:1;padding:6px 10px;font-size:12px}.castle-key-tab+.castle-key-tab{border-left:1px solid #3a3a3a}.castle-key-tab:hover{color:#e8e8e8}.castle-key-tab.active{color:#e8e8e8;background:#3a3a3a}.castle-key-input{box-sizing:border-box;color:#e8e8e8;width:100%;font:inherit;background:#1b1b1b;border:1px solid #3a3a3a;border-radius:4px;outline:none;padding:7px 9px;font-size:12px;display:block}.castle-key-input:focus{border-color:#4a4a4a}.castle-key-input::placeholder{color:#6a6a6a}.castle-key-stored{color:#8a8a8a;margin-top:8px;font-size:11px}.castle-key-error{color:#e8705a;margin-top:8px;font-size:11px;line-height:1.4}.castle-key-row{color:#c8c8c8;justify-content:space-between;align-items:center;gap:10px;margin-bottom:12px;display:flex}.castle-key-row button{color:#e8e8e8;font:inherit;cursor:pointer;background:#2e2e2e;border:1px solid #3a3a3a;border-radius:4px;padding:5px 12px;font-size:12px}.castle-key-row button:hover{background:#383838}.castle-key-login{margin-bottom:12px}.castle-key-signin{color:#e8e8e8;width:100%;font:inherit;cursor:pointer;background:#2e2e2e;border:1px solid #3a3a3a;border-radius:4px;padding:9px 12px;font-size:13px;display:block}.castle-key-signin:hover{background:#383838}.castle-key-or{color:#7a7a7a;letter-spacing:.08em;text-transform:uppercase;align-items:center;gap:10px;margin:14px 0;font-size:11px;display:flex}.castle-key-or:before,.castle-key-or:after{content:"";background:#3a3a3a;flex:1;height:1px}.castle-key-field-label{color:#c8c8c8;margin-bottom:6px;font-size:12px}.castle-key-url{color:#7aa2f7;word-break:break-all;-webkit-user-select:all;user-select:all;background:#1b1b1b;border:1px solid #3a3a3a;border-radius:4px;padding:8px 9px;font-size:11px;line-height:1.4;display:block}#chat-messages{scrollbar-width:none;-ms-overflow-style:none;flex-direction:column;flex:1 1 0;min-height:0;padding:0;font-size:14px;line-height:1.5;display:flex;overflow-y:auto}#chat-messages .chat-thread{opacity:0;flex-direction:column;transition:opacity .12s;display:flex}#chat-messages .chat-thread.ready{opacity:1}.shell-root.docked #chat-messages{-webkit-mask-image:linear-gradient(to bottom, var(--v2-gutter) calc(100% - var(--composer-reserve,88px)), transparent 100%);-webkit-mask-image:linear-gradient(to bottom, var(--v2-gutter) calc(100% - var(--composer-reserve,88px)), transparent 100%);mask-image:linear-gradient(to bottom, var(--v2-gutter) calc(100% - var(--composer-reserve,88px)), transparent 100%);padding:0}.shell-root.docked #chat-messages .chat-thread{padding-bottom:var(--composer-reserve,88px)}.shell-root.docked #chat-messages>:first-child{margin-top:auto}#chat-messages::-webkit-scrollbar{width:0;height:0}#chat-empty{color:var(--v2-muted)}#chat-host .msg{margin:5px 0}#chat-host .msg.user{text-align:right}#chat-host .msg.user span{background:var(--v2-white);color:var(--v2-ink);text-align:left;white-space:pre-wrap;word-break:break-word;border-radius:17px;max-width:85%;padding:7px 14px;display:inline-block}#chat-host .msg-image{border:1px solid var(--v2-border);border-radius:8px;max-width:220px;max-height:150px;margin:0 0 6px auto;display:block}#chat-host .assistant-turn{flex-direction:column;align-items:flex-start;gap:4px;margin:5px 0;display:flex}#chat-host .msg.assistant{background:var(--v2-accent);width:fit-content;color:var(--v2-white);word-break:break-word;border-radius:17px;max-width:85%;margin:0;padding:7px 14px}#chat-host .msg.assistant.errbubble{background:var(--v2-error-bg)}#chat-host .msg.assistant.streaming:after{content:"▌";opacity:.6;animation:1s step-end infinite chat-blink}@keyframes chat-blink{50%{opacity:0}}#chat-host .msg.toolline{color:var(--v2-muted);font-size:12px;font-family:var(--v2-mono);word-break:break-word;margin:4px 0}#chat-host .msg-activity{color:var(--v2-muted);font-size:12px;animation:1.4s ease-in-out infinite chat-pulse}@keyframes chat-pulse{50%{opacity:.35}}#chat-host .msg-interrupted,#chat-host .msg-error-detail{color:var(--v2-muted);font-size:12px}#chat-host .msg-error-detail summary{cursor:pointer;-webkit-user-select:none;user-select:none}#chat-host .msg-error-detail pre{background:var(--v2-overlay-scrim);white-space:pre-wrap;word-break:break-word;border-radius:6px;max-height:160px;margin:4px 0 0;padding:6px 8px;font-size:11px;overflow-y:auto}#chat-host .msg-thinking{color:var(--v2-muted);font-size:12px}#chat-host div.msg-thinking,#chat-host .msg-thinking summary{align-items:center;gap:8px;display:flex}#chat-host .msg-thinking summary{cursor:pointer;-webkit-user-select:none;user-select:none;list-style:none}#chat-host .msg-thinking summary::-webkit-details-marker{display:none}#chat-host .msg-thinking .thinking-caret{opacity:.7;border-top:4px solid #0000;border-bottom:4px solid #0000;border-left:5px solid;flex:none;width:0;height:0;transition:transform .12s}#chat-host .msg-thinking[open] .thinking-caret{transform:rotate(90deg)}#chat-host .msg-thinking .thinking-dots{gap:4px;display:inline-flex}#chat-host .msg-thinking .thinking-dots i{background:currentColor;border-radius:50%;width:6px;height:6px;animation:1.2s ease-in-out infinite thinking-bounce}#chat-host .msg-thinking .thinking-dots i:nth-child(2){animation-delay:.18s}#chat-host .msg-thinking .thinking-dots i:nth-child(3){animation-delay:.36s}#chat-host .msg-thinking .thinking-dots+.thinking-label{animation:1.4s ease-in-out infinite chat-pulse}@keyframes thinking-bounce{0%,80%,to{opacity:.3;transform:translateY(0)}40%{opacity:1;transform:translateY(-3px)}}@media (prefers-reduced-motion:reduce){#chat-host .msg-thinking .thinking-dots i,#chat-host .msg-thinking .thinking-label{animation:none}#chat-host .msg-thinking .thinking-dots i{opacity:.6}}#chat-host .msg-thinking-body{background:var(--v2-overlay-scrim);color:var(--v2-muted);border-radius:6px;max-height:160px;padding:0 12px;font-size:12px;overflow-y:auto}#chat-host .msg.md>:first-child,#chat-host .task-notes>:first-child{margin-top:0}#chat-host .msg.md>:last-child,#chat-host .task-notes>:last-child{margin-bottom:0}#chat-host .msg.md p:empty{display:none}#chat-host .msg.md p,#chat-host .task-notes p{margin:.4em 0}#chat-host .msg.md ul,#chat-host .msg.md ol,#chat-host .task-notes ul,#chat-host .task-notes ol{margin:.4em 0;padding-left:1.3em}#chat-host .msg.md li{margin:.1em 0}#chat-host .msg.md h1,#chat-host .msg.md h2,#chat-host .msg.md h3{margin:.5em 0 .3em;font-weight:700;line-height:1.25}#chat-host .msg.md h1{font-size:1.2em}#chat-host .msg.md h2{font-size:1.12em}#chat-host .msg.md h3{font-size:1.05em}#chat-host .msg.md a{color:var(--v2-white);text-underline-offset:2px;text-decoration:underline}#chat-host .msg.md code,#chat-host .task-notes code{font-family:var(--v2-mono);background:var(--v2-overlay-code);border-radius:4px;padding:.1em .35em;font-size:.9em}#chat-host .msg.md pre{background:var(--v2-overlay-code-block);white-space:pre-wrap;word-break:break-word;font-family:var(--v2-mono);border-radius:8px;margin:.5em 0;padding:8px 10px;font-size:.9em;line-height:1.4;overflow-x:auto}#chat-host .msg.md pre code{background:0 0;border-radius:0;padding:0}#chat-host .msg.md blockquote{border-left:3px solid var(--v2-overlay-white-quote);color:var(--v2-overlay-white-dim);margin:.5em 0;padding-left:.8em}.shell-root.docked #chat-host .operator-inset{min-height:0;padding:0 var(--operator-pad);flex-direction:column;flex:1 1 0;display:flex;overflow:hidden}.shell-root.docked #chat-host .chat-divider{background:var(--v2-border);flex:0 0 1px}.task-stack{gap:5px;padding-top:10px}#task-board{border-bottom:1px solid var(--v2-border);scrollbar-width:thin;scrollbar-color:transparent transparent;flex-direction:column;flex:0 auto;max-height:40vh;padding-top:0;padding-bottom:12px;display:flex;overflow-y:auto}#task-board.scrolling{scrollbar-color:var(--v2-dim) transparent}#task-board::-webkit-scrollbar{width:6px}#task-board::-webkit-scrollbar-track{background:0 0}#task-board::-webkit-scrollbar-thumb{background:0 0;border-radius:3px;transition:background .25s}#task-board.scrolling::-webkit-scrollbar-thumb{background:var(--v2-dim)}#chat-host .task{cursor:pointer;border-radius:8px;transition:background .12s,box-shadow .12s}#chat-host .task:hover,#chat-host .task.open{background:var(--v2-overlay-task);box-shadow:inset 0 0 0 1px var(--v2-border)}#chat-host .task-row{align-items:center;gap:10px;padding:5px 6px 5px 4px;display:flex;position:relative}#chat-host .task.open .task-row{align-items:flex-start}#chat-host .pie{border-radius:50%;flex:0 0 32px;width:32px;height:32px;padding:2px;display:flex;position:relative}#chat-host .pie .avatar{background:var(--v2-raised);width:100%;height:100%;color:var(--v2-gutter);border-radius:50%;justify-content:center;align-items:center;display:flex;overflow:hidden}#chat-host .pie .avatar .avatar-icon-wrap{justify-content:center;align-items:center;width:16px;height:16px;font-size:16px;display:flex}#chat-host .pie .avatar .avatar-icon-wrap svg{width:16px;height:16px;display:block}#chat-host .task-meta{flex:1;min-width:0}#chat-host .task-head{align-items:center;gap:8px;display:flex}#chat-host .task.open .task-head{min-height:32px}#chat-host .task-text{flex:1;min-width:0}#chat-host .task-name{color:var(--v2-fg);white-space:nowrap;text-overflow:ellipsis;font-size:12px;font-weight:400;overflow:hidden}#chat-host .task-name .tn{color:var(--v2-head);font-weight:600}#chat-host .task-sub{color:var(--v2-muted);white-space:nowrap;text-overflow:ellipsis;font-variant-numeric:tabular-nums;margin-top:2px;font-size:10px;overflow:hidden}#chat-host .task-dismiss{border:1px solid var(--v2-border);color:var(--v2-muted);font:inherit;cursor:pointer;visibility:hidden;background:0 0;border-radius:6px;flex-shrink:0;padding:3px 10px;font-size:12px}#chat-host .task-dismiss:hover{color:var(--v2-fg);background:var(--v2-hover)}#chat-host .task-board-header{z-index:1;background:var(--v2-gutter);border-bottom:1px solid var(--v2-border);justify-content:space-between;align-items:center;gap:8px;padding:10px 2px 8px;display:flex;position:sticky;top:0}#chat-host .task-board-heading{align-items:baseline;gap:8px;min-width:0;display:flex}#chat-host .task-board-title{color:var(--v2-fg);font-size:13px;font-weight:600}#chat-host .task-board-status{color:var(--v2-muted);font-size:12px}#chat-host .task-clear-completed{border:1px solid var(--v2-border);color:var(--v2-muted);font:inherit;cursor:pointer;background:0 0;border-radius:6px;flex-shrink:0;padding:3px 10px;font-size:12px}#chat-host .task-clear-completed:hover{color:var(--v2-fg);background:var(--v2-hover)}#chat-host .task:hover .task-dismiss{visibility:visible}#chat-host .task-body{color:var(--v2-fg);padding:0 0 4px;font-size:12px;display:none}#chat-host .task.open .task-body{display:block}#chat-host .task-notes{color:var(--v2-secondary);word-break:break-word;margin-top:6px;font-size:12px}#chat-host .task-notes code{font-size:12px}#chat-host .task-playtest-frames{margin-top:8px}#chat-host .task-playtest-frames-label{color:var(--v2-muted);margin-bottom:4px;font-size:11px}#chat-host .task-playtest-frames-row{flex-wrap:wrap;gap:6px;display:flex}#chat-host .task-playtest-frame{object-fit:cover;border:1px solid var(--v2-border);background:var(--v2-ink);border-radius:4px;width:64px;height:90px;display:block}#chat-host .task-feed{scrollbar-width:none;-ms-overflow-style:none;max-height:96px;color:var(--v2-secondary);cursor:default;word-break:break-word;-webkit-mask-image:linear-gradient(to bottom, transparent, var(--v2-gutter) 5px, var(--v2-gutter) 100%);-webkit-mask-image:linear-gradient(to bottom, transparent, var(--v2-gutter) 5px, var(--v2-gutter) 100%);mask-image:linear-gradient(to bottom, transparent, var(--v2-gutter) 5px, var(--v2-gutter) 100%);margin-top:6px;font-size:13px;line-height:1.5;overflow-y:auto}#chat-host .task-feed::-webkit-scrollbar{width:0;height:0}#chat-host .task-feed-tool{color:var(--v2-muted);font-family:var(--v2-mono);white-space:pre-wrap;padding-left:14px;font-size:13px}#chat-host .task-feed-msg{margin:0}#chat-host .task-feed-msg>:first-child{margin-top:0}#chat-host .task-feed-msg>:last-child{margin-bottom:0}#chat-host .task-feed-msg p{margin:0}#chat-host .task-feed-msg code{background:var(--v2-overlay-feed-code);font-family:var(--v2-mono);border-radius:3px;padding:0 3px;font-size:13px}.chat-input{padding:10px var(--operator-pad);flex:none}.shell-root.docked .chat-input{padding:0 var(--operator-pad) 10px;pointer-events:none;z-index:6;position:absolute;bottom:0;left:0;right:0}.shell-root.docked .chat-input .ta,.shell-root.docked .chat-input .chat-queue{pointer-events:auto}.shell-root.docked #chat-pending{left:var(--operator-pad);right:var(--operator-pad);bottom:var(--composer-reserve,88px);z-index:6;pointer-events:auto;padding:0;position:absolute}#chat-host .chat-input .ta{background:var(--v2-surface);border:1px solid var(--v2-border);border-radius:var(--panel-chrome-radius);cursor:text;flex-direction:column;gap:6px;width:100%;min-height:60px;padding:8px 4px;transition:height .3s cubic-bezier(.4,0,.2,1);display:flex;overflow:hidden}#chat-input{width:100%;min-height:21px;color:var(--v2-fg);font:inherit;resize:none;scrollbar-width:none;-ms-overflow-style:none;background:0 0;border:none;outline:none;max-height:120px;padding:0 6px;font-size:14px;line-height:1.5;display:block;overflow-y:auto}#chat-input::-webkit-scrollbar{width:0;height:0}#chat-input::placeholder{color:var(--v2-muted)}#chat-host .chat-input .ta-bottom{justify-content:space-between;align-items:center;gap:8px;min-width:0;display:flex}#chat-host .composer-settings{flex:auto;min-width:0}#chat-host .composer-pill{max-width:100%;height:22px;color:var(--v2-dim);font:inherit;cursor:pointer;background:0 0;border:none;border-radius:6px;align-items:center;gap:5px;padding:0 6px;font-size:12px;display:inline-flex}#chat-host .composer-pill:hover{color:var(--v2-secondary);background:var(--v2-hover)}#chat-host .composer-pill.usage-warn{color:var(--v2-warn)}#chat-host .composer-pill.usage-blocked{color:var(--v2-error)}#chat-host .composer-pill-label{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}#chat-host .composer-pill svg{flex-shrink:0;display:block}#chat-host .composer-pill .mode-caret{opacity:.7}#chat-send{background:var(--v2-white);width:26px;height:26px;color:var(--v2-ink);border:1px solid var(--v2-white);cursor:pointer;border-radius:50%;flex-shrink:0;justify-content:center;align-items:center;margin-right:6px;padding:0;font-size:12px;display:flex}#chat-send:hover:not(:disabled){color:var(--v2-ink);background:var(--v2-fg);border-color:var(--v2-fg)}#chat-send svg{display:block}#chat-pending{flex:none;gap:6px;padding:10px 10px 0;display:flex}#chat-pending img{border:1px solid var(--v2-border);cursor:pointer;border-radius:6px;height:44px}#chat-host .chat-input .chat-queue{flex-direction:column;gap:4px;margin-bottom:6px;display:flex}#chat-host .chat-input .queue-row{background:var(--v2-gutter);border:1px dashed var(--v2-border);color:var(--v2-muted);border-radius:8px;align-items:center;gap:8px;padding:5px 6px 5px 12px;font-size:12px;display:flex}#chat-host .chat-input .queue-snippet{text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;overflow:hidden}#chat-host .chat-input .queue-send-now{border:1px solid var(--v2-border);color:var(--v2-muted);font:inherit;cursor:pointer;background:0 0;border-radius:6px;flex-shrink:0;padding:2px 8px;font-size:11px}#chat-host .chat-input .queue-send-now:hover{color:var(--v2-fg);background:var(--v2-hover)}#chat-host .chat-input .queue-remove{width:20px;height:20px;color:var(--v2-muted);cursor:pointer;background:0 0;border:none;border-radius:5px;flex-shrink:0;justify-content:center;align-items:center;padding:0;font-size:11px;display:flex}#chat-host .chat-input .queue-remove:hover{color:var(--v2-fg);background:var(--v2-hover)}#chat-send:disabled{color:var(--v2-muted);border-color:var(--v2-border);cursor:default;background:0 0}#chat-host .picker{background:var(--v2-surface);border:1px dashed var(--v2-border);border-radius:12px;flex-direction:column;align-self:flex-start;gap:12px;width:100%;max-width:100%;margin:4px 0;padding:12px;display:flex}#chat-host .picker-locked{opacity:.72}#chat-host .picker-q{border:none;min-width:0;margin:0;padding:0}#chat-host .picker-q-label{color:var(--v2-head);margin:0 0 6px;padding:0;font-size:13px;font-weight:600}#chat-host .picker-options{flex-wrap:wrap;gap:6px;display:flex}#chat-host .picker-option{background:var(--v2-gutter);border:1px solid var(--v2-border);color:var(--v2-fg);cursor:pointer;border-radius:12px 12px 4px;align-items:center;gap:6px;padding:5px 10px;font-size:13px;line-height:1.3;display:inline-flex}#chat-host .picker:not(.picker-locked) .picker-option:hover{border-color:var(--v2-accent)}#chat-host .picker-option.is-checked{background:var(--v2-accent);border-color:var(--v2-accent);color:var(--v2-white)}#chat-host .picker-option input{accent-color:var(--v2-accent);cursor:inherit;margin:0}#chat-host .picker-locked .picker-option{cursor:default}#chat-host .picker-actions{justify-content:flex-end;display:flex}#chat-host .picker-submit{font:inherit;background:var(--v2-accent);color:var(--v2-white);border:1px solid var(--v2-accent);cursor:pointer;border-radius:8px;padding:6px 16px;font-size:13px}#chat-host .picker-submit:hover{background:var(--v2-accent-hover)}#chat-host .chips{flex-wrap:wrap;justify-content:flex-end;align-self:flex-end;gap:6px;max-width:85%;margin:2px 0 4px;display:flex}#chat-host .chip{font:inherit;text-align:left;color:var(--v2-white);border:1px dotted var(--v2-white);cursor:pointer;background:0 0;border-radius:17px;padding:6px 13px;font-size:13px;line-height:1.3}#chat-host .chip:hover:not(:disabled){background:var(--v2-overlay-white-hover)}#chat-host .chips-inert .chip{color:var(--v2-muted);border-color:var(--v2-dim);cursor:default}#chat-host .chip.is-picked,#chat-host .chips-inert .chip.is-picked{background:var(--v2-white);border-style:solid;border-color:var(--v2-white);color:var(--v2-ink)}#chat-host .msg-plan{color:var(--v2-muted);text-align:left;cursor:pointer;background:0 0;border:0;align-self:flex-start;margin:0 0 2px;padding:0;font-family:inherit;font-size:11px}#chat-host .msg-plan:hover{color:var(--v2-fg);text-underline-offset:2px;text-decoration:underline}#chat-host .msg-file{color:inherit;font:inherit;text-underline-offset:2px;text-decoration:underline;-webkit-text-decoration-color:color-mix(in srgb, currentColor 40%, transparent);text-decoration-color:color-mix(in srgb, currentColor 40%, transparent);cursor:pointer;word-break:break-all;background:0 0;border:0;margin:0;padding:0;display:inline}#chat-host .msg-file:hover{text-decoration-color:currentColor}#chat-host .picker-skeleton{pointer-events:none}#chat-host .picker-skeleton-hint{color:var(--v2-muted);letter-spacing:.01em;font-size:12px}#chat-host .picker-skeleton-line,#chat-host .picker-skeleton-chip{background:linear-gradient(90deg, var(--v2-border) 0%, var(--v2-border) 50%, var(--v2-border) 100%);background-size:200% 100%;border-radius:6px;animation:1.3s ease-in-out infinite picker-shimmer;display:block}#chat-host .picker-skeleton-label{width:60%;height:11px;margin-bottom:8px}#chat-host .picker-skeleton-chip{border-radius:12px 12px 4px;height:26px}@keyframes picker-shimmer{0%{background-position:200% 0}to{background-position:-200% 0}}@media (prefers-reduced-motion:reduce){#chat-host .picker-skeleton-line,#chat-host .picker-skeleton-chip{animation:none}}.xterm,.xterm-viewport,.xterm-screen,.xterm-helpers{background-color:#0000!important}.xterm{overscroll-behavior:contain}.xterm-viewport{overscroll-behavior:contain;scrollbar-width:none;-ms-overflow-style:none}.xterm-viewport::-webkit-scrollbar{width:0;height:0}.xterm .xterm-scrollable-element>.scrollbar,.xterm .xterm-scrollable-element>.scrollbar.visible,.xterm .xterm-scrollable-element>.visible.scrollbar,.xterm .xterm-scrollable-element>.invisible.scrollbar,.xterm .xterm-scrollable-element>.xterm-scrollbar{opacity:0!important;pointer-events:none!important;width:0!important;min-width:0!important;height:0!important;min-height:0!important;display:none!important}.xterm .xterm-scrollable-element>.scrollbar>.slider,.xterm .xterm-scrollable-element>.scrollbar>.scra,.xterm .xterm-scrollable-element>.xterm-scrollbar>.xterm-slider{width:0!important;height:0!important;display:none!important}.xterm .xterm-scrollable-element>.shadow{display:none!important}.quick-open-backdrop{z-index:2147483100;justify-content:center;align-items:flex-start;padding-top:12vh;display:flex;position:fixed;inset:0}.quick-open{background:#232323;border:1px solid #3a3a3a;border-radius:8px;flex-direction:column;width:min(600px,90vw);max-height:60vh;display:flex;overflow:hidden;box-shadow:0 16px 48px #0009}.quick-open-input{color:#f0f0f0;background:#161616;border:1px solid #4a4a4a;border-radius:5px;outline:none;flex:none;margin:8px;padding:8px 10px;font-size:14px}.quick-open-input:focus{border-color:#5a8bd6}.quick-open-list{flex:auto;padding:4px;overflow-y:auto}.quick-open-item{color:#e6e6e6;text-align:left;cursor:pointer;background:0 0;border:0;border-radius:4px;align-items:baseline;gap:8px;width:100%;padding:5px 8px;font-size:13px;display:flex}.quick-open-item.active{background:#37506f}.quick-open-name{white-space:nowrap;flex:none}.quick-open-dir{text-overflow:ellipsis;white-space:nowrap;color:#8a8a8a;flex:auto;min-width:0;font-size:12px;overflow:hidden}.quick-open-empty{color:#8a8a8a;text-align:center;padding:12px;font-size:13px}.quick-open-keys{color:#b0b0b0;white-space:nowrap;border:1px solid #4a4a4a;border-radius:4px;flex:none;margin-left:8px;padding:1px 6px;font-family:SFMono-Regular,Consolas,monospace;font-size:11px}.mention-picker{z-index:2147483100;background:#232323;border:1px solid #3a3a3a;border-radius:8px;width:min(360px,90vw);max-height:40vh;padding:4px;position:fixed;overflow-y:auto;box-shadow:0 16px 48px #0009}.mention-item{color:#e6e6e6;text-align:left;cursor:pointer;background:0 0;border:0;border-radius:4px;align-items:baseline;gap:8px;width:100%;padding:5px 8px;font-size:13px;display:flex}.mention-item.active{background:#37506f}.mention-name{white-space:nowrap;flex:none}.mention-dir{text-overflow:ellipsis;white-space:nowrap;color:#8a8a8a;flex:auto;min-width:0;font-size:12px;overflow:hidden}.chord-hint{z-index:2147483200;color:#c7c7c7;background:#232323;border:1px solid #3a3a3a;border-radius:8px;align-items:center;gap:8px;padding:6px 12px;font-size:12px;display:flex;position:fixed;bottom:24px;left:50%;transform:translate(-50%);box-shadow:0 8px 24px #0000008c}.chord-hint kbd{color:#f0f0f0;background:#333;border:1px solid #4a4a4a;border-radius:4px;padding:2px 7px;font-family:SFMono-Regular,Consolas,monospace;font-size:12px}@media (pointer:coarse){input,textarea,select,[contenteditable]:not(.cm-content){font-size:16px!important}}.cm-url,.cm-md-link{color:var(--v2-link,#82aaff);text-underline-offset:2px;cursor:pointer;text-decoration:underline;text-decoration-thickness:1px}.cm-url:hover,.cm-md-link:hover{color:var(--v2-white,#fff)}.castle-file-panel,.castle-code-panel,.castle-params-panel,.castle-params-overlay,.flow-class-files{--castle-font-mono:"SFMono-Regular", Consolas, "Liberation Mono", monospace;--castle-black:var(--v2-ink);--castle-panel-raised:var(--v2-raised);--castle-border:#444;--castle-text:var(--v2-white);--castle-text-dim:var(--v2-muted);--castle-inspector-bg:var(--v2-surface);--castle-inspector-text:var(--v2-fg);--castle-inspector-muted:var(--v2-muted);--castle-inspector-border:var(--v2-border);--castle-inspector-divider:var(--v2-border);--castle-inspector-input-bg:var(--v2-raised);--castle-workspace-bg:var(--v2-surface);--castle-sheet-bg:var(--v2-surface);--castle-radius:4px}.castle-file-panel{background:var(--castle-sheet-bg);flex-direction:column;height:100%;display:flex;overflow:hidden;transform:translateZ(0)}.castle-file-panel>.fileBrowserBare{flex:1 1 0;height:auto;min-height:0}.castle-file-toolbar{border-bottom:1px solid var(--castle-inspector-border);flex-wrap:wrap;flex:none;align-items:center;gap:6px;padding:6px 8px;display:flex}.castle-file-toolbar .button-icon{margin-left:auto}.castle-file-toolbar .button-icon+.button-icon{margin-left:0}.castle-file-toolbar.versions-toolbar{padding-left:var(--castle-space-large);justify-content:space-between}.versions-toolbar-label{text-overflow:ellipsis;white-space:nowrap;min-width:0;color:var(--castle-text-muted);line-height:1;overflow:hidden}.castle-versions{flex-direction:column;flex:1 1 0;min-height:0;display:flex}.versions-error{align-items:flex-start}.versions-error>span:not(.icon-cell){white-space:pre-line}.versions-save{align-items:center;gap:var(--castle-space-base);flex-wrap:wrap;padding:0;display:flex}.versions-save .text-field{flex:130px;width:auto;min-width:0}.versions-save .button{white-space:nowrap;flex:none}.versions-note{padding:var(--castle-space-large) var(--castle-space-large) 0;color:var(--castle-text-muted);font-size:var(--castle-text-size-base)}.versions-empty{padding:var(--castle-space-large);color:var(--castle-text-muted);font-size:var(--castle-text-size-base)}.castle-versions-list{flex:1 1 0;min-height:0;overflow-y:auto}.version{align-items:start;column-gap:var(--castle-space-base);padding:var(--castle-space-base) var(--castle-space-base) var(--castle-space-large);border-bottom:1px solid var(--castle-border-1);grid-template-columns:minmax(0,1fr) auto;display:grid}.version-toggle{grid-template-columns:var(--castle-button-height) minmax(0, 1fr);align-items:start;column-gap:var(--castle-space-base);min-width:0;color:inherit;font:inherit;text-align:left;cursor:pointer;background:0 0;border:0;grid-area:1/1/auto/-1;margin:0;padding:0;display:grid}.version.is-expanded:not(.version-new) .version-toggle{grid-column:1}.version-toggle:focus-visible{outline:1px solid var(--castle-border-2);outline-offset:2px}.version.later,.version.later .icon-cell,.version.later .version-message,.version.later .version-nomessage,.version.later .version-meta,.version.later .version-summary{color:var(--castle-text-dim)}.version:hover{background:var(--castle-surface-3)}.version-main{gap:var(--castle-space-small);flex-direction:column;min-width:0;display:flex}.version-heading{align-items:center;gap:var(--castle-space-base);min-width:0;min-height:var(--castle-button-height);display:flex}.version-message{text-overflow:ellipsis;white-space:nowrap;min-width:0;color:var(--castle-text-primary);font-size:var(--castle-text-size-base);flex:auto;overflow:hidden}.version-nomessage{color:var(--castle-text-muted);font-style:italic}.version-meta{color:var(--castle-text-muted);font-size:var(--castle-text-size-small);margin:0;display:block}.version-actions{min-height:var(--castle-button-height);flex:none;grid-area:1/2;align-items:center;display:none}.version.is-expanded .version-actions{display:flex}.version-detail{padding-left:calc(var(--castle-button-height) + var(--castle-space-base));grid-column:1/-1;display:none}.version-new{flex:none}.version.is-expanded .version-detail{gap:var(--castle-space-small);flex-direction:column;display:flex}.version-summary{color:var(--castle-text-secondary);font-size:var(--castle-text-size-base);overflow-wrap:anywhere;margin:0}.files-feedback-banner{flex:none}.fileEditInput{border:1px solid var(--castle-border);background:var(--castle-inspector-input-bg);min-width:0;color:var(--castle-inspector-text);font:inherit;border-radius:3px;flex:auto;padding:1px 4px;font-size:13px}.fileEditInput:focus{border-color:#5a8bd6;outline:none}.castle-file-menu{z-index:1000;min-width:168px;position:fixed}.castle-file-menu .menu-keys{font-family:SFMono-Regular,Consolas,monospace}.castle-file-picker{gap:var(--castle-space-small);flex-direction:column;min-width:180px;display:flex}.castle-file-picker .text-field{width:100%}.castle-file-picker-label{color:var(--castle-text-muted);margin:0}.castle-file-picker-list{gap:var(--castle-space-small);flex-direction:column;max-height:min(40vh,180px);display:flex;overflow-y:auto}.castle-file-picker-list[hidden]{display:none}.fileBrowserBare{flex-direction:column;min-width:0;height:100%;display:flex}.fileTree{min-height:0;padding:var(--castle-space-base);flex:1 1 0;overflow-y:auto}.fileBranch{min-width:0}.file-row,.file-row.folder-row{align-items:center;gap:var(--castle-space-base);width:100%;min-width:0;height:var(--castle-button-height);margin:0 0 var(--castle-space-small);padding:0 var(--castle-space-base);padding-left:calc(var(--castle-space-base) + var(--file-depth,0) * (var(--castle-button-icon-size) + var(--castle-space-base)));border-radius:var(--castle-radius-small);color:var(--castle-text-secondary);font-size:var(--castle-text-size-base);text-align:left;cursor:pointer;background:0 0;border:0;line-height:1;display:flex}.file-row.folder-row{color:var(--castle-text-muted)}.file-row>span:not(.icon-slot):not(.icon-inline):not(.icon-cell){text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}.file-row:hover{background:var(--castle-surface-3);color:var(--castle-text-primary)}.file-row.imported-row{color:var(--castle-text-muted);font-style:italic}.file-row.forked-row{color:var(--castle-text-secondary);font-style:normal}.file-row.selected-row,.file-row.selected-row:hover{background:var(--castle-surface-4);color:var(--castle-text-primary)}.file-row.hidden-row{color:var(--castle-text-dim)}:is(.file-row:has(.button-icon),.file-row:has(.icon-cell)){padding-right:0}.file-row .button-icon,.file-row .icon-cell{margin-left:auto}.file-row.edit-row{height:auto;min-height:var(--castle-button-height);cursor:default;flex-wrap:wrap}.file-row.edit-row .text-field{flex:auto;width:auto}.file-suffix{color:var(--castle-text-muted);flex:none}.file-row .file-edit-feedback{padding-left:calc(var(--castle-button-icon-size) + var(--castle-space-base));padding-bottom:var(--castle-space-small);font-size:var(--castle-text-size-small);white-space:normal;flex:1 0 100%;line-height:1.45;overflow:visible}.flow-root.is-mobile .castle-file-panel,.flow-mobile-switch{--castle-button-height:var(--castle-button-height-large)}.flow-mobile-switch{--castle-text-size-small:14px;--castle-text-size-base:16px;--castle-text-style-smallcaps-size:var(--castle-text-size-small)}.flow-root.is-mobile .castle-file-panel .button:not(.button-icon){padding-left:var(--castle-space-large);padding-right:var(--castle-space-large)}.flow-root.is-mobile .file-row,.flow-mobile-switch .file-row{margin-bottom:0}.flow-root.is-mobile .file-row>span:not(.icon-slot):not(.icon-inline):not(.icon-cell),.flow-mobile-switch .file-row>span:not(.icon-slot):not(.icon-inline):not(.icon-cell){line-height:var(--castle-button-height)}.flow-root.is-mobile .file-row:hover,.flow-mobile-switch .file-row:hover{color:var(--castle-text-secondary);background:0 0}.flow-root.is-mobile .file-row.folder-row:hover,.flow-root.is-mobile .file-row.imported-row:hover,.flow-mobile-switch .file-row.folder-row:hover,.flow-mobile-switch .file-row.imported-row:hover{color:var(--castle-text-muted)}.flow-root.is-mobile .file-row.hidden-row:hover,.flow-mobile-switch .file-row.hidden-row:hover{color:var(--castle-text-dim)}.flow-root.is-mobile .file-row.selected-row:hover,.flow-mobile-switch .file-row.selected-row:hover{background:var(--castle-surface-4);color:var(--castle-text-primary)}.flow-root.is-mobile .version:hover{background:0 0}.castle-code-panel{width:100%;height:100%;position:relative}.mainEditor{background:var(--castle-sheet-bg);flex-direction:column;width:100%;min-width:0;height:100%;min-height:0;display:flex}.editorBody{flex:1;min-height:0;display:flex;overflow:hidden;container:editor/inline-size}.codeEditor{background:var(--castle-workspace-bg);flex:1;grid-template-columns:1fr;min-width:0;min-height:0;display:grid}.codeMirrorHost{min-width:0;height:100%;min-height:0}.castle-code-overlay{color:var(--castle-inspector-muted);pointer-events:none;font-size:12px;position:absolute;top:10px;left:12px}.castle-code-overlay.castle-code-error{color:var(--v2-error)}.castle-code-savebar{background:var(--v2-error-bg);color:var(--v2-error);padding:4px 10px;font-size:11px;position:absolute;bottom:0;left:0;right:0}.castle-tab-import{color:var(--v2-muted);font-style:italic}.castle-modal-scrim{z-index:1000;background:#00000080;justify-content:center;align-items:center;display:flex;position:fixed;inset:0}.castle-modal{color:#e8e8e8;background:#232323;border:1px solid #3a3a3a;border-radius:6px;min-width:260px;max-width:380px;padding:16px;font-size:13px;box-shadow:0 8px 24px #0000008c}.castle-modal-text{margin-bottom:14px}.castle-modal-actions{justify-content:flex-end;gap:8px;margin-top:16px;display:flex}.castle-modal-actions button,.castle-import-link-row button{color:#e8e8e8;cursor:pointer;background:#2e2e2e;border:1px solid #3a3a3a;border-radius:4px;padding:5px 12px;font-size:12px}.castle-modal-actions button:hover:not(:disabled),.castle-import-link-row button:hover:not(:disabled){background:#383838}.castle-modal-actions button:disabled,.castle-import-link-row button:disabled{opacity:.6;cursor:default}.castle-upload-modal{flex-direction:column;gap:10px;width:min(460px,100vw - 24px);max-width:none;max-height:calc(100vh - 32px);display:flex;overflow-y:auto}.castle-upload-modal>.castle-modal-text{margin-bottom:0}.castle-upload-modal>.castle-file-picker{width:100%;min-width:0}.castle-upload-input{opacity:0;pointer-events:none;width:1px;height:1px;position:absolute}.castle-upload-drop{justify-content:center;align-items:center;gap:var(--castle-space-small);width:100%;padding:calc(var(--castle-space-large) + var(--castle-space-base)) var(--castle-space-large);border:1px dashed var(--castle-border-3);border-radius:var(--castle-radius-small);background:var(--castle-surface-3);color:var(--castle-text-primary);font:inherit;cursor:pointer;flex-direction:column;display:flex}.castle-upload-drop:hover,.castle-upload-drop.over{border-color:var(--castle-border-2);background:var(--castle-surface-5)}.castle-upload-drop svg{font-size:var(--castle-button-icon-size)}.castle-upload-drop-label{font-size:var(--castle-text-size-base)}.castle-upload-drop-hint{color:var(--castle-text-muted);font-size:var(--castle-text-size-small)}.castle-upload-picked{flex-direction:column;max-height:132px;display:flex;overflow-y:auto}.castle-upload-picked-row{align-items:center;gap:var(--castle-space-base);min-height:var(--castle-button-height);padding:var(--castle-space-small) 0;display:flex}.castle-upload-picked-row+.castle-upload-picked-row{border-top:1px solid var(--castle-border-1)}.castle-upload-picked-name{min-width:0;font-size:var(--castle-text-size-base);flex-direction:column;flex:auto;justify-content:center;display:flex}.castle-upload-picked-label{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.castle-upload-picked-name .text-field{width:100%}.castle-upload-picked-warning{color:var(--castle-warn-text);font-size:var(--castle-text-size-small);white-space:normal;margin-top:2px;display:block}.castle-upload-picked-size{color:var(--castle-text-muted);font-size:var(--castle-text-size-small);font-variant-numeric:tabular-nums;flex:none}.castle-upload-status{text-overflow:ellipsis;white-space:nowrap;opacity:.7;text-align:left;flex:auto;min-width:0;font-size:12px;overflow:hidden}@media (width<=520px){.castle-upload-modal{width:calc(100vw - 16px);min-width:0;padding:12px}.castle-upload-drop{padding:var(--castle-space-large) var(--castle-space-base)}.castle-upload-picked{max-height:104px}.castle-file-picker-list{max-height:132px}}.castle-import-modal{flex-direction:column;width:min(520px,100vw - 32px);max-width:none;height:min(560px,100vh - 64px);max-height:none;display:flex}.castle-import-modal>.castle-modal-text,.castle-import-modal>.castle-key-tabs,.castle-import-modal>.castle-import-select-bar,.castle-import-modal>.castle-import-filter,.castle-import-modal>.castle-import-note,.castle-import-modal>.castle-import-error,.castle-import-modal>.castle-modal-actions{flex:none}.castle-import-select-bar{align-items:center;gap:10px;margin-bottom:8px;display:flex}.castle-import-select-all{padding:4px 8px}.castle-import-update-row{align-items:center}.castle-import-tick{color:#1b1b1b;border:1px solid #5a5a5a;border-radius:3px;flex:none;justify-content:center;align-items:center;width:16px;height:16px;font-size:10px;display:flex}.castle-import-tick.checked{background:#8ab4f8;border-color:#8ab4f8}.castle-import-filter{margin-bottom:8px}.castle-import-empty{color:#9a9a9a;text-align:center;flex:auto;justify-content:center;align-items:center;min-height:0;padding:10px;font-size:11px;display:flex}.castle-import-tabs .castle-key-tab{min-height:34px}.castle-import-list{background:#1b1b1b;border:1px solid #3a3a3a;border-radius:4px;flex:auto;min-height:0;overflow-y:auto}.castle-import-row{color:#e8e8e8;width:100%;font:inherit;text-align:left;cursor:pointer;background:0 0;border:0;border-bottom:1px solid #2e2e2e;gap:10px;padding:8px;font-size:12px;display:flex}.castle-import-row:last-child{border-bottom:0}.castle-import-row:hover{background:#262626}.castle-import-row.selected{background:#3a3a3a}.castle-import-row.disabled{opacity:.5}.castle-import-thumb{object-fit:cover;background:#2e2e2e;border-radius:3px;flex:none;width:56px;height:79px}.castle-import-row-text{flex-direction:column;gap:3px;min-width:0;display:flex}.castle-import-row-title{white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.castle-import-row-meta{color:#9a9a9a;font-size:11px}.castle-import-link{flex-direction:column;flex:auto;gap:8px;min-height:0;display:flex}.castle-import-link-row{gap:8px;display:flex}.castle-import-link-row button{white-space:nowrap}.castle-import-note{color:#9a9a9a;padding:10px 2px;font-size:11px}.castle-import-error{color:#ff8f8f;margin-top:8px;font-size:11px}.castle-params-panel{background:var(--castle-sheet-bg);height:100%;color:var(--castle-inspector-text);-webkit-overflow-scrolling:touch;font-size:14px;overflow:hidden auto}.paramsFields{padding:10px 16px 24px}.paramsGroup+.paramsGroup{margin-top:6px}.paramsGroupTitle{border-top:1px solid var(--castle-inspector-divider);color:var(--castle-inspector-muted);text-transform:uppercase;letter-spacing:.06em;margin:10px 0;padding-top:10px;font-size:12px}.paramsNotice{color:var(--castle-inspector-muted);padding:16px}.paramsSaveError{border-bottom:1px solid var(--castle-inspector-border);color:var(--castle-inspector-text);background:#be464629;padding:8px 16px;font-size:13px}.paramsEmpty{max-width:46em;padding:20px 16px}.paramsEmptyLead{color:var(--castle-inspector-text);margin:0 0 10px;font-size:15px}.paramsEmptyBody{color:var(--castle-inspector-muted);margin:0 0 12px;line-height:1.5}.paramsEmpty code{font-family:var(--castle-font-mono);color:var(--castle-inspector-text);font-size:13px}.paramsEmptyCode{border:1px solid var(--castle-inspector-border);border-radius:var(--castle-radius);background:var(--castle-inspector-input-bg);color:var(--castle-inspector-text);font-family:var(--castle-font-mono);margin:0 0 14px;padding:10px 12px;font-size:13px;line-height:1.45;overflow-x:auto}.castle-params-panel .paramExpr{text-overflow:ellipsis;white-space:nowrap;border:1px dashed var(--castle-inspector-border);border-radius:var(--castle-radius);min-width:0;color:var(--castle-inspector-muted);font-family:var(--castle-font-mono);cursor:default;padding:5px 8px;font-size:13px;overflow:hidden}.castle-params-panel .fieldRow{grid-template-columns:minmax(82px,.5fr) minmax(0,1fr);align-items:center;gap:12px;min-height:28px;padding-bottom:12px;display:grid}.castle-params-panel .fieldLabel{color:var(--castle-inspector-text);text-overflow:ellipsis;font-size:14px;overflow:hidden}.castle-params-panel .input{border:1px solid var(--castle-inspector-border);border-radius:var(--castle-radius);background:var(--castle-inspector-input-bg);width:100%;color:var(--castle-inspector-text);font:inherit;outline:0;padding:5px 8px}.castle-params-panel .numberField{width:100%;position:relative}.castle-params-panel .numberInput{appearance:textfield}.castle-params-panel .numberInput::-webkit-inner-spin-button{appearance:none;margin:0}.castle-params-panel .numberInput::-webkit-outer-spin-button{appearance:none;margin:0}.castle-params-panel .numberScrub{cursor:ew-resize;-webkit-user-select:none;user-select:none;align-items:center;gap:6px;display:flex;position:relative;overflow:hidden}.castle-params-panel .numberValue{z-index:1;text-align:right;font-variant-numeric:tabular-nums;flex:auto;min-width:0;position:relative}.castle-params-panel .scrubGrip{z-index:1;color:var(--castle-inspector-muted);letter-spacing:-2px;opacity:.4;flex:none;font-size:12px;line-height:1;position:relative}.castle-params-panel .colorInput{border:1px solid var(--castle-inspector-border);border-radius:var(--castle-radius);background:var(--castle-inspector-input-bg);cursor:pointer;outline:0;width:100%;height:28px;padding:2px}.castle-params-panel .checkbox{border:1px solid var(--castle-inspector-border);border-radius:var(--castle-radius);background:var(--castle-inspector-input-bg);cursor:pointer;width:20px;height:20px;box-shadow:none;color:var(--castle-text);flex:none;justify-content:center;justify-self:end;align-items:center;padding:0;display:flex}.castle-params-panel .checkboxOn{background:var(--castle-black)}.castle-params-panel .checkboxMark{width:12px;height:12px;display:none}.castle-params-panel .checkboxOn .checkboxMark{display:block}.castle-params-overlay .scrubBubble{z-index:1001;border:1px solid var(--castle-inspector-border);color:var(--castle-inspector-text);font-variant-numeric:tabular-nums;pointer-events:none;background:#14181ef5;border-radius:8px;padding:3px 10px;font-size:15px;position:fixed;transform:translate(-50%,-100%);box-shadow:0 2px 10px #00000073}.castle-params-overlay .numpadBackdrop{z-index:1000;background:#00000059;flex-direction:column;justify-content:flex-end;display:flex;position:fixed;inset:0}.castle-params-overlay .numpadSheet{background:var(--castle-inspector-bg,#16181d);border-top:1px solid var(--castle-inspector-border);padding:10px 10px calc(10px + env(safe-area-inset-bottom,0px));border-radius:14px 14px 0 0;box-shadow:0 -8px 24px #0006}.castle-params-overlay .numpadValueRow{justify-content:space-between;align-items:baseline;gap:12px;padding:6px 8px 12px;display:flex}.castle-params-overlay .numpadValueLabel{color:var(--castle-inspector-text);text-overflow:ellipsis;white-space:nowrap;min-width:0;font-size:22px;overflow:hidden}.castle-params-overlay .numpadValueNum{color:var(--castle-inspector-text);font-variant-numeric:tabular-nums;flex:none;font-size:22px}.castle-params-overlay .numpadGrid{grid-template-columns:repeat(4,1fr);gap:8px;display:grid}.castle-params-overlay .numpadKey{border:1px solid var(--castle-inspector-border);background:var(--castle-inspector-input-bg);height:52px;color:var(--castle-inspector-text);cursor:pointer;touch-action:manipulation;border-radius:10px;font-size:20px}.castle-params-overlay .numpadKey:active{background:var(--castle-inspector-divider)}.castle-params-overlay .numpadKeyZero{grid-column:span 3}.castle-params-overlay .numpadKeyDone{color:#fff;background:#5a8cd2e6;border-color:#0000;font-size:16px}.xterm{cursor:text;-webkit-user-select:none;user-select:none;position:relative}.xterm.focus,.xterm:focus{outline:none}.xterm .xterm-helpers{z-index:5;position:absolute;top:0}.xterm .xterm-helper-textarea{opacity:0;z-index:-5;white-space:nowrap;resize:none;border:0;width:0;height:0;margin:0;padding:0;position:absolute;top:0;left:-9999em;overflow:hidden}.xterm .composition-view{color:#fff;white-space:nowrap;z-index:1;background:#000;display:none;position:absolute}.xterm .composition-view.active{display:block}.xterm .xterm-viewport{cursor:default;background-color:#000;position:absolute;inset:0;overflow-y:scroll}.xterm .xterm-screen{position:relative}.xterm .xterm-screen canvas{position:absolute;top:0;left:0}.xterm-char-measure-element{visibility:hidden;line-height:normal;display:inline-block;position:absolute;top:0;left:-9999em}.xterm.enable-mouse-events{cursor:default}.xterm.xterm-cursor-pointer,.xterm .xterm-cursor-pointer{cursor:pointer}.xterm.column-select.focus{cursor:crosshair}.xterm .xterm-accessibility:not(.debug),.xterm .xterm-message{z-index:10;color:#0000;pointer-events:none;position:absolute;inset:0}.xterm .xterm-accessibility-tree:not(.debug) ::selection{color:#0000}.xterm .xterm-accessibility-tree{-webkit-user-select:text;user-select:text;white-space:pre;font-family:monospace}.xterm .xterm-accessibility-tree>div{transform-origin:0;width:fit-content}.xterm .live-region{width:1px;height:1px;position:absolute;left:-9999px;overflow:hidden}.xterm-dim{opacity:1!important}.xterm-underline-1{text-decoration:underline}.xterm-underline-2{-webkit-text-decoration:underline double;text-decoration:underline double}.xterm-underline-3{-webkit-text-decoration:underline wavy;text-decoration:underline wavy}.xterm-underline-4{-webkit-text-decoration:underline dotted;text-decoration:underline dotted}.xterm-underline-5{-webkit-text-decoration:underline dashed;text-decoration:underline dashed}.xterm-overline{text-decoration:overline}.xterm-overline.xterm-underline-1{text-decoration:underline overline}.xterm-overline.xterm-underline-2{-webkit-text-decoration:overline double underline;text-decoration:overline double underline}.xterm-overline.xterm-underline-3{-webkit-text-decoration:overline wavy underline;text-decoration:overline wavy underline}.xterm-overline.xterm-underline-4{-webkit-text-decoration:overline dotted underline;text-decoration:overline dotted underline}.xterm-overline.xterm-underline-5{-webkit-text-decoration:overline dashed underline;text-decoration:overline dashed underline}.xterm-strikethrough{text-decoration:line-through}.xterm-screen .xterm-decoration-container .xterm-decoration{z-index:6;position:absolute}.xterm-screen .xterm-decoration-container .xterm-decoration.xterm-decoration-top-layer{z-index:7}.xterm-decoration-overview-ruler{z-index:8;pointer-events:none;position:absolute;top:0;right:0}.xterm-decoration-top{z-index:2;position:relative}.xterm .xterm-scrollable-element>.scrollbar{cursor:default}.xterm .xterm-scrollable-element>.scrollbar>.scra{cursor:pointer;font-size:11px!important}.xterm .xterm-scrollable-element>.visible{opacity:1;z-index:11;background:0 0;transition:opacity .1s linear}.xterm .xterm-scrollable-element>.invisible{opacity:0;pointer-events:none}.xterm .xterm-scrollable-element>.invisible.fade{transition:opacity .8s linear}.xterm .xterm-scrollable-element>.shadow{display:none;position:absolute}.xterm .xterm-scrollable-element>.shadow.top{width:100%;height:3px;box-shadow:var(--vscode-scrollbar-shadow,#000) 0 6px 6px -6px inset;display:block;top:0;left:3px}.xterm .xterm-scrollable-element>.shadow.left{width:3px;height:100%;box-shadow:var(--vscode-scrollbar-shadow,#000) 6px 0 6px -6px inset;display:block;top:3px;left:0}.xterm .xterm-scrollable-element>.shadow.top-left-corner{width:3px;height:3px;display:block;top:0;left:0}.xterm .xterm-scrollable-element>.shadow.top.left{box-shadow:var(--vscode-scrollbar-shadow,#000) 6px 0 6px -6px inset}@font-face{font-family:Basteleur;src:url(/__castle/ide/assets/Basteleur-Bold-DKFKedNb.woff2)format("woff2"),url(/__castle/ide/assets/Basteleur-Bold-CK8LF7Pt.woff)format("woff");font-weight:700;font-style:normal}.flow-root{--flow-gutter:#000;--flow-surface:#181818;--flow-chip:#282828;--flow-font-display:"Basteleur", Georgia, "Times New Roman", serif;--flow-fg:#e6e6e6;--flow-secondary:#b3b3b3;--flow-muted:#888;--flow-dim:#525252;--flow-border:#2a2a2a;--flow-border-active:#5a5a5a;--flow-gap:12px;--flow-dock-h:36px;--flow-tab-h:var(--castle-panel-header-height);--flow-icon-dock:var(--castle-button-icon-size);--flow-btn-sm:var(--castle-button-height);--flow-host-l:0px;--flow-host-r:0px;--flow-max-chips:6;--flow-chip-size:36px;--flow-chips-w:calc(var(--flow-max-chips) * var(--flow-chip-size));--flow-fade:22px;background:var(--flow-gutter);color:var(--flow-fg);flex-direction:column;font:13px ui-sans-serif,system-ui,-apple-system,sans-serif;display:flex;position:fixed;inset:0;overflow:hidden}.flow-root *{box-sizing:border-box}body.flow-reordering,body.flow-reordering *{touch-action:none;-webkit-user-select:none!important;user-select:none!important;cursor:grabbing!important}.flow-topbar{top:var(--flow-gap);left:var(--flow-gap);right:var(--flow-gap);height:var(--flow-dock-h);align-items:center;gap:var(--castle-space-base);z-index:40;pointer-events:none;padding-left:var(--flow-host-l);padding-right:var(--flow-host-r);grid-template-columns:minmax(0,1fr) minmax(0,auto) minmax(0,1fr);display:grid;position:absolute}.flow-topbar-leading{justify-self:start;align-items:center;gap:var(--castle-space-base);pointer-events:none;min-width:0;display:flex}.flow-topbar-leading>*{pointer-events:auto}.flow-castle-wrap{flex-shrink:0;position:relative}.flow-menu-backdrop{z-index:49;position:fixed;inset:0}.flow-castle-menu{top:calc(var(--flow-dock-h) + var(--castle-space-base));z-index:50;position:absolute;left:0}.flow-menu-narrow{display:none}.flow-deck-identity{max-width:260px}.flow-deck-vis{color:var(--flow-secondary);flex-shrink:0;font-size:14px;display:inline-flex}.flow-deck-vis svg{width:14px;height:14px}.flow-deck-name{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.flow-deck-caret{color:var(--flow-muted);flex-shrink:0;display:inline-flex}.flow-draft-status{color:var(--flow-muted);font-size:var(--castle-text-size-small);white-space:nowrap;flex-shrink:0}.flow-draft-status.is-error{color:var(--castle-danger-text)}.flow-tabs-wrap{pointer-events:auto;justify-self:center;align-items:center;gap:var(--castle-space-base);min-width:0;max-width:100%;display:flex}.flow-tabs{min-width:0;max-width:var(--flow-chips-w);flex:0 auto;position:relative}.flow-tabs-scroll{scrollbar-width:none;align-items:stretch;gap:0;height:100%;padding:0;display:flex;overflow:auto hidden}.flow-tabs-scroll::-webkit-scrollbar{display:none}.flow-tabs.more-left{-webkit-mask-image:linear-gradient(to right, transparent, #000 var(--flow-fade));-webkit-mask-image:linear-gradient(to right, transparent, #000 var(--flow-fade));mask-image:linear-gradient(to right, transparent, #000 var(--flow-fade));border-top-left-radius:0;border-bottom-left-radius:0}.flow-tabs.more-right{-webkit-mask-image:linear-gradient(to left, transparent, #000 var(--flow-fade));-webkit-mask-image:linear-gradient(to left, transparent, #000 var(--flow-fade));mask-image:linear-gradient(to left, transparent, #000 var(--flow-fade));border-top-right-radius:0;border-bottom-right-radius:0}.flow-tabs.more-left.more-right{-webkit-mask-image:linear-gradient(to right, transparent, #000 var(--flow-fade), #000 calc(100% - var(--flow-fade)), transparent);-webkit-mask-image:linear-gradient(to right, transparent, #000 var(--flow-fade), #000 calc(100% - var(--flow-fade)), transparent);mask-image:linear-gradient(to right, transparent, #000 var(--flow-fade), #000 calc(100% - var(--flow-fade)), transparent)}.button.flow-tabs-add{width:var(--castle-button-height-large);height:var(--castle-button-height-large);border-radius:var(--castle-radius-base);flex-shrink:0}.flow-chip-icon{font-size:var(--flow-icon-dock);display:inline-flex}.flow-chip-icon svg{width:var(--flow-icon-dock);height:var(--flow-icon-dock)}.flow-topbar-trailing{justify-self:end;align-items:center;gap:var(--castle-space-base);pointer-events:none;min-width:0;display:flex}.flow-preview-btn{pointer-events:auto;flex-shrink:0}.flow-preview-btn-failed{color:var(--castle-danger-text);border-color:var(--castle-danger-text)}.flow-preview-label{justify-items:center;display:grid}.flow-preview-label>*{grid-area:1/1}.flow-preview-label-sizer{visibility:hidden;pointer-events:none}.flow-root.is-mobile{--flow-max-chips:4;--flow-gap:var(--castle-space-base);--castle-text-size-small:14px;--castle-text-size-base:16px;--castle-text-style-smallcaps-size:var(--castle-text-size-small);--flow-tab-h:var(--castle-panel-header-height-mobile);--flow-icon-dock:var(--castle-button-icon-size-large);--flow-btn-sm:var(--castle-button-height-large)}.flow-root.is-mobile .flow-deck-identity,.flow-root.is-mobile .flow-topbar-trailing{display:none}.flow-root.is-mobile .flow-topbar{grid-template-columns:auto minmax(0,1fr)}.flow-root.is-mobile .flow-tabs-wrap{justify-self:start}.flow-root.is-mobile .flow-topbar-leading:not(:has(.flow-castle-wrap)):not(:has(.flow-draft-status)){display:none}.flow-root.is-mobile .menu-item.flow-menu-narrow{display:flex}.flow-root.is-mobile .menu-separator.flow-menu-narrow{display:block}.flow-scroller{flex:auto;min-height:0;overflow:auto}.flow-field{width:max-content;min-width:100%;min-height:100%}.flow-row{align-items:flex-start;gap:var(--flow-gap);width:max-content;min-height:100%;padding:calc(var(--flow-dock-h) + var(--flow-gap) * 2) var(--flow-gap) var(--flow-gap);padding-right:calc(var(--flow-gap) + var(--flow-overscroll,0px));display:flex}.flow-group{flex-direction:column;min-width:200px;display:flex}.flow-root.is-mobile .panel:hover,.flow-root.is-mobile .panel.is-hover,.flow-root.is-maximized .panel:hover,.flow-root.is-maximized .panel.is-hover{border-color:var(--castle-border-1)}.flow-root.is-mobile .panel-header:hover,.flow-root.is-mobile .panel-tabs-header:hover{background:var(--castle-surface-3);cursor:default}.flow-tab-icon{font-size:var(--flow-icon-dock);flex-shrink:0;justify-content:center;align-items:center;display:inline-flex}.flow-drop-indicator{background:var(--castle-border-4);z-index:60;pointer-events:none;border-radius:2px;width:3px;position:fixed;transform:translate(-50%)}.flow-group.pinned{left:var(--flow-gap);z-index:5;position:sticky;box-shadow:0 6px 24px #00000073}.flow-panel-body{flex:auto;min-height:0;position:relative;overflow:hidden}.flow-panel-slot{width:100%;height:100%}.flow-resize-e{top:var(--flow-tab-h);cursor:col-resize;touch-action:none;z-index:20;width:16px;position:absolute;bottom:0;right:-8px}.flow-resize-s{cursor:row-resize;touch-action:none;z-index:20;height:16px;position:absolute;bottom:-8px;left:0;right:0}.flow-resize-se{cursor:nwse-resize;touch-action:none;z-index:21;width:22px;height:22px;position:absolute;bottom:-11px;right:-11px}.flow-placeholder{height:100%;color:var(--flow-muted);text-align:center;flex-direction:column;justify-content:center;align-items:center;gap:8px;padding:16px;display:flex}.flow-placeholder-icon :is(svg){width:34px;height:34px}.flow-placeholder-label{color:var(--flow-secondary);font-size:14px}.flow-placeholder-kind{color:var(--flow-muted);font:11px ui-monospace,SFMono-Regular,Menlo,monospace}.flow-placeholder.kind-play{background:repeating-linear-gradient(45deg,#101018,#101018 10px,#0d0d14 10px 20px)}.flow-picker{z-index:50;max-height:min(60vh,420px);position:fixed}.flow-picker-input{margin-bottom:var(--castle-space-base);color:var(--flow-fg);background:var(--flow-surface);border:1px solid var(--flow-border);border-radius:var(--castle-radius-small);outline:none;flex:none;padding:7px 9px;font:13px ui-sans-serif,system-ui,sans-serif}.flow-picker-input:focus{border-color:var(--flow-border-active)}.flow-picker-list{flex:auto;min-height:0;overflow-y:auto}.flow-picker-empty{color:var(--flow-muted);padding:10px 8px;font-size:12px}.flow-operator-host{width:100%;height:100%}.flow-root.is-maximized .flow-scroller{overflow:hidden}.flow-root.is-maximized .flow-field,.flow-root.is-maximized .flow-row{width:100%;height:100%}.flow-root.is-maximized .flow-row{align-items:stretch}.flow-group.maximized{width:100%;height:100%}.flow-group.hidden{display:none}.flow-root.is-mobile .flow-scroller{position:relative;overflow:clip}.flow-root.is-mobile .flow-field{inset:calc(var(--flow-dock-h) + var(--flow-gap) * 2) 0 var(--flow-gap);width:auto;min-width:0;height:auto;min-height:0;position:absolute;overflow:clip}.flow-root.is-mobile .flow-row{width:100%;height:100%;transform:translateX(calc(var(--flow-page,0) * -100% + var(--flow-drag,0px)));will-change:transform;flex-wrap:nowrap;align-items:stretch;gap:0;padding:0;transition:transform .28s cubic-bezier(.22,.61,.36,1);display:flex}.flow-root.is-mobile.flow-dragging .flow-row{transition:none}.flow-root.is-mobile .flow-group{flex:0 0 100%;min-width:0;margin:0}.flow-root.is-mobile .flow-resize-e,.flow-root.is-mobile .flow-resize-s,.flow-root.is-mobile .flow-resize-se{display:none}@media (prefers-reduced-motion:reduce){.flow-root.is-mobile .flow-row{transition:none}}.flow-push-modal-backdrop{z-index:1000;-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);pointer-events:auto;background:#0000008c;justify-content:center;align-items:center;padding:24px;display:flex;position:fixed;inset:0}.flow-push-modal{border:1px solid var(--flow-border);text-align:center;background:#141414;border-radius:18px;flex-direction:column;align-items:center;gap:10px;width:min(360px,100%);padding:28px 24px;display:flex;box-shadow:0 20px 60px #0009}.flow-push-spinner{border:3px solid #ffffff26;border-top-color:var(--flow-fg);border-radius:50%;width:34px;height:34px;animation:.8s linear infinite flow-push-spin}@keyframes flow-push-spin{to{transform:rotate(360deg)}}.flow-push-check{color:#fff;background:#2e7d32;border-radius:50%;justify-content:center;align-items:center;width:34px;height:34px;font-size:20px;font-weight:700;display:flex}.flow-push-check-failed{background:var(--castle-danger-surface)}.flow-push-title{color:var(--flow-fg);font-size:16px;font-weight:600}.flow-push-sub{color:var(--flow-secondary);font-size:12px}.flow-push-url{overflow-wrap:anywhere;color:#7aa2ff;max-width:100%;font:13px ui-monospace,SFMono-Regular,Menlo,monospace;text-decoration:none}.flow-push-url:hover{text-decoration:underline}.flow-push-done{background:var(--flow-fg);color:var(--flow-gutter);cursor:pointer;border:none;border-radius:999px;margin-top:8px;padding:9px 24px;font-size:14px;font-weight:600}.flow-tabstrip{height:var(--flow-tab-h);-webkit-user-select:none;user-select:none;touch-action:none;flex-shrink:0}.flow-tabs-row{position:relative;overflow:hidden}.flow-tabs-row .panel-tab{flex:0 auto;min-width:0}.flow-tab-icon svg{width:var(--flow-icon-dock);height:var(--flow-icon-dock)}.flow-tabs-row .panel-tab-insert{z-index:3;height:auto;position:absolute;top:0;bottom:0}.panel-tab-ghost,.dock-segment-ghost{z-index:80;position:fixed}.flow-tabstrip .button{flex-shrink:0;align-self:center}.flow-tab-body{position:absolute;inset:0}.flow-tab-body.inactive{display:none}.flow-class-drawer{background:var(--castle-sheet-bg,var(--v2-surface));border-right:1px solid var(--flow-border);flex-direction:column;flex:none;width:220px;min-height:0;padding:2px 4px 6px;display:flex;overflow:hidden}.flow-class-files{flex:auto;min-height:0;overflow-y:auto}.flow-class-files .fileBrowserBare,.flow-class-files .fileTree{flex:none;height:auto;overflow:visible}.flow-class-recent{border-bottom:1px solid var(--castle-inspector-divider,var(--flow-border));margin-bottom:10px;padding-bottom:10px}.flow-class-section{color:var(--v2-muted,var(--flow-muted));padding:5px 9px;font-size:14px}.flow-class-drawer .flow-view-segments{margin:4px 2px 8px}.flow-class-drawer-empty{color:var(--flow-muted);padding:10px 8px;font-size:12px}.flow-empty-editor{flex:auto;height:100%;min-height:0;display:flex}.flow-empty-editor .flow-class-drawer{flex:0 0 220px}.flow-empty-editor-msg{color:var(--flow-muted);background:var(--castle-sheet-bg,var(--v2-surface));flex:auto;justify-content:center;align-items:center;font-size:13px;display:flex}.flow-tabstrip-mobile{cursor:default;grid-template-columns:1fr auto 1fr;align-items:center;display:grid}.flow-mobile-strip-left,.flow-mobile-strip-right{min-width:0}.flow-mobile-strip-right{justify-content:flex-end;align-items:center;display:flex}.flow-tabstrip-mobile .panel-header-actions{margin-left:0}.panel-mobile-current .flow-tab-icon,.panel-mobile-current .flow-tab-icon svg{width:var(--castle-button-icon-size-large);height:var(--castle-button-icon-size-large)}.flow-mobile-chevron{width:var(--castle-button-icon-size-large);height:var(--castle-button-icon-size-large);opacity:.6;flex-shrink:0;justify-content:center;align-items:center;display:inline-flex}.flow-mobile-chevron svg{width:var(--castle-button-icon-size-large);height:var(--castle-button-icon-size-large);display:block}.flow-mobile-switch-backdrop{z-index:900;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);pointer-events:auto;background:#0000008c;align-items:flex-end;display:flex;position:fixed;inset:0}.flow-mobile-switch{border-top:1px solid var(--flow-border);background:#141414;border-radius:16px 16px 0 0;flex-direction:column;width:100%;max-height:70vh;display:flex;overflow:hidden}.flow-mobile-switch-header{border-bottom:1px solid var(--flow-border);justify-content:space-between;align-items:center;padding:14px 16px;font-weight:600;display:flex}.flow-mobile-switch-close{color:var(--flow-secondary);cursor:pointer;background:0 0;border:none;font-size:22px;line-height:1}.flow-view-segments{background:var(--v2-inset,#0e0e0e);border-radius:8px;flex:none;gap:2px;margin:10px 16px 6px;padding:2px;display:flex}.flow-view-segment{color:var(--flow-secondary);font:inherit;cursor:pointer;background:0 0;border:none;border-radius:6px;flex:1 1 0;padding:7px 10px;font-size:13px;font-weight:600}.flow-view-segment.on{color:var(--flow-text,#eee);background:#282828}.flow-mobile-switch-list{background:var(--v2-surface,#141414);flex-direction:column;flex:auto;min-height:0;display:flex;overflow:hidden}.flow-mobile-switch-list .flow-class-files{padding:4px 6px 10px}