@blinq_ai/widget 0.1.0 → 0.1.2

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.
@@ -535,6 +535,12 @@ function collectNormalizedPageContext() {
535
535
  }
536
536
 
537
537
  // src/page-tools.ts
538
+ var DEFAULT_ACTION_POLICY = {
539
+ actions_enabled: true,
540
+ action_mode: "execute_with_confirmation",
541
+ pointer_overlay_enabled: true
542
+ };
543
+ var GUIDANCE_SAFE_TOOL_NAMES = /* @__PURE__ */ new Set(["blinq.scroll_to_element"]);
538
544
  function isBrowser2() {
539
545
  return typeof window !== "undefined" && typeof document !== "undefined";
540
546
  }
@@ -631,6 +637,12 @@ function findTarget(selector) {
631
637
  }
632
638
  return target;
633
639
  }
640
+ function shouldRequestConfirmation(toolName, readOnly) {
641
+ if (readOnly) {
642
+ return false;
643
+ }
644
+ return !GUIDANCE_SAFE_TOOL_NAMES.has(toolName);
645
+ }
634
646
  function isDuplicateNativeToolError(error) {
635
647
  if (!(error instanceof Error)) {
636
648
  return false;
@@ -792,6 +804,15 @@ function buildSemanticToolDefinition(descriptor) {
792
804
  }
793
805
  return null;
794
806
  }
807
+ function selectorFromArguments(argumentsPayload) {
808
+ for (const key of ["selector", "field_selector", "submit_selector", "form_selector"]) {
809
+ const value = argumentsPayload[key];
810
+ if (typeof value === "string" && value.trim()) {
811
+ return value.trim();
812
+ }
813
+ }
814
+ return null;
815
+ }
795
816
  function detectNativeWebMcpSupport() {
796
817
  if (!isBrowser2() || !window.isSecureContext) {
797
818
  return false;
@@ -807,10 +828,17 @@ var PageToolRegistry = class {
807
828
  nativeToolsActive = false;
808
829
  highlightLayer = null;
809
830
  highlightTimer = null;
831
+ actionPolicy = { ...DEFAULT_ACTION_POLICY };
810
832
  constructor(confirmationHandler) {
811
833
  this.confirmationHandler = confirmationHandler;
812
834
  this.refreshToolCatalog();
813
835
  }
836
+ setActionPolicy(nextPolicy) {
837
+ this.actionPolicy = {
838
+ ...DEFAULT_ACTION_POLICY,
839
+ ...nextPolicy
840
+ };
841
+ }
814
842
  buildBaseTools() {
815
843
  const tools = /* @__PURE__ */ new Map();
816
844
  tools.set("blinq.read_visible_page_context", {
@@ -984,7 +1012,7 @@ var PageToolRegistry = class {
984
1012
  }
985
1013
  getToolCapabilities() {
986
1014
  this.refreshToolCatalog();
987
- return Array.from(this.tools.values()).map((tool) => tool.capability);
1015
+ return Array.from(this.tools.values()).filter((tool) => this.isToolAllowed(tool)).map((tool) => tool.capability);
988
1016
  }
989
1017
  clearHighlights() {
990
1018
  if (this.highlightTimer !== null) {
@@ -1010,13 +1038,52 @@ var PageToolRegistry = class {
1010
1038
  this.highlightLayer = layer;
1011
1039
  return layer;
1012
1040
  }
1041
+ ensureHighlightStyle() {
1042
+ if (document.getElementById("blinq-highlight-style")) {
1043
+ return;
1044
+ }
1045
+ const style = document.createElement("style");
1046
+ style.id = "blinq-highlight-style";
1047
+ style.textContent = `
1048
+ @keyframes blinq-highlight-pulse {
1049
+ 0%, 100% { opacity: 0.55; transform: scale(1); }
1050
+ 50% { opacity: 1; transform: scale(1.02); }
1051
+ }
1052
+
1053
+ @keyframes blinq-highlight-ripple {
1054
+ 0% { opacity: 0.36; transform: translate(-50%, -50%) scale(0.8); }
1055
+ 100% { opacity: 0; transform: translate(-50%, -50%) scale(1.7); }
1056
+ }
1057
+
1058
+ @keyframes blinq-pointer-bob {
1059
+ 0%, 100% { transform: translate3d(0, 0, 0) scale(1); }
1060
+ 50% { transform: translate3d(0, -2px, 0) scale(1.03); }
1061
+ }
1062
+ `;
1063
+ document.head.appendChild(style);
1064
+ }
1013
1065
  highlightTargets(targets, options) {
1014
1066
  if (!isBrowser2() || targets.length === 0) {
1015
1067
  return false;
1016
1068
  }
1017
1069
  this.clearHighlights();
1018
1070
  const layer = this.ensureHighlightLayer();
1071
+ this.ensureHighlightStyle();
1019
1072
  let highlightedCount = 0;
1073
+ let primaryRect = null;
1074
+ const backdrop = document.createElement("div");
1075
+ Object.assign(backdrop.style, {
1076
+ position: "fixed",
1077
+ inset: "0",
1078
+ background: "rgba(15, 23, 42, 0.08)",
1079
+ backdropFilter: "blur(1.5px)",
1080
+ opacity: "0",
1081
+ transition: "opacity 180ms ease"
1082
+ });
1083
+ layer.appendChild(backdrop);
1084
+ window.requestAnimationFrame(() => {
1085
+ backdrop.style.opacity = "1";
1086
+ });
1020
1087
  for (const target of targets) {
1021
1088
  if (!target.selector) {
1022
1089
  continue;
@@ -1030,21 +1097,30 @@ var PageToolRegistry = class {
1030
1097
  if (!element) {
1031
1098
  continue;
1032
1099
  }
1100
+ if (!primaryRect) {
1101
+ element.scrollIntoView({
1102
+ block: "center",
1103
+ inline: "nearest"
1104
+ });
1105
+ }
1033
1106
  const rect = element.getBoundingClientRect();
1034
1107
  if (rect.width <= 0 || rect.height <= 0) {
1035
1108
  continue;
1036
1109
  }
1110
+ if (!primaryRect) {
1111
+ primaryRect = rect;
1112
+ }
1037
1113
  const frame = document.createElement("div");
1038
1114
  Object.assign(frame.style, {
1039
1115
  position: "fixed",
1040
- left: `${Math.max(rect.left - 6, 4)}px`,
1041
- top: `${Math.max(rect.top - 6, 4)}px`,
1042
- width: `${Math.max(rect.width + 12, 18)}px`,
1043
- height: `${Math.max(rect.height + 12, 18)}px`,
1044
- border: "2px solid rgba(17, 17, 17, 0.92)",
1045
- borderRadius: "16px",
1046
- background: "rgba(17, 17, 17, 0.05)",
1047
- boxShadow: "0 0 0 1px rgba(255, 255, 255, 0.85), 0 18px 38px rgba(17, 17, 17, 0.14)",
1116
+ left: `${Math.max(rect.left - 8, 4)}px`,
1117
+ top: `${Math.max(rect.top - 8, 4)}px`,
1118
+ width: `${Math.max(rect.width + 16, 24)}px`,
1119
+ height: `${Math.max(rect.height + 16, 24)}px`,
1120
+ border: "3px solid rgba(17, 17, 17, 0.94)",
1121
+ borderRadius: "18px",
1122
+ background: "rgba(255, 255, 255, 0.16)",
1123
+ boxShadow: "0 0 0 1px rgba(255, 255, 255, 0.9), 0 24px 48px rgba(15, 23, 42, 0.18)",
1048
1124
  opacity: "0",
1049
1125
  transform: "scale(0.985)",
1050
1126
  transition: "opacity 180ms ease, transform 180ms ease"
@@ -1052,9 +1128,9 @@ var PageToolRegistry = class {
1052
1128
  const glow = document.createElement("div");
1053
1129
  Object.assign(glow.style, {
1054
1130
  position: "absolute",
1055
- inset: "-8px",
1056
- borderRadius: "20px",
1057
- border: "1px solid rgba(17, 17, 17, 0.14)",
1131
+ inset: "-10px",
1132
+ borderRadius: "22px",
1133
+ border: "1px solid rgba(37, 99, 235, 0.22)",
1058
1134
  animation: "blinq-highlight-pulse 1.2s ease-in-out infinite"
1059
1135
  });
1060
1136
  frame.appendChild(glow);
@@ -1063,15 +1139,15 @@ var PageToolRegistry = class {
1063
1139
  badge.textContent = target.label;
1064
1140
  Object.assign(badge.style, {
1065
1141
  position: "absolute",
1066
- top: "-14px",
1142
+ top: "-16px",
1067
1143
  left: "10px",
1068
- maxWidth: "min(220px, 70vw)",
1069
- padding: "4px 10px",
1144
+ maxWidth: "min(260px, 70vw)",
1145
+ padding: "6px 12px",
1070
1146
  borderRadius: "999px",
1071
1147
  background: "#111111",
1072
1148
  color: "#ffffff",
1073
1149
  fontFamily: '"Inter", ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif',
1074
- fontSize: "11px",
1150
+ fontSize: "12px",
1075
1151
  fontWeight: "600",
1076
1152
  lineHeight: "1.3",
1077
1153
  whiteSpace: "nowrap",
@@ -1088,16 +1164,57 @@ var PageToolRegistry = class {
1088
1164
  });
1089
1165
  highlightedCount += 1;
1090
1166
  }
1091
- if (!document.getElementById("blinq-highlight-style")) {
1092
- const style = document.createElement("style");
1093
- style.id = "blinq-highlight-style";
1094
- style.textContent = `
1095
- @keyframes blinq-highlight-pulse {
1096
- 0%, 100% { opacity: 0.55; transform: scale(1); }
1097
- 50% { opacity: 1; transform: scale(1.02); }
1098
- }
1167
+ if (this.actionPolicy.pointer_overlay_enabled && primaryRect) {
1168
+ const pointer = document.createElement("div");
1169
+ pointer.setAttribute("data-blinq-pointer", options?.interaction ?? "explain");
1170
+ pointer.innerHTML = `
1171
+ <div style="position:absolute;inset:0;border-radius:999px;background:rgba(255,255,255,0.92);box-shadow:0 14px 28px rgba(15,23,42,0.18);"></div>
1172
+ <svg viewBox="0 0 40 40" width="40" height="40" fill="none" aria-hidden="true" style="position:relative;z-index:1;">
1173
+ <path d="M8 5L28 22H18.4L23.2 34.8L17.8 36.8L13 24H6.6L8 5Z" fill="#111111"/>
1174
+ <path d="M8 5L28 22H18.4L23.2 34.8L17.8 36.8L13 24H6.6L8 5Z" stroke="#ffffff" stroke-width="1.4" stroke-linejoin="round"/>
1175
+ </svg>
1099
1176
  `;
1100
- document.head.appendChild(style);
1177
+ Object.assign(pointer.style, {
1178
+ position: "fixed",
1179
+ left: `${Math.max(primaryRect.left - 72, 12)}px`,
1180
+ top: `${Math.max(primaryRect.bottom + 44, 12)}px`,
1181
+ width: "40px",
1182
+ height: "40px",
1183
+ zIndex: "2147483647",
1184
+ opacity: "0",
1185
+ transform: "translate3d(0, 0, 0) scale(0.92)",
1186
+ transition: "left 380ms cubic-bezier(.22,1,.36,1), top 380ms cubic-bezier(.22,1,.36,1), opacity 180ms ease, transform 380ms cubic-bezier(.22,1,.36,1)",
1187
+ filter: "drop-shadow(0 16px 28px rgba(15, 23, 42, 0.2))",
1188
+ animation: "blinq-pointer-bob 1.1s ease-in-out infinite"
1189
+ });
1190
+ layer.appendChild(pointer);
1191
+ const pointerTargetLeft = Math.max(primaryRect.left + 14, 8);
1192
+ const pointerTargetTop = Math.max(primaryRect.top + 14, 8);
1193
+ window.requestAnimationFrame(() => {
1194
+ pointer.style.opacity = "1";
1195
+ pointer.style.left = `${pointerTargetLeft}px`;
1196
+ pointer.style.top = `${pointerTargetTop}px`;
1197
+ pointer.style.transform = "translate3d(0, 0, 0) scale(1)";
1198
+ });
1199
+ if (options?.interaction === "execute") {
1200
+ const ripple = document.createElement("div");
1201
+ Object.assign(ripple.style, {
1202
+ position: "fixed",
1203
+ left: `${primaryRect.left + Math.min(primaryRect.width, 32) / 2}px`,
1204
+ top: `${primaryRect.top + Math.min(primaryRect.height, 32) / 2}px`,
1205
+ width: "34px",
1206
+ height: "34px",
1207
+ borderRadius: "999px",
1208
+ border: "3px solid rgba(17, 17, 17, 0.58)",
1209
+ background: "rgba(17, 17, 17, 0.12)",
1210
+ pointerEvents: "none",
1211
+ opacity: "0",
1212
+ transform: "translate(-50%, -50%) scale(0.8)",
1213
+ animation: "blinq-highlight-ripple 560ms ease-out 1 forwards",
1214
+ animationDelay: "320ms"
1215
+ });
1216
+ layer.appendChild(ripple);
1217
+ }
1101
1218
  }
1102
1219
  if (highlightedCount === 0) {
1103
1220
  this.clearHighlights();
@@ -1108,8 +1225,38 @@ var PageToolRegistry = class {
1108
1225
  }, options?.durationMs ?? 2200);
1109
1226
  return true;
1110
1227
  }
1228
+ isToolAllowed(tool) {
1229
+ if (tool.capability.read_only) {
1230
+ return true;
1231
+ }
1232
+ if (GUIDANCE_SAFE_TOOL_NAMES.has(tool.capability.name)) {
1233
+ return this.actionPolicy.actions_enabled;
1234
+ }
1235
+ return this.actionPolicy.actions_enabled && this.actionPolicy.action_mode === "execute_with_confirmation";
1236
+ }
1237
+ async previewToolRequest(request, options) {
1238
+ const selector = selectorFromArguments(request.arguments);
1239
+ if (!selector) {
1240
+ return false;
1241
+ }
1242
+ const label = (request.target_summary || request.display_name || "").trim() || void 0;
1243
+ const highlighted = this.highlightTargets(
1244
+ [{ selector, label }],
1245
+ {
1246
+ durationMs: options?.durationMs ?? (options?.interaction === "execute" ? 1600 : 2200),
1247
+ interaction: options?.interaction ?? "explain"
1248
+ }
1249
+ );
1250
+ if (!highlighted) {
1251
+ return false;
1252
+ }
1253
+ await new Promise(
1254
+ (resolve) => window.setTimeout(resolve, options?.interaction === "execute" ? 520 : 240)
1255
+ );
1256
+ return true;
1257
+ }
1111
1258
  canExecuteWriteTools() {
1112
- return isBrowser2();
1259
+ return isBrowser2() && this.actionPolicy.actions_enabled && this.actionPolicy.action_mode === "execute_with_confirmation";
1113
1260
  }
1114
1261
  async executeTool(request) {
1115
1262
  let tool = this.tools.get(request.tool_name);
@@ -1125,7 +1272,22 @@ var PageToolRegistry = class {
1125
1272
  }
1126
1273
  const displayName = request.display_name ?? tool.capability.name;
1127
1274
  const targetSummary = request.target_summary ?? tool.describeTarget?.(request.arguments) ?? tool.capability.description;
1128
- const requiresConfirmation = request.requires_confirmation ?? !tool.capability.read_only;
1275
+ const requiresConfirmation = request.requires_confirmation ?? shouldRequestConfirmation(request.tool_name, tool.capability.read_only);
1276
+ if (request.tool_name !== "blinq.highlight_element") {
1277
+ await this.previewToolRequest(request, {
1278
+ interaction: tool.capability.read_only ? "explain" : "execute"
1279
+ });
1280
+ }
1281
+ if (!tool.capability.read_only && !this.isToolAllowed(tool)) {
1282
+ return {
1283
+ status: "success",
1284
+ result: {
1285
+ success: true,
1286
+ guided: true,
1287
+ preview_only: true
1288
+ }
1289
+ };
1290
+ }
1129
1291
  if (!tool.capability.read_only && requiresConfirmation) {
1130
1292
  const confirmed = await this.confirmationHandler({
1131
1293
  displayName,
@@ -1167,6 +1329,9 @@ var PageToolRegistry = class {
1167
1329
  this.refreshToolCatalog();
1168
1330
  this.unregisterNativeTools();
1169
1331
  for (const [toolName, tool] of this.tools) {
1332
+ if (!this.isToolAllowed(tool)) {
1333
+ continue;
1334
+ }
1170
1335
  const controller = new AbortController();
1171
1336
  try {
1172
1337
  modelContext.registerTool(
@@ -1209,6 +1374,7 @@ var PageToolRegistry = class {
1209
1374
 
1210
1375
  // src/embed-shell.tsx
1211
1376
  import * as React from "react";
1377
+ import { Bot } from "lucide-react";
1212
1378
  import {
1213
1379
  AssistantRuntimeProvider,
1214
1380
  MessagePrimitive,
@@ -1216,7 +1382,7 @@ import {
1216
1382
  useExternalStoreRuntime,
1217
1383
  useMessage
1218
1384
  } from "@assistant-ui/react";
1219
- import { jsx, jsxs } from "react/jsx-runtime";
1385
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
1220
1386
  function cn(...values) {
1221
1387
  return values.filter(Boolean).join(" ");
1222
1388
  }
@@ -1271,87 +1437,44 @@ function Badge({
1271
1437
  return /* @__PURE__ */ jsx("div", { className: cn(badgeClassName(variant), className), ...props });
1272
1438
  }
1273
1439
  function LauncherIcon() {
1274
- return /* @__PURE__ */ jsxs(
1275
- "svg",
1276
- {
1277
- viewBox: "0 0 24 24",
1278
- width: "18",
1279
- height: "18",
1280
- fill: "none",
1281
- "aria-hidden": "true",
1282
- className: "blinq-launcher-agent",
1283
- children: [
1284
- /* @__PURE__ */ jsx("circle", { className: "blinq-agent-orbit", cx: "12", cy: "12", r: "9" }),
1285
- /* @__PURE__ */ jsx("circle", { className: "blinq-agent-spark", cx: "18.6", cy: "8.2", r: "1.2" }),
1286
- /* @__PURE__ */ jsx(
1287
- "path",
1288
- {
1289
- className: "blinq-agent-antenna",
1290
- d: "M12 4.8V6.8",
1291
- stroke: "currentColor",
1292
- strokeWidth: "1.6",
1293
- strokeLinecap: "round"
1294
- }
1295
- ),
1296
- /* @__PURE__ */ jsx("circle", { className: "blinq-agent-antenna-dot", cx: "12", cy: "4.1", r: "1.1", fill: "currentColor" }),
1297
- /* @__PURE__ */ jsx(
1298
- "rect",
1299
- {
1300
- className: "blinq-agent-head",
1301
- x: "7",
1302
- y: "7.4",
1303
- width: "10",
1304
- height: "9.2",
1305
- rx: "3.2",
1306
- fill: "currentColor"
1307
- }
1308
- ),
1309
- /* @__PURE__ */ jsx("circle", { className: "blinq-agent-eye", cx: "10.2", cy: "11.3", r: "0.9", fill: "#111111" }),
1310
- /* @__PURE__ */ jsx("circle", { className: "blinq-agent-eye", cx: "13.8", cy: "11.3", r: "0.9", fill: "#111111" }),
1311
- /* @__PURE__ */ jsx(
1312
- "path",
1313
- {
1314
- className: "blinq-agent-mouth",
1315
- d: "M10 14.2c.7.55 1.38.82 2 .82s1.3-.27 2-.82",
1316
- stroke: "#111111",
1317
- strokeWidth: "1.3",
1318
- strokeLinecap: "round"
1319
- }
1320
- ),
1321
- /* @__PURE__ */ jsx(
1322
- "path",
1323
- {
1324
- className: "blinq-agent-neck",
1325
- d: "M10.2 17.1h3.6",
1326
- stroke: "currentColor",
1327
- strokeWidth: "1.4",
1328
- strokeLinecap: "round"
1329
- }
1330
- )
1331
- ]
1332
- }
1333
- );
1440
+ return /* @__PURE__ */ jsx(Bot, { "aria-hidden": "true", className: "blinq-launcher-icon", size: 30, strokeWidth: 1.7 });
1441
+ }
1442
+ function AssistantAvatar({
1443
+ avatarUrl,
1444
+ assistantName
1445
+ }) {
1446
+ return /* @__PURE__ */ jsxs("div", { className: "blinq-avatar", "aria-hidden": "true", children: [
1447
+ avatarUrl ? /* @__PURE__ */ jsx("img", { src: avatarUrl, alt: "", className: "blinq-avatar-image" }) : /* @__PURE__ */ jsx(Bot, { className: "blinq-avatar-icon", size: 24, strokeWidth: 1.8 }),
1448
+ /* @__PURE__ */ jsx("span", { className: "blinq-avatar-status" }),
1449
+ /* @__PURE__ */ jsx("span", { className: "blinq-avatar-label", children: assistantName.slice(0, 1) })
1450
+ ] });
1334
1451
  }
1335
1452
  function CollapseIcon() {
1336
1453
  return /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", width: "16", height: "16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx("path", { d: "M6 12h12", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round" }) });
1337
1454
  }
1338
1455
  function MicrophoneIcon({ listening }) {
1339
1456
  if (listening) {
1340
- return /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", width: "16", height: "16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx("rect", { x: "7", y: "7", width: "10", height: "10", rx: "2.5", fill: "currentColor" }) });
1457
+ return /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 24 24", width: "16", height: "16", fill: "none", "aria-hidden": "true", children: [
1458
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "8.25", stroke: "currentColor", strokeWidth: "1.65" }),
1459
+ /* @__PURE__ */ jsx("rect", { x: "9.1", y: "9.1", width: "5.8", height: "5.8", rx: "1.6", fill: "currentColor" })
1460
+ ] });
1341
1461
  }
1342
1462
  return /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 24 24", width: "16", height: "16", fill: "none", "aria-hidden": "true", children: [
1343
1463
  /* @__PURE__ */ jsx(
1344
1464
  "path",
1345
1465
  {
1346
- d: "M12 3.75a2.75 2.75 0 0 1 2.75 2.75v5.25a2.75 2.75 0 1 1-5.5 0V6.5A2.75 2.75 0 0 1 12 3.75Z",
1347
- fill: "currentColor"
1466
+ d: "M12 4.35a3.05 3.05 0 0 1 3.05 3.05v4.7a3.05 3.05 0 1 1-6.1 0V7.4A3.05 3.05 0 0 1 12 4.35Z",
1467
+ stroke: "currentColor",
1468
+ strokeWidth: "1.7"
1348
1469
  }
1349
1470
  ),
1350
1471
  /* @__PURE__ */ jsx(
1351
1472
  "path",
1352
1473
  {
1353
- d: "M7.5 10.5a.75.75 0 0 1 .75.75a3.75 3.75 0 1 0 7.5 0a.75.75 0 0 1 1.5 0A5.25 5.25 0 0 1 12.75 16.4V18.5H15a.75.75 0 0 1 0 1.5H9a.75.75 0 0 1 0-1.5h2.25v-2.1A5.25 5.25 0 0 1 6.75 11.25a.75.75 0 0 1 .75-.75Z",
1354
- fill: "currentColor"
1474
+ d: "M7.95 11.35a4.05 4.05 0 1 0 8.1 0M12 16.45v3.2M9.2 19.65h5.6",
1475
+ stroke: "currentColor",
1476
+ strokeWidth: "1.7",
1477
+ strokeLinecap: "round"
1355
1478
  }
1356
1479
  )
1357
1480
  ] });
@@ -1360,7 +1483,7 @@ function SendIcon() {
1360
1483
  return /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", width: "16", height: "16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx(
1361
1484
  "path",
1362
1485
  {
1363
- d: "M5.5 12h11M12.5 5l6.5 7-6.5 7",
1486
+ d: "M5.5 18.5 18.5 5.5M8.25 5.5h10.25v10.25",
1364
1487
  stroke: "currentColor",
1365
1488
  strokeWidth: "1.8",
1366
1489
  strokeLinecap: "round",
@@ -1522,7 +1645,7 @@ function VoiceWaveform({
1522
1645
  const waveform = samples.length > 0 ? samples : [0.18];
1523
1646
  return /* @__PURE__ */ jsxs("div", { className: "blinq-recording-input", role: "status", "aria-live": "polite", children: [
1524
1647
  /* @__PURE__ */ jsx("div", { className: "blinq-recording-time", children: formatRecordingDuration(durationMs) }),
1525
- /* @__PURE__ */ jsx("div", { className: "blinq-recording-waveform", "aria-hidden": "true", children: waveform.map((sample, index) => {
1648
+ /* @__PURE__ */ jsx("div", { className: "blinq-recording-wave-shell", children: /* @__PURE__ */ jsx("div", { className: "blinq-recording-waveform", "aria-hidden": "true", children: waveform.map((sample, index) => {
1526
1649
  const scale = Math.max(0.16, Math.min(1, sample));
1527
1650
  return /* @__PURE__ */ jsx(
1528
1651
  "span",
@@ -1532,9 +1655,21 @@ function VoiceWaveform({
1532
1655
  },
1533
1656
  `voice-wave-${index}`
1534
1657
  );
1535
- }) })
1658
+ }) }) })
1536
1659
  ] });
1537
1660
  }
1661
+ function planStepStatusLabel(step, isCurrent) {
1662
+ if (step.status === "completed") {
1663
+ return "\u0413\u043E\u0442\u043E\u0432\u043E";
1664
+ }
1665
+ if (step.status === "failed") {
1666
+ return "\u041E\u0448\u0438\u0431\u043A\u0430";
1667
+ }
1668
+ if (step.status === "cancelled") {
1669
+ return "\u041E\u0442\u043C\u0435\u043D\u0435\u043D\u043E";
1670
+ }
1671
+ return isCurrent ? "\u0421\u0435\u0439\u0447\u0430\u0441" : "\u0414\u0430\u043B\u0435\u0435";
1672
+ }
1538
1673
  function ActionCard({
1539
1674
  item,
1540
1675
  accentColor,
@@ -1564,9 +1699,6 @@ function ActionCard({
1564
1699
  {
1565
1700
  type: "button",
1566
1701
  onClick: onApprove,
1567
- style: {
1568
- background: accentColor
1569
- },
1570
1702
  children: "\u0412\u044B\u043F\u043E\u043B\u043D\u0438\u0442\u044C"
1571
1703
  }
1572
1704
  )
@@ -1582,17 +1714,17 @@ function PlanCard({
1582
1714
  onDecline
1583
1715
  }) {
1584
1716
  return /* @__PURE__ */ jsxs(Card, { className: "blinq-action-card blinq-plan-card", children: [
1585
- /* @__PURE__ */ jsx(CardHeader, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-3", children: [
1717
+ /* @__PURE__ */ jsx(CardHeader, { children: /* @__PURE__ */ jsxs("div", { className: "blinq-plan-header", children: [
1586
1718
  /* @__PURE__ */ jsxs("div", { children: [
1587
1719
  /* @__PURE__ */ jsx(CardTitle, { children: "\u041F\u043B\u0430\u043D" }),
1588
1720
  /* @__PURE__ */ jsx(CardDescription, { children: item.goal })
1589
1721
  ] }),
1590
1722
  /* @__PURE__ */ jsx(Badge, { variant: item.status === "completed" ? "default" : item.status === "failed" ? "outline" : "soft", children: item.status === "completed" ? "\u0413\u043E\u0442\u043E\u0432\u043E" : item.status === "failed" ? "\u041E\u0448\u0438\u0431\u043A\u0430" : item.status === "awaiting_navigation" ? "\u041F\u0435\u0440\u0435\u0445\u043E\u0434" : "\u0412 \u0440\u0430\u0431\u043E\u0442\u0435" })
1591
1723
  ] }) }),
1592
- /* @__PURE__ */ jsxs(CardContent, { className: "space-y-3", children: [
1724
+ /* @__PURE__ */ jsxs(CardContent, { className: "blinq-plan-content", children: [
1593
1725
  item.progressLabel ? /* @__PURE__ */ jsx("div", { className: "blinq-action-state", children: item.progressLabel }) : null,
1594
1726
  item.statusReason ? /* @__PURE__ */ jsx("div", { className: "blinq-card-description", children: item.statusReason }) : null,
1595
- /* @__PURE__ */ jsx("div", { className: "space-y-2", children: item.steps.map((step, index) => /* @__PURE__ */ jsxs(
1727
+ /* @__PURE__ */ jsx("div", { className: "blinq-plan-steps", children: item.steps.map((step, index) => /* @__PURE__ */ jsxs(
1596
1728
  "div",
1597
1729
  {
1598
1730
  className: "blinq-plan-step",
@@ -1601,7 +1733,10 @@ function PlanCard({
1601
1733
  children: [
1602
1734
  /* @__PURE__ */ jsx("span", { className: "blinq-plan-step-index", children: index + 1 }),
1603
1735
  /* @__PURE__ */ jsxs("div", { className: "blinq-plan-step-copy", children: [
1604
- /* @__PURE__ */ jsx("div", { children: step.title }),
1736
+ /* @__PURE__ */ jsxs("div", { className: "blinq-plan-step-title-row", children: [
1737
+ /* @__PURE__ */ jsx("div", { className: "blinq-plan-step-title", children: step.title }),
1738
+ /* @__PURE__ */ jsx("span", { className: "blinq-plan-step-status-pill", children: planStepStatusLabel(step, index === item.currentStepIndex) })
1739
+ ] }),
1605
1740
  /* @__PURE__ */ jsx("div", { className: "blinq-plan-step-meta", children: step.status === "completed" ? "\u0412\u044B\u043F\u043E\u043B\u043D\u0435\u043D\u043E" : step.status === "failed" ? "\u041E\u0448\u0438\u0431\u043A\u0430" : step.status === "cancelled" ? "\u041E\u0442\u043C\u0435\u043D\u0435\u043D\u043E" : index === item.currentStepIndex ? "\u0422\u0435\u043A\u0443\u0449\u0438\u0439 \u0448\u0430\u0433" : "\u041E\u0436\u0438\u0434\u0430\u0435\u0442" })
1606
1741
  ] })
1607
1742
  ]
@@ -1615,6 +1750,53 @@ function PlanCard({
1615
1750
  ] })
1616
1751
  ] });
1617
1752
  }
1753
+ function GuideCard({
1754
+ guide,
1755
+ onStartGuide,
1756
+ onAdvanceGuide,
1757
+ onDismissGuide,
1758
+ onCompleteGuide,
1759
+ onRunGuideStep
1760
+ }) {
1761
+ const currentStep = guide.steps[Math.min(guide.currentStepIndex, Math.max(guide.steps.length - 1, 0))] ?? null;
1762
+ const isStarted = guide.state === "started";
1763
+ const isCompleted = guide.state === "completed";
1764
+ return /* @__PURE__ */ jsxs(Card, { className: "blinq-guide-card", children: [
1765
+ /* @__PURE__ */ jsx(CardHeader, { children: /* @__PURE__ */ jsxs("div", { className: "blinq-plan-header", children: [
1766
+ /* @__PURE__ */ jsxs("div", { children: [
1767
+ /* @__PURE__ */ jsx(CardTitle, { children: "Guide \u043D\u0430 \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u0435" }),
1768
+ /* @__PURE__ */ jsx(CardDescription, { children: guide.summary || "\u041F\u043E\u0448\u0430\u0433\u043E\u0432\u0430\u044F \u043F\u043E\u043C\u043E\u0449\u044C \u043F\u043E \u0442\u0435\u043A\u0443\u0449\u0435\u043C\u0443 \u0438\u043D\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0443." })
1769
+ ] }),
1770
+ /* @__PURE__ */ jsx(Badge, { variant: guide.source === "live" ? "soft" : "accent", children: guide.source === "live" ? "Live" : "Published" })
1771
+ ] }) }),
1772
+ /* @__PURE__ */ jsx(CardContent, { className: "blinq-guide-content", children: !isStarted ? /* @__PURE__ */ jsxs(Fragment, { children: [
1773
+ /* @__PURE__ */ jsx("div", { className: "blinq-card-description", children: "\u0410\u0441\u0441\u0438\u0441\u0442\u0435\u043D\u0442 \u0443\u0436\u0435 \u043F\u043E\u0434\u0433\u043E\u0442\u043E\u0432\u0438\u043B guide \u0434\u043B\u044F \u044D\u0442\u043E\u0439 \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u044B \u0438 \u043C\u043E\u0436\u0435\u0442 \u043F\u0440\u043E\u0432\u0435\u0441\u0442\u0438 \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044F \u043F\u043E \u0448\u0430\u0433\u0430\u043C." }),
1774
+ /* @__PURE__ */ jsxs("div", { className: "blinq-actions", children: [
1775
+ /* @__PURE__ */ jsx(Button, { type: "button", variant: "outline", onClick: onDismissGuide, children: "\u0421\u043A\u0440\u044B\u0442\u044C" }),
1776
+ /* @__PURE__ */ jsx(Button, { type: "button", onClick: onStartGuide, children: "\u041D\u0430\u0447\u0430\u0442\u044C guide" })
1777
+ ] })
1778
+ ] }) : currentStep && !isCompleted ? /* @__PURE__ */ jsxs(Fragment, { children: [
1779
+ /* @__PURE__ */ jsxs("div", { className: "blinq-guide-step-shell", children: [
1780
+ /* @__PURE__ */ jsxs("div", { className: "blinq-guide-step-meta", children: [
1781
+ "\u0428\u0430\u0433 ",
1782
+ Math.min(guide.currentStepIndex + 1, guide.totalSteps),
1783
+ " \u0438\u0437 ",
1784
+ guide.totalSteps
1785
+ ] }),
1786
+ /* @__PURE__ */ jsx("div", { className: "blinq-guide-step-title", children: currentStep.title }),
1787
+ /* @__PURE__ */ jsx("div", { className: "blinq-guide-step-copy", children: currentStep.body })
1788
+ ] }),
1789
+ /* @__PURE__ */ jsxs("div", { className: "blinq-actions", children: [
1790
+ /* @__PURE__ */ jsx(Button, { type: "button", variant: "outline", onClick: onDismissGuide, children: "\u0421\u043A\u0440\u044B\u0442\u044C" }),
1791
+ /* @__PURE__ */ jsx(Button, { type: "button", variant: "outline", onClick: onRunGuideStep, children: currentStep.actionKind ? "\u041F\u043E\u043A\u0430\u0437\u0430\u0442\u044C / \u0432\u044B\u043F\u043E\u043B\u043D\u0438\u0442\u044C \u0448\u0430\u0433" : "\u041F\u043E\u043A\u0430\u0437\u0430\u0442\u044C \u043D\u0430 \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u0435" }),
1792
+ guide.currentStepIndex + 1 >= guide.totalSteps ? /* @__PURE__ */ jsx(Button, { type: "button", onClick: onCompleteGuide, children: "\u0417\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u044C" }) : /* @__PURE__ */ jsx(Button, { type: "button", onClick: onAdvanceGuide, children: "\u0414\u0430\u043B\u044C\u0448\u0435" })
1793
+ ] })
1794
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
1795
+ /* @__PURE__ */ jsx("div", { className: "blinq-card-description", children: "Guide \u0437\u0430\u0432\u0435\u0440\u0448\u0451\u043D. \u041C\u043E\u0436\u043D\u043E \u043F\u0440\u043E\u0434\u043E\u043B\u0436\u0438\u0442\u044C \u0440\u0430\u0431\u043E\u0442\u0443 \u043D\u0430 \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u0435 \u0441\u0430\u043C\u043E\u0441\u0442\u043E\u044F\u0442\u0435\u043B\u044C\u043D\u043E." }),
1796
+ /* @__PURE__ */ jsx("div", { className: "blinq-actions", children: /* @__PURE__ */ jsx(Button, { type: "button", onClick: onDismissGuide, children: "\u0417\u0430\u043A\u0440\u044B\u0442\u044C" }) })
1797
+ ] }) })
1798
+ ] });
1799
+ }
1618
1800
  function AssistantConversationThread({
1619
1801
  items,
1620
1802
  showThinkingIndicator,
@@ -1691,34 +1873,52 @@ function WidgetEmbedShell({
1691
1873
  onApproveAction,
1692
1874
  onDeclineAction,
1693
1875
  onApprovePlan,
1694
- onDeclinePlan
1876
+ onDeclinePlan,
1877
+ onStartGuide,
1878
+ onAdvanceGuide,
1879
+ onDismissGuide,
1880
+ onCompleteGuide,
1881
+ onRunGuideStep
1695
1882
  }) {
1696
1883
  return /* @__PURE__ */ jsxs(
1697
1884
  "div",
1698
1885
  {
1699
1886
  className: "blinq-shell",
1700
1887
  "data-side": state.side,
1888
+ "data-theme": state.themeVariant,
1701
1889
  style: { ["--blinq-accent"]: state.accentColor },
1702
1890
  children: [
1703
1891
  !state.minimized ? /* @__PURE__ */ jsxs("div", { className: "blinq-panel", children: [
1704
- /* @__PURE__ */ jsxs("div", { className: "blinq-header", children: [
1705
- /* @__PURE__ */ jsxs("div", { className: "blinq-header-row", children: [
1706
- /* @__PURE__ */ jsx("div", { className: "blinq-header-copy", children: /* @__PURE__ */ jsx("div", { className: "blinq-heading", children: state.assistantName }) }),
1707
- /* @__PURE__ */ jsx(
1708
- Button,
1709
- {
1710
- type: "button",
1711
- size: "icon-sm",
1712
- variant: "ghost",
1713
- "aria-label": "\u0421\u0432\u0435\u0440\u043D\u0443\u0442\u044C \u0432\u0438\u0434\u0436\u0435\u0442",
1714
- title: "\u0421\u0432\u0435\u0440\u043D\u0443\u0442\u044C \u0432\u0438\u0434\u0436\u0435\u0442",
1715
- onClick: onCollapse,
1716
- children: /* @__PURE__ */ jsx(CollapseIcon, {})
1717
- }
1718
- )
1892
+ /* @__PURE__ */ jsx("div", { className: "blinq-header", children: /* @__PURE__ */ jsxs("div", { className: "blinq-header-row", children: [
1893
+ /* @__PURE__ */ jsx(AssistantAvatar, { avatarUrl: state.avatarUrl, assistantName: state.assistantName }),
1894
+ /* @__PURE__ */ jsxs("div", { className: "blinq-header-copy", children: [
1895
+ /* @__PURE__ */ jsx("div", { className: "blinq-heading", children: state.assistantName }),
1896
+ state.statusText ? /* @__PURE__ */ jsx("div", { className: "blinq-status-line", children: state.statusText }) : null
1719
1897
  ] }),
1720
- state.statusText ? /* @__PURE__ */ jsx("div", { className: "blinq-status-line", children: state.statusText }) : null
1721
- ] }),
1898
+ /* @__PURE__ */ jsx(
1899
+ Button,
1900
+ {
1901
+ type: "button",
1902
+ size: "icon-sm",
1903
+ variant: "ghost",
1904
+ "aria-label": "\u0421\u0432\u0435\u0440\u043D\u0443\u0442\u044C \u0432\u0438\u0434\u0436\u0435\u0442",
1905
+ title: "\u0421\u0432\u0435\u0440\u043D\u0443\u0442\u044C \u0432\u0438\u0434\u0436\u0435\u0442",
1906
+ onClick: onCollapse,
1907
+ children: /* @__PURE__ */ jsx(CollapseIcon, {})
1908
+ }
1909
+ )
1910
+ ] }) }),
1911
+ state.guide ? /* @__PURE__ */ jsx(
1912
+ GuideCard,
1913
+ {
1914
+ guide: state.guide,
1915
+ onStartGuide,
1916
+ onAdvanceGuide,
1917
+ onDismissGuide,
1918
+ onCompleteGuide,
1919
+ onRunGuideStep
1920
+ }
1921
+ ) : null,
1722
1922
  /* @__PURE__ */ jsx(
1723
1923
  AssistantConversationThread,
1724
1924
  {
@@ -1764,7 +1964,7 @@ function WidgetEmbedShell({
1764
1964
  Input,
1765
1965
  {
1766
1966
  value: state.inputValue,
1767
- placeholder: "\u041D\u0430\u043F\u0440\u0438\u043C\u0435\u0440: \u043D\u0430\u0439\u0434\u0438 \u043D\u0443\u0436\u043D\u0443\u044E \u043A\u043D\u043E\u043F\u043A\u0443 \u0438\u043B\u0438 \u0437\u0430\u043F\u043E\u043B\u043D\u0438 \u0444\u043E\u0440\u043C\u0443",
1967
+ placeholder: "Type a message...",
1768
1968
  onChange: (event) => onInputChange(event.currentTarget.value),
1769
1969
  disabled: state.isSending
1770
1970
  }
@@ -1783,7 +1983,8 @@ function WidgetEmbedShell({
1783
1983
  )
1784
1984
  ] }) })
1785
1985
  }
1786
- )
1986
+ ),
1987
+ /* @__PURE__ */ jsx("div", { className: "blinq-powered", children: "POWERED BY BLINQ" })
1787
1988
  ] }) : null,
1788
1989
  state.minimized ? /* @__PURE__ */ jsx(
1789
1990
  Button,
@@ -1794,7 +1995,7 @@ function WidgetEmbedShell({
1794
1995
  "aria-label": `\u041E\u0442\u043A\u0440\u044B\u0442\u044C ${state.assistantName}`,
1795
1996
  title: `\u041E\u0442\u043A\u0440\u044B\u0442\u044C ${state.assistantName}`,
1796
1997
  onClick: onOpen,
1797
- children: /* @__PURE__ */ jsx("span", { className: "blinq-launcher-badge", children: /* @__PURE__ */ jsx(LauncherIcon, {}) })
1998
+ children: /* @__PURE__ */ jsx(LauncherIcon, {})
1798
1999
  }
1799
2000
  ) : null
1800
2001
  ]
@@ -2204,6 +2405,41 @@ var SESSION_STORAGE_PREFIX = "blinq-widget-session";
2204
2405
  var MAX_STORED_HISTORY = 30;
2205
2406
  var MAX_HISTORY_FOR_REQUEST = 12;
2206
2407
  var DEFAULT_GREETING = "Blinq \u043F\u043E\u0434\u043A\u043B\u044E\u0447\u0435\u043D. \u0421\u043F\u0440\u043E\u0441\u0438\u0442\u0435 \u043F\u0440\u043E \u0442\u0435\u043A\u0443\u0449\u0443\u044E \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u0443, \u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0443 \u043F\u043B\u0430\u0442\u0444\u043E\u0440\u043C\u044B \u0438\u043B\u0438 \u0441\u043B\u0435\u0434\u0443\u044E\u0449\u0438\u0439 \u0448\u0430\u0433.";
2408
+ var PLAN_APPROVE_TEXTS = /* @__PURE__ */ new Set([
2409
+ "\u0434\u0430",
2410
+ "\u0430\u0433\u0430",
2411
+ "\u043E\u043A",
2412
+ "okay",
2413
+ "\u043E\u043A\u0435\u0439",
2414
+ "\u0445\u043E\u0440\u043E\u0448\u043E",
2415
+ "\u043B\u0430\u0434\u043D\u043E",
2416
+ "\u0434\u0435\u043B\u0430\u0439",
2417
+ "\u0441\u0434\u0435\u043B\u0430\u0439",
2418
+ "\u043F\u043E\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0430\u044E",
2419
+ "yes",
2420
+ "ok",
2421
+ "sure",
2422
+ "go ahead",
2423
+ "approve",
2424
+ "\u0438\u04D9",
2425
+ "\u0438\u044F",
2426
+ "\u0438\u0441\u0442\u0435",
2427
+ "\u0436\u0430\u0440\u0430\u0439\u0434\u044B",
2428
+ "\u043C\u0430\u049B\u04B1\u043B"
2429
+ ]);
2430
+ var PLAN_DECLINE_TEXTS = /* @__PURE__ */ new Set([
2431
+ "\u043D\u0435\u0442",
2432
+ "\u043D\u0435 \u043D\u0430\u0434\u043E",
2433
+ "\u043D\u0435 \u043D\u0443\u0436\u043D\u043E",
2434
+ "\u043E\u0442\u043C\u0435\u043D\u0430",
2435
+ "\u043E\u0442\u043C\u0435\u043D\u0438",
2436
+ "cancel",
2437
+ "no",
2438
+ "stop",
2439
+ "\u0436\u043E\u049B",
2440
+ "\u0442\u043E\u049B\u0442\u0430",
2441
+ "\u043A\u0435\u0440\u0435\u043A \u0435\u043C\u0435\u0441"
2442
+ ]);
2207
2443
  function isBrowser3() {
2208
2444
  return typeof window !== "undefined" && typeof document !== "undefined";
2209
2445
  }
@@ -2237,9 +2473,9 @@ function getOrCreateFingerprint() {
2237
2473
  }
2238
2474
  function runtimeMessage(mode) {
2239
2475
  if (mode === "read-only-fallback") {
2240
- return "\u0413\u043E\u0442\u043E\u0432 \u043E\u0431\u044A\u044F\u0441\u043D\u0438\u0442\u044C \u0442\u0435\u043A\u0443\u0449\u0443\u044E \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u0443 \u0438 \u043F\u043E\u0434\u0441\u043A\u0430\u0437\u0430\u0442\u044C \u0441\u043B\u0435\u0434\u0443\u044E\u0449\u0438\u0439 \u0448\u0430\u0433.";
2476
+ return "\u0414\u0435\u0439\u0441\u0442\u0432\u0438\u044F \u043D\u0430 \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u0435 \u043D\u0435\u0434\u043E\u0441\u0442\u0443\u043F\u043D\u044B. \u042F \u043C\u043E\u0433\u0443 \u043E\u0431\u044A\u044F\u0441\u043D\u044F\u0442\u044C \u0438\u043D\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0438 \u043E\u0442\u0432\u0435\u0447\u0430\u0442\u044C \u043F\u043E \u0431\u0430\u0437\u0435 \u0437\u043D\u0430\u043D\u0438\u0439.";
2241
2477
  }
2242
- return "\u0413\u043E\u0442\u043E\u0432 \u043F\u043E\u043C\u043E\u0447\u044C \u0441 \u043E\u043D\u0431\u043E\u0440\u0434\u0438\u043D\u0433\u043E\u043C \u0438 \u0432\u043E\u043F\u0440\u043E\u0441\u0430\u043C\u0438 \u043F\u043E \u043F\u043B\u0430\u0442\u0444\u043E\u0440\u043C\u0435.";
2478
+ return "\u0413\u043E\u0442\u043E\u0432 \u043F\u043E\u043C\u043E\u0433\u0430\u0442\u044C \u0441 \u0438\u043D\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u043E\u043C, \u0437\u043D\u0430\u043D\u0438\u044F\u043C\u0438 \u0438 \u0441\u043B\u0435\u0434\u0443\u044E\u0449\u0438\u043C\u0438 \u0448\u0430\u0433\u0430\u043C\u0438.";
2243
2479
  }
2244
2480
  function normalizedRouteFromUrl(value) {
2245
2481
  try {
@@ -2316,7 +2552,7 @@ var BlinqWidget = class {
2316
2552
  minimized = false;
2317
2553
  isSending = false;
2318
2554
  inputValue = "";
2319
- statusText = "\u041F\u0440\u043E\u0432\u0435\u0440\u044F\u0435\u043C \u0434\u043E\u0441\u0442\u0443\u043F\u043D\u044B\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044F \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u044B.";
2555
+ statusText = "";
2320
2556
  voiceSupported = false;
2321
2557
  voiceListening = false;
2322
2558
  voiceWaveform = [];
@@ -2326,6 +2562,7 @@ var BlinqWidget = class {
2326
2562
  confirmResolve = null;
2327
2563
  confirmItemId = null;
2328
2564
  activeRun = null;
2565
+ activeGuide = null;
2329
2566
  pendingAssistantIndicator = false;
2330
2567
  executedToolCounts = /* @__PURE__ */ new Map();
2331
2568
  lastAutoResumeKey = null;
@@ -2355,12 +2592,34 @@ var BlinqWidget = class {
2355
2592
  },
2356
2593
  onDeclinePlan: () => {
2357
2594
  void this.respondToPlan(false);
2595
+ },
2596
+ onStartGuide: () => {
2597
+ void this.startGuide();
2598
+ },
2599
+ onAdvanceGuide: () => {
2600
+ void this.advanceGuide();
2601
+ },
2602
+ onDismissGuide: () => {
2603
+ void this.dismissGuide();
2604
+ },
2605
+ onCompleteGuide: () => {
2606
+ void this.completeGuide();
2607
+ },
2608
+ onRunGuideStep: () => {
2609
+ void this.runGuideStep();
2358
2610
  }
2359
2611
  };
2360
2612
  constructor(options) {
2361
2613
  this.options = options;
2362
2614
  this.apiBaseUrl = options.apiBaseUrl ?? DEFAULT_API_BASE_URL;
2363
2615
  }
2616
+ currentActionPolicy() {
2617
+ return this.runtimeStatus?.action_policy ?? {
2618
+ actions_enabled: this.widgetConfig?.actions_enabled ?? true,
2619
+ action_mode: this.widgetConfig?.action_mode ?? "execute_with_confirmation",
2620
+ pointer_overlay_enabled: this.widgetConfig?.pointer_overlay_enabled ?? true
2621
+ };
2622
+ }
2364
2623
  async init() {
2365
2624
  await this.startSession();
2366
2625
  if (isBrowser3()) {
@@ -2370,8 +2629,10 @@ var BlinqWidget = class {
2370
2629
  this.render();
2371
2630
  this.setupVoiceInput();
2372
2631
  this.registry = new PageToolRegistry(this.confirmToolExecution.bind(this));
2632
+ this.registry.setActionPolicy(this.currentActionPolicy());
2373
2633
  const nativeRegistered = await this.registry.registerNativeTools();
2374
2634
  this.syncRuntimeStatus(nativeRegistered);
2635
+ this.syncGuideHighlight();
2375
2636
  if (this.shouldAutoResumeActiveRun()) {
2376
2637
  window.setTimeout(() => {
2377
2638
  void this.continueActiveRun();
@@ -2396,18 +2657,21 @@ var BlinqWidget = class {
2396
2657
  currentState() {
2397
2658
  return {
2398
2659
  minimized: this.minimized,
2399
- assistantName: this.widgetConfig?.ai_persona_name ?? "Blinq \u0410\u0441\u0441\u0438\u0441\u0442\u0435\u043D\u0442",
2660
+ assistantName: this.widgetConfig?.name ?? "Blinq \u0410\u0441\u0441\u0438\u0441\u0442\u0435\u043D\u0442",
2661
+ avatarUrl: this.widgetConfig?.avatar_url ?? null,
2400
2662
  runtimeLabel: "webmcp://embedded",
2401
2663
  statusText: this.statusText,
2402
2664
  showThinkingIndicator: this.pendingAssistantIndicator,
2403
2665
  inputValue: this.inputValue,
2404
- accentColor: "#111111",
2666
+ accentColor: this.widgetConfig?.theme_color ?? "#111111",
2667
+ themeVariant: "light",
2405
2668
  side: this.widgetConfig?.position === "bottom-left" ? "left" : "right",
2406
2669
  isSending: this.isSending,
2407
2670
  voiceSupported: this.voiceSupported,
2408
2671
  voiceListening: this.voiceListening,
2409
2672
  voiceWaveform: this.voiceWaveform,
2410
2673
  voiceDurationMs: this.voiceDurationMs,
2674
+ guide: this.activeGuide,
2411
2675
  items: this.items
2412
2676
  };
2413
2677
  }
@@ -2450,6 +2714,7 @@ var BlinqWidget = class {
2450
2714
  this.sessionToken = payload.session_token;
2451
2715
  this.widgetConfig = payload.widget_config;
2452
2716
  this.activeRun = payload.active_run ?? null;
2717
+ this.activeGuide = this.normalizeGuidePayload(payload.active_guide ?? payload.guide_offer ?? null);
2453
2718
  this.runtimeStatus = {
2454
2719
  ...payload.runtime,
2455
2720
  message: runtimeMessage(payload.runtime.mode)
@@ -2693,6 +2958,62 @@ var BlinqWidget = class {
2693
2958
  this.upsertPlanItem(this.activeRun);
2694
2959
  }
2695
2960
  }
2961
+ normalizeGuideStep(step) {
2962
+ return {
2963
+ id: step.id,
2964
+ position: step.position,
2965
+ title: step.title,
2966
+ body: step.body,
2967
+ targetSelector: step.target_selector ?? null,
2968
+ targetLabel: step.target_label ?? null,
2969
+ actionKind: step.action_kind ?? null,
2970
+ actionPayload: step.action_payload ?? null,
2971
+ expectedRoute: step.expected_route ?? null,
2972
+ completionMode: step.completion_mode
2973
+ };
2974
+ }
2975
+ normalizeGuidePayload(payload) {
2976
+ if (!payload) {
2977
+ return null;
2978
+ }
2979
+ const guide = payload.guide;
2980
+ return {
2981
+ id: guide.id,
2982
+ state: payload.state,
2983
+ source: guide.source,
2984
+ route: guide.route,
2985
+ summary: guide.summary ?? null,
2986
+ currentStepIndex: payload.state === "started" ? Math.min(payload.current_step_index, Math.max(guide.steps.length - 1, 0)) : payload.state === "completed" ? guide.steps.length : 0,
2987
+ totalSteps: guide.steps.length,
2988
+ steps: guide.steps.map((step) => this.normalizeGuideStep(step))
2989
+ };
2990
+ }
2991
+ setGuideState(payload, options) {
2992
+ const normalized = this.normalizeGuidePayload(payload);
2993
+ if (options?.clearIfFinished !== false && normalized && (normalized.state === "dismissed" || normalized.state === "completed")) {
2994
+ this.activeGuide = null;
2995
+ } else {
2996
+ this.activeGuide = normalized;
2997
+ }
2998
+ this.renderReactApp();
2999
+ this.syncGuideHighlight();
3000
+ }
3001
+ currentGuideStep() {
3002
+ if (!this.activeGuide || this.activeGuide.state !== "started") {
3003
+ return null;
3004
+ }
3005
+ return this.activeGuide.steps[Math.min(this.activeGuide.currentStepIndex, Math.max(this.activeGuide.steps.length - 1, 0))] ?? null;
3006
+ }
3007
+ syncGuideHighlight() {
3008
+ const step = this.currentGuideStep();
3009
+ if (!step?.targetSelector || !this.registry) {
3010
+ return;
3011
+ }
3012
+ this.registry.highlightTargets(
3013
+ [{ selector: step.targetSelector, label: step.targetLabel || step.title }],
3014
+ { interaction: step.actionKind ? "execute" : "explain", durationMs: 2100 }
3015
+ );
3016
+ }
2696
3017
  updateActionState(id, state) {
2697
3018
  this.items = this.items.map(
2698
3019
  (item) => item.type === "action" && item.id === id ? { ...item, state } : item
@@ -2706,8 +3027,24 @@ var BlinqWidget = class {
2706
3027
  const existingPlanItem = this.items.find(
2707
3028
  (item) => item.type === "plan" && item.id === this.planItemId(run.id)
2708
3029
  );
2709
- if (this.activeRun?.id && this.activeRun.id !== run.id) {
3030
+ const isNewActiveRun = Boolean(this.activeRun?.id && this.activeRun.id !== run.id);
3031
+ if (isNewActiveRun) {
2710
3032
  this.executedToolCounts.clear();
3033
+ this.items = this.items.map((item) => {
3034
+ if (item.type !== "plan" || item.id === this.planItemId(run.id)) {
3035
+ return item;
3036
+ }
3037
+ if (item.status === "completed" || item.status === "failed" || item.status === "abandoned") {
3038
+ return item;
3039
+ }
3040
+ return {
3041
+ ...item,
3042
+ status: "abandoned",
3043
+ approvalState: "declined",
3044
+ progressLabel: item.progressLabel ?? "\u041F\u043B\u0430\u043D \u0437\u0430\u043C\u0435\u043D\u0451\u043D \u043D\u043E\u0432\u044B\u043C \u0437\u0430\u043F\u0440\u043E\u0441\u043E\u043C.",
3045
+ statusReason: item.statusReason ?? "\u041F\u043B\u0430\u043D \u0437\u0430\u043C\u0435\u043D\u0451\u043D \u043D\u043E\u0432\u044B\u043C \u0437\u0430\u043F\u0440\u043E\u0441\u043E\u043C."
3046
+ };
3047
+ });
2711
3048
  }
2712
3049
  this.activeRun = {
2713
3050
  ...run,
@@ -2791,7 +3128,7 @@ var BlinqWidget = class {
2791
3128
  if (!this.runtimeStatus) {
2792
3129
  return;
2793
3130
  }
2794
- const mode = nativeRegistered ? "native-webmcp-active" : this.registry?.canExecuteWriteTools() ? "blinq-page-tools-active" : "read-only-fallback";
3131
+ const mode = nativeRegistered ? "native-webmcp-active" : this.registry ? "blinq-page-tools-active" : "read-only-fallback";
2795
3132
  this.runtimeStatus = {
2796
3133
  ...this.runtimeStatus,
2797
3134
  mode,
@@ -2805,6 +3142,124 @@ var BlinqWidget = class {
2805
3142
  this.statusText = text;
2806
3143
  this.renderReactApp();
2807
3144
  }
3145
+ async guideRequest(path, body) {
3146
+ if (!this.sessionToken) {
3147
+ throw new Error("\u0421\u0435\u0441\u0441\u0438\u044F \u0432\u0438\u0434\u0436\u0435\u0442\u0430 \u0435\u0449\u0451 \u043D\u0435 \u0438\u043D\u0438\u0446\u0438\u0430\u043B\u0438\u0437\u0438\u0440\u043E\u0432\u0430\u043D\u0430");
3148
+ }
3149
+ const response = await fetch(`${this.apiBaseUrl}${path}`, {
3150
+ method: "POST",
3151
+ headers: {
3152
+ "Content-Type": "application/json",
3153
+ Authorization: `Bearer ${this.sessionToken}`
3154
+ },
3155
+ body: JSON.stringify(body)
3156
+ });
3157
+ if (!response.ok) {
3158
+ const payload = await response.json().catch(() => ({}));
3159
+ throw new Error(payload.detail ?? "\u041D\u0435 \u0443\u0434\u0430\u043B\u043E\u0441\u044C \u043E\u0431\u043D\u043E\u0432\u0438\u0442\u044C \u0441\u043E\u0441\u0442\u043E\u044F\u043D\u0438\u0435 guide");
3160
+ }
3161
+ return await response.json();
3162
+ }
3163
+ async startGuide() {
3164
+ if (!this.sessionId || !this.activeGuide) {
3165
+ return;
3166
+ }
3167
+ const payload = await this.guideRequest("/pub/guide/start", {
3168
+ session_id: this.sessionId,
3169
+ guide_id: this.activeGuide.source === "published" ? this.activeGuide.id : null
3170
+ });
3171
+ this.setGuideState(payload, { clearIfFinished: false });
3172
+ this.setStatus("Guide \u0437\u0430\u043F\u0443\u0449\u0435\u043D.");
3173
+ }
3174
+ async advanceGuide() {
3175
+ if (!this.sessionId) {
3176
+ return;
3177
+ }
3178
+ const payload = await this.guideRequest("/pub/guide/advance", {
3179
+ session_id: this.sessionId
3180
+ });
3181
+ this.setGuideState(payload);
3182
+ this.setStatus(payload.state === "completed" ? "Guide \u0437\u0430\u0432\u0435\u0440\u0448\u0451\u043D." : "\u041F\u0435\u0440\u0435\u0445\u043E\u0434\u0438\u043C \u043A \u0441\u043B\u0435\u0434\u0443\u044E\u0449\u0435\u043C\u0443 \u0448\u0430\u0433\u0443.");
3183
+ }
3184
+ async dismissGuide() {
3185
+ if (!this.sessionId) {
3186
+ return;
3187
+ }
3188
+ const payload = await this.guideRequest("/pub/guide/dismiss", {
3189
+ session_id: this.sessionId
3190
+ });
3191
+ this.setGuideState(payload);
3192
+ this.setStatus("Guide \u0441\u043A\u0440\u044B\u0442.");
3193
+ }
3194
+ async completeGuide() {
3195
+ if (!this.sessionId) {
3196
+ return;
3197
+ }
3198
+ const payload = await this.guideRequest("/pub/guide/complete", {
3199
+ session_id: this.sessionId
3200
+ });
3201
+ this.setGuideState(payload);
3202
+ this.setStatus("Guide \u0437\u0430\u0432\u0435\u0440\u0448\u0451\u043D.");
3203
+ }
3204
+ async runGuideStep() {
3205
+ const step = this.currentGuideStep();
3206
+ if (!step || !this.registry) {
3207
+ return;
3208
+ }
3209
+ if (step.actionKind && step.actionPayload && this.currentActionPolicy().actions_enabled && this.currentActionPolicy().action_mode === "execute_with_confirmation") {
3210
+ const outcome = await this.registry.executeTool({
3211
+ tool_name: step.actionKind,
3212
+ display_name: step.title,
3213
+ target_summary: step.targetLabel || step.body,
3214
+ arguments: step.actionPayload
3215
+ });
3216
+ if (outcome.status === "success") {
3217
+ this.setStatus("\u0428\u0430\u0433 \u0432\u044B\u043F\u043E\u043B\u043D\u0435\u043D \u043D\u0430 \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u0435.");
3218
+ const deferredNavigationHref = outcome.result && typeof outcome.result.href === "string" && outcome.result.deferred_navigation ? outcome.result.href : null;
3219
+ await this.advanceGuide();
3220
+ if (deferredNavigationHref) {
3221
+ window.location.assign(deferredNavigationHref);
3222
+ }
3223
+ } else if (outcome.status === "cancelled") {
3224
+ this.setStatus("\u0412\u044B\u043F\u043E\u043B\u043D\u0435\u043D\u0438\u0435 \u0448\u0430\u0433\u0430 \u043E\u0442\u043C\u0435\u043D\u0435\u043D\u043E.");
3225
+ } else {
3226
+ await this.healGuideStep();
3227
+ }
3228
+ return;
3229
+ }
3230
+ if (step.targetSelector) {
3231
+ const highlighted = this.registry.highlightTargets(
3232
+ [{ selector: step.targetSelector, label: step.targetLabel || step.title }],
3233
+ { interaction: "explain", durationMs: 2200 }
3234
+ );
3235
+ if (highlighted) {
3236
+ this.setStatus("\u041F\u043E\u043A\u0430\u0437\u0430\u043B, \u043A\u0443\u0434\u0430 \u043D\u0430\u0436\u0430\u0442\u044C \u043D\u0430 \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u0435.");
3237
+ } else {
3238
+ await this.healGuideStep();
3239
+ }
3240
+ }
3241
+ }
3242
+ async healGuideStep() {
3243
+ if (!this.sessionId || !this.activeGuide || !this.registry) {
3244
+ return;
3245
+ }
3246
+ this.setStatus("\u041A\u0430\u0436\u0435\u0442\u0441\u044F \u044D\u043B\u0435\u043C\u0435\u043D\u0442 \u043F\u0435\u0440\u0435\u0435\u0445\u0430\u043B. \u0418\u0449\u0443 \u043D\u043E\u0432\u044B\u0435 \u0441\u043F\u043E\u0441\u043E\u0431\u044B \u0441 \u043F\u043E\u043C\u043E\u0449\u044C\u044E \u0418\u0418...");
3247
+ const pageContext = this.registry.collectPageContext();
3248
+ try {
3249
+ const payload = await this.guideRequest("/pub/guide/heal", {
3250
+ session_id: this.sessionId,
3251
+ step_index: this.activeGuide.currentStepIndex,
3252
+ page_context: pageContext
3253
+ });
3254
+ this.setGuideState(payload, { clearIfFinished: false });
3255
+ this.setStatus("\u0421\u0446\u0435\u043D\u0430\u0440\u0438\u0439 \u043F\u0435\u0440\u0435\u0441\u0442\u0440\u043E\u0435\u043D. \u041F\u0440\u043E\u0434\u043E\u043B\u0436\u0430\u044E...");
3256
+ window.setTimeout(() => {
3257
+ void this.runGuideStep();
3258
+ }, 1500);
3259
+ } catch (e) {
3260
+ this.setStatus("\u041D\u0435 \u0443\u0434\u0430\u043B\u043E\u0441\u044C \u043F\u0435\u0440\u0435\u0441\u0442\u0440\u043E\u0438\u0442\u044C \u0448\u0430\u0433.");
3261
+ }
3262
+ }
2808
3263
  appendMessage(text, role, options) {
2809
3264
  const id = createConversationId("message");
2810
3265
  this.items = [
@@ -2865,6 +3320,19 @@ var BlinqWidget = class {
2865
3320
  currentRoute() {
2866
3321
  return normalizedRouteFromUrl(window.location.href);
2867
3322
  }
3323
+ normalizedUserPlanDecision(message) {
3324
+ const normalized = message.trim().toLowerCase();
3325
+ if (!normalized || !this.activeRun?.requires_approval) {
3326
+ return null;
3327
+ }
3328
+ if (PLAN_APPROVE_TEXTS.has(normalized)) {
3329
+ return true;
3330
+ }
3331
+ if (PLAN_DECLINE_TEXTS.has(normalized)) {
3332
+ return false;
3333
+ }
3334
+ return null;
3335
+ }
2868
3336
  shouldAutoResumeActiveRun() {
2869
3337
  if (!this.activeRun || this.activeRun.status !== "awaiting_navigation") {
2870
3338
  return false;
@@ -2963,7 +3431,13 @@ var BlinqWidget = class {
2963
3431
  }
2964
3432
  if (event === "highlight") {
2965
3433
  const highlight = JSON.parse(data);
2966
- this.registry?.highlightTargets(highlight.targets ?? []);
3434
+ this.registry?.highlightTargets(highlight.targets ?? [], { interaction: "explain" });
3435
+ }
3436
+ if (event === "guide") {
3437
+ this.hideThinkingIndicator();
3438
+ this.setGuideState(JSON.parse(data), {
3439
+ clearIfFinished: false
3440
+ });
2967
3441
  }
2968
3442
  if (event === "delta" && payload.text) {
2969
3443
  const normalizedChunk = normalizeAssistantStreamChunk(finalText, payload.text);
@@ -3045,6 +3519,18 @@ var BlinqWidget = class {
3045
3519
  let responseMessageId = null;
3046
3520
  try {
3047
3521
  this.appendMessage(message, "user");
3522
+ const directPlanDecision = this.normalizedUserPlanDecision(message);
3523
+ if (directPlanDecision !== null) {
3524
+ const finalText2 = await this.respondToPlan(directPlanDecision, {
3525
+ appendAssistantMessage: false,
3526
+ manageSendingState: false
3527
+ });
3528
+ if (finalText2.trim()) {
3529
+ this.finalizeAssistantMessage(finalText2, { persist: false });
3530
+ this.rememberMessage({ role: "assistant", text: finalText2 });
3531
+ }
3532
+ return finalText2;
3533
+ }
3048
3534
  const finalText = await this.streamChatStep(
3049
3535
  "/pub/chat",
3050
3536
  {
@@ -3105,16 +3591,19 @@ var BlinqWidget = class {
3105
3591
  this.renderReactApp();
3106
3592
  }
3107
3593
  }
3108
- async respondToPlan(approved) {
3594
+ async respondToPlan(approved, options) {
3109
3595
  if (!this.sessionId || !this.sessionToken || !this.activeRun) {
3110
- return;
3596
+ return "";
3111
3597
  }
3112
- if (this.isSending) {
3113
- return;
3598
+ const manageSendingState = options?.manageSendingState ?? true;
3599
+ if (manageSendingState && this.isSending) {
3600
+ return "";
3601
+ }
3602
+ if (manageSendingState) {
3603
+ this.isSending = true;
3604
+ this.showThinkingIndicator();
3605
+ this.renderReactApp();
3114
3606
  }
3115
- this.isSending = true;
3116
- this.showThinkingIndicator();
3117
- this.renderReactApp();
3118
3607
  try {
3119
3608
  const finalText = await this.streamChatStep(
3120
3609
  "/pub/plan/approve",
@@ -3126,14 +3615,17 @@ var BlinqWidget = class {
3126
3615
  },
3127
3616
  null
3128
3617
  );
3129
- if (finalText.trim()) {
3618
+ if (options?.appendAssistantMessage !== false && finalText.trim()) {
3130
3619
  this.finalizeAssistantMessage(finalText, { persist: false });
3131
3620
  this.rememberMessage({ role: "assistant", text: finalText });
3132
3621
  }
3622
+ return finalText;
3133
3623
  } finally {
3134
- this.hideThinkingIndicator();
3135
- this.isSending = false;
3136
- this.renderReactApp();
3624
+ if (manageSendingState) {
3625
+ this.hideThinkingIndicator();
3626
+ this.isSending = false;
3627
+ this.renderReactApp();
3628
+ }
3137
3629
  }
3138
3630
  }
3139
3631
  async endSession() {
@@ -3165,10 +3657,1257 @@ async function createBlinqWidget(options) {
3165
3657
  return init(options);
3166
3658
  }
3167
3659
 
3660
+ // src/embed-styles.ts
3661
+ var EMBED_WIDGET_STYLES = `
3662
+ :host {
3663
+ all: initial;
3664
+ display: block;
3665
+ position: static;
3666
+ color-scheme: light;
3667
+ }
3668
+
3669
+ *, *::before, *::after {
3670
+ box-sizing: border-box;
3671
+ }
3672
+
3673
+ button,
3674
+ input {
3675
+ font: inherit;
3676
+ }
3677
+
3678
+ .blinq-shell {
3679
+ position: fixed;
3680
+ bottom: 24px;
3681
+ z-index: 2147483647;
3682
+ display: flex;
3683
+ flex-direction: column;
3684
+ gap: 12px;
3685
+ width: 432px;
3686
+ max-width: calc(100vw - 24px);
3687
+ pointer-events: none;
3688
+ font-family:
3689
+ "SF Pro Display",
3690
+ "SF Pro Text",
3691
+ "Inter",
3692
+ ui-sans-serif,
3693
+ system-ui,
3694
+ -apple-system,
3695
+ BlinkMacSystemFont,
3696
+ "Segoe UI",
3697
+ sans-serif;
3698
+ --blinq-accent: #111111;
3699
+ --blinq-text: rgba(18, 18, 20, 0.96);
3700
+ --blinq-text-soft: rgba(32, 34, 38, 0.82);
3701
+ --blinq-text-muted: rgba(56, 60, 66, 0.58);
3702
+ --blinq-glass-fill: linear-gradient(180deg, rgba(255, 255, 255, 0.78), rgba(240, 243, 248, 0.52));
3703
+ --blinq-glass-fill-strong: linear-gradient(180deg, rgba(255, 255, 255, 0.88), rgba(245, 247, 250, 0.62));
3704
+ --blinq-glass-fill-dense: linear-gradient(180deg, rgba(249, 250, 252, 0.92), rgba(231, 235, 241, 0.66));
3705
+ --blinq-glass-stroke: rgba(255, 255, 255, 0.68);
3706
+ --blinq-glass-stroke-soft: rgba(255, 255, 255, 0.5);
3707
+ --blinq-glass-edge: rgba(100, 109, 123, 0.14);
3708
+ --blinq-shadow:
3709
+ 0 28px 80px rgba(155, 164, 180, 0.22),
3710
+ 0 10px 30px rgba(174, 182, 193, 0.18);
3711
+ --blinq-shadow-soft:
3712
+ 0 14px 40px rgba(170, 177, 189, 0.18),
3713
+ 0 4px 14px rgba(202, 208, 216, 0.18);
3714
+ --blinq-inner-highlight: inset 0 1px 0 rgba(255, 255, 255, 0.92);
3715
+ --blinq-blur: blur(28px) saturate(170%);
3716
+ --blinq-radius-panel: 32px;
3717
+ --blinq-radius-pill: 999px;
3718
+ --blinq-radius-bubble: 28px;
3719
+ --blinq-radius-card: 30px;
3720
+ }
3721
+
3722
+ .blinq-shell[data-side="left"] {
3723
+ left: 24px;
3724
+ align-items: flex-start;
3725
+ }
3726
+
3727
+ .blinq-shell[data-side="right"] {
3728
+ right: 24px;
3729
+ align-items: flex-end;
3730
+ }
3731
+
3732
+ .blinq-panel,
3733
+ .blinq-launcher {
3734
+ pointer-events: auto;
3735
+ }
3736
+
3737
+ .blinq-shell {
3738
+ width: 520px;
3739
+ }
3740
+
3741
+ .blinq-panel {
3742
+ position: relative;
3743
+ width: 100%;
3744
+ max-width: 432px;
3745
+ overflow: hidden;
3746
+ border-radius: var(--blinq-radius-panel);
3747
+ border: 1px solid var(--blinq-glass-stroke);
3748
+ background: var(--blinq-glass-fill);
3749
+ box-shadow: var(--blinq-shadow);
3750
+ backdrop-filter: var(--blinq-blur);
3751
+ -webkit-backdrop-filter: var(--blinq-blur);
3752
+ }
3753
+
3754
+ .blinq-panel::before,
3755
+ .blinq-launcher::before {
3756
+ content: "";
3757
+ position: absolute;
3758
+ inset: 0;
3759
+ pointer-events: none;
3760
+ border-radius: inherit;
3761
+ box-shadow: var(--blinq-inner-highlight);
3762
+ }
3763
+
3764
+ .blinq-launcher::after {
3765
+ content: "";
3766
+ position: absolute;
3767
+ inset: 1px;
3768
+ pointer-events: none;
3769
+ border-radius: inherit;
3770
+ background:
3771
+ radial-gradient(circle at 28% 22%, rgba(255, 255, 255, 0.82), transparent 32%),
3772
+ linear-gradient(135deg, rgba(255, 255, 255, 0.46), transparent 55%);
3773
+ opacity: 0.88;
3774
+ transition:
3775
+ opacity 180ms ease;
3776
+ }
3777
+
3778
+ .blinq-panel::after {
3779
+ content: "";
3780
+ position: absolute;
3781
+ inset: 0;
3782
+ pointer-events: none;
3783
+ border-radius: inherit;
3784
+ background:
3785
+ radial-gradient(circle at top left, rgba(255, 255, 255, 0.72), transparent 34%),
3786
+ radial-gradient(circle at bottom center, rgba(255, 255, 255, 0.26), transparent 38%);
3787
+ opacity: 0.95;
3788
+ }
3789
+
3790
+ .blinq-header,
3791
+ .blinq-thread,
3792
+ .blinq-composer {
3793
+ position: relative;
3794
+ z-index: 1;
3795
+ }
3796
+
3797
+ .blinq-header {
3798
+ display: flex;
3799
+ flex-direction: column;
3800
+ gap: 12px;
3801
+ padding: 18px 18px 10px;
3802
+ }
3803
+
3804
+ .blinq-header-row {
3805
+ display: flex;
3806
+ align-items: flex-start;
3807
+ justify-content: space-between;
3808
+ gap: 12px;
3809
+ }
3810
+
3811
+ .blinq-header-copy {
3812
+ display: flex;
3813
+ flex-direction: column;
3814
+ gap: 8px;
3815
+ min-width: 0;
3816
+ flex: 1;
3817
+ }
3818
+
3819
+ .blinq-heading {
3820
+ font-size: 17px;
3821
+ line-height: 1.15;
3822
+ font-weight: 600;
3823
+ letter-spacing: -0.03em;
3824
+ color: var(--blinq-text);
3825
+ }
3826
+
3827
+ .blinq-status-line {
3828
+ display: inline-flex;
3829
+ align-items: center;
3830
+ gap: 8px;
3831
+ max-width: fit-content;
3832
+ min-height: 32px;
3833
+ padding: 0 12px;
3834
+ border-radius: var(--blinq-radius-pill);
3835
+ border: 1px solid var(--blinq-glass-stroke-soft);
3836
+ background: linear-gradient(180deg, rgba(255, 255, 255, 0.72), rgba(242, 244, 248, 0.46));
3837
+ color: var(--blinq-text-soft);
3838
+ font-size: 12px;
3839
+ line-height: 1.35;
3840
+ box-shadow: var(--blinq-shadow-soft);
3841
+ backdrop-filter: blur(22px) saturate(170%);
3842
+ -webkit-backdrop-filter: blur(22px) saturate(170%);
3843
+ }
3844
+
3845
+ .blinq-status-line::before {
3846
+ content: "";
3847
+ width: 7px;
3848
+ height: 7px;
3849
+ border-radius: 999px;
3850
+ background: rgba(17, 17, 17, 0.74);
3851
+ box-shadow: 0 0 0 4px rgba(255, 255, 255, 0.34);
3852
+ flex: none;
3853
+ }
3854
+
3855
+ .blinq-launcher {
3856
+ position: relative;
3857
+ display: inline-flex;
3858
+ align-items: center;
3859
+ justify-content: center;
3860
+ width: 76px;
3861
+ min-width: 76px;
3862
+ height: 76px;
3863
+ padding: 0;
3864
+ border-radius: 999px;
3865
+ border: 1px solid var(--blinq-glass-stroke);
3866
+ background: var(--blinq-glass-fill-strong);
3867
+ box-shadow: var(--blinq-shadow-soft);
3868
+ backdrop-filter: blur(26px) saturate(175%);
3869
+ -webkit-backdrop-filter: blur(26px) saturate(175%);
3870
+ color: var(--blinq-text);
3871
+ isolation: isolate;
3872
+ }
3873
+
3874
+ .blinq-launcher:hover {
3875
+ border-color: var(--blinq-glass-stroke);
3876
+ box-shadow: var(--blinq-shadow-soft);
3877
+ }
3878
+
3879
+ .blinq-launcher-icon-only {
3880
+ border-radius: 999px;
3881
+ }
3882
+
3883
+ .blinq-launcher-icon {
3884
+ position: relative;
3885
+ z-index: 1;
3886
+ width: 30px;
3887
+ height: 30px;
3888
+ color: rgba(17, 17, 17, 0.96);
3889
+ opacity: 1;
3890
+ filter:
3891
+ drop-shadow(0 1px 0 rgba(255, 255, 255, 0.66))
3892
+ drop-shadow(0 2px 6px rgba(17, 17, 17, 0.08));
3893
+ }
3894
+
3895
+ .blinq-thread {
3896
+ min-height: 0;
3897
+ }
3898
+
3899
+ .blinq-thread-viewport {
3900
+ width: 100%;
3901
+ }
3902
+
3903
+ .blinq-scroll {
3904
+ display: flex;
3905
+ flex-direction: column;
3906
+ gap: 12px;
3907
+ min-height: 0;
3908
+ max-height: 432px;
3909
+ padding: 6px 18px 14px;
3910
+ overflow-y: auto;
3911
+ }
3912
+
3913
+ .blinq-scroll::-webkit-scrollbar {
3914
+ width: 8px;
3915
+ }
3916
+
3917
+ .blinq-scroll::-webkit-scrollbar-thumb {
3918
+ background: rgba(144, 151, 162, 0.22);
3919
+ border-radius: 999px;
3920
+ }
3921
+
3922
+ .blinq-message {
3923
+ position: relative;
3924
+ max-width: 88%;
3925
+ padding: 14px 16px;
3926
+ border-radius: var(--blinq-radius-bubble);
3927
+ border: 1px solid var(--blinq-glass-stroke-soft);
3928
+ background: var(--blinq-glass-fill-strong);
3929
+ color: var(--blinq-text);
3930
+ font-size: 14px;
3931
+ line-height: 1.55;
3932
+ white-space: pre-wrap;
3933
+ box-shadow: var(--blinq-shadow-soft);
3934
+ backdrop-filter: blur(24px) saturate(170%);
3935
+ -webkit-backdrop-filter: blur(24px) saturate(170%);
3936
+ }
3937
+
3938
+ .blinq-message::before {
3939
+ content: "";
3940
+ position: absolute;
3941
+ inset: 0;
3942
+ border-radius: inherit;
3943
+ pointer-events: none;
3944
+ box-shadow: var(--blinq-inner-highlight);
3945
+ }
3946
+
3947
+ .blinq-message[data-role="assistant"] {
3948
+ align-self: flex-start;
3949
+ background: linear-gradient(180deg, rgba(255, 255, 255, 0.86), rgba(241, 244, 249, 0.58));
3950
+ }
3951
+
3952
+ .blinq-message[data-role="user"] {
3953
+ align-self: flex-end;
3954
+ background: linear-gradient(180deg, rgba(249, 250, 252, 0.94), rgba(227, 232, 238, 0.66));
3955
+ border-color: rgba(255, 255, 255, 0.74);
3956
+ }
3957
+
3958
+ .blinq-message[data-kind="artifact"] {
3959
+ width: 100%;
3960
+ max-width: 100%;
3961
+ padding: 0;
3962
+ border: 0;
3963
+ background: transparent;
3964
+ box-shadow: none;
3965
+ backdrop-filter: none;
3966
+ -webkit-backdrop-filter: none;
3967
+ }
3968
+
3969
+ .blinq-message[data-kind="artifact"]::before {
3970
+ display: none;
3971
+ }
3972
+
3973
+ .blinq-message-copy {
3974
+ display: block;
3975
+ }
3976
+
3977
+ .blinq-message-copy-reveal {
3978
+ animation: blinq-copy-reveal 240ms cubic-bezier(0.16, 1, 0.3, 1);
3979
+ will-change: opacity, transform;
3980
+ }
3981
+
3982
+ .blinq-thinking-card {
3983
+ max-width: fit-content;
3984
+ padding-right: 18px;
3985
+ }
3986
+
3987
+ .blinq-thinking {
3988
+ display: inline-flex;
3989
+ align-items: center;
3990
+ gap: 10px;
3991
+ color: var(--blinq-text-soft);
3992
+ font-size: 13px;
3993
+ }
3994
+
3995
+ .blinq-thinking-dots {
3996
+ display: inline-flex;
3997
+ align-items: center;
3998
+ gap: 4px;
3999
+ }
4000
+
4001
+ .blinq-thinking-dots > span {
4002
+ width: 6px;
4003
+ height: 6px;
4004
+ border-radius: 999px;
4005
+ background: rgba(17, 17, 17, 0.74);
4006
+ animation: blinq-thinking-pulse 1.2s ease-in-out infinite;
4007
+ }
4008
+
4009
+ .blinq-thinking-dots > span:nth-child(2) {
4010
+ animation-delay: 100ms;
4011
+ }
4012
+
4013
+ .blinq-thinking-dots > span:nth-child(3) {
4014
+ animation-delay: 200ms;
4015
+ }
4016
+
4017
+ .blinq-card {
4018
+ display: flex;
4019
+ flex-direction: column;
4020
+ gap: 12px;
4021
+ border-radius: var(--blinq-radius-card);
4022
+ border: 1px solid var(--blinq-glass-stroke-soft);
4023
+ background: linear-gradient(180deg, rgba(255, 255, 255, 0.78), rgba(240, 243, 248, 0.52));
4024
+ color: var(--blinq-text);
4025
+ box-shadow: var(--blinq-shadow-soft);
4026
+ backdrop-filter: blur(26px) saturate(170%);
4027
+ -webkit-backdrop-filter: blur(26px) saturate(170%);
4028
+ }
4029
+
4030
+ .blinq-card-header {
4031
+ display: flex;
4032
+ flex-direction: column;
4033
+ gap: 8px;
4034
+ padding: 16px 16px 0;
4035
+ }
4036
+
4037
+ .blinq-card-title {
4038
+ font-size: 15px;
4039
+ line-height: 1.2;
4040
+ font-weight: 600;
4041
+ letter-spacing: -0.02em;
4042
+ color: var(--blinq-text);
4043
+ }
4044
+
4045
+ .blinq-card-description {
4046
+ font-size: 13px;
4047
+ line-height: 1.45;
4048
+ color: var(--blinq-text-muted);
4049
+ }
4050
+
4051
+ .blinq-card-content {
4052
+ padding: 0 16px 16px;
4053
+ }
4054
+
4055
+ .blinq-action-card,
4056
+ .blinq-plan-card,
4057
+ .blinq-guide-card {
4058
+ align-self: stretch;
4059
+ }
4060
+
4061
+ .blinq-guide-content {
4062
+ display: flex;
4063
+ flex-direction: column;
4064
+ gap: 12px;
4065
+ }
4066
+
4067
+ .blinq-guide-step-shell {
4068
+ display: flex;
4069
+ flex-direction: column;
4070
+ gap: 8px;
4071
+ padding: 14px;
4072
+ border-radius: 22px;
4073
+ border: 1px solid rgba(255, 255, 255, 0.64);
4074
+ background:
4075
+ radial-gradient(circle at top left, rgba(255, 255, 255, 0.8), transparent 42%),
4076
+ linear-gradient(180deg, rgba(255, 255, 255, 0.82), rgba(242, 245, 249, 0.56));
4077
+ box-shadow:
4078
+ inset 0 1px 0 rgba(255, 255, 255, 0.94),
4079
+ 0 10px 22px rgba(183, 191, 201, 0.13);
4080
+ }
4081
+
4082
+ .blinq-guide-step-meta {
4083
+ font-size: 11px;
4084
+ font-weight: 600;
4085
+ letter-spacing: 0.08em;
4086
+ text-transform: uppercase;
4087
+ color: var(--blinq-text-soft);
4088
+ }
4089
+
4090
+ .blinq-guide-step-title {
4091
+ font-size: 14px;
4092
+ line-height: 1.35;
4093
+ font-weight: 600;
4094
+ color: var(--blinq-text);
4095
+ }
4096
+
4097
+ .blinq-guide-step-copy {
4098
+ font-size: 13px;
4099
+ line-height: 1.5;
4100
+ color: var(--blinq-text-muted);
4101
+ }
4102
+
4103
+ .blinq-plan-step {
4104
+ display: flex;
4105
+ align-items: flex-start;
4106
+ gap: 12px;
4107
+ padding: 12px 13px;
4108
+ margin-top: 10px;
4109
+ border-radius: 24px;
4110
+ border: 1px solid rgba(255, 255, 255, 0.62);
4111
+ background:
4112
+ radial-gradient(circle at top left, rgba(255, 255, 255, 0.72), transparent 38%),
4113
+ linear-gradient(180deg, rgba(255, 255, 255, 0.76), rgba(238, 242, 247, 0.54));
4114
+ box-shadow:
4115
+ inset 0 1px 0 rgba(255, 255, 255, 0.94),
4116
+ 0 8px 20px rgba(189, 196, 206, 0.12);
4117
+ }
4118
+
4119
+ .blinq-plan-step:first-child {
4120
+ margin-top: 0;
4121
+ }
4122
+
4123
+ .blinq-plan-step-index {
4124
+ display: inline-flex;
4125
+ align-items: center;
4126
+ justify-content: center;
4127
+ width: 26px;
4128
+ height: 26px;
4129
+ border-radius: 999px;
4130
+ border: 1px solid rgba(255, 255, 255, 0.7);
4131
+ background: linear-gradient(180deg, rgba(255, 255, 255, 0.86), rgba(240, 243, 247, 0.62));
4132
+ color: rgba(17, 17, 17, 0.82);
4133
+ font-size: 11px;
4134
+ font-weight: 700;
4135
+ flex: none;
4136
+ }
4137
+
4138
+ .blinq-plan-step-copy {
4139
+ min-width: 0;
4140
+ display: flex;
4141
+ flex-direction: column;
4142
+ gap: 6px;
4143
+ color: var(--blinq-text);
4144
+ font-size: 13px;
4145
+ flex: 1;
4146
+ }
4147
+
4148
+ .blinq-plan-header {
4149
+ display: flex;
4150
+ align-items: flex-start;
4151
+ justify-content: space-between;
4152
+ gap: 12px;
4153
+ }
4154
+
4155
+ .blinq-plan-content {
4156
+ display: flex;
4157
+ flex-direction: column;
4158
+ gap: 12px;
4159
+ }
4160
+
4161
+ .blinq-plan-steps {
4162
+ display: flex;
4163
+ flex-direction: column;
4164
+ gap: 0;
4165
+ }
4166
+
4167
+ .blinq-plan-step-title-row {
4168
+ display: flex;
4169
+ align-items: flex-start;
4170
+ justify-content: space-between;
4171
+ gap: 10px;
4172
+ }
4173
+
4174
+ .blinq-plan-step-title {
4175
+ min-width: 0;
4176
+ font-size: 13px;
4177
+ line-height: 1.4;
4178
+ font-weight: 600;
4179
+ letter-spacing: -0.01em;
4180
+ }
4181
+
4182
+ .blinq-plan-step-status-pill {
4183
+ display: inline-flex;
4184
+ align-items: center;
4185
+ justify-content: center;
4186
+ min-height: 24px;
4187
+ padding: 0 10px;
4188
+ border-radius: 999px;
4189
+ border: 1px solid rgba(255, 255, 255, 0.58);
4190
+ background: rgba(255, 255, 255, 0.58);
4191
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.88);
4192
+ color: var(--blinq-text-soft);
4193
+ font-size: 11px;
4194
+ font-weight: 600;
4195
+ line-height: 1;
4196
+ letter-spacing: 0.01em;
4197
+ white-space: nowrap;
4198
+ }
4199
+
4200
+ .blinq-plan-step-meta {
4201
+ font-size: 12px;
4202
+ color: var(--blinq-text-muted);
4203
+ }
4204
+
4205
+ .blinq-plan-step[data-current="true"] {
4206
+ background:
4207
+ radial-gradient(circle at top left, rgba(255, 255, 255, 0.82), transparent 40%),
4208
+ linear-gradient(180deg, rgba(255, 255, 255, 0.88), rgba(243, 246, 250, 0.64));
4209
+ border-color: rgba(255, 255, 255, 0.74);
4210
+ box-shadow:
4211
+ inset 0 1px 0 rgba(255, 255, 255, 0.96),
4212
+ 0 12px 26px rgba(183, 191, 201, 0.15);
4213
+ }
4214
+
4215
+ .blinq-plan-step[data-current="true"] .blinq-plan-step-index {
4216
+ box-shadow: 0 0 0 4px rgba(255, 255, 255, 0.48);
4217
+ }
4218
+
4219
+ .blinq-plan-step[data-current="true"] .blinq-plan-step-status-pill {
4220
+ background: linear-gradient(180deg, rgba(255, 255, 255, 0.82), rgba(240, 243, 247, 0.66));
4221
+ color: var(--blinq-text);
4222
+ }
4223
+
4224
+ .blinq-plan-step[data-status="completed"] .blinq-plan-step-index {
4225
+ background: rgba(227, 232, 237, 0.88);
4226
+ }
4227
+
4228
+ .blinq-plan-step[data-status="completed"] .blinq-plan-step-status-pill {
4229
+ background: rgba(244, 246, 249, 0.78);
4230
+ }
4231
+
4232
+ .blinq-plan-step[data-status="failed"],
4233
+ .blinq-plan-step[data-status="cancelled"] {
4234
+ opacity: 0.72;
4235
+ }
4236
+
4237
+ .blinq-action-meta-row {
4238
+ display: flex;
4239
+ align-items: center;
4240
+ justify-content: space-between;
4241
+ gap: 8px;
4242
+ flex-wrap: wrap;
4243
+ }
4244
+
4245
+ .blinq-action-details {
4246
+ margin-top: 8px;
4247
+ }
4248
+
4249
+ .blinq-action-details > summary {
4250
+ display: inline-flex;
4251
+ align-items: center;
4252
+ min-height: 34px;
4253
+ padding: 0 12px;
4254
+ border-radius: 999px;
4255
+ border: 1px solid rgba(255, 255, 255, 0.56);
4256
+ background: rgba(255, 255, 255, 0.46);
4257
+ color: var(--blinq-text-soft);
4258
+ font-size: 12px;
4259
+ font-weight: 600;
4260
+ list-style: none;
4261
+ cursor: pointer;
4262
+ }
4263
+
4264
+ .blinq-action-details > summary::-webkit-details-marker {
4265
+ display: none;
4266
+ }
4267
+
4268
+ .blinq-code {
4269
+ margin-top: 10px;
4270
+ padding: 12px 14px;
4271
+ border-radius: 20px;
4272
+ border: 1px solid rgba(255, 255, 255, 0.56);
4273
+ background: rgba(255, 255, 255, 0.52);
4274
+ color: var(--blinq-text-soft);
4275
+ font-size: 12px;
4276
+ line-height: 1.5;
4277
+ white-space: pre-wrap;
4278
+ font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
4279
+ }
4280
+
4281
+ .blinq-action-state {
4282
+ margin-top: 12px;
4283
+ font-size: 12px;
4284
+ line-height: 1.4;
4285
+ color: var(--blinq-text-muted);
4286
+ }
4287
+
4288
+ .blinq-action-state[data-state="approved"] {
4289
+ color: var(--blinq-text-soft);
4290
+ }
4291
+
4292
+ .blinq-action-state[data-state="declined"] {
4293
+ color: var(--blinq-text-muted);
4294
+ }
4295
+
4296
+ .blinq-actions {
4297
+ display: flex;
4298
+ gap: 10px;
4299
+ margin-top: 14px;
4300
+ }
4301
+
4302
+ .blinq-actions > * {
4303
+ flex: 1;
4304
+ }
4305
+
4306
+ .blinq-badge-pill {
4307
+ display: inline-flex;
4308
+ align-items: center;
4309
+ justify-content: center;
4310
+ min-height: 30px;
4311
+ padding: 0 12px;
4312
+ border-radius: 999px;
4313
+ border: 1px solid rgba(255, 255, 255, 0.54);
4314
+ background: rgba(255, 255, 255, 0.46);
4315
+ font-size: 11px;
4316
+ font-weight: 600;
4317
+ letter-spacing: 0.02em;
4318
+ color: var(--blinq-text-soft);
4319
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.82);
4320
+ }
4321
+
4322
+ .blinq-badge-pill-default {
4323
+ background: rgba(255, 255, 255, 0.5);
4324
+ }
4325
+
4326
+ .blinq-badge-pill-outline {
4327
+ background: rgba(247, 248, 250, 0.34);
4328
+ color: var(--blinq-text-muted);
4329
+ }
4330
+
4331
+ .blinq-badge-pill-soft {
4332
+ background: rgba(255, 255, 255, 0.68);
4333
+ color: var(--blinq-text-soft);
4334
+ }
4335
+
4336
+ .blinq-badge-pill-accent {
4337
+ background: rgba(243, 245, 249, 0.84);
4338
+ color: var(--blinq-text);
4339
+ }
4340
+
4341
+ .blinq-composer {
4342
+ padding: 8px 18px 18px;
4343
+ }
4344
+
4345
+ .blinq-composer-controls {
4346
+ display: flex;
4347
+ }
4348
+
4349
+ .blinq-input-shell {
4350
+ position: relative;
4351
+ width: 100%;
4352
+ }
4353
+
4354
+ .blinq-input,
4355
+ .blinq-recording-input {
4356
+ width: 100%;
4357
+ min-width: 0;
4358
+ height: 58px;
4359
+ padding: 0 54px 0 54px;
4360
+ border-radius: 999px;
4361
+ border: 1px solid var(--blinq-glass-stroke);
4362
+ background: linear-gradient(180deg, rgba(255, 255, 255, 0.82), rgba(239, 242, 247, 0.54));
4363
+ color: var(--blinq-text);
4364
+ box-shadow:
4365
+ var(--blinq-inner-highlight),
4366
+ 0 10px 26px rgba(183, 189, 198, 0.16);
4367
+ font-size: 13px;
4368
+ outline: none;
4369
+ backdrop-filter: blur(22px) saturate(170%);
4370
+ -webkit-backdrop-filter: blur(22px) saturate(170%);
4371
+ }
4372
+
4373
+ .blinq-input::placeholder {
4374
+ color: var(--blinq-text-muted);
4375
+ }
4376
+
4377
+ .blinq-recording-input {
4378
+ display: flex;
4379
+ align-items: center;
4380
+ gap: 12px;
4381
+ }
4382
+
4383
+ .blinq-recording-time {
4384
+ flex: none;
4385
+ min-width: 42px;
4386
+ font-size: 12px;
4387
+ font-weight: 600;
4388
+ letter-spacing: 0.04em;
4389
+ color: var(--blinq-text-soft);
4390
+ font-variant-numeric: tabular-nums;
4391
+ }
4392
+
4393
+ .blinq-recording-wave-shell {
4394
+ position: relative;
4395
+ display: flex;
4396
+ align-items: center;
4397
+ flex: 1 1 auto;
4398
+ min-width: 0;
4399
+ height: 30px;
4400
+ padding: 0 10px;
4401
+ border-radius: 999px;
4402
+ border: 1px solid rgba(255, 255, 255, 0.54);
4403
+ background:
4404
+ linear-gradient(180deg, rgba(255, 255, 255, 0.54), rgba(242, 245, 248, 0.34));
4405
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.84);
4406
+ overflow: hidden;
4407
+ }
4408
+
4409
+ .blinq-recording-wave-shell::before {
4410
+ content: "";
4411
+ position: absolute;
4412
+ left: 10px;
4413
+ right: 10px;
4414
+ top: 50%;
4415
+ height: 1px;
4416
+ border-radius: 999px;
4417
+ background: linear-gradient(90deg, transparent, rgba(17, 17, 17, 0.12), transparent);
4418
+ transform: translateY(-50%);
4419
+ pointer-events: none;
4420
+ }
4421
+
4422
+ .blinq-recording-waveform {
4423
+ position: relative;
4424
+ display: flex;
4425
+ align-items: center;
4426
+ gap: 4px;
4427
+ flex: 1;
4428
+ min-width: 0;
4429
+ height: 100%;
4430
+ overflow: hidden;
4431
+ }
4432
+
4433
+ .blinq-recording-waveform-bar {
4434
+ width: 4px;
4435
+ min-width: 4px;
4436
+ height: 62%;
4437
+ border-radius: 999px;
4438
+ background: linear-gradient(180deg, rgba(17, 17, 17, 0.14), rgba(17, 17, 17, 0.36));
4439
+ transform-origin: center;
4440
+ transition:
4441
+ transform 120ms ease,
4442
+ opacity 160ms ease;
4443
+ opacity: 0.92;
4444
+ box-shadow:
4445
+ 0 0 0 1px rgba(255, 255, 255, 0.26),
4446
+ 0 2px 8px rgba(17, 17, 17, 0.08);
4447
+ }
4448
+
4449
+ .blinq-button {
4450
+ display: inline-flex;
4451
+ align-items: center;
4452
+ justify-content: center;
4453
+ gap: 8px;
4454
+ border: 1px solid transparent;
4455
+ border-radius: 999px;
4456
+ color: var(--blinq-text);
4457
+ font-size: 14px;
4458
+ font-weight: 600;
4459
+ background: linear-gradient(180deg, rgba(255, 255, 255, 0.72), rgba(236, 239, 244, 0.5));
4460
+ box-shadow: var(--blinq-shadow-soft);
4461
+ backdrop-filter: blur(20px) saturate(170%);
4462
+ -webkit-backdrop-filter: blur(20px) saturate(170%);
4463
+ transition:
4464
+ transform 160ms ease,
4465
+ box-shadow 180ms ease,
4466
+ border-color 180ms ease,
4467
+ background 180ms ease,
4468
+ opacity 120ms ease;
4469
+ cursor: pointer;
4470
+ outline: none;
4471
+ }
4472
+
4473
+ .blinq-button:hover:not(:disabled) {
4474
+ transform: translateY(-1px);
4475
+ border-color: rgba(255, 255, 255, 0.82);
4476
+ box-shadow:
4477
+ 0 14px 28px rgba(175, 181, 191, 0.22),
4478
+ 0 4px 10px rgba(189, 195, 204, 0.16);
4479
+ }
4480
+
4481
+ .blinq-input-mic:hover:not(:disabled),
4482
+ .blinq-input-send:hover:not(:disabled) {
4483
+ transform: translateY(-50%);
4484
+ border-color: rgba(255, 255, 255, 0.82);
4485
+ box-shadow:
4486
+ 0 14px 28px rgba(175, 181, 191, 0.16),
4487
+ 0 4px 10px rgba(189, 195, 204, 0.12);
4488
+ }
4489
+
4490
+ .blinq-button:disabled {
4491
+ opacity: 0.52;
4492
+ cursor: not-allowed;
4493
+ }
4494
+
4495
+ .blinq-button:focus-visible,
4496
+ .blinq-input:focus-visible {
4497
+ box-shadow:
4498
+ 0 0 0 3px rgba(255, 255, 255, 0.68),
4499
+ 0 0 0 6px rgba(17, 17, 17, 0.08);
4500
+ }
4501
+
4502
+ .blinq-button-default {
4503
+ border-color: rgba(255, 255, 255, 0.74);
4504
+ background: linear-gradient(180deg, rgba(255, 255, 255, 0.84), rgba(237, 241, 247, 0.66));
4505
+ color: var(--blinq-text);
4506
+ }
4507
+
4508
+ .blinq-button-outline,
4509
+ .blinq-button-ghost {
4510
+ border-color: rgba(255, 255, 255, 0.58);
4511
+ background: rgba(255, 255, 255, 0.42);
4512
+ color: var(--blinq-text-soft);
4513
+ }
4514
+
4515
+ .blinq-button-destructive {
4516
+ border-color: rgba(255, 255, 255, 0.58);
4517
+ background: linear-gradient(180deg, rgba(248, 249, 251, 0.7), rgba(230, 233, 239, 0.54));
4518
+ color: var(--blinq-text);
4519
+ }
4520
+
4521
+ .blinq-button-md {
4522
+ height: 44px;
4523
+ padding: 0 16px;
4524
+ }
4525
+
4526
+ .blinq-button-sm {
4527
+ height: 38px;
4528
+ padding: 0 13px;
4529
+ font-size: 13px;
4530
+ }
4531
+
4532
+ .blinq-button-icon {
4533
+ width: 48px;
4534
+ height: 48px;
4535
+ padding: 0;
4536
+ }
4537
+
4538
+ .blinq-button-icon-sm {
4539
+ width: 38px;
4540
+ height: 38px;
4541
+ padding: 0;
4542
+ }
4543
+
4544
+ .blinq-input-mic,
4545
+ .blinq-input-send {
4546
+ position: absolute;
4547
+ top: 50%;
4548
+ z-index: 2;
4549
+ width: 42px;
4550
+ height: 42px;
4551
+ min-width: 42px;
4552
+ transform: translateY(-50%);
4553
+ }
4554
+
4555
+ .blinq-input-mic {
4556
+ left: 8px;
4557
+ }
4558
+
4559
+ .blinq-input-send {
4560
+ right: 8px;
4561
+ }
4562
+
4563
+ .blinq-panel {
4564
+ display: flex;
4565
+ flex-direction: column;
4566
+ height: min(720px, calc(100vh - 64px));
4567
+ max-width: 520px;
4568
+ border: 1px solid rgba(226, 232, 240, 0.96);
4569
+ border-radius: 30px;
4570
+ background: #ffffff;
4571
+ box-shadow:
4572
+ 0 28px 80px rgba(15, 23, 42, 0.14),
4573
+ 0 10px 28px rgba(15, 23, 42, 0.08);
4574
+ backdrop-filter: none;
4575
+ -webkit-backdrop-filter: none;
4576
+ }
4577
+
4578
+ .blinq-panel::before,
4579
+ .blinq-panel::after,
4580
+ .blinq-message::before,
4581
+ .blinq-status-line::before {
4582
+ display: none;
4583
+ }
4584
+
4585
+ .blinq-header {
4586
+ flex: none;
4587
+ gap: 0;
4588
+ padding: 22px 24px 18px;
4589
+ border-bottom: 1px solid rgba(226, 232, 240, 0.86);
4590
+ background: #ffffff;
4591
+ }
4592
+
4593
+ .blinq-header-row {
4594
+ align-items: center;
4595
+ gap: 14px;
4596
+ }
4597
+
4598
+ .blinq-header-copy {
4599
+ gap: 5px;
4600
+ }
4601
+
4602
+ .blinq-heading {
4603
+ font-size: 22px;
4604
+ line-height: 1.05;
4605
+ font-weight: 700;
4606
+ letter-spacing: -0.04em;
4607
+ color: #111827;
4608
+ }
4609
+
4610
+ .blinq-status-line {
4611
+ display: block;
4612
+ max-width: 100%;
4613
+ min-height: 0;
4614
+ padding: 0;
4615
+ border: 0;
4616
+ background: transparent;
4617
+ box-shadow: none;
4618
+ color: #6b7280;
4619
+ font-size: 13px;
4620
+ line-height: 1.35;
4621
+ backdrop-filter: none;
4622
+ -webkit-backdrop-filter: none;
4623
+ }
4624
+
4625
+ .blinq-avatar {
4626
+ position: relative;
4627
+ display: inline-flex;
4628
+ align-items: center;
4629
+ justify-content: center;
4630
+ width: 64px;
4631
+ min-width: 64px;
4632
+ height: 64px;
4633
+ overflow: visible;
4634
+ border: 1px solid rgba(226, 232, 240, 0.95);
4635
+ border-radius: 999px;
4636
+ background:
4637
+ radial-gradient(circle at 30% 20%, rgba(255, 255, 255, 0.98), rgba(248, 250, 252, 0.86)),
4638
+ #ffffff;
4639
+ box-shadow:
4640
+ 0 14px 26px rgba(15, 23, 42, 0.08),
4641
+ inset 0 1px 0 rgba(255, 255, 255, 0.9);
4642
+ color: #111827;
4643
+ flex: none;
4644
+ }
4645
+
4646
+ .blinq-avatar-image {
4647
+ width: 100%;
4648
+ height: 100%;
4649
+ border-radius: inherit;
4650
+ object-fit: cover;
4651
+ }
4652
+
4653
+ .blinq-avatar-icon {
4654
+ color: #111827;
4655
+ }
4656
+
4657
+ .blinq-avatar-status {
4658
+ position: absolute;
4659
+ right: 5px;
4660
+ bottom: 6px;
4661
+ width: 11px;
4662
+ height: 11px;
4663
+ border: 2px solid #ffffff;
4664
+ border-radius: 999px;
4665
+ background: #21d262;
4666
+ box-shadow: 0 0 0 1px rgba(15, 23, 42, 0.04);
4667
+ }
4668
+
4669
+ .blinq-avatar-label {
4670
+ display: none;
4671
+ }
4672
+
4673
+ .blinq-thread {
4674
+ display: flex;
4675
+ flex: 1 1 auto;
4676
+ min-height: 0;
4677
+ background: #ffffff;
4678
+ }
4679
+
4680
+ .blinq-thread-viewport {
4681
+ flex: 1 1 auto;
4682
+ height: 100%;
4683
+ }
4684
+
4685
+ .blinq-scroll {
4686
+ flex: 1 1 auto;
4687
+ gap: 12px;
4688
+ max-height: none;
4689
+ min-height: 0;
4690
+ padding: 30px 24px 20px;
4691
+ background: #ffffff;
4692
+ }
4693
+
4694
+ .blinq-message {
4695
+ max-width: 82%;
4696
+ padding: 10px 15px;
4697
+ border: 1px solid rgba(226, 232, 240, 0.96);
4698
+ border-radius: 18px;
4699
+ background: #ffffff;
4700
+ box-shadow: none;
4701
+ color: #111827;
4702
+ font-size: 15px;
4703
+ line-height: 1.48;
4704
+ backdrop-filter: none;
4705
+ -webkit-backdrop-filter: none;
4706
+ }
4707
+
4708
+ .blinq-message[data-role="assistant"] {
4709
+ background: #ffffff;
4710
+ }
4711
+
4712
+ .blinq-message[data-role="user"] {
4713
+ border-color: rgba(209, 213, 219, 0.96);
4714
+ background: #f8fafc;
4715
+ }
4716
+
4717
+ .blinq-card,
4718
+ .blinq-guide-step-shell,
4719
+ .blinq-plan-step {
4720
+ border-color: rgba(226, 232, 240, 0.92);
4721
+ background: #ffffff;
4722
+ box-shadow: none;
4723
+ backdrop-filter: none;
4724
+ -webkit-backdrop-filter: none;
4725
+ }
4726
+
4727
+ .blinq-composer {
4728
+ flex: none;
4729
+ padding: 18px 24px 8px;
4730
+ border-top: 1px solid rgba(226, 232, 240, 0.86);
4731
+ background: #ffffff;
4732
+ }
4733
+
4734
+ .blinq-input,
4735
+ .blinq-recording-input {
4736
+ height: 56px;
4737
+ padding: 0 60px 0 54px;
4738
+ border: 1px solid rgba(209, 213, 219, 0.92);
4739
+ border-radius: 999px;
4740
+ background: #ffffff;
4741
+ box-shadow: none;
4742
+ color: #111827;
4743
+ font-size: 15px;
4744
+ backdrop-filter: none;
4745
+ -webkit-backdrop-filter: none;
4746
+ }
4747
+
4748
+ .blinq-input::placeholder {
4749
+ color: #9ca3af;
4750
+ }
4751
+
4752
+ .blinq-input-mic {
4753
+ left: 7px;
4754
+ width: 42px;
4755
+ min-width: 42px;
4756
+ height: 42px;
4757
+ border: 0;
4758
+ background: transparent;
4759
+ box-shadow: none;
4760
+ color: #6b7280;
4761
+ }
4762
+
4763
+ .blinq-input-send {
4764
+ right: 7px;
4765
+ width: 42px;
4766
+ min-width: 42px;
4767
+ height: 42px;
4768
+ border: 0;
4769
+ background: #6b6f76;
4770
+ box-shadow: none;
4771
+ color: #ffffff;
4772
+ }
4773
+
4774
+ .blinq-input-send:hover:not(:disabled) {
4775
+ transform: translateY(-50%);
4776
+ background: #4b5563;
4777
+ box-shadow: none;
4778
+ }
4779
+
4780
+ .blinq-button-ghost {
4781
+ border-color: transparent;
4782
+ background: transparent;
4783
+ box-shadow: none;
4784
+ }
4785
+
4786
+ .blinq-powered {
4787
+ flex: none;
4788
+ padding: 0 24px 18px;
4789
+ color: #c0c4ca;
4790
+ font-size: 10px;
4791
+ font-weight: 800;
4792
+ letter-spacing: 0.16em;
4793
+ line-height: 1;
4794
+ text-align: center;
4795
+ }
4796
+
4797
+ @keyframes blinq-thinking-pulse {
4798
+ 0%, 100% {
4799
+ opacity: 0.28;
4800
+ transform: translateY(0);
4801
+ }
4802
+
4803
+ 50% {
4804
+ opacity: 1;
4805
+ transform: translateY(-1.5px);
4806
+ }
4807
+ }
4808
+
4809
+ @keyframes blinq-copy-reveal {
4810
+ 0% {
4811
+ opacity: 0;
4812
+ transform: translateY(3px);
4813
+ }
4814
+
4815
+ 100% {
4816
+ opacity: 1;
4817
+ transform: translateY(0);
4818
+ }
4819
+ }
4820
+
4821
+ @keyframes blinq-orbit-drift {
4822
+ from {
4823
+ transform: rotate(0deg);
4824
+ }
4825
+
4826
+ to {
4827
+ transform: rotate(360deg);
4828
+ }
4829
+ }
4830
+
4831
+ @keyframes blinq-orbit-pulse {
4832
+ 0%, 100% {
4833
+ transform: scale(1);
4834
+ opacity: 0.9;
4835
+ }
4836
+
4837
+ 50% {
4838
+ transform: scale(1.16);
4839
+ opacity: 1;
4840
+ }
4841
+ }
4842
+
4843
+ @keyframes blinq-core-breathe {
4844
+ 0%, 100% {
4845
+ transform: scale(1);
4846
+ }
4847
+
4848
+ 50% {
4849
+ transform: scale(1.04);
4850
+ }
4851
+ }
4852
+
4853
+ @media (max-width: 720px) {
4854
+ .blinq-shell {
4855
+ right: 12px;
4856
+ left: 12px;
4857
+ bottom: 12px;
4858
+ width: auto;
4859
+ max-width: none;
4860
+ align-items: stretch;
4861
+ }
4862
+
4863
+ .blinq-shell[data-side="left"],
4864
+ .blinq-shell[data-side="right"] {
4865
+ right: 12px;
4866
+ left: 12px;
4867
+ align-items: stretch;
4868
+ }
4869
+
4870
+ .blinq-panel,
4871
+ .blinq-launcher {
4872
+ width: 100%;
4873
+ max-width: none;
4874
+ }
4875
+
4876
+ .blinq-launcher {
4877
+ width: 76px;
4878
+ min-width: 76px;
4879
+ height: 76px;
4880
+ align-self: flex-end;
4881
+ }
4882
+
4883
+ .blinq-message {
4884
+ max-width: 92%;
4885
+ }
4886
+
4887
+ .blinq-actions {
4888
+ flex-direction: column;
4889
+ }
4890
+
4891
+ .blinq-input,
4892
+ .blinq-recording-input {
4893
+ height: 56px;
4894
+ }
4895
+
4896
+ .blinq-panel {
4897
+ height: min(700px, calc(100vh - 24px));
4898
+ }
4899
+ }
4900
+ `;
4901
+
3168
4902
  export {
4903
+ collectNormalizedPageContext,
4904
+ detectNativeWebMcpSupport,
4905
+ PageToolRegistry,
4906
+ WidgetEmbedShell,
3169
4907
  BlinqWidget,
3170
4908
  init,
3171
4909
  initFromConfig,
3172
- createBlinqWidget
4910
+ createBlinqWidget,
4911
+ EMBED_WIDGET_STYLES
3173
4912
  };
3174
- //# sourceMappingURL=chunk-2BSH3PRA.js.map
4913
+ //# sourceMappingURL=chunk-DQF42RXH.js.map