browsertrack 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/.github/workflows/docs.yml +54 -0
  2. package/AGENTS.md +133 -0
  3. package/README.md +1 -1
  4. package/dist/{chunk-6A7FFDIB.js → chunk-6VA7GBAO.js} +29 -4
  5. package/dist/chunk-6VA7GBAO.js.map +1 -0
  6. package/dist/{chunk-ANMR5WBH.js → chunk-G2Y3CXCY.js} +2 -2
  7. package/dist/{chunk-BSKNG4V7.js → chunk-ILRYKMME.js} +30 -1
  8. package/dist/chunk-ILRYKMME.js.map +1 -0
  9. package/dist/{chunk-X7C5CHBO.js → chunk-SKCMT2DE.js} +637 -76
  10. package/dist/chunk-SKCMT2DE.js.map +1 -0
  11. package/dist/{chunk-ZLNGOOH2.js → chunk-SPCIROIU.js} +65 -3
  12. package/dist/chunk-SPCIROIU.js.map +1 -0
  13. package/dist/cli/index.js +115 -2
  14. package/dist/cli/index.js.map +1 -1
  15. package/dist/client/index.cjs +637 -75
  16. package/dist/client/index.d.ts +16 -2
  17. package/dist/client/index.js +2 -2
  18. package/dist/client.iife.js +393 -72
  19. package/dist/core/index.d.ts +12 -4
  20. package/dist/core/index.js +9 -3
  21. package/dist/daemon/index.d.ts +1 -1
  22. package/dist/daemon/index.js +3 -3
  23. package/dist/{engine-DKloFjvs.d.ts → engine-CeT9URuN.d.ts} +4 -0
  24. package/dist/index.d.ts +4 -3
  25. package/dist/index.js +13 -7
  26. package/dist/mcp/index.d.ts +2 -2
  27. package/dist/mcp/index.js +2 -2
  28. package/dist/{server-CN-se8td.d.ts → server-Dd8NX2Mk.d.ts} +1 -1
  29. package/docboot.config.js +16 -0
  30. package/docs/cli.md +51 -0
  31. package/docs/closed-loop-verification.md +57 -0
  32. package/docs/getting-started.md +122 -0
  33. package/docs/incidents-diagnostics.md +61 -0
  34. package/docs/index.md +46 -0
  35. package/docs/mcp-reference.md +128 -0
  36. package/docs/security-privacy.md +32 -0
  37. package/docs/visual-notes.md +67 -0
  38. package/package.json +6 -2
  39. package/packages/client/package.json +2 -2
  40. package/packages/client/src/notes/inspector.ts +689 -79
  41. package/packages/client/src/transport/websocket.ts +15 -0
  42. package/packages/core/package.json +3 -0
  43. package/packages/core/src/redaction.ts +40 -5
  44. package/packages/daemon/src/server/ws.ts +72 -1
  45. package/packages/daemon/src/session/manager.ts +21 -0
  46. package/packages/daemon/src/storage/db.ts +10 -1
  47. package/test/client/interceptors.test.ts +61 -0
  48. package/test/core/redaction.test.ts +12 -0
  49. package/dist/chunk-6A7FFDIB.js.map +0 -1
  50. package/dist/chunk-BSKNG4V7.js.map +0 -1
  51. package/dist/chunk-X7C5CHBO.js.map +0 -1
  52. package/dist/chunk-ZLNGOOH2.js.map +0 -1
  53. package/packages/core/dist/index.d.ts +0 -317
  54. package/packages/core/dist/index.js +0 -221
  55. /package/dist/{chunk-ANMR5WBH.js.map → chunk-G2Y3CXCY.js.map} +0 -0
@@ -2,7 +2,7 @@ import {
2
2
  getSemanticSelector,
3
3
  redactUrl,
4
4
  truncate
5
- } from "./chunk-6A7FFDIB.js";
5
+ } from "./chunk-6VA7GBAO.js";
6
6
 
7
7
  // packages/client/src/breadcrumbs.ts
8
8
  var BreadcrumbBuffer = class {
@@ -880,6 +880,7 @@ var WebSocketTransport = class {
880
880
  maxReconnectDelay = 1e4;
881
881
  reconnectTimer = null;
882
882
  commandHandler;
883
+ messageListeners = [];
883
884
  isDestroyed = false;
884
885
  constructor(options) {
885
886
  this.wsUrl = options.url || "ws://127.0.0.1:7331";
@@ -889,6 +890,12 @@ var WebSocketTransport = class {
889
890
  setCommandHandler(handler) {
890
891
  this.commandHandler = handler;
891
892
  }
893
+ onMessage(listener) {
894
+ this.messageListeners.push(listener);
895
+ return () => {
896
+ this.messageListeners = this.messageListeners.filter((l) => l !== listener);
897
+ };
898
+ }
892
899
  getSessionId() {
893
900
  return this.sessionId;
894
901
  }
@@ -912,6 +919,12 @@ var WebSocketTransport = class {
912
919
  const raw = typeof event.data === "string" ? event.data : "";
913
920
  if (!raw) return;
914
921
  const msg = JSON.parse(raw);
922
+ for (const listener of this.messageListeners) {
923
+ try {
924
+ listener(msg);
925
+ } catch {
926
+ }
927
+ }
915
928
  if (msg.type === "hello_ack") {
916
929
  this.sessionId = msg.sessionId;
917
930
  if (this.debug) {
@@ -1025,8 +1038,11 @@ var NoteInspector = class {
1025
1038
  highlightOverlay = null;
1026
1039
  regionOverlay = null;
1027
1040
  regionBox = null;
1041
+ regionBanner = null;
1042
+ markersContainer = null;
1028
1043
  toolbarElement = null;
1029
1044
  modalOverlay = null;
1045
+ cardOverlay = null;
1030
1046
  activeMode = "idle";
1031
1047
  hoveredElement = null;
1032
1048
  selectedElement = null;
@@ -1034,6 +1050,8 @@ var NoteInspector = class {
1034
1050
  isDraggingRegion = false;
1035
1051
  dragStartX = 0;
1036
1052
  dragStartY = 0;
1053
+ savedNotes = [];
1054
+ showMarkers = true;
1037
1055
  cleanups = [];
1038
1056
  constructor(transport, screenshotDriver, options = {}) {
1039
1057
  this.transport = transport;
@@ -1054,8 +1072,19 @@ var NoteInspector = class {
1054
1072
  } else {
1055
1073
  this.ensureContainer();
1056
1074
  }
1075
+ const unsubscribe = this.transport.onMessage((msg) => {
1076
+ if (msg && msg.type === "notes_sync" && Array.isArray(msg.notes)) {
1077
+ this.syncNotes(msg.notes);
1078
+ }
1079
+ });
1080
+ this.cleanups.push(unsubscribe);
1057
1081
  this.setupListeners();
1058
1082
  }
1083
+ syncNotes(notes) {
1084
+ this.savedNotes = notes;
1085
+ this.updateToolbarCount();
1086
+ this.renderMarkers();
1087
+ }
1059
1088
  setMode(mode) {
1060
1089
  this.activeMode = mode;
1061
1090
  this.updateToolbarState();
@@ -1083,16 +1112,17 @@ var NoteInspector = class {
1083
1112
  const style = document.createElement("style");
1084
1113
  style.textContent = `
1085
1114
  :host {
1086
- font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
1115
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
1087
1116
  color-scheme: dark;
1088
1117
  -webkit-font-smoothing: antialiased;
1118
+ -moz-osx-font-smoothing: grayscale;
1089
1119
  }
1090
1120
 
1091
1121
  /* 1. Element Highlight Overlay */
1092
1122
  .bt-highlight {
1093
1123
  position: fixed;
1094
1124
  border: 2px solid #3b82f6;
1095
- background: rgba(59, 130, 246, 0.15);
1125
+ background: rgba(59, 130, 246, 0.16);
1096
1126
  border-radius: 4px;
1097
1127
  pointer-events: none;
1098
1128
  transition: all 0.05s ease-out;
@@ -1102,18 +1132,19 @@ var NoteInspector = class {
1102
1132
 
1103
1133
  .bt-badge {
1104
1134
  position: absolute;
1105
- top: -24px;
1135
+ top: -26px;
1106
1136
  left: 0;
1107
- background: #1e293b;
1137
+ background: #0f172a;
1108
1138
  color: #38bdf8;
1109
1139
  border: 1px solid #3b82f6;
1110
1140
  font-size: 11px;
1111
1141
  font-weight: 600;
1112
- padding: 2px 6px;
1113
- border-radius: 3px;
1142
+ font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
1143
+ padding: 2px 7px;
1144
+ border-radius: 4px;
1114
1145
  white-space: nowrap;
1115
1146
  pointer-events: none;
1116
- box-shadow: 0 2px 4px rgba(0,0,0,0.3);
1147
+ box-shadow: 0 4px 6px -1px rgba(0,0,0,0.5);
1117
1148
  }
1118
1149
 
1119
1150
  /* 2. Region Selection Overlay */
@@ -1125,7 +1156,8 @@ var NoteInspector = class {
1125
1156
  cursor: crosshair;
1126
1157
  z-index: 2147483642;
1127
1158
  pointer-events: auto;
1128
- background: rgba(15, 23, 42, 0.2);
1159
+ background: rgba(15, 23, 42, 0.25);
1160
+ user-select: none;
1129
1161
  }
1130
1162
 
1131
1163
  .bt-region-box {
@@ -1139,32 +1171,171 @@ var NoteInspector = class {
1139
1171
 
1140
1172
  .bt-region-badge {
1141
1173
  position: absolute;
1142
- top: -24px;
1174
+ top: -26px;
1143
1175
  left: 0;
1144
1176
  background: #0f172a;
1145
1177
  color: #38bdf8;
1146
1178
  border: 1px solid #0284c7;
1147
1179
  font-size: 11px;
1148
1180
  font-weight: 600;
1149
- padding: 2px 6px;
1150
- border-radius: 3px;
1181
+ font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
1182
+ padding: 2px 7px;
1183
+ border-radius: 4px;
1151
1184
  white-space: nowrap;
1152
1185
  pointer-events: none;
1186
+ box-shadow: 0 4px 6px -1px rgba(0,0,0,0.5);
1187
+ }
1188
+
1189
+ .bt-region-banner {
1190
+ position: fixed;
1191
+ top: 20px;
1192
+ left: 50%;
1193
+ transform: translateX(-50%);
1194
+ background: #0f172a;
1195
+ color: #f8fafc;
1196
+ border: 1px solid #0284c7;
1197
+ border-radius: 30px;
1198
+ padding: 8px 16px;
1199
+ display: flex;
1200
+ align-items: center;
1201
+ gap: 12px;
1202
+ box-shadow: 0 10px 25px -5px rgba(0,0,0,0.6);
1203
+ font-size: 12.5px;
1204
+ font-weight: 500;
1205
+ pointer-events: auto;
1206
+ z-index: 2147483645;
1207
+ user-select: none;
1208
+ }
1209
+
1210
+ .bt-region-cancel-btn {
1211
+ background: rgba(239, 68, 68, 0.15);
1212
+ color: #fca5a5;
1213
+ border: 1px solid rgba(239, 68, 68, 0.4);
1214
+ padding: 3px 10px;
1215
+ border-radius: 20px;
1216
+ font-size: 11px;
1217
+ font-weight: 600;
1218
+ cursor: pointer;
1219
+ transition: all 0.15s ease;
1220
+ display: inline-flex;
1221
+ align-items: center;
1222
+ gap: 4px;
1223
+ font-family: inherit;
1224
+ }
1225
+
1226
+ .bt-region-cancel-btn:hover {
1227
+ background: rgba(239, 68, 68, 0.3);
1228
+ color: #ffffff;
1229
+ }
1230
+
1231
+ /* 3. Note Markers on Page */
1232
+ .bt-markers-layer {
1233
+ position: fixed;
1234
+ top: 0;
1235
+ left: 0;
1236
+ width: 0;
1237
+ height: 0;
1238
+ pointer-events: none;
1239
+ z-index: 2147483638;
1240
+ }
1241
+
1242
+ .bt-note-marker {
1243
+ position: fixed;
1244
+ pointer-events: auto;
1245
+ background: linear-gradient(135deg, #2563eb, #1d4ed8);
1246
+ color: #ffffff;
1247
+ border: 2px solid #ffffff;
1248
+ box-shadow: 0 4px 12px rgba(0,0,0,0.5), 0 0 0 1px rgba(37,99,235,0.4);
1249
+ border-radius: 999px;
1250
+ height: 26px;
1251
+ min-width: 26px;
1252
+ padding: 0 7px;
1253
+ display: inline-flex;
1254
+ align-items: center;
1255
+ justify-content: center;
1256
+ gap: 4px;
1257
+ cursor: pointer;
1258
+ font-size: 11px;
1259
+ font-weight: 700;
1260
+ user-select: none;
1261
+ transition: transform 0.15s cubic-bezier(0.16, 1, 0.3, 1), box-shadow 0.15s ease;
1262
+ animation: bt-pop-in 0.2s ease-out;
1263
+ box-sizing: border-box;
1264
+ z-index: 2147483641;
1265
+ }
1266
+
1267
+ @keyframes bt-pop-in {
1268
+ 0% { transform: scale(0.6); opacity: 0; }
1269
+ 100% { transform: scale(1); opacity: 1; }
1270
+ }
1271
+
1272
+ .bt-note-marker:hover {
1273
+ transform: scale(1.15) translateY(-2px);
1274
+ box-shadow: 0 8px 20px rgba(37,99,235,0.6), 0 0 0 2px #60a5fa;
1153
1275
  }
1154
1276
 
1155
- /* 3. Floating Quick Toolbar */
1277
+ .bt-marker-resolved {
1278
+ background: linear-gradient(135deg, #475569, #334155);
1279
+ border-color: #94a3b8;
1280
+ opacity: 0.75;
1281
+ }
1282
+
1283
+ .bt-region-marker-box {
1284
+ position: fixed;
1285
+ border: 2px dashed #0284c7;
1286
+ background: rgba(14, 165, 233, 0.08);
1287
+ pointer-events: none;
1288
+ box-sizing: border-box;
1289
+ border-radius: 6px;
1290
+ z-index: 2147483639;
1291
+ }
1292
+
1293
+ .bt-page-notes-dock {
1294
+ position: fixed;
1295
+ top: 16px;
1296
+ right: 16px;
1297
+ display: flex;
1298
+ flex-direction: column;
1299
+ gap: 6px;
1300
+ pointer-events: none;
1301
+ z-index: 2147483641;
1302
+ }
1303
+
1304
+ .bt-page-note-pill {
1305
+ background: #0f172a;
1306
+ color: #c084fc;
1307
+ border: 1px solid #7e22ce;
1308
+ border-radius: 20px;
1309
+ padding: 5px 12px;
1310
+ font-size: 11.5px;
1311
+ font-weight: 600;
1312
+ display: inline-flex;
1313
+ align-items: center;
1314
+ gap: 6px;
1315
+ box-shadow: 0 4px 12px rgba(0,0,0,0.5);
1316
+ cursor: pointer;
1317
+ pointer-events: auto;
1318
+ transition: all 0.15s ease;
1319
+ }
1320
+
1321
+ .bt-page-note-pill:hover {
1322
+ background: #1e1b4b;
1323
+ transform: translateY(-1px);
1324
+ }
1325
+
1326
+ /* 4. Floating Quick Toolbar */
1156
1327
  .bt-toolbar {
1157
1328
  position: fixed;
1158
1329
  bottom: 20px;
1159
1330
  right: 20px;
1160
- background: #1e293b;
1331
+ background: #0f172a;
1161
1332
  border: 1px solid #334155;
1162
1333
  border-radius: 30px;
1163
1334
  padding: 4px 6px;
1164
1335
  display: flex;
1165
1336
  align-items: center;
1166
1337
  gap: 4px;
1167
- box-shadow: 0 10px 15px -3px rgba(0,0,0,0.5), 0 4px 6px -4px rgba(0,0,0,0.5);
1338
+ box-shadow: 0 10px 25px -3px rgba(0,0,0,0.6), 0 4px 6px -4px rgba(0,0,0,0.4);
1168
1339
  pointer-events: auto;
1169
1340
  z-index: 2147483646;
1170
1341
  user-select: none;
@@ -1177,17 +1348,18 @@ var NoteInspector = class {
1177
1348
  color: #94a3b8;
1178
1349
  font-size: 12px;
1179
1350
  font-weight: 500;
1180
- padding: 6px 10px;
1351
+ padding: 6px 12px;
1181
1352
  border-radius: 20px;
1182
1353
  cursor: pointer;
1183
1354
  display: flex;
1184
1355
  align-items: center;
1185
- gap: 5px;
1356
+ gap: 6px;
1186
1357
  transition: all 0.15s ease;
1358
+ font-family: inherit;
1187
1359
  }
1188
1360
 
1189
1361
  .bt-toolbar-btn:hover {
1190
- background: #334155;
1362
+ background: #1e293b;
1191
1363
  color: #f8fafc;
1192
1364
  }
1193
1365
 
@@ -1195,15 +1367,27 @@ var NoteInspector = class {
1195
1367
  background: #2563eb;
1196
1368
  color: #ffffff;
1197
1369
  font-weight: 600;
1370
+ box-shadow: 0 2px 6px rgba(37, 99, 235, 0.35);
1371
+ }
1372
+
1373
+ .bt-count-pill {
1374
+ background: rgba(255, 255, 255, 0.2);
1375
+ color: #ffffff;
1376
+ font-size: 10px;
1377
+ font-weight: 700;
1378
+ padding: 1px 6px;
1379
+ border-radius: 10px;
1380
+ line-height: 1.2;
1198
1381
  }
1199
1382
 
1200
1383
  .bt-toolbar-divider {
1201
1384
  width: 1px;
1202
1385
  height: 16px;
1203
1386
  background: #334155;
1387
+ margin: 0 2px;
1204
1388
  }
1205
1389
 
1206
- /* 4. Modal Backdrop & Editor */
1390
+ /* 5. Modals & Popover Card */
1207
1391
  .bt-modal-backdrop {
1208
1392
  position: fixed;
1209
1393
  top: 0;
@@ -1211,7 +1395,7 @@ var NoteInspector = class {
1211
1395
  width: 100vw;
1212
1396
  height: 100vh;
1213
1397
  background: rgba(15, 23, 42, 0.75);
1214
- backdrop-filter: blur(4px);
1398
+ backdrop-filter: blur(6px);
1215
1399
  display: flex;
1216
1400
  align-items: center;
1217
1401
  justify-content: center;
@@ -1219,20 +1403,26 @@ var NoteInspector = class {
1219
1403
  z-index: 2147483647;
1220
1404
  opacity: 1;
1221
1405
  box-sizing: border-box;
1406
+ animation: bt-fade-in 0.15s ease-out;
1407
+ }
1408
+
1409
+ @keyframes bt-fade-in {
1410
+ from { opacity: 0; transform: scale(0.98); }
1411
+ to { opacity: 1; transform: scale(1); }
1222
1412
  }
1223
1413
 
1224
1414
  .bt-modal {
1225
- background: #1e293b;
1415
+ background: #0f172a;
1226
1416
  color: #f8fafc;
1227
1417
  border: 1px solid #334155;
1228
- border-radius: 12px;
1229
- padding: 18px;
1230
- width: 420px;
1231
- max-width: 90vw;
1232
- box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.7), 0 8px 10px -6px rgba(0, 0, 0, 0.7);
1418
+ border-radius: 14px;
1419
+ padding: 20px;
1420
+ width: 450px;
1421
+ max-width: 92vw;
1422
+ box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.8), 0 0 0 1px rgba(255, 255, 255, 0.05);
1233
1423
  display: flex;
1234
1424
  flex-direction: column;
1235
- gap: 12px;
1425
+ gap: 14px;
1236
1426
  box-sizing: border-box;
1237
1427
  }
1238
1428
 
@@ -1243,87 +1433,181 @@ var NoteInspector = class {
1243
1433
  }
1244
1434
 
1245
1435
  .bt-modal-title {
1246
- font-size: 14px;
1436
+ font-size: 14.5px;
1247
1437
  font-weight: 600;
1438
+ letter-spacing: -0.01em;
1248
1439
  display: flex;
1249
1440
  align-items: center;
1250
- gap: 6px;
1441
+ gap: 8px;
1251
1442
  color: #f8fafc;
1252
1443
  }
1253
1444
 
1254
1445
  .bt-mode-badge {
1255
1446
  font-size: 10px;
1256
1447
  font-weight: 700;
1448
+ letter-spacing: 0.05em;
1257
1449
  text-transform: uppercase;
1258
- background: rgba(59, 130, 246, 0.2);
1450
+ padding: 2px 7px;
1451
+ border-radius: 6px;
1452
+ }
1453
+
1454
+ .bt-badge-element {
1455
+ background: rgba(59, 130, 246, 0.15);
1259
1456
  color: #60a5fa;
1260
- border: 1px solid #3b82f6;
1261
- padding: 2px 6px;
1262
- border-radius: 4px;
1457
+ border: 1px solid rgba(59, 130, 246, 0.4);
1458
+ }
1459
+
1460
+ .bt-badge-region {
1461
+ background: rgba(14, 165, 233, 0.15);
1462
+ color: #38bdf8;
1463
+ border: 1px solid rgba(14, 165, 233, 0.4);
1464
+ }
1465
+
1466
+ .bt-badge-page {
1467
+ background: rgba(168, 85, 247, 0.15);
1468
+ color: #c084fc;
1469
+ border: 1px solid rgba(168, 85, 247, 0.4);
1470
+ }
1471
+
1472
+ .bt-badge-status-open {
1473
+ background: rgba(16, 185, 129, 0.15);
1474
+ color: #34d399;
1475
+ border: 1px solid rgba(16, 185, 129, 0.4);
1476
+ }
1477
+
1478
+ .bt-badge-status-resolved {
1479
+ background: rgba(100, 116, 139, 0.2);
1480
+ color: #94a3b8;
1481
+ border: 1px solid rgba(100, 116, 139, 0.4);
1263
1482
  }
1264
1483
 
1265
1484
  .bt-close-btn {
1266
1485
  background: transparent;
1267
1486
  border: none;
1268
1487
  color: #94a3b8;
1269
- font-size: 16px;
1488
+ font-size: 15px;
1270
1489
  cursor: pointer;
1271
- padding: 2px 6px;
1272
- border-radius: 4px;
1490
+ padding: 3px 7px;
1491
+ border-radius: 6px;
1492
+ transition: all 0.12s ease;
1493
+ display: flex;
1494
+ align-items: center;
1495
+ justify-content: center;
1273
1496
  }
1274
1497
  .bt-close-btn:hover {
1275
- background: #334155;
1498
+ background: #1e293b;
1276
1499
  color: #ffffff;
1277
1500
  }
1278
1501
 
1279
1502
  .bt-target-pill {
1280
- background: #0f172a;
1503
+ background: #090d16;
1281
1504
  color: #94a3b8;
1282
- border: 1px solid #334155;
1283
- border-radius: 6px;
1284
- padding: 6px 10px;
1505
+ border: 1px solid #1e293b;
1506
+ border-radius: 8px;
1507
+ padding: 8px 12px;
1285
1508
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
1286
- font-size: 11px;
1509
+ font-size: 11.5px;
1510
+ display: flex;
1511
+ align-items: center;
1512
+ gap: 8px;
1513
+ overflow: hidden;
1514
+ }
1515
+
1516
+ .bt-pill-content {
1287
1517
  overflow: hidden;
1288
1518
  text-overflow: ellipsis;
1289
1519
  white-space: nowrap;
1520
+ color: #cbd5e1;
1521
+ }
1522
+
1523
+ .bt-note-message-box {
1524
+ background: #090d16;
1525
+ border: 1px solid #1e293b;
1526
+ border-radius: 8px;
1527
+ padding: 12px 14px;
1528
+ font-size: 13.5px;
1529
+ line-height: 1.5;
1530
+ color: #f1f5f9;
1531
+ white-space: pre-wrap;
1532
+ word-break: break-word;
1533
+ max-height: 180px;
1534
+ overflow-y: auto;
1290
1535
  }
1291
1536
 
1292
1537
  .bt-textarea {
1293
- background: #0f172a;
1538
+ background: #090d16;
1294
1539
  color: #f8fafc;
1295
1540
  border: 1px solid #334155;
1296
- border-radius: 6px;
1297
- padding: 10px;
1298
- font-size: 13px;
1541
+ border-radius: 8px;
1542
+ padding: 12px;
1543
+ font-size: 13.5px;
1544
+ line-height: 1.5;
1299
1545
  resize: vertical;
1300
- min-height: 85px;
1546
+ min-height: 95px;
1301
1547
  outline: none;
1302
1548
  box-sizing: border-box;
1303
1549
  width: 100%;
1304
1550
  font-family: inherit;
1551
+ transition: border-color 0.15s ease, box-shadow 0.15s ease;
1552
+ }
1553
+
1554
+ .bt-textarea::placeholder {
1555
+ color: #64748b;
1305
1556
  }
1306
1557
 
1307
1558
  .bt-textarea:focus {
1308
1559
  border-color: #3b82f6;
1309
- box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.25);
1560
+ box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.25);
1561
+ }
1562
+
1563
+ .bt-modal-footer {
1564
+ display: flex;
1565
+ justify-content: space-between;
1566
+ align-items: center;
1567
+ gap: 12px;
1568
+ margin-top: 2px;
1569
+ }
1570
+
1571
+ .bt-kbd-hint {
1572
+ font-size: 11px;
1573
+ color: #64748b;
1574
+ display: flex;
1575
+ align-items: center;
1576
+ gap: 4px;
1577
+ user-select: none;
1578
+ }
1579
+
1580
+ .bt-kbd-hint kbd {
1581
+ background: #1e293b;
1582
+ color: #94a3b8;
1583
+ border: 1px solid #334155;
1584
+ border-radius: 4px;
1585
+ padding: 1px 5px;
1586
+ font-family: inherit;
1587
+ font-size: 10px;
1588
+ font-weight: 600;
1310
1589
  }
1311
1590
 
1312
1591
  .bt-modal-actions {
1313
1592
  display: flex;
1314
1593
  justify-content: flex-end;
1594
+ align-items: center;
1315
1595
  gap: 8px;
1316
1596
  }
1317
1597
 
1318
1598
  .bt-btn {
1319
- padding: 8px 14px;
1320
- border-radius: 6px;
1321
- font-size: 12px;
1599
+ padding: 8px 16px;
1600
+ border-radius: 7px;
1601
+ font-size: 12.5px;
1322
1602
  font-weight: 600;
1323
1603
  cursor: pointer;
1324
1604
  border: 1px solid transparent;
1325
- transition: all 0.1s ease;
1605
+ transition: all 0.15s ease;
1326
1606
  font-family: inherit;
1607
+ display: inline-flex;
1608
+ align-items: center;
1609
+ justify-content: center;
1610
+ gap: 6px;
1327
1611
  }
1328
1612
 
1329
1613
  .bt-btn-cancel {
@@ -1331,20 +1615,38 @@ var NoteInspector = class {
1331
1615
  color: #94a3b8;
1332
1616
  }
1333
1617
  .bt-btn-cancel:hover {
1334
- background: #334155;
1618
+ background: #1e293b;
1335
1619
  color: #f8fafc;
1336
1620
  }
1337
1621
 
1338
1622
  .bt-btn-save {
1339
1623
  background: #2563eb;
1340
1624
  color: #ffffff;
1625
+ box-shadow: 0 2px 6px rgba(37, 99, 235, 0.35);
1341
1626
  }
1342
1627
  .bt-btn-save:hover {
1343
1628
  background: #1d4ed8;
1629
+ box-shadow: 0 4px 10px rgba(37, 99, 235, 0.45);
1630
+ }
1631
+
1632
+ .bt-btn-resolve {
1633
+ background: rgba(16, 185, 129, 0.15);
1634
+ color: #6ee7b7;
1635
+ border: 1px solid rgba(16, 185, 129, 0.35);
1636
+ }
1637
+ .bt-btn-resolve:hover {
1638
+ background: rgba(16, 185, 129, 0.3);
1639
+ color: #ffffff;
1640
+ }
1641
+
1642
+ .bt-btn-delete {
1643
+ background: rgba(239, 68, 68, 0.15);
1644
+ color: #fca5a5;
1645
+ border: 1px solid rgba(239, 68, 68, 0.35);
1344
1646
  }
1345
- .bt-btn-save:disabled {
1346
- opacity: 0.6;
1347
- cursor: not-allowed;
1647
+ .bt-btn-delete:hover {
1648
+ background: rgba(239, 68, 68, 0.3);
1649
+ color: #ffffff;
1348
1650
  }
1349
1651
  `;
1350
1652
  this.shadowRoot.appendChild(style);
@@ -1352,6 +1654,9 @@ var NoteInspector = class {
1352
1654
  this.highlightOverlay.className = "bt-highlight";
1353
1655
  this.highlightOverlay.style.display = "none";
1354
1656
  this.shadowRoot.appendChild(this.highlightOverlay);
1657
+ this.markersContainer = document.createElement("div");
1658
+ this.markersContainer.className = "bt-markers-layer";
1659
+ this.shadowRoot.appendChild(this.markersContainer);
1355
1660
  if (this.options.showToolbar) {
1356
1661
  this.createToolbar();
1357
1662
  }
@@ -1378,19 +1683,33 @@ var NoteInspector = class {
1378
1683
  <button class="bt-toolbar-btn" id="bt-mode-page" title="Leave full-page note">
1379
1684
  <span>\u{1F4C4}</span> Page
1380
1685
  </button>
1686
+ <div class="bt-toolbar-divider"></div>
1687
+ <button class="bt-toolbar-btn active" id="bt-toggle-notes" title="Toggle visible note markers on screen">
1688
+ <span>\u{1F4CC}</span> Notes <span class="bt-count-pill" id="bt-notes-count">0</span>
1689
+ </button>
1381
1690
  `;
1382
1691
  const btnElement = this.toolbarElement.querySelector("#bt-mode-element");
1383
1692
  const btnRegion = this.toolbarElement.querySelector("#bt-mode-region");
1384
1693
  const btnPage = this.toolbarElement.querySelector("#bt-mode-page");
1385
- btnElement.onclick = () => {
1694
+ const btnToggleNotes = this.toolbarElement.querySelector("#bt-toggle-notes");
1695
+ btnElement.onclick = (e) => {
1696
+ e.stopPropagation();
1386
1697
  this.setMode(this.activeMode === "element" ? "idle" : "element");
1387
1698
  };
1388
- btnRegion.onclick = () => {
1699
+ btnRegion.onclick = (e) => {
1700
+ e.stopPropagation();
1389
1701
  this.setMode(this.activeMode === "region" ? "idle" : "region");
1390
1702
  };
1391
- btnPage.onclick = () => {
1703
+ btnPage.onclick = (e) => {
1704
+ e.stopPropagation();
1392
1705
  this.setMode("page");
1393
1706
  };
1707
+ btnToggleNotes.onclick = (e) => {
1708
+ e.stopPropagation();
1709
+ this.showMarkers = !this.showMarkers;
1710
+ btnToggleNotes.classList.toggle("active", this.showMarkers);
1711
+ this.renderMarkers();
1712
+ };
1394
1713
  this.shadowRoot.appendChild(this.toolbarElement);
1395
1714
  }
1396
1715
  updateToolbarState() {
@@ -1402,9 +1721,186 @@ var NoteInspector = class {
1402
1721
  btnRegion?.classList.toggle("active", this.activeMode === "region");
1403
1722
  btnPage?.classList.toggle("active", this.activeMode === "page");
1404
1723
  }
1724
+ updateToolbarCount() {
1725
+ if (!this.toolbarElement) return;
1726
+ const countEl = this.toolbarElement.querySelector("#bt-notes-count");
1727
+ if (countEl) {
1728
+ const openCount = this.savedNotes.filter((n) => n.status === "OPEN").length;
1729
+ countEl.textContent = String(openCount);
1730
+ }
1731
+ }
1732
+ renderMarkers() {
1733
+ const root = this.ensureContainer();
1734
+ if (!root || !this.markersContainer) return;
1735
+ this.markersContainer.innerHTML = "";
1736
+ if (!this.showMarkers) return;
1737
+ const currentPath = window.location.pathname;
1738
+ const activeNotes = this.savedNotes.filter(
1739
+ (n) => n.status === "OPEN" && (n.route === currentPath || !n.route || n.route === "/" || window.location.href.includes(n.route))
1740
+ );
1741
+ const pageNotes = [];
1742
+ activeNotes.forEach((note, index) => {
1743
+ if (note.type === "page") {
1744
+ pageNotes.push(note);
1745
+ return;
1746
+ }
1747
+ if (note.type === "region" && note.region) {
1748
+ const regBox = document.createElement("div");
1749
+ regBox.className = "bt-region-marker-box";
1750
+ regBox.style.left = `${note.region.x}px`;
1751
+ regBox.style.top = `${note.region.y}px`;
1752
+ regBox.style.width = `${note.region.width}px`;
1753
+ regBox.style.height = `${note.region.height}px`;
1754
+ this.markersContainer.appendChild(regBox);
1755
+ const pin = document.createElement("div");
1756
+ pin.className = "bt-note-marker";
1757
+ pin.style.left = `${Math.max(4, note.region.x - 12)}px`;
1758
+ pin.style.top = `${Math.max(4, note.region.y - 12)}px`;
1759
+ pin.title = note.message;
1760
+ pin.innerHTML = `<span>\u{1F4D0}</span> <span>#${index + 1}</span>`;
1761
+ pin.onclick = (e) => {
1762
+ e.stopPropagation();
1763
+ this.openNoteCard(note);
1764
+ };
1765
+ this.markersContainer.appendChild(pin);
1766
+ return;
1767
+ }
1768
+ let targetEl = null;
1769
+ if (note.target?.selector) {
1770
+ try {
1771
+ targetEl = document.querySelector(note.target.selector);
1772
+ } catch {
1773
+ }
1774
+ }
1775
+ const rect = targetEl ? targetEl.getBoundingClientRect() : note.target?.boundingRect;
1776
+ if (rect) {
1777
+ const pin = document.createElement("div");
1778
+ pin.className = "bt-note-marker";
1779
+ pin.setAttribute("data-note-id", note.id);
1780
+ pin.title = note.message;
1781
+ pin.style.left = `${Math.max(4, rect.left - 10)}px`;
1782
+ pin.style.top = `${Math.max(4, rect.top - 12)}px`;
1783
+ pin.innerHTML = `<span>\u{1F4DD}</span> <span>#${index + 1}</span>`;
1784
+ pin.onclick = (e) => {
1785
+ e.stopPropagation();
1786
+ this.openNoteCard(note);
1787
+ };
1788
+ if (targetEl) {
1789
+ pin.onmouseenter = () => this.updateHighlight(targetEl);
1790
+ pin.onmouseleave = () => this.hideHighlight();
1791
+ }
1792
+ this.markersContainer.appendChild(pin);
1793
+ }
1794
+ });
1795
+ if (pageNotes.length > 0) {
1796
+ const pageDock = document.createElement("div");
1797
+ pageDock.className = "bt-page-notes-dock";
1798
+ pageNotes.forEach((pNote, idx) => {
1799
+ const pill = document.createElement("div");
1800
+ pill.className = "bt-page-note-pill";
1801
+ pill.innerHTML = `<span>\u{1F4C4}</span> <span>Page Note (${truncate(pNote.message, 25)})</span>`;
1802
+ pill.onclick = (e) => {
1803
+ e.stopPropagation();
1804
+ this.openNoteCard(pNote);
1805
+ };
1806
+ pageDock.appendChild(pill);
1807
+ });
1808
+ this.markersContainer.appendChild(pageDock);
1809
+ }
1810
+ }
1811
+ updateMarkerPositions() {
1812
+ if (!this.showMarkers || !this.markersContainer) return;
1813
+ this.renderMarkers();
1814
+ }
1815
+ openNoteCard(note) {
1816
+ const root = this.ensureContainer();
1817
+ if (!root) return;
1818
+ if (this.cardOverlay && this.cardOverlay.parentElement) {
1819
+ this.cardOverlay.parentElement.removeChild(this.cardOverlay);
1820
+ this.cardOverlay = null;
1821
+ }
1822
+ const backdrop = document.createElement("div");
1823
+ backdrop.className = "bt-modal-backdrop";
1824
+ this.cardOverlay = backdrop;
1825
+ const badgeClass = `bt-badge-${note.type.toLowerCase()}`;
1826
+ const statusClass = note.status === "OPEN" ? "bt-badge-status-open" : "bt-badge-status-resolved";
1827
+ const icon = note.type === "region" ? "\u{1F4D0}" : note.type === "page" ? "\u{1F4C4}" : "\u{1F3AF}";
1828
+ const contextText = note.type === "region" && note.region ? `Region: ${note.region.width} \xD7 ${note.region.height} px \xB7 Route: ${note.route}` : note.type === "page" ? `Page Note \xB7 Route: ${note.route}` : `${note.target?.selector || "Element"} (${note.target?.boundingRect?.width || 0}\xD7${note.target?.boundingRect?.height || 0}px) \xB7 ${note.route}`;
1829
+ const formattedDate = new Date(note.createdAt).toLocaleString();
1830
+ backdrop.innerHTML = `
1831
+ <div class="bt-modal">
1832
+ <div class="bt-modal-header">
1833
+ <div class="bt-modal-title">
1834
+ <span>${icon} Visual Note Details</span>
1835
+ <span class="bt-mode-badge ${badgeClass}">${note.type.toUpperCase()}</span>
1836
+ <span class="bt-mode-badge ${statusClass}">${note.status}</span>
1837
+ </div>
1838
+ <button class="bt-close-btn" id="btn-card-close" title="Close (Esc)">\u2715</button>
1839
+ </div>
1840
+
1841
+ <div class="bt-target-pill" title="${contextText}">
1842
+ <span>\u{1F3F7}\uFE0F</span>
1843
+ <span class="bt-pill-content">${contextText}</span>
1844
+ </div>
1845
+
1846
+ <div class="bt-note-message-box">${note.message}</div>
1847
+
1848
+ <div style="font-size: 11px; color: #64748b; display: flex; justify-content: space-between; padding: 0 2px;">
1849
+ <span>Created: ${formattedDate}</span>
1850
+ <span>ID: <code style="font-family: monospace; color: #94a3b8;">${note.id}</code></span>
1851
+ </div>
1852
+
1853
+ <div class="bt-modal-footer">
1854
+ <button class="bt-btn bt-btn-delete" id="btn-card-delete" title="Delete this note">
1855
+ <span>\u{1F5D1}\uFE0F</span> Delete
1856
+ </button>
1857
+ <div class="bt-modal-actions">
1858
+ <button class="bt-btn bt-btn-cancel" id="btn-card-dismiss">Close</button>
1859
+ <button class="bt-btn ${note.status === "OPEN" ? "bt-btn-resolve" : "bt-btn-save"}" id="btn-card-resolve">
1860
+ ${note.status === "OPEN" ? "<span>\u2705</span> Resolve Note" : "<span>\u21BA</span> Reopen"}
1861
+ </button>
1862
+ </div>
1863
+ </div>
1864
+ </div>
1865
+ `;
1866
+ const btnClose = backdrop.querySelector("#btn-card-close");
1867
+ const btnDismiss = backdrop.querySelector("#btn-card-dismiss");
1868
+ const btnResolve = backdrop.querySelector("#btn-card-resolve");
1869
+ const btnDelete = backdrop.querySelector("#btn-card-delete");
1870
+ const closeCard = () => {
1871
+ if (this.cardOverlay) {
1872
+ root.removeChild(this.cardOverlay);
1873
+ this.cardOverlay = null;
1874
+ this.hideHighlight();
1875
+ }
1876
+ };
1877
+ btnClose.onclick = closeCard;
1878
+ btnDismiss.onclick = closeCard;
1879
+ backdrop.onclick = (e) => {
1880
+ if (e.target === backdrop) closeCard();
1881
+ };
1882
+ btnResolve.onclick = () => {
1883
+ if (note.status === "OPEN") {
1884
+ this.transport.send({ type: "resolve_note", noteId: note.id });
1885
+ } else {
1886
+ this.transport.send({ type: "reopen_note", noteId: note.id });
1887
+ }
1888
+ closeCard();
1889
+ };
1890
+ btnDelete.onclick = () => {
1891
+ this.transport.send({ type: "delete_note", noteId: note.id });
1892
+ closeCard();
1893
+ };
1894
+ root.appendChild(backdrop);
1895
+ }
1405
1896
  setupListeners() {
1406
1897
  const onMouseMove = (e) => {
1407
- if (this.modalOverlay || this.isDraggingRegion || this.activeMode === "region") return;
1898
+ if (this.modalOverlay || this.cardOverlay || this.isDraggingRegion || this.activeMode === "region") return;
1899
+ const path = e.composedPath ? e.composedPath() : [];
1900
+ if (this.container && path.includes(this.container)) {
1901
+ this.hideHighlight();
1902
+ return;
1903
+ }
1408
1904
  if (e.altKey || this.activeMode === "element") {
1409
1905
  const target = document.elementFromPoint(e.clientX, e.clientY);
1410
1906
  if (target && target !== this.container && !this.container?.contains(target)) {
@@ -1418,7 +1914,12 @@ var NoteInspector = class {
1418
1914
  }
1419
1915
  };
1420
1916
  const onClick = (e) => {
1421
- if (this.modalOverlay || this.activeMode === "region") return;
1917
+ if (this.modalOverlay || this.cardOverlay) return;
1918
+ const path = e.composedPath ? e.composedPath() : [];
1919
+ if (this.container && path.includes(this.container)) {
1920
+ return;
1921
+ }
1922
+ if (this.activeMode === "region") return;
1422
1923
  if (e.altKey || this.activeMode === "element") {
1423
1924
  e.preventDefault();
1424
1925
  e.stopPropagation();
@@ -1432,18 +1933,39 @@ var NoteInspector = class {
1432
1933
  }
1433
1934
  }
1434
1935
  };
1936
+ const onKeyDown = (e) => {
1937
+ if (e.key === "Escape") {
1938
+ if (this.cardOverlay && this.cardOverlay.parentElement && this.shadowRoot) {
1939
+ this.shadowRoot.removeChild(this.cardOverlay);
1940
+ this.cardOverlay = null;
1941
+ } else if (this.activeMode === "region" || this.activeMode === "element") {
1942
+ this.setMode("idle");
1943
+ }
1944
+ }
1945
+ };
1435
1946
  const onKeyUp = (e) => {
1436
- if (e.key === "Alt" && !this.modalOverlay && this.activeMode !== "element") {
1947
+ if (e.key === "Alt" && !this.modalOverlay && !this.cardOverlay && this.activeMode !== "element") {
1437
1948
  this.hideHighlight();
1438
1949
  }
1439
1950
  };
1951
+ const onScrollOrResize = () => {
1952
+ requestAnimationFrame(() => {
1953
+ this.updateMarkerPositions();
1954
+ });
1955
+ };
1440
1956
  window.addEventListener("mousemove", onMouseMove, { capture: true, passive: true });
1441
1957
  window.addEventListener("click", onClick, { capture: true });
1958
+ window.addEventListener("keydown", onKeyDown, { capture: true });
1442
1959
  window.addEventListener("keyup", onKeyUp, { capture: true });
1960
+ window.addEventListener("scroll", onScrollOrResize, { capture: true, passive: true });
1961
+ window.addEventListener("resize", onScrollOrResize, { passive: true });
1443
1962
  this.cleanups.push(() => {
1444
1963
  window.removeEventListener("mousemove", onMouseMove, { capture: true });
1445
1964
  window.removeEventListener("click", onClick, { capture: true });
1965
+ window.removeEventListener("keydown", onKeyDown, { capture: true });
1446
1966
  window.removeEventListener("keyup", onKeyUp, { capture: true });
1967
+ window.removeEventListener("scroll", onScrollOrResize, { capture: true });
1968
+ window.removeEventListener("resize", onScrollOrResize);
1447
1969
  });
1448
1970
  }
1449
1971
  showRegionOverlay() {
@@ -1456,7 +1978,26 @@ var NoteInspector = class {
1456
1978
  this.regionBox.className = "bt-region-box";
1457
1979
  this.regionBox.style.display = "none";
1458
1980
  this.regionOverlay.appendChild(this.regionBox);
1981
+ this.regionBanner = document.createElement("div");
1982
+ this.regionBanner.className = "bt-region-banner";
1983
+ this.regionBanner.innerHTML = `
1984
+ <span>\u{1F4D0} Drag rectangle on screen to select region</span>
1985
+ <button class="bt-region-cancel-btn" id="bt-region-cancel">\u2715 Cancel (Esc)</button>
1986
+ `;
1987
+ const btnCancel = this.regionBanner.querySelector("#bt-region-cancel");
1988
+ btnCancel.onclick = (e) => {
1989
+ e.stopPropagation();
1990
+ this.setMode("idle");
1991
+ };
1992
+ this.regionOverlay.appendChild(this.regionBanner);
1993
+ this.regionOverlay.oncontextmenu = (e) => {
1994
+ e.preventDefault();
1995
+ this.setMode("idle");
1996
+ };
1459
1997
  this.regionOverlay.onmousedown = (e) => {
1998
+ const path = e.composedPath ? e.composedPath() : [];
1999
+ if (this.regionBanner && path.includes(this.regionBanner)) return;
2000
+ if (this.toolbarElement && path.includes(this.toolbarElement)) return;
1460
2001
  this.isDraggingRegion = true;
1461
2002
  this.dragStartX = e.clientX;
1462
2003
  this.dragStartY = e.clientY;
@@ -1497,7 +2038,7 @@ var NoteInspector = class {
1497
2038
  const top = Math.min(this.dragStartY, currentY);
1498
2039
  const width = Math.abs(currentX - this.dragStartX);
1499
2040
  const height = Math.abs(currentY - this.dragStartY);
1500
- if (width > 20 && height > 20) {
2041
+ if (width > 15 && height > 15) {
1501
2042
  this.selectedRegion = {
1502
2043
  x: Math.round(left),
1503
2044
  y: Math.round(top),
@@ -1513,11 +2054,16 @@ var NoteInspector = class {
1513
2054
  }
1514
2055
  };
1515
2056
  }
1516
- root.appendChild(this.regionOverlay);
2057
+ if (this.toolbarElement && this.toolbarElement.parentNode === root) {
2058
+ root.insertBefore(this.regionOverlay, this.toolbarElement);
2059
+ } else {
2060
+ root.appendChild(this.regionOverlay);
2061
+ }
1517
2062
  }
1518
2063
  hideRegionOverlay() {
1519
- if (this.regionOverlay && this.regionOverlay.parentElement) {
1520
- this.regionOverlay.parentElement.removeChild(this.regionOverlay);
2064
+ this.isDraggingRegion = false;
2065
+ if (this.regionOverlay && this.regionOverlay.parentNode) {
2066
+ this.regionOverlay.parentNode.removeChild(this.regionOverlay);
1521
2067
  }
1522
2068
  if (this.regionBox) {
1523
2069
  this.regionBox.style.display = "none";
@@ -1556,7 +2102,7 @@ var NoteInspector = class {
1556
2102
  this.updateHighlight(targetEl);
1557
2103
  }
1558
2104
  this.renderNoteModal({
1559
- title: "\u{1F4DD} Add Visual Note",
2105
+ title: "Add Visual Note",
1560
2106
  modeBadge: noteType.toUpperCase(),
1561
2107
  pillText: noteType === "page" ? `Page Viewport: ${window.innerWidth} \xD7 ${window.innerHeight} px` : `${getSemanticSelector(targetEl)} (${Math.round(targetEl.getBoundingClientRect().width)}\xD7${Math.round(targetEl.getBoundingClientRect().height)}) \xB7 Viewport: ${window.innerWidth}\xD7${window.innerHeight}`,
1562
2108
  onSave: async (message) => {
@@ -1566,7 +2112,7 @@ var NoteInspector = class {
1566
2112
  }
1567
2113
  openRegionNoteEditor(region) {
1568
2114
  this.renderNoteModal({
1569
- title: "\u{1F4DD} Add Region Note",
2115
+ title: "Add Region Note",
1570
2116
  modeBadge: "REGION",
1571
2117
  pillText: `Selected Area: x:${region.x}, y:${region.y} (${region.width} \xD7 ${region.height} px)`,
1572
2118
  onSave: async (message) => {
@@ -1584,22 +2130,31 @@ var NoteInspector = class {
1584
2130
  const backdrop = document.createElement("div");
1585
2131
  backdrop.className = "bt-modal-backdrop";
1586
2132
  this.modalOverlay = backdrop;
2133
+ const badgeClass = `bt-badge-${options.modeBadge.toLowerCase()}`;
2134
+ const icon = options.modeBadge === "REGION" ? "\u{1F4D0}" : options.modeBadge === "PAGE" ? "\u{1F4C4}" : "\u{1F3AF}";
2135
+ const isMac = typeof navigator !== "undefined" && /Mac|iPod|iPhone|iPad/.test(navigator.platform);
1587
2136
  backdrop.innerHTML = `
1588
2137
  <div class="bt-modal">
1589
2138
  <div class="bt-modal-header">
1590
2139
  <div class="bt-modal-title">
1591
- <span>${options.title}</span>
1592
- <span class="bt-mode-badge">${options.modeBadge}</span>
2140
+ <span>\u{1F4DD} ${options.title}</span>
2141
+ <span class="bt-mode-badge ${badgeClass}">${options.modeBadge}</span>
1593
2142
  </div>
1594
- <button class="bt-close-btn" id="btn-close" title="Close">\u2715</button>
2143
+ <button class="bt-close-btn" id="btn-close" title="Close (Esc)">\u2715</button>
1595
2144
  </div>
1596
2145
  <div class="bt-target-pill" title="${options.pillText}">
1597
- \u{1F3AF} ${options.pillText}
2146
+ <span>${icon}</span>
2147
+ <span class="bt-pill-content">${options.pillText}</span>
1598
2148
  </div>
1599
2149
  <textarea class="bt-textarea" placeholder="Describe the layout issue, styling bug, or note for AI agent..." autofocus></textarea>
1600
- <div class="bt-modal-actions">
1601
- <button class="bt-btn bt-btn-cancel" id="btn-cancel">Cancel</button>
1602
- <button class="bt-btn bt-btn-save" id="btn-save">Save Note</button>
2150
+ <div class="bt-modal-footer">
2151
+ <div class="bt-kbd-hint">
2152
+ <kbd>${isMac ? "\u2318" : "Ctrl"}+Enter</kbd> save \xB7 <kbd>Esc</kbd> cancel
2153
+ </div>
2154
+ <div class="bt-modal-actions">
2155
+ <button class="bt-btn bt-btn-cancel" id="btn-cancel">Cancel</button>
2156
+ <button class="bt-btn bt-btn-save" id="btn-save">Save Note</button>
2157
+ </div>
1603
2158
  </div>
1604
2159
  </div>
1605
2160
  `;
@@ -1819,6 +2374,12 @@ var NoteInspector = class {
1819
2374
  this.container = null;
1820
2375
  this.shadowRoot = null;
1821
2376
  this.toolbarElement = null;
2377
+ this.regionOverlay = null;
2378
+ this.regionBox = null;
2379
+ this.regionBanner = null;
2380
+ this.markersContainer = null;
2381
+ this.modalOverlay = null;
2382
+ this.cardOverlay = null;
1822
2383
  }
1823
2384
  };
1824
2385
 
@@ -2077,4 +2638,4 @@ export {
2077
2638
  init,
2078
2639
  getClient
2079
2640
  };
2080
- //# sourceMappingURL=chunk-X7C5CHBO.js.map
2641
+ //# sourceMappingURL=chunk-SKCMT2DE.js.map