browsentic 0.4.6 → 0.4.9

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.
@@ -3722,7 +3722,7 @@ var import_websocket = __toESM(require_websocket(), 1);
3722
3722
  var import_websocket_server = __toESM(require_websocket_server(), 1);
3723
3723
 
3724
3724
  // ../lib/actions/protocol.ts
3725
- var SOCKET_PROTOCOL_VERSION = 14;
3725
+ var SOCKET_PROTOCOL_VERSION = 16;
3726
3726
  var EXTERNAL_RUN_ID = "external";
3727
3727
  var DAEMON_PORTS = [8765, 8766, 8767];
3728
3728
  var EXTENSION_REQUEST_FRAMES = [
@@ -3740,6 +3740,7 @@ var EXTENSION_REQUEST_FRAMES = [
3740
3740
  "analyzeRecording",
3741
3741
  "agentState",
3742
3742
  "setAgent",
3743
+ "setAgentModel",
3743
3744
  "grantAgent",
3744
3745
  "listSkills",
3745
3746
  "guardrails",
@@ -20100,6 +20101,28 @@ var hoverElement = defineAction({
20100
20101
  }
20101
20102
  });
20102
20103
 
20104
+ // ../lib/actions/page/inject-code.ts
20105
+ var MAX_CODE_LENGTH = 32768;
20106
+ var injectCode = defineAction({
20107
+ name: "page.injectCode",
20108
+ description: "Install a small toolkit of JavaScript functions into the page, to be called later with page.runCode. Reach for it only when the ordinary tools are the wrong shape: a step sequence you are about to repeat three or more times with different inputs (create 20 tags, delete every row), or a capability no tool covers (seek a video, read a canvas, drive a bespoke editor API). The user reviews and approves the code before it runs \u2014 one approval covers every later page.runCode call and survives page reloads, so batch work needs no further prompts. The toolkit is bound to the tab and origin it was approved on; navigating to another site voids it. Installing goes through Chrome\u2019s debugger, so the browser shows a \u201CBrowsentic is debugging this browser\u201D bar for the moment it takes, it cannot install on a tab that has DevTools open, and it is unavailable on Firefox \u2014 the calls afterwards are cheap and show nothing. For a one-off click or fill, the ordinary tools are always the better choice.",
20109
+ input: external_exports.object({
20110
+ purpose: external_exports.string().min(1).max(200).describe(
20111
+ "One plain sentence saying what this toolkit does and why it is needed \u2014 shown to the user on the approval prompt, so write it for them, not for the page."
20112
+ ),
20113
+ code: external_exports.string().min(1).max(MAX_CODE_LENGTH).describe(
20114
+ "JavaScript source that assigns each entry point onto the provided `tools` object: `tools.addTag = async (name) => {\u2026}`. It runs once in the page\u2019s main world after the user approves it, so it can use the page\u2019s DOM, globals and same-origin fetch, but nothing of the extension. Keep it pure of data: anything that varies per call arrives as arguments through page.runCode, and secrets never belong in it. Async functions are awaited; return values must be JSON-serializable."
20115
+ ),
20116
+ call: external_exports.object({
20117
+ function: external_exports.string().min(1).describe("Name of a function the code assigns onto `tools`."),
20118
+ args: external_exports.array(external_exports.unknown()).default([]).describe("Arguments for that first call, JSON values only.")
20119
+ }).optional().describe("Call one of the new functions immediately after installing, saving a round trip when the first use is already known.")
20120
+ }),
20121
+ execute() {
20122
+ throw new ActionError("page.injectCode is resolved by the Browsentic extension, not in the page", "UNSUPPORTED");
20123
+ }
20124
+ });
20125
+
20103
20126
  // ../lib/actions/page/list-downloads.ts
20104
20127
  var listDownloads = defineAction({
20105
20128
  name: "page.listDownloads",
@@ -20228,12 +20251,9 @@ var CURSOR_PATHS = [
20228
20251
  ];
20229
20252
  var CURSOR2 = `url("data:image/svg+xml,${encodeURIComponent(cursorSvg())}") 14 14, crosshair`;
20230
20253
  var DEFAULT_HINT = "Click the element you mean";
20231
- var picking = false;
20232
- function lensIsUp() {
20233
- return picking;
20234
- }
20254
+ var dismissCurrent = null;
20235
20255
  function pickWithLens({ hint, timeoutMs }) {
20236
- picking = true;
20256
+ dismissCurrent?.();
20237
20257
  const host = document.createElement("div");
20238
20258
  host.id = HOST_ID;
20239
20259
  host.style.cssText = "all: initial; position: static;";
@@ -20248,6 +20268,8 @@ function pickWithLens({ hint, timeoutMs }) {
20248
20268
  const chip = root.querySelector(".chip");
20249
20269
  let hovered = null;
20250
20270
  return new Promise((resolve4) => {
20271
+ const dismiss = () => settle2({ cancelled: true });
20272
+ dismissCurrent = dismiss;
20251
20273
  const timer = setTimeout(() => settle2({ timedOut: true }), timeoutMs);
20252
20274
  const mute = (event) => {
20253
20275
  event.stopPropagation();
@@ -20312,7 +20334,7 @@ function pickWithLens({ hint, timeoutMs }) {
20312
20334
  }
20313
20335
  host.remove();
20314
20336
  cursor.remove();
20315
- picking = false;
20337
+ if (dismissCurrent === dismiss) dismissCurrent = null;
20316
20338
  resolve4(outcome);
20317
20339
  }
20318
20340
  });
@@ -20391,18 +20413,16 @@ function styles() {
20391
20413
 
20392
20414
  // ../lib/actions/page/pick-element.ts
20393
20415
  var MAX_CONTENT = 2e4;
20416
+ var PICK_DEFAULT_TIMEOUT_MS = 6e4;
20394
20417
  var pickElement = defineAction({
20395
20418
  name: "page.pickElement",
20396
- description: "Ask the user to point at an element \u2014 A-Eye. Their cursor becomes a lens, whatever they hover is outlined, and the element they click comes back with its selector, its role and its rendered text. Use it when a target is genuinely ambiguous \u2014 several things share a label, or the user said \u201Cthis one\u201D about something you cannot see \u2014 and pointing is faster than describing. It takes over the page and waits for a person, so never call it to explore, and never call it twice in a row.",
20419
+ description: "Ask the user to point at an element \u2014 A-Eye. Their cursor becomes a lens, whatever they hover is outlined, and the element they click comes back with its selector, its role, its rendered text and a screenshot of it exactly as they saw it. Use it when a target is genuinely ambiguous \u2014 several things share a label, or the user said \u201Cthis one\u201D about something you cannot see \u2014 and pointing is faster than describing. It takes over the page and waits for a person, so never call it to explore; a new call dismisses a pick already waiting.",
20397
20420
  input: external_exports.object({
20398
20421
  hint: external_exports.string().max(120).optional().describe("One line shown over the page saying what to point at, e.g. \u201CPoint at the price you mean\u201D"),
20399
20422
  maxContentLength: external_exports.number().int().positive().max(MAX_CONTENT).default(2e3).describe('Characters of the element\u2019s rendered text to return; past that it is cut and "truncated" comes back true'),
20400
- timeoutMs: external_exports.number().int().min(5e3).max(3e5).default(6e4).describe("How long to wait for the user to click before giving up")
20423
+ timeoutMs: external_exports.number().int().min(5e3).max(3e5).default(PICK_DEFAULT_TIMEOUT_MS).describe("How long to wait for the user to click before giving up")
20401
20424
  }),
20402
20425
  async execute({ hint, maxContentLength, timeoutMs }) {
20403
- if (lensIsUp()) {
20404
- throw new ActionError("A-Eye is already waiting for the user to point at something", "ACTION_FAILED");
20405
- }
20406
20426
  const outcome = await pickWithLens({ hint, timeoutMs });
20407
20427
  if ("timedOut" in outcome) {
20408
20428
  throw new ActionError(
@@ -20416,12 +20436,18 @@ var pickElement = defineAction({
20416
20436
  const element = outcome.picked;
20417
20437
  const rendered2 = element instanceof HTMLElement ? element.innerText : element.textContent ?? "";
20418
20438
  const content = rendered2.replace(/\n{3,}/g, "\n\n").trim() || accessibleText(element);
20439
+ const rect = element.getBoundingClientRect();
20419
20440
  return {
20420
20441
  element: describeElement(element),
20421
20442
  content: content.slice(0, maxContentLength),
20422
20443
  truncated: content.length > maxContentLength,
20423
20444
  url: location.href,
20424
- title: document.title
20445
+ title: document.title,
20446
+ capture: {
20447
+ region: { x: rect.x, y: rect.y, w: rect.width, h: rect.height },
20448
+ viewport: { w: window.innerWidth, h: window.innerHeight },
20449
+ dpr: window.devicePixelRatio || 1
20450
+ }
20425
20451
  };
20426
20452
  }
20427
20453
  });
@@ -20733,6 +20759,64 @@ function renderDiagram2(tree) {
20733
20759
  return lines.join("\n");
20734
20760
  }
20735
20761
 
20762
+ // ../lib/actions/page/toolkit.ts
20763
+ var TOOLKIT_ATTRIBUTE = "data-browsentic-toolkit";
20764
+ var TOOLKIT_CALL_EVENT = "browsentic:toolkit:call";
20765
+ var TOOLKIT_RESULT_EVENT = "browsentic:toolkit:result";
20766
+ var TOOLKIT_MISSING = "TOOLKIT_MISSING";
20767
+ var CODE_ERROR = "CODE_ERROR";
20768
+ function callToolkit(fn, args, timeoutMs) {
20769
+ if (!document.documentElement.hasAttribute(TOOLKIT_ATTRIBUTE)) {
20770
+ throw new ActionError("No toolkit is installed in this page.", TOOLKIT_MISSING);
20771
+ }
20772
+ const callId = crypto.randomUUID();
20773
+ return new Promise((resolve4, reject) => {
20774
+ const onResult = (event) => {
20775
+ const reply = parseReply(event.detail);
20776
+ if (reply?.id !== callId) return;
20777
+ stop();
20778
+ if (reply.ok) resolve4(reply.value ?? null);
20779
+ else reject(new ActionError(reply.error ?? "The function threw.", CODE_ERROR));
20780
+ };
20781
+ const timer = setTimeout(() => {
20782
+ stop();
20783
+ reject(new ActionError(`\u201C${fn}\u201D did not finish within ${timeoutMs}ms.`, "TIMEOUT"));
20784
+ }, timeoutMs);
20785
+ function stop() {
20786
+ clearTimeout(timer);
20787
+ window.removeEventListener(TOOLKIT_RESULT_EVENT, onResult);
20788
+ }
20789
+ window.addEventListener(TOOLKIT_RESULT_EVENT, onResult);
20790
+ window.dispatchEvent(
20791
+ new CustomEvent(TOOLKIT_CALL_EVENT, { detail: JSON.stringify({ id: callId, fn, args }) })
20792
+ );
20793
+ });
20794
+ }
20795
+ function parseReply(detail) {
20796
+ if (typeof detail !== "string") return null;
20797
+ try {
20798
+ return JSON.parse(detail);
20799
+ } catch {
20800
+ return null;
20801
+ }
20802
+ }
20803
+
20804
+ // ../lib/actions/page/run-code.ts
20805
+ var runCode = defineAction({
20806
+ name: "page.runCode",
20807
+ description: "Call one function from the toolkit page.injectCode installed in this tab, with fresh arguments. This is the cheap, repeatable half of the pair: the user approved the code once, so every call runs without another prompt, and a page reload re-installs the approved toolkit on its own. It refuses if nothing is installed here, or if the tab has moved to a different site than the one the code was approved on \u2014 inject again in either case. The function\u2019s return value comes back as JSON.",
20808
+ input: external_exports.object({
20809
+ function: external_exports.string().min(1).describe("Name of a function the installed toolkit assigned onto `tools`."),
20810
+ args: external_exports.array(external_exports.unknown()).default([]).describe(
20811
+ "Arguments passed to the function, in order. JSON values only \u2014 this is where per-call data like a tag name belongs."
20812
+ ),
20813
+ timeoutMs: external_exports.number().int().min(100).max(12e4).default(1e4).describe("How long the call may run before it is abandoned. Raise it for functions that wait on the page.")
20814
+ }),
20815
+ async execute({ function: fn, args, timeoutMs }) {
20816
+ return { function: fn, returned: await callToolkit(fn, args, timeoutMs) };
20817
+ }
20818
+ });
20819
+
20736
20820
  // ../lib/actions/page/screenshot.ts
20737
20821
  var screenshot = defineAction({
20738
20822
  name: "page.screenshot",
@@ -21444,6 +21528,8 @@ var actions = new Map(
21444
21528
  pressKey,
21445
21529
  submitForm,
21446
21530
  waitForElement,
21531
+ injectCode,
21532
+ runCode,
21447
21533
  findProgress,
21448
21534
  findSearch,
21449
21535
  readTheme,
@@ -21489,6 +21575,7 @@ var SAVE_SITE_MAP_ACTION = `${RESERVED_PREFIX}saveSiteMap`;
21489
21575
  var START_RECORDING_ACTION = `${RESERVED_PREFIX}startRecording`;
21490
21576
  var STOP_RECORDING_ACTION = `${RESERVED_PREFIX}stopRecording`;
21491
21577
  var READ_SITEMAP_ACTION = `${RESERVED_PREFIX}readSitemap`;
21578
+ var FOCUS_SHOT_ACTION = `${RESERVED_PREFIX}focusShot`;
21492
21579
 
21493
21580
  // ../lib/agents/catalog.ts
21494
21581
  var AGENT_KINDS = ["claude", "codex", "antigravity"];
@@ -21500,7 +21587,8 @@ var AGENTS = {
21500
21587
  vendor: "Anthropic",
21501
21588
  bin: "claude",
21502
21589
  install: "npm i -g @anthropic-ai/claude-code",
21503
- docs: "https://claude.com/claude-code"
21590
+ docs: "https://claude.com/claude-code",
21591
+ models: ["claude-fable-5", "claude-opus-5", "claude-sonnet-5", "claude-haiku-4-5"]
21504
21592
  },
21505
21593
  codex: {
21506
21594
  kind: "codex",
@@ -21508,7 +21596,8 @@ var AGENTS = {
21508
21596
  vendor: "OpenAI",
21509
21597
  bin: "codex",
21510
21598
  install: "npm i -g @openai/codex",
21511
- docs: "https://developers.openai.com/codex/cli"
21599
+ docs: "https://developers.openai.com/codex/cli",
21600
+ models: ["gpt-5.6-terra", "gpt-5.1-codex-max", "gpt-5.1-codex", "gpt-5.1-codex-mini"]
21512
21601
  },
21513
21602
  antigravity: {
21514
21603
  kind: "antigravity",
@@ -21516,7 +21605,8 @@ var AGENTS = {
21516
21605
  vendor: "Google",
21517
21606
  bin: "agy",
21518
21607
  install: "https://antigravity.google/docs/cli/install",
21519
- docs: "https://antigravity.google/docs/cli"
21608
+ docs: "https://antigravity.google/docs/cli",
21609
+ models: ["gemini-3-pro", "gemini-3-flash"]
21520
21610
  }
21521
21611
  };
21522
21612
  var AGENT_LIST = AGENT_KINDS.map((kind) => AGENTS[kind]);
@@ -21642,6 +21732,21 @@ function writeActiveAgent(kind) {
21642
21732
  const stored = readStored();
21643
21733
  write({ ...stored, agent: kind });
21644
21734
  }
21735
+ function writeAgentModel(kind, model) {
21736
+ const stored = readStored();
21737
+ const agents = { ...stored.agents ?? {} };
21738
+ const scoped = { ...agents[kind] ?? {} };
21739
+ const value = text(model);
21740
+ if (value) scoped.model = value;
21741
+ else delete scoped.model;
21742
+ if (Object.keys(scoped).length) agents[kind] = scoped;
21743
+ else delete agents[kind];
21744
+ const next = { ...stored };
21745
+ if (Object.keys(agents).length) next.agents = agents;
21746
+ else delete next.agents;
21747
+ if (kind === "claude") delete next.model;
21748
+ write(next);
21749
+ }
21645
21750
  function writeGuardrailSetting(setting, value) {
21646
21751
  const stored = readStored();
21647
21752
  const guardrails = { ...stored.guardrails ?? {} };
@@ -21917,9 +22022,10 @@ function readDir(dir, source) {
21917
22022
  }
21918
22023
  }
21919
22024
  }
22025
+ var SCRIPTING_SKILL = "page-scripting";
21920
22026
  function routeSkill(skills, instruction, context) {
21921
22027
  if (!skills.length) return null;
21922
- const bases = skills.filter((skill) => skill.category === "general");
22028
+ const bases = skills.filter((skill) => skill.category === "general" && skill.name !== SCRIPTING_SKILL);
21923
22029
  const fallback = bases.find((skill) => skill.isDefault) ?? bases[0] ?? skills[0];
21924
22030
  let text2 = instruction;
21925
22031
  const forced = [];
@@ -21947,7 +22053,8 @@ function routeSkill(skills, instruction, context) {
21947
22053
  function overlaysFor(skills, context, forced) {
21948
22054
  const host = context?.url ? hostnameOf(context.url) : "";
21949
22055
  const matched = host ? skills.filter((skill) => skill.category === "site-exploration" && !forced.includes(skill)).map((skill) => ({ skill, match: matchedDomains(host, skill.domains)[0] ?? "" })).filter((entry) => entry.match).sort((a, b) => b.match.length - a.match.length).map((entry) => entry.skill) : [];
21950
- return [...forced, ...matched];
22056
+ const scripting = context?.liveTools ? skills.filter((skill) => skill.name === SCRIPTING_SKILL && !forced.includes(skill)) : [];
22057
+ return [...forced, ...matched, ...scripting];
21951
22058
  }
21952
22059
  function parseSkill(raw, fallbackName, source) {
21953
22060
  const { fields, body } = splitFrontMatter(raw);
@@ -22485,6 +22592,8 @@ var DOWNLOAD_ACTION = "page.captureDownload";
22485
22592
  var EXTRACT_ACTION = "page.extractText";
22486
22593
  var CAPTCHA_ACTION = "page.solveCaptcha";
22487
22594
  var NETWORK_ACTION = "page.readNetwork";
22595
+ var INJECT_ACTION = "page.injectCode";
22596
+ var RUN_CODE_ACTION = "page.runCode";
22488
22597
  var CONDITIONS = {
22489
22598
  /** Internal actions that only the daemon may originate. */
22490
22599
  reservedAction: (request) => request.action.startsWith(RESERVED_PREFIX),
@@ -22518,6 +22627,18 @@ var CONDITIONS = {
22518
22627
  leavesPinnedTab: (request) => targetsAnotherTab(request.action, request.input, request.scope),
22519
22628
  /** Acting on another site's human-verification control. */
22520
22629
  answersCaptcha: (request) => request.action === CAPTCHA_ACTION,
22630
+ /**
22631
+ * Installing agent-written JavaScript into the page. The code is the whole of what is
22632
+ * being authorised — `page.runCode` only ever calls back into what this approved.
22633
+ */
22634
+ injectsCode: (request) => request.action === INJECT_ACTION,
22635
+ /**
22636
+ * The one place a caller is named in a condition rather than left to `unattended`.
22637
+ * A toolkit is approved by a person reading it in the side panel, for the conversation
22638
+ * they were having; an MCP client was never in that room, and the switch the user
22639
+ * turned off is not one it can see.
22640
+ */
22641
+ runsCodeOutsideThePanel: (request) => request.action === RUN_CODE_ACTION && request.caller === "external",
22521
22642
  /**
22522
22643
  * Turns a sealed placeholder back into the credential it stands for. The release
22523
22644
  * itself happens in the extension, one hop from the page; this is where a person gets
@@ -22600,6 +22721,26 @@ var DEFAULT_RULES = [
22600
22721
  title: "Saves a file from the page to disk",
22601
22722
  reason: "That writes a file the page chose into the user\u2019s download folder."
22602
22723
  },
22724
+ {
22725
+ // The most powerful thing an agent can ask for, and the one gate that has to show
22726
+ // its work: the panel puts the source behind a Review button, because "allow this
22727
+ // action?" is not a question anyone can answer about code they have not read. It
22728
+ // confirms rather than denies because a reviewed function is how twenty repetitions
22729
+ // stop being twenty round trips — and `unattended: deny` keeps an external MCP
22730
+ // client, which has nobody to show the code to, from installing any at all.
22731
+ id: "code-injection",
22732
+ when: "injectsCode",
22733
+ effect: "confirm",
22734
+ title: "Runs code it wrote in the page",
22735
+ reason: "That installs JavaScript the agent wrote into the page, with your logged-in session."
22736
+ },
22737
+ {
22738
+ id: "external-code-execution",
22739
+ when: "runsCodeOutsideThePanel",
22740
+ effect: "deny",
22741
+ title: "Calls injected code from outside the panel",
22742
+ reason: "Code installed by page.injectCode was reviewed and approved for the side-panel conversation that asked for it. It is not available to an MCP client."
22743
+ },
22603
22744
  {
22604
22745
  id: "leaves-pinned-tab",
22605
22746
  when: "leavesPinnedTab",
@@ -23346,6 +23487,11 @@ function revokeSessions(predicate) {
23346
23487
  // agent/service.ts
23347
23488
  import { randomUUID as randomUUID6 } from "crypto";
23348
23489
 
23490
+ // ../lib/actions/tool-names.ts
23491
+ function toolNameFor(actionName) {
23492
+ return actionName.replaceAll(".", "_");
23493
+ }
23494
+
23349
23495
  // ../lib/skills/scrub.ts
23350
23496
  var CONTROL_CHARS = new RegExp(
23351
23497
  "[\\u0000-\\u0008\\u000b-\\u001f\\u007f-\\u009f\\u200b-\\u200f\\u202a-\\u202e\\u2066-\\u2069\\ufeff]",
@@ -23615,6 +23761,15 @@ var claudeRunner = {
23615
23761
  };
23616
23762
  },
23617
23763
  reader() {
23764
+ let generated = 0;
23765
+ const report = (usage, sink) => {
23766
+ if (!usage) return;
23767
+ generated += usage.output_tokens ?? 0;
23768
+ sink.usage({
23769
+ contextTokens: (usage.input_tokens ?? 0) + (usage.cache_read_input_tokens ?? 0) + (usage.cache_creation_input_tokens ?? 0) + (usage.output_tokens ?? 0),
23770
+ outputTokens: generated
23771
+ });
23772
+ };
23618
23773
  return (line, sink) => {
23619
23774
  const message = parseJsonLine(line);
23620
23775
  if (!message) return;
@@ -23638,10 +23793,14 @@ var claudeRunner = {
23638
23793
  }
23639
23794
  return;
23640
23795
  }
23796
+ case "assistant":
23797
+ if (!message.parent_tool_use_id) report(message.message?.usage, sink);
23798
+ return;
23641
23799
  case "result":
23642
23800
  if (message.is_error) {
23643
23801
  return sink.fail("AGENT_FAILED", message.result || message.subtype || "Claude Code reported an error");
23644
23802
  }
23803
+ if (!generated) report(message.usage, sink);
23645
23804
  return sink.done(message.stop_reason || "end_turn");
23646
23805
  }
23647
23806
  };
@@ -23952,6 +24111,17 @@ var codexRunner = {
23952
24111
  return finish(msg.message, sink);
23953
24112
  case "web_search_begin":
23954
24113
  return sink.tool(randomUUID4(), WEB_TOOL);
24114
+ case "token_count": {
24115
+ const last = msg.info?.last_token_usage ?? msg.info?.total_token_usage;
24116
+ const total = msg.info?.total_token_usage ?? last;
24117
+ if (last) {
24118
+ sink.usage({
24119
+ contextTokens: (last.input_tokens ?? 0) + (last.output_tokens ?? 0),
24120
+ outputTokens: total?.output_tokens ?? 0
24121
+ });
24122
+ }
24123
+ return;
24124
+ }
23955
24125
  case "task_complete":
23956
24126
  return sink.done("end_turn");
23957
24127
  case "error":
@@ -23975,8 +24145,16 @@ var codexRunner = {
23975
24145
  if (kind === "web_search") return sink.tool(item?.id ?? randomUUID4(), WEB_TOOL);
23976
24146
  return;
23977
24147
  }
23978
- case "turn.completed":
24148
+ case "turn.completed": {
24149
+ const usage = frame.usage;
24150
+ if (usage) {
24151
+ sink.usage({
24152
+ contextTokens: (usage.input_tokens ?? 0) + (usage.output_tokens ?? 0),
24153
+ outputTokens: usage.output_tokens ?? 0
24154
+ });
24155
+ }
23979
24156
  return sink.done("end_turn");
24157
+ }
23980
24158
  case "turn.failed":
23981
24159
  return sink.fail("AGENT_FAILED", frame.error?.message || "Codex could not finish the turn");
23982
24160
  case "error":
@@ -24087,6 +24265,7 @@ async function probe2(runner, settings) {
24087
24265
  return {
24088
24266
  kind: runner.kind,
24089
24267
  bin: settings.bin,
24268
+ model: settings.model,
24090
24269
  ready: false,
24091
24270
  problem: {
24092
24271
  code: "AGENT_MISSING",
@@ -24099,6 +24278,7 @@ async function probe2(runner, settings) {
24099
24278
  return {
24100
24279
  kind: runner.kind,
24101
24280
  bin: settings.bin,
24281
+ model: settings.model,
24102
24282
  ready: false,
24103
24283
  problem: {
24104
24284
  code: "AGENT_UNUSABLE",
@@ -24108,7 +24288,14 @@ async function probe2(runner, settings) {
24108
24288
  };
24109
24289
  }
24110
24290
  const problem = await runner.check?.(settings) ?? null;
24111
- return { kind: runner.kind, bin: settings.bin, ready: !problem, version: found.detail, problem: problem ?? void 0 };
24291
+ return {
24292
+ kind: runner.kind,
24293
+ bin: settings.bin,
24294
+ model: settings.model,
24295
+ ready: !problem,
24296
+ version: found.detail,
24297
+ problem: problem ?? void 0
24298
+ };
24112
24299
  }
24113
24300
  function version2(bin, args) {
24114
24301
  return new Promise((resolve4) => {
@@ -24614,6 +24801,7 @@ function runStream(runner, context, signal, emit) {
24614
24801
  session: (id) => {
24615
24802
  if (id) sessionId = id;
24616
24803
  },
24804
+ usage: (usage) => emit({ kind: "usage", usage }),
24617
24805
  done: (stopReason) => settle2(() => {
24618
24806
  flush();
24619
24807
  resolve4({ stopReason, sessionId });
@@ -25287,6 +25475,7 @@ function isPrivateAddress(address) {
25287
25475
  }
25288
25476
 
25289
25477
  // agent/service.ts
25478
+ var FOCUS_SHOT_TOOL_NAME = toolNameFor(FOCUS_SHOT_ACTION);
25290
25479
  var AgentSession = class {
25291
25480
  constructor(deps) {
25292
25481
  this.deps = deps;
@@ -25333,6 +25522,23 @@ var AgentSession = class {
25333
25522
  emit({ kind: "toolResult", toolId, ok: result2.ok, summary: summarize(input2, result2) });
25334
25523
  return result2;
25335
25524
  }
25525
+ if (action === FOCUS_SHOT_ACTION) {
25526
+ const result2 = run.focusShot ? success({ dataUrl: run.focusShot }) : failure("NO_FOCUS_SHOT", "No A-Eye pick came with this instruction, so nothing was photographed.");
25527
+ emit({
25528
+ kind: "toolResult",
25529
+ toolId,
25530
+ ok: result2.ok,
25531
+ summary: result2.ok ? "the picked element, as photographed" : "no pick attached"
25532
+ });
25533
+ return result2;
25534
+ }
25535
+ if (!run.liveTools && (action === INJECT_ACTION || action === RUN_CODE_ACTION)) {
25536
+ emit({ kind: "toolResult", toolId, ok: false, summary: "live tools are switched off" });
25537
+ return failure(
25538
+ "LIVE_TOOLS_OFF",
25539
+ "Writing and running your own page code is switched off for this message. The user turns it on with the \u201CLive tool\u201D switch beside the message box, and only they can. Do the job with the ordinary page tools, or say that this one needs that switch and why."
25540
+ );
25541
+ }
25336
25542
  if (run.map) {
25337
25543
  const gate = gateMappingInvoke(run.map, action, input2);
25338
25544
  if (!gate.allow) {
@@ -25442,7 +25648,9 @@ var AgentSession = class {
25442
25648
  site: siteOf(context?.url),
25443
25649
  abort: new AbortController(),
25444
25650
  pending: /* @__PURE__ */ new Map(),
25445
- ownedTabIds: []
25651
+ ownedTabIds: [],
25652
+ focusShot: context?.focus?.shot,
25653
+ liveTools: context?.liveTools === true
25446
25654
  };
25447
25655
  this.runs.set(runId, run);
25448
25656
  const runner = activeRunner(await agentState(config2));
@@ -25648,6 +25856,11 @@ function focusBlock(focus) {
25648
25856
  ];
25649
25857
  if (focus.label) lines.push(`- Label: ${flatten2(focus.label)}`);
25650
25858
  lines.push(`- On: ${flatten2(focus.title)} \u2014 ${flatten2(focus.url)}`);
25859
+ if (focus.shot) {
25860
+ lines.push(
25861
+ `- A screenshot of it, taken at the instant they picked it, is attached \u2014 call \`${FOCUS_SHOT_TOOL_NAME}\` once to see it.`
25862
+ );
25863
+ }
25651
25864
  const content = focus.content.slice(0, MAX_FOCUS_CONTENT);
25652
25865
  const cut = focus.truncated || content.length < focus.content.length;
25653
25866
  lines.push(
@@ -26297,6 +26510,7 @@ function timeoutFor(action, input2) {
26297
26510
  if (action === typeText.name) return typingDurationMs(input2) + DEFAULT_TIMEOUT_MS2;
26298
26511
  if (action === startMonitor.name) return DEFAULT_TIMEOUT_MS2;
26299
26512
  if (action === awaitMonitor.name) return (declaredTimeout(input2) ?? AWAIT_DEFAULT_TIMEOUT_MS) + 5e3;
26513
+ if (action === pickElement.name) return (declaredTimeout(input2) ?? PICK_DEFAULT_TIMEOUT_MS) + 5e3;
26300
26514
  const declared = declaredTimeout(input2);
26301
26515
  return declared != null ? declared + 5e3 : DEFAULT_TIMEOUT_MS2;
26302
26516
  }
@@ -26525,7 +26739,7 @@ async function startDaemon({ version: version3, idleExit = true }) {
26525
26739
  );
26526
26740
  return;
26527
26741
  }
26528
- if (request.t === "agentState" || request.t === "setAgent" || request.t === "grantAgent") {
26742
+ if (request.t === "agentState" || request.t === "setAgent" || request.t === "setAgentModel" || request.t === "grantAgent") {
26529
26743
  void settleAgent(request).then((state) => {
26530
26744
  source.send({ t: "agentInfo", id: request.id, result: state });
26531
26745
  if (request.t === "setAgent") pushSkillCatalog(source);
@@ -26584,6 +26798,11 @@ async function startDaemon({ version: version3, idleExit = true }) {
26584
26798
  agent?.handle({ t: "reset" });
26585
26799
  log(`agent set to ${AGENTS[request.agent].label}`);
26586
26800
  }
26801
+ if (request.t === "setAgentModel") {
26802
+ const model = typeof request.model === "string" ? request.model : null;
26803
+ writeAgentModel(request.agent, model);
26804
+ log(`${AGENTS[request.agent].label} model set to ${model?.trim() || "the default"}`);
26805
+ }
26587
26806
  if (request.t === "grantAgent") await grantRunner(request.agent);
26588
26807
  const refresh = request.t !== "agentState" || request.refresh === true;
26589
26808
  return success(await agentState(readAgentConfig(), { refresh }));
@@ -26874,7 +27093,7 @@ X-Browsentic-Reason: ${reason}\r
26874
27093
  // package.json
26875
27094
  var package_default = {
26876
27095
  name: "browsentic",
26877
- version: "0.4.6",
27096
+ version: "0.4.9",
26878
27097
  description: "Hand your real, logged-in browser to the AI agent you already run. Installs the browser extension, runs the local daemon, and speaks MCP.",
26879
27098
  type: "module",
26880
27099
  license: "MIT",
@@ -0,0 +1,2 @@
1
+ /*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */
2
+ @layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial;--tw-ease:initial;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1;--tw-animation-delay:0s;--tw-animation-direction:normal;--tw-animation-duration:initial;--tw-animation-fill-mode:none;--tw-animation-iteration-count:1;--tw-enter-blur:0;--tw-enter-opacity:1;--tw-enter-rotate:0;--tw-enter-scale:1;--tw-enter-translate-x:0;--tw-enter-translate-y:0;--tw-exit-blur:0;--tw-exit-opacity:1;--tw-exit-rotate:0;--tw-exit-scale:1;--tw-exit-translate-x:0;--tw-exit-translate-y:0}}}@layer theme{:root,:host{--font-sans:"Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;--font-mono:"JetBrains Mono", "Fira Code", ui-monospace, "SF Mono", "Cascadia Code", Menlo, Consolas, monospace;--color-black:#000;--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--font-weight-medium:500;--font-weight-semibold:600;--tracking-tight:-.025em;--tracking-wider:.05em;--tracking-widest:.1em;--leading-snug:1.375;--leading-relaxed:1.625;--radius-2xl:1rem;--ease-in-out:cubic-bezier(.4, 0, .2, 1);--animate-spin:spin 1s linear infinite;--animate-ping:ping 1s cubic-bezier(0, 0, .2, 1) infinite;--animate-pulse:pulse 2s cubic-bezier(.4, 0, .6, 1) infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--font-display:"Inter Tight", "Inter", ui-sans-serif, system-ui, -apple-system, sans-serif;--ease-out-expo:cubic-bezier(.16, 1, .3, 1)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring:where(:not(iframe)){outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}*{border-color:var(--border);outline-color:var(--ring)}@supports (color:color-mix(in lab, red, red)){*{outline-color:color-mix(in oklab, var(--ring) 50%, transparent)}}body{background-color:var(--background);font-family:var(--font-sans);color:var(--foreground);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-feature-settings:"cv02", "cv03", "cv04", "ss01";text-rendering:optimizelegibility}h1,h2,h3{font-family:var(--font-display);letter-spacing:-.024em}body:after{content:"";z-index:100;pointer-events:none;opacity:.03;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");position:fixed;inset:0}::selection{background:var(--brand)}@supports (color:color-mix(in lab, red, red)){::selection{background:color-mix(in oklch, var(--brand) 32%, transparent)}}::selection{color:var(--ink)}::-webkit-scrollbar{width:8px;height:8px}::-webkit-scrollbar-track{background:0 0}::-webkit-scrollbar-thumb{background:var(--surface-2);border-radius:999px}::-webkit-scrollbar-thumb:hover{background:var(--brand)}@supports (color:color-mix(in lab, red, red)){::-webkit-scrollbar-thumb:hover{background:color-mix(in oklch, var(--brand) 40%, var(--surface-2))}}}@layer components{[data-stream] .tok{animation:browsentic-token .42s var(--ease-out-expo) both}[data-stream=live]>:last-child:after{content:"";vertical-align:-.12em;background:var(--brand);width:.42em;height:.95em;box-shadow:0 0 10px var(--brand);border-radius:1px;margin-left:.14em;display:inline-block}@supports (color:color-mix(in lab, red, red)){[data-stream=live]>:last-child:after{box-shadow:0 0 10px color-mix(in oklch, var(--brand) 70%, transparent)}}[data-stream=live]>:last-child:after{animation:1.05s step-end infinite browsentic-caret}.enters{animation:browsentic-enter .34s var(--ease-out-expo) both}.think-dot{animation:1.2s ease-in-out infinite browsentic-think}.think-dot:nth-child(2){animation-delay:.16s}.think-dot:nth-child(3){animation-delay:.32s}.sweep:after{content:"";background:linear-gradient(90deg, transparent, var(--brand), transparent);width:30%;height:1px;animation:browsentic-sweep 1.8s var(--ease-out-expo) infinite;position:absolute;inset-block-start:0;inset-inline-start:0}}@layer utilities{.pointer-events-none{pointer-events:none}.collapse{visibility:collapse}.invisible{visibility:hidden}.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.inset-0{inset:0}.inset-x-0{inset-inline:0}.top-1{top:var(--spacing)}.right-1{right:var(--spacing)}.right-1\.5{right:calc(var(--spacing) * 1.5)}.bottom-3{bottom:calc(var(--spacing) * 3)}.bottom-full{bottom:100%}.left-1\/2{left:50%}.z-20{z-index:20}.z-50{z-index:50}.mx-auto{margin-inline:auto}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:var(--spacing)}.mt-1\.5{margin-top:calc(var(--spacing) * 1.5)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-2\.5{margin-top:calc(var(--spacing) * 2.5)}.mt-px{margin-top:1px}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.ml-auto{margin-left:auto}.line-clamp-2{-webkit-line-clamp:2;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.line-clamp-3{-webkit-line-clamp:3;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-flex{display:inline-flex}.table{display:table}.field-sizing-content{field-sizing:content}.size-1\.5{width:calc(var(--spacing) * 1.5);height:calc(var(--spacing) * 1.5)}.size-2{width:calc(var(--spacing) * 2);height:calc(var(--spacing) * 2)}.size-2\.5{width:calc(var(--spacing) * 2.5);height:calc(var(--spacing) * 2.5)}.size-3{width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3)}.size-3\.5{width:calc(var(--spacing) * 3.5);height:calc(var(--spacing) * 3.5)}.size-5{width:calc(var(--spacing) * 5);height:calc(var(--spacing) * 5)}.size-6{width:calc(var(--spacing) * 6);height:calc(var(--spacing) * 6)}.size-7{width:calc(var(--spacing) * 7);height:calc(var(--spacing) * 7)}.size-8{width:calc(var(--spacing) * 8);height:calc(var(--spacing) * 8)}.size-9{width:calc(var(--spacing) * 9);height:calc(var(--spacing) * 9)}.size-20{width:calc(var(--spacing) * 20);height:calc(var(--spacing) * 20)}.size-full{width:100%;height:100%}.h-1{height:var(--spacing)}.h-1\.5{height:calc(var(--spacing) * 1.5)}.h-2\.5{height:calc(var(--spacing) * 2.5)}.h-3{height:calc(var(--spacing) * 3)}.h-4{height:calc(var(--spacing) * 4)}.h-6{height:calc(var(--spacing) * 6)}.h-7{height:calc(var(--spacing) * 7)}.h-8{height:calc(var(--spacing) * 8)}.h-9{height:calc(var(--spacing) * 9)}.h-10{height:calc(var(--spacing) * 10)}.h-auto{height:auto}.h-full{height:100%}.h-screen{height:100vh}.max-h-7{max-height:calc(var(--spacing) * 7)}.max-h-40{max-height:calc(var(--spacing) * 40)}.max-h-48{max-height:calc(var(--spacing) * 48)}.max-h-56{max-height:calc(var(--spacing) * 56)}.max-h-64{max-height:calc(var(--spacing) * 64)}.max-h-\[45\%\]{max-height:45%}.max-h-\[60\%\]{max-height:60%}.max-h-\[var\(--radix-select-content-available-height\)\]{max-height:var(--radix-select-content-available-height)}.min-h-0{min-height:0}.min-h-8{min-height:calc(var(--spacing) * 8)}.min-h-14{min-height:calc(var(--spacing) * 14)}.min-h-16{min-height:calc(var(--spacing) * 16)}.w-2\.5{width:calc(var(--spacing) * 2.5)}.w-7{width:calc(var(--spacing) * 7)}.w-\[22rem\]{width:22rem}.w-fit{width:fit-content}.w-full{width:100%}.max-w-14{max-width:calc(var(--spacing) * 14)}.max-w-\[88\%\]{max-width:88%}.max-w-full{max-width:100%}.min-w-0{min-width:0}.min-w-\[8rem\]{min-width:8rem}.min-w-\[var\(--radix-select-trigger-width\)\]{min-width:var(--radix-select-trigger-width)}.min-w-full{min-width:100%}.flex-1{flex:1}.shrink-0{flex-shrink:0}.border-collapse{border-collapse:collapse}.-translate-x-1\/2{--tw-translate-x:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.translate-x-0\.5{--tw-translate-x:calc(var(--spacing) * .5);translate:var(--tw-translate-x) var(--tw-translate-y)}.translate-x-3\.5{--tw-translate-x:calc(var(--spacing) * 3.5);translate:var(--tw-translate-x) var(--tw-translate-y)}.rotate-180{rotate:180deg}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.animate-ping{animation:var(--animate-ping)}.animate-pulse{animation:var(--animate-pulse)}.animate-spin{animation:var(--animate-spin)}.cursor-default{cursor:default}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.cursor-text{cursor:text}.touch-none{touch-action:none}.resize{resize:both}.resize-none{resize:none}.\[scrollbar-width\:none\]{scrollbar-width:none}.list-decimal{list-style-type:decimal}.list-disc{list-style-type:disc}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-baseline{align-items:baseline}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-0\.5{gap:calc(var(--spacing) * .5)}.gap-1{gap:var(--spacing)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-2\.5{gap:calc(var(--spacing) * 2.5)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-px{gap:1px}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(var(--spacing) * var(--tw-space-y-reverse));margin-block-end:calc(var(--spacing) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-1\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 1.5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 1.5) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 2) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 4) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 4) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 5) * calc(1 - var(--tw-space-y-reverse)))}.gap-x-2{column-gap:calc(var(--spacing) * 2)}.gap-x-3{column-gap:calc(var(--spacing) * 3)}.gap-y-0\.5{row-gap:calc(var(--spacing) * .5)}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-x-hidden{overflow-x:hidden}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:var(--radius-2xl)}.rounded-\[inherit\]{border-radius:inherit}.rounded-full{border-radius:2147483647px}.rounded-lg{border-radius:var(--radius)}.rounded-md{border-radius:calc(var(--radius) - 2px)}.rounded-none{border-radius:0}.rounded-xl{border-radius:calc(var(--radius) + 4px)}.rounded-tl-md{border-top-left-radius:calc(var(--radius) - 2px)}.rounded-br-md{border-bottom-right-radius:calc(var(--radius) - 2px)}.border{border-style:var(--tw-border-style);border-width:1px}.border-0{border-style:var(--tw-border-style);border-width:0}.border-y{border-block-style:var(--tw-border-style);border-block-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.border-l-2{border-left-style:var(--tw-border-style);border-left-width:2px}.border-amber\/25{border-color:var(--amber)}@supports (color:color-mix(in lab, red, red)){.border-amber\/25{border-color:color-mix(in oklab, var(--amber) 25%, transparent)}}.border-amber\/40{border-color:var(--amber)}@supports (color:color-mix(in lab, red, red)){.border-amber\/40{border-color:color-mix(in oklab, var(--amber) 40%, transparent)}}.border-brand\/25{border-color:var(--brand)}@supports (color:color-mix(in lab, red, red)){.border-brand\/25{border-color:color-mix(in oklab, var(--brand) 25%, transparent)}}.border-brand\/30{border-color:var(--brand)}@supports (color:color-mix(in lab, red, red)){.border-brand\/30{border-color:color-mix(in oklab, var(--brand) 30%, transparent)}}.border-brand\/35{border-color:var(--brand)}@supports (color:color-mix(in lab, red, red)){.border-brand\/35{border-color:color-mix(in oklab, var(--brand) 35%, transparent)}}.border-brand\/40{border-color:var(--brand)}@supports (color:color-mix(in lab, red, red)){.border-brand\/40{border-color:color-mix(in oklab, var(--brand) 40%, transparent)}}.border-brand\/45{border-color:var(--brand)}@supports (color:color-mix(in lab, red, red)){.border-brand\/45{border-color:color-mix(in oklab, var(--brand) 45%, transparent)}}.border-brand\/50{border-color:var(--brand)}@supports (color:color-mix(in lab, red, red)){.border-brand\/50{border-color:color-mix(in oklab, var(--brand) 50%, transparent)}}.border-destructive\/35{border-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.border-destructive\/35{border-color:color-mix(in oklab, var(--destructive) 35%, transparent)}}.border-destructive\/40{border-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.border-destructive\/40{border-color:color-mix(in oklab, var(--destructive) 40%, transparent)}}.border-ember\/30{border-color:var(--ember)}@supports (color:color-mix(in lab, red, red)){.border-ember\/30{border-color:color-mix(in oklab, var(--ember) 30%, transparent)}}.border-ember\/40{border-color:var(--ember)}@supports (color:color-mix(in lab, red, red)){.border-ember\/40{border-color:color-mix(in oklab, var(--ember) 40%, transparent)}}.border-ember\/45{border-color:var(--ember)}@supports (color:color-mix(in lab, red, red)){.border-ember\/45{border-color:color-mix(in oklab, var(--ember) 45%, transparent)}}.border-line{border-color:var(--line)}.border-line-strong{border-color:var(--line-strong)}.border-magenta\/35{border-color:var(--magenta)}@supports (color:color-mix(in lab, red, red)){.border-magenta\/35{border-color:color-mix(in oklab, var(--magenta) 35%, transparent)}}.border-magenta\/60{border-color:var(--magenta)}@supports (color:color-mix(in lab, red, red)){.border-magenta\/60{border-color:color-mix(in oklab, var(--magenta) 60%, transparent)}}.border-t-transparent{border-top-color:#0000}.border-l-transparent{border-left-color:#0000}.bg-amber,.bg-amber\/8{background-color:var(--amber)}@supports (color:color-mix(in lab, red, red)){.bg-amber\/8{background-color:color-mix(in oklab, var(--amber) 8%, transparent)}}.bg-amber\/10{background-color:var(--amber)}@supports (color:color-mix(in lab, red, red)){.bg-amber\/10{background-color:color-mix(in oklab, var(--amber) 10%, transparent)}}.bg-amber\/12{background-color:var(--amber)}@supports (color:color-mix(in lab, red, red)){.bg-amber\/12{background-color:color-mix(in oklab, var(--amber) 12%, transparent)}}.bg-amber\/15{background-color:var(--amber)}@supports (color:color-mix(in lab, red, red)){.bg-amber\/15{background-color:color-mix(in oklab, var(--amber) 15%, transparent)}}.bg-brand,.bg-brand\/5{background-color:var(--brand)}@supports (color:color-mix(in lab, red, red)){.bg-brand\/5{background-color:color-mix(in oklab, var(--brand) 5%, transparent)}}.bg-brand\/8{background-color:var(--brand)}@supports (color:color-mix(in lab, red, red)){.bg-brand\/8{background-color:color-mix(in oklab, var(--brand) 8%, transparent)}}.bg-brand\/10{background-color:var(--brand)}@supports (color:color-mix(in lab, red, red)){.bg-brand\/10{background-color:color-mix(in oklab, var(--brand) 10%, transparent)}}.bg-brand\/12{background-color:var(--brand)}@supports (color:color-mix(in lab, red, red)){.bg-brand\/12{background-color:color-mix(in oklab, var(--brand) 12%, transparent)}}.bg-brand\/20{background-color:var(--brand)}@supports (color:color-mix(in lab, red, red)){.bg-brand\/20{background-color:color-mix(in oklab, var(--brand) 20%, transparent)}}.bg-brand\/70{background-color:var(--brand)}@supports (color:color-mix(in lab, red, red)){.bg-brand\/70{background-color:color-mix(in oklab, var(--brand) 70%, transparent)}}.bg-destructive,.bg-destructive\/8{background-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.bg-destructive\/8{background-color:color-mix(in oklab, var(--destructive) 8%, transparent)}}.bg-destructive\/10{background-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.bg-destructive\/10{background-color:color-mix(in oklab, var(--destructive) 10%, transparent)}}.bg-destructive\/12{background-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.bg-destructive\/12{background-color:color-mix(in oklab, var(--destructive) 12%, transparent)}}.bg-ember,.bg-ember\/8{background-color:var(--ember)}@supports (color:color-mix(in lab, red, red)){.bg-ember\/8{background-color:color-mix(in oklab, var(--ember) 8%, transparent)}}.bg-ember\/10{background-color:var(--ember)}@supports (color:color-mix(in lab, red, red)){.bg-ember\/10{background-color:color-mix(in oklab, var(--ember) 10%, transparent)}}.bg-ember\/12{background-color:var(--ember)}@supports (color:color-mix(in lab, red, red)){.bg-ember\/12{background-color:color-mix(in oklab, var(--ember) 12%, transparent)}}.bg-ground-2\/70{background-color:var(--ground-2)}@supports (color:color-mix(in lab, red, red)){.bg-ground-2\/70{background-color:color-mix(in oklab, var(--ground-2) 70%, transparent)}}.bg-ground-2\/80{background-color:var(--ground-2)}@supports (color:color-mix(in lab, red, red)){.bg-ground-2\/80{background-color:color-mix(in oklab, var(--ground-2) 80%, transparent)}}.bg-ground\/40{background-color:var(--ground)}@supports (color:color-mix(in lab, red, red)){.bg-ground\/40{background-color:color-mix(in oklab, var(--ground) 40%, transparent)}}.bg-ground\/60{background-color:var(--ground)}@supports (color:color-mix(in lab, red, red)){.bg-ground\/60{background-color:color-mix(in oklab, var(--ground) 60%, transparent)}}.bg-ground\/70{background-color:var(--ground)}@supports (color:color-mix(in lab, red, red)){.bg-ground\/70{background-color:color-mix(in oklab, var(--ground) 70%, transparent)}}.bg-ground\/96{background-color:var(--ground)}@supports (color:color-mix(in lab, red, red)){.bg-ground\/96{background-color:color-mix(in oklab, var(--ground) 96%, transparent)}}.bg-ink{background-color:var(--ink)}.bg-ink-faint,.bg-ink-faint\/50{background-color:var(--ink-faint)}@supports (color:color-mix(in lab, red, red)){.bg-ink-faint\/50{background-color:color-mix(in oklab, var(--ink-faint) 50%, transparent)}}.bg-ink-faint\/60{background-color:var(--ink-faint)}@supports (color:color-mix(in lab, red, red)){.bg-ink-faint\/60{background-color:color-mix(in oklab, var(--ink-faint) 60%, transparent)}}.bg-lime{background-color:var(--lime)}.bg-magenta,.bg-magenta\/8{background-color:var(--magenta)}@supports (color:color-mix(in lab, red, red)){.bg-magenta\/8{background-color:color-mix(in oklab, var(--magenta) 8%, transparent)}}.bg-magenta\/15{background-color:var(--magenta)}@supports (color:color-mix(in lab, red, red)){.bg-magenta\/15{background-color:color-mix(in oklab, var(--magenta) 15%, transparent)}}.bg-magenta\/25{background-color:var(--magenta)}@supports (color:color-mix(in lab, red, red)){.bg-magenta\/25{background-color:color-mix(in oklab, var(--magenta) 25%, transparent)}}.bg-magenta\/30{background-color:var(--magenta)}@supports (color:color-mix(in lab, red, red)){.bg-magenta\/30{background-color:color-mix(in oklab, var(--magenta) 30%, transparent)}}.bg-surface{background-color:var(--surface)}.bg-surface-2{background-color:var(--surface-2)}.bg-surface\/20{background-color:var(--surface)}@supports (color:color-mix(in lab, red, red)){.bg-surface\/20{background-color:color-mix(in oklab, var(--surface) 20%, transparent)}}.bg-surface\/30{background-color:var(--surface)}@supports (color:color-mix(in lab, red, red)){.bg-surface\/30{background-color:color-mix(in oklab, var(--surface) 30%, transparent)}}.bg-surface\/40{background-color:var(--surface)}@supports (color:color-mix(in lab, red, red)){.bg-surface\/40{background-color:color-mix(in oklab, var(--surface) 40%, transparent)}}.bg-surface\/60{background-color:var(--surface)}@supports (color:color-mix(in lab, red, red)){.bg-surface\/60{background-color:color-mix(in oklab, var(--surface) 60%, transparent)}}.bg-surface\/70{background-color:var(--surface)}@supports (color:color-mix(in lab, red, red)){.bg-surface\/70{background-color:color-mix(in oklab, var(--surface) 70%, transparent)}}.bg-transparent{background-color:#0000}.dot-grid{background-image:radial-gradient(circle at 1px 1px,oklch(98% .01 60/.09) 1px,#0000 0);background-size:22px 22px}.fade-bottom{-webkit-mask-image:linear-gradient(#000 78%,#0000 100%);mask-image:linear-gradient(#000 78%,#0000 100%)}.fill-current{fill:currentColor}.object-cover{object-fit:cover}.p-0\.5{padding:calc(var(--spacing) * .5)}.p-1{padding:var(--spacing)}.p-2{padding:calc(var(--spacing) * 2)}.p-2\.5{padding:calc(var(--spacing) * 2.5)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-px{padding:1px}.px-1{padding-inline:var(--spacing)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-6{padding-inline:calc(var(--spacing) * 6)}.py-0{padding-block:0}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:var(--spacing)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-6{padding-block:calc(var(--spacing) * 6)}.py-8{padding-block:calc(var(--spacing) * 8)}.py-px{padding-block:1px}.pt-2{padding-top:calc(var(--spacing) * 2)}.pt-2\.5{padding-top:calc(var(--spacing) * 2.5)}.pr-6{padding-right:calc(var(--spacing) * 6)}.pb-0{padding-bottom:0}.pb-1{padding-bottom:var(--spacing)}.pb-1\.5{padding-bottom:calc(var(--spacing) * 1.5)}.pb-2{padding-bottom:calc(var(--spacing) * 2)}.pb-6{padding-bottom:calc(var(--spacing) * 6)}.pl-2{padding-left:calc(var(--spacing) * 2)}.pl-2\.5{padding-left:calc(var(--spacing) * 2.5)}.pl-5{padding-left:calc(var(--spacing) * 5)}.pl-\[18px\]{padding-left:18px}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.align-top{vertical-align:top}.font-display{font-family:var(--font-display)}.font-mono{font-family:var(--font-mono)}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[0\.85em\]{font-size:.85em}.text-\[0\.95rem\]{font-size:.95rem}.text-\[0\.9375rem\]{font-size:.9375rem}.text-\[8px\]{font-size:8px}.text-\[9px\]{font-size:9px}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.leading-none{--tw-leading:1;line-height:1}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.leading-snug{--tw-leading:var(--leading-snug);line-height:var(--leading-snug)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-\[0\.1em\]{--tw-tracking:.1em;letter-spacing:.1em}.tracking-\[0\.08em\]{--tw-tracking:.08em;letter-spacing:.08em}.tracking-\[0\.12em\]{--tw-tracking:.12em;letter-spacing:.12em}.tracking-\[0\.14em\]{--tw-tracking:.14em;letter-spacing:.14em}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.tracking-widest{--tw-tracking:var(--tracking-widest);letter-spacing:var(--tracking-widest)}.break-words{overflow-wrap:break-word}.wrap-anywhere{overflow-wrap:anywhere}.break-all{word-break:break-all}.whitespace-nowrap{white-space:nowrap}.whitespace-pre{white-space:pre}.whitespace-pre-wrap{white-space:pre-wrap}.text-amber{color:var(--amber)}.text-brand{color:var(--brand)}.text-destructive{color:var(--destructive)}.text-ember{color:var(--ember)}.text-ground{color:var(--ground)}.text-ink{color:var(--ink)}.text-ink-dim{color:var(--ink-dim)}.text-ink-faint{color:var(--ink-faint)}.text-lime,.text-lime\/80{color:var(--lime)}@supports (color:color-mix(in lab, red, red)){.text-lime\/80{color:color-mix(in oklab, var(--lime) 80%, transparent)}}.text-magenta{color:var(--magenta)}.lowercase{text-transform:lowercase}.uppercase{text-transform:uppercase}.italic{font-style:italic}.ordinal{--tw-ordinal:ordinal;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.underline{text-decoration-line:underline}.decoration-1{text-decoration-thickness:1px}.underline-offset-2{text-underline-offset:2px}.underline-offset-4{text-underline-offset:4px}.accent-brand{accent-color:var(--brand)}.accent-destructive{accent-color:var(--destructive)}.opacity-40{opacity:.4}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.opacity-70{opacity:.7}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a), 0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.glow-brand{box-shadow:0 6px 26px -10px var(--brand)}@supports (color:color-mix(in lab, red, red)){.glow-brand{box-shadow:0 6px 26px -10px color-mix(in oklch, var(--brand) 70%, transparent)}}.glow-destructive{box-shadow:0 6px 26px -10px var(--destructive)}@supports (color:color-mix(in lab, red, red)){.glow-destructive{box-shadow:0 6px 26px -10px color-mix(in oklch, var(--destructive) 70%, transparent)}}.glow-dot{box-shadow:0 0 8px 1px}@supports (color:color-mix(in lab, red, red)){.glow-dot{box-shadow:0 0 8px 1px color-mix(in oklch, currentColor 75%, transparent)}}.shadow-black\/50{--tw-shadow-color:#00000080}@supports (color:color-mix(in lab, red, red)){.shadow-black\/50{--tw-shadow-color:color-mix(in oklab, color-mix(in oklab, var(--color-black) 50%, transparent) var(--tw-shadow-alpha), transparent)}}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.blur{--tw-blur:blur(8px);filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.invert{--tw-invert:invert(100%);filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.backdrop-blur{--tw-backdrop-blur:blur(8px);-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\[width\]{transition-property:width;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-200{--tw-duration:.2s;transition-duration:.2s}.duration-500{--tw-duration:.5s;transition-duration:.5s}.ease-in-out{--tw-ease:var(--ease-in-out);transition-timing-function:var(--ease-in-out)}.outline-none{--tw-outline-style:none;outline-style:none}.panel-card{border:1px solid var(--line);background:linear-gradient(oklch(98% .01 60/.045),oklch(98% .01 60/.015))}.select-none{-webkit-user-select:none;user-select:none}.blur-in{--tw-enter-blur:20px}.running{animation-play-state:running}@media (hover:hover){.group-hover\:opacity-85:is(:where(.group):hover *){opacity:.85}}.selection\:bg-brand\/30 ::selection{background-color:var(--brand)}@supports (color:color-mix(in lab, red, red)){.selection\:bg-brand\/30 ::selection{background-color:color-mix(in oklab, var(--brand) 30%, transparent)}}.selection\:bg-brand\/30::selection{background-color:var(--brand)}@supports (color:color-mix(in lab, red, red)){.selection\:bg-brand\/30::selection{background-color:color-mix(in oklab, var(--brand) 30%, transparent)}}.selection\:text-ink ::selection{color:var(--ink)}.selection\:text-ink::selection{color:var(--ink)}.placeholder\:text-ink-faint::placeholder{color:var(--ink-faint)}@media (hover:hover){.hover\:border-brand\/40:hover{border-color:var(--brand)}@supports (color:color-mix(in lab, red, red)){.hover\:border-brand\/40:hover{border-color:color-mix(in oklab, var(--brand) 40%, transparent)}}.hover\:border-brand\/45:hover{border-color:var(--brand)}@supports (color:color-mix(in lab, red, red)){.hover\:border-brand\/45:hover{border-color:color-mix(in oklab, var(--brand) 45%, transparent)}}.hover\:border-brand\/50:hover{border-color:var(--brand)}@supports (color:color-mix(in lab, red, red)){.hover\:border-brand\/50:hover{border-color:color-mix(in oklab, var(--brand) 50%, transparent)}}.hover\:border-line-strong:hover{border-color:var(--line-strong)}.hover\:bg-brand\/12:hover{background-color:var(--brand)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-brand\/12:hover{background-color:color-mix(in oklab, var(--brand) 12%, transparent)}}.hover\:bg-brand\/15:hover{background-color:var(--brand)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-brand\/15:hover{background-color:color-mix(in oklab, var(--brand) 15%, transparent)}}.hover\:bg-brand\/20:hover{background-color:var(--brand)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-brand\/20:hover{background-color:color-mix(in oklab, var(--brand) 20%, transparent)}}.hover\:bg-brand\/40:hover{background-color:var(--brand)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-brand\/40:hover{background-color:color-mix(in oklab, var(--brand) 40%, transparent)}}.hover\:bg-brand\/90:hover{background-color:var(--brand)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-brand\/90:hover{background-color:color-mix(in oklab, var(--brand) 90%, transparent)}}.hover\:bg-destructive\/90:hover{background-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-destructive\/90:hover{background-color:color-mix(in oklab, var(--destructive) 90%, transparent)}}.hover\:bg-ground\/40:hover{background-color:var(--ground)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-ground\/40:hover{background-color:color-mix(in oklab, var(--ground) 40%, transparent)}}.hover\:bg-surface:hover{background-color:var(--surface)}.hover\:bg-surface-2:hover{background-color:var(--surface-2)}.hover\:bg-surface\/60:hover{background-color:var(--surface)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-surface\/60:hover{background-color:color-mix(in oklab, var(--surface) 60%, transparent)}}.hover\:bg-surface\/70:hover{background-color:var(--surface)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-surface\/70:hover{background-color:color-mix(in oklab, var(--surface) 70%, transparent)}}.hover\:text-brand:hover{color:var(--brand)}.hover\:text-destructive:hover{color:var(--destructive)}.hover\:text-ink:hover{color:var(--ink)}.hover\:text-ink-dim:hover{color:var(--ink-dim)}.hover\:text-magenta:hover{color:var(--magenta)}.hover\:underline:hover{text-decoration-line:underline}.hover\:opacity-80:hover{opacity:.8}}.focus\:bg-brand\/15:focus{background-color:var(--brand)}@supports (color:color-mix(in lab, red, red)){.focus\:bg-brand\/15:focus{background-color:color-mix(in oklab, var(--brand) 15%, transparent)}}.focus\:text-brand:focus{color:var(--brand)}.focus-visible\:border-0:focus-visible{border-style:var(--tw-border-style);border-width:0}.focus-visible\:border-brand\/55:focus-visible{border-color:var(--brand)}@supports (color:color-mix(in lab, red, red)){.focus-visible\:border-brand\/55:focus-visible{border-color:color-mix(in oklab, var(--brand) 55%, transparent)}}.focus-visible\:bg-ground\/80:focus-visible{background-color:var(--ground)}@supports (color:color-mix(in lab, red, red)){.focus-visible\:bg-ground\/80:focus-visible{background-color:color-mix(in oklab, var(--ground) 80%, transparent)}}.focus-visible\:ring-2:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus-visible\:ring-brand\/50:focus-visible{--tw-ring-color:var(--brand)}@supports (color:color-mix(in lab, red, red)){.focus-visible\:ring-brand\/50:focus-visible{--tw-ring-color:color-mix(in oklab, var(--brand) 50%, transparent)}}.focus-visible\:ring-ring\/60:focus-visible{--tw-ring-color:var(--ring)}@supports (color:color-mix(in lab, red, red)){.focus-visible\:ring-ring\/60:focus-visible{--tw-ring-color:color-mix(in oklab, var(--ring) 60%, transparent)}}.focus-visible\:ring-offset-2:focus-visible{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)}.focus-visible\:ring-offset-ground:focus-visible{--tw-ring-offset-color:var(--ground)}.focus-visible\:outline-none:focus-visible{--tw-outline-style:none;outline-style:none}@media (hover:hover){.enabled\:hover\:scale-105:enabled:hover{--tw-scale-x:105%;--tw-scale-y:105%;--tw-scale-z:105%;scale:var(--tw-scale-x) var(--tw-scale-y)}.enabled\:hover\:border-line-strong:enabled:hover{border-color:var(--line-strong)}.enabled\:hover\:bg-brand\/20:enabled:hover{background-color:var(--brand)}@supports (color:color-mix(in lab, red, red)){.enabled\:hover\:bg-brand\/20:enabled:hover{background-color:color-mix(in oklab, var(--brand) 20%, transparent)}}.enabled\:hover\:text-ink:enabled:hover{color:var(--ink)}}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-40:disabled{opacity:.4}.disabled\:opacity-45:disabled{opacity:.45}.disabled\:opacity-50:disabled{opacity:.5}.has-\[textarea\:focus\]\:border-brand\/50:has(:is(textarea:focus)){border-color:var(--brand)}@supports (color:color-mix(in lab, red, red)){.has-\[textarea\:focus\]\:border-brand\/50:has(:is(textarea:focus)){border-color:color-mix(in oklab, var(--brand) 50%, transparent)}}.has-\[\>svg\]\:px-2\.5:has(>svg){padding-inline:calc(var(--spacing) * 2.5)}.has-\[\>svg\]\:px-3\.5:has(>svg){padding-inline:calc(var(--spacing) * 3.5)}.has-\[\>svg\]\:px-5:has(>svg){padding-inline:calc(var(--spacing) * 5)}.aria-invalid\:border-destructive[aria-invalid=true],.aria-invalid\:border-destructive\/60[aria-invalid=true]{border-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.aria-invalid\:border-destructive\/60[aria-invalid=true]{border-color:color-mix(in oklab, var(--destructive) 60%, transparent)}}.data-\[disabled\]\:pointer-events-none[data-disabled]{pointer-events:none}.data-\[disabled\]\:opacity-50[data-disabled]{opacity:.5}.data-\[side\=bottom\]\:slide-in-from-top-1[data-side=bottom]{--tw-enter-translate-y:calc(1*var(--spacing)*-1)}.data-\[side\=top\]\:slide-in-from-bottom-1[data-side=top]{--tw-enter-translate-y:calc(1*var(--spacing))}.data-\[state\=closed\]\:animate-out[data-state=closed]{animation:exit var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none)}.data-\[state\=closed\]\:fade-out-0[data-state=closed]{--tw-exit-opacity:0}.data-\[state\=closed\]\:zoom-out-95[data-state=closed]{--tw-exit-scale:.95}.data-\[state\=open\]\:animate-in[data-state=open]{animation:enter var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none)}.data-\[state\=open\]\:fade-in-0[data-state=open]{--tw-enter-opacity:0}.data-\[state\=open\]\:zoom-in-95[data-state=open]{--tw-enter-scale:.95}@media not all and (width>=19rem){.max-\[19rem\]\:hidden{display:none}}.\[\&_svg\]\:pointer-events-none svg{pointer-events:none}.\[\&_svg\]\:shrink-0 svg{flex-shrink:0}.\[\&_svg\:not\(\[class\*\=\'size-\'\]\)\]\:size-4 svg:not([class*=size-]){width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.\[\&\:\:-webkit-scrollbar\]\:hidden::-webkit-scrollbar{display:none}.\[\&\>div\]\:block\!>div{display:block!important}.\[\&\>span\]\:min-w-0>span{min-width:0}.\[\&\>span\]\:truncate>span{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.\[\&\>svg\]\:pointer-events-none>svg{pointer-events:none}.\[\&\>svg\]\:size-2\.5>svg{width:calc(var(--spacing) * 2.5);height:calc(var(--spacing) * 2.5)}}@property --tw-animation-delay{syntax:"*";inherits:false;initial-value:0s}@property --tw-animation-direction{syntax:"*";inherits:false;initial-value:normal}@property --tw-animation-duration{syntax:"*";inherits:false}@property --tw-animation-fill-mode{syntax:"*";inherits:false;initial-value:none}@property --tw-animation-iteration-count{syntax:"*";inherits:false;initial-value:1}@property --tw-enter-blur{syntax:"*";inherits:false;initial-value:0}@property --tw-enter-opacity{syntax:"*";inherits:false;initial-value:1}@property --tw-enter-rotate{syntax:"*";inherits:false;initial-value:0}@property --tw-enter-scale{syntax:"*";inherits:false;initial-value:1}@property --tw-enter-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-enter-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-exit-blur{syntax:"*";inherits:false;initial-value:0}@property --tw-exit-opacity{syntax:"*";inherits:false;initial-value:1}@property --tw-exit-rotate{syntax:"*";inherits:false;initial-value:0}@property --tw-exit-scale{syntax:"*";inherits:false;initial-value:1}@property --tw-exit-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-exit-translate-y{syntax:"*";inherits:false;initial-value:0}:root{--radius:.75rem;--ground:oklch(15.2% .016 52);--ground-2:oklch(18.3% .018 50);--surface:oklch(21.3% .019 48);--surface-2:oklch(25.3% .021 46);--ink:oklch(95.8% .012 70);--ink-dim:oklch(73.5% .018 60);--ink-faint:oklch(57.5% .02 55);--line:oklch(98% .01 60/.1);--line-strong:oklch(98% .01 60/.18);--brand:oklch(83% .13 195);--brand-deep:oklch(62% .12 200);--ember:oklch(73.5% .168 42);--magenta:oklch(70% .21 335);--lime:oklch(84% .18 150);--amber:oklch(84% .15 85);--background:var(--ground);--foreground:var(--ink);--card:var(--ground-2);--card-foreground:var(--ink);--popover:var(--surface);--popover-foreground:var(--ink);--primary:var(--brand);--primary-foreground:var(--ground);--secondary:var(--surface);--secondary-foreground:var(--ink);--muted:var(--ground-2);--muted-foreground:var(--ink-dim);--accent:var(--surface-2);--accent-foreground:var(--ink);--destructive:oklch(64.5% .205 25);--border:var(--line);--input:var(--line-strong);--ring:var(--brand)}@keyframes browsentic-countdown{0%{width:100%}to{width:0%}}@keyframes browsentic-token{0%{opacity:0;filter:blur(4px);transform:translateY(2px)}to{opacity:1;filter:blur();transform:none}}@keyframes browsentic-enter{0%{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}@keyframes browsentic-caret{0%,45%{opacity:1}55%,to{opacity:0}}@keyframes browsentic-think{0%,70%,to{opacity:.25;transform:translateY(0)}35%{opacity:1;transform:translateY(-2px)}}@keyframes browsentic-sweep{0%{transform:translate(-100%)}to{transform:translate(320%)}}@media (prefers-reduced-motion:reduce){*,:before,:after{transition-duration:.01ms!important;animation-duration:.01ms!important;animation-iteration-count:1!important}}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@property --tw-scale-x{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-y{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-z{syntax:"*";inherits:false;initial-value:1}@keyframes spin{to{transform:rotate(360deg)}}@keyframes ping{75%,to{opacity:0;transform:scale(2)}}@keyframes pulse{50%{opacity:.5}}@keyframes enter{0%{opacity:var(--tw-enter-opacity,1);transform:translate3d(var(--tw-enter-translate-x,0),var(--tw-enter-translate-y,0),0)scale3d(var(--tw-enter-scale,1),var(--tw-enter-scale,1),var(--tw-enter-scale,1))rotate(var(--tw-enter-rotate,0));filter:blur(var(--tw-enter-blur,0))}}@keyframes exit{to{opacity:var(--tw-exit-opacity,1);transform:translate3d(var(--tw-exit-translate-x,0),var(--tw-exit-translate-y,0),0)scale3d(var(--tw-exit-scale,1),var(--tw-exit-scale,1),var(--tw-exit-scale,1))rotate(var(--tw-exit-rotate,0));filter:blur(var(--tw-exit-blur,0))}}