@quanta-intellect/vessel-browser 0.1.71 → 0.1.74

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.
@@ -59,6 +59,10 @@ const Channels = {
59
59
  BOOKMARK_SAVE: "bookmarks:save",
60
60
  BOOKMARK_UPDATE: "bookmarks:update-item",
61
61
  BOOKMARK_REMOVE: "bookmarks:remove",
62
+ BOOKMARKS_EXPORT_HTML: "bookmarks:export-html",
63
+ BOOKMARKS_EXPORT_JSON: "bookmarks:export-json",
64
+ BOOKMARKS_IMPORT_HTML: "bookmarks:import-html",
65
+ BOOKMARKS_IMPORT_JSON: "bookmarks:import-json",
62
66
  BOOKMARK_ADD_CONTEXT_TO_CHAT: "bookmarks:add-context-to-chat",
63
67
  FOLDER_CREATE: "bookmarks:folder-create",
64
68
  FOLDER_REMOVE: "bookmarks:folder-remove",
@@ -82,10 +86,32 @@ const Channels = {
82
86
  TAB_ZOOM_IN: "tab:zoom-in",
83
87
  TAB_ZOOM_OUT: "tab:zoom-out",
84
88
  TAB_ZOOM_RESET: "tab:zoom-reset",
89
+ // Security indicator
90
+ SECURITY_STATE_UPDATE: "security:state-update",
91
+ SECURITY_SHOW_DETAILS: "security:show-details",
92
+ SECURITY_PROCEED_ANYWAY: "security:proceed-anyway",
93
+ SECURITY_GO_BACK_TO_SAFETY: "security:go-back-to-safety",
85
94
  // Closed tabs / duplication
86
95
  TAB_REOPEN_CLOSED: "tab:reopen-closed",
87
96
  TAB_DUPLICATE: "tab:duplicate",
88
97
  TAB_CONTEXT_MENU: "tab:context-menu",
98
+ // Pin tabs
99
+ TAB_PIN: "tab:pin",
100
+ TAB_UNPIN: "tab:unpin",
101
+ // Tab groups
102
+ TAB_GROUP_CREATE: "tab-group:create",
103
+ TAB_GROUP_ADD_TAB: "tab-group:add-tab",
104
+ TAB_GROUP_REMOVE_TAB: "tab-group:remove-tab",
105
+ TAB_GROUP_TOGGLE_COLLAPSED: "tab-group:toggle-collapsed",
106
+ TAB_GROUP_SET_COLOR: "tab-group:set-color",
107
+ TAB_GROUP_CONTEXT_MENU: "tab-group:context-menu",
108
+ // Audio / mute
109
+ TAB_TOGGLE_MUTE: "tab:toggle-mute",
110
+ // Print
111
+ TAB_PRINT: "tab:print",
112
+ TAB_PRINT_TO_PDF: "tab:print-to-pdf",
113
+ // Windows
114
+ OPEN_NEW_WINDOW: "window:open-new",
89
115
  // Private browsing
90
116
  OPEN_PRIVATE_WINDOW: "private:open-window",
91
117
  IS_PRIVATE_MODE: "private:is-private",
@@ -99,6 +125,9 @@ const Channels = {
99
125
  HISTORY_SEARCH: "history:search",
100
126
  HISTORY_CLEAR: "history:clear",
101
127
  HISTORY_UPDATE: "history:update",
128
+ HISTORY_EXPORT_HTML: "history:export-html",
129
+ HISTORY_EXPORT_JSON: "history:export-json",
130
+ HISTORY_IMPORT: "history:import",
102
131
  // Downloads
103
132
  DOWNLOAD_STARTED: "download:started",
104
133
  DOWNLOAD_PROGRESS: "download:progress",
@@ -123,6 +152,13 @@ const Channels = {
123
152
  VAULT_UPDATE: "vault:update",
124
153
  VAULT_REMOVE: "vault:remove",
125
154
  VAULT_AUDIT_LOG: "vault:audit-log",
155
+ // Human Password Manager
156
+ HUMAN_VAULT_LIST: "human-vault:list",
157
+ HUMAN_VAULT_GET: "human-vault:get",
158
+ HUMAN_VAULT_SAVE: "human-vault:save",
159
+ HUMAN_VAULT_UPDATE: "human-vault:update",
160
+ HUMAN_VAULT_REMOVE: "human-vault:remove",
161
+ HUMAN_VAULT_AUDIT_LOG: "human-vault:audit-log",
126
162
  // Automation kits
127
163
  AUTOMATION_GET_INSTALLED: "automation:get-installed",
128
164
  AUTOMATION_INSTALL_FROM_FILE: "automation:install-from-file",
@@ -145,7 +181,12 @@ const Channels = {
145
181
  AUTOFILL_FILL: "autofill:fill",
146
182
  PAGE_CHANGED: "page:changed",
147
183
  PAGE_DIFF_GET: "page:diff-get",
148
- PAGE_DIFF_HISTORY: "page:diff-history"
184
+ PAGE_DIFF_HISTORY: "page:diff-history",
185
+ // Clear browsing data
186
+ CLEAR_BROWSING_DATA: "browsing-data:clear",
187
+ CLEAR_BROWSING_DATA_OPEN: "browsing-data:open",
188
+ // Picture-in-Picture
189
+ TAB_TOGGLE_PIP: "tab:toggle-pip"
149
190
  };
150
191
  const api = {
151
192
  tabs: {
@@ -165,6 +206,18 @@ const api = {
165
206
  showContextMenu: (id) => electron.ipcRenderer.send(Channels.TAB_CONTEXT_MENU, id),
166
207
  openPrivateWindow: () => electron.ipcRenderer.invoke(Channels.OPEN_PRIVATE_WINDOW),
167
208
  isPrivateMode: () => electron.ipcRenderer.invoke(Channels.IS_PRIVATE_MODE),
209
+ pin: (id) => electron.ipcRenderer.invoke(Channels.TAB_PIN, id),
210
+ unpin: (id) => electron.ipcRenderer.invoke(Channels.TAB_UNPIN, id),
211
+ createGroup: (id) => electron.ipcRenderer.invoke(Channels.TAB_GROUP_CREATE, id),
212
+ addToGroup: (id, groupId) => electron.ipcRenderer.invoke(Channels.TAB_GROUP_ADD_TAB, id, groupId),
213
+ removeFromGroup: (id) => electron.ipcRenderer.invoke(Channels.TAB_GROUP_REMOVE_TAB, id),
214
+ toggleGroupCollapsed: (groupId) => electron.ipcRenderer.invoke(Channels.TAB_GROUP_TOGGLE_COLLAPSED, groupId),
215
+ setGroupColor: (groupId, color) => electron.ipcRenderer.invoke(Channels.TAB_GROUP_SET_COLOR, groupId, color),
216
+ showGroupContextMenu: (groupId) => electron.ipcRenderer.send(Channels.TAB_GROUP_CONTEXT_MENU, groupId),
217
+ toggleMute: (id) => electron.ipcRenderer.invoke(Channels.TAB_TOGGLE_MUTE, id),
218
+ print: (id) => electron.ipcRenderer.invoke(Channels.TAB_PRINT, id),
219
+ printToPdf: (id) => electron.ipcRenderer.invoke(Channels.TAB_PRINT_TO_PDF, id),
220
+ openNewWindow: () => electron.ipcRenderer.invoke(Channels.OPEN_NEW_WINDOW),
168
221
  getState: () => electron.ipcRenderer.invoke(Channels.TAB_STATE_GET),
169
222
  onStateUpdate: (cb) => {
170
223
  const handler = (_, tabs, activeId) => cb(tabs, activeId);
@@ -304,6 +357,10 @@ const api = {
304
357
  ),
305
358
  updateBookmark: (id, updates) => electron.ipcRenderer.invoke(Channels.BOOKMARK_UPDATE, id, updates),
306
359
  removeBookmark: (id) => electron.ipcRenderer.invoke(Channels.BOOKMARK_REMOVE, id),
360
+ exportHtml: (options) => electron.ipcRenderer.invoke(Channels.BOOKMARKS_EXPORT_HTML, options),
361
+ exportJson: () => electron.ipcRenderer.invoke(Channels.BOOKMARKS_EXPORT_JSON),
362
+ importHtml: () => electron.ipcRenderer.invoke(Channels.BOOKMARKS_IMPORT_HTML),
363
+ importJson: () => electron.ipcRenderer.invoke(Channels.BOOKMARKS_IMPORT_JSON),
307
364
  createFolder: (name) => electron.ipcRenderer.invoke(Channels.FOLDER_CREATE, name),
308
365
  createFolderWithSummary: (name, summary) => electron.ipcRenderer.invoke(Channels.FOLDER_CREATE, name, summary),
309
366
  removeFolder: (id, deleteContents) => electron.ipcRenderer.invoke(Channels.FOLDER_REMOVE, id, deleteContents),
@@ -345,6 +402,9 @@ const api = {
345
402
  get: () => electron.ipcRenderer.invoke(Channels.HISTORY_GET),
346
403
  search: (query) => electron.ipcRenderer.invoke(Channels.HISTORY_SEARCH, query),
347
404
  clear: () => electron.ipcRenderer.invoke(Channels.HISTORY_CLEAR),
405
+ exportHtml: () => electron.ipcRenderer.invoke(Channels.HISTORY_EXPORT_HTML),
406
+ exportJson: () => electron.ipcRenderer.invoke(Channels.HISTORY_EXPORT_JSON),
407
+ importFile: () => electron.ipcRenderer.invoke(Channels.HISTORY_IMPORT),
348
408
  onUpdate: (cb) => {
349
409
  const handler = (_, state) => cb(state);
350
410
  electron.ipcRenderer.on(Channels.HISTORY_UPDATE, handler);
@@ -383,6 +443,14 @@ const api = {
383
443
  remove: (id) => electron.ipcRenderer.invoke(Channels.VAULT_REMOVE, id),
384
444
  auditLog: (limit) => electron.ipcRenderer.invoke(Channels.VAULT_AUDIT_LOG, limit)
385
445
  },
446
+ humanVault: {
447
+ list: (domain) => electron.ipcRenderer.invoke(Channels.HUMAN_VAULT_LIST, domain),
448
+ get: (id) => electron.ipcRenderer.invoke(Channels.HUMAN_VAULT_GET, id),
449
+ save: (entry) => electron.ipcRenderer.invoke(Channels.HUMAN_VAULT_SAVE, entry),
450
+ update: (id, updates) => electron.ipcRenderer.invoke(Channels.HUMAN_VAULT_UPDATE, id, updates),
451
+ remove: (id) => electron.ipcRenderer.invoke(Channels.HUMAN_VAULT_REMOVE, id),
452
+ auditLog: (limit) => electron.ipcRenderer.invoke(Channels.HUMAN_VAULT_AUDIT_LOG, limit)
453
+ },
386
454
  automation: {
387
455
  getInstalled: () => electron.ipcRenderer.invoke(Channels.AUTOMATION_GET_INSTALLED),
388
456
  installFromFile: () => electron.ipcRenderer.invoke(Channels.AUTOMATION_INSTALL_FROM_FILE),
@@ -436,6 +504,27 @@ const api = {
436
504
  },
437
505
  get: () => electron.ipcRenderer.invoke(Channels.PAGE_DIFF_GET),
438
506
  getHistory: () => electron.ipcRenderer.invoke(Channels.PAGE_DIFF_HISTORY)
507
+ },
508
+ security: {
509
+ onStateUpdate: (cb) => {
510
+ const handler = (_, data) => cb(data.tabId, data.state);
511
+ electron.ipcRenderer.on(Channels.SECURITY_STATE_UPDATE, handler);
512
+ return () => electron.ipcRenderer.removeListener(Channels.SECURITY_STATE_UPDATE, handler);
513
+ },
514
+ showDetails: (state) => electron.ipcRenderer.invoke(Channels.SECURITY_SHOW_DETAILS, state),
515
+ proceedAnyway: (tabId) => electron.ipcRenderer.invoke(Channels.SECURITY_PROCEED_ANYWAY, tabId),
516
+ goBackToSafety: (tabId) => electron.ipcRenderer.invoke(Channels.SECURITY_GO_BACK_TO_SAFETY, tabId)
517
+ },
518
+ browsingData: {
519
+ clear: (options) => electron.ipcRenderer.invoke(Channels.CLEAR_BROWSING_DATA, options),
520
+ onOpenDialog: (cb) => {
521
+ const handler = () => cb();
522
+ electron.ipcRenderer.on(Channels.CLEAR_BROWSING_DATA_OPEN, handler);
523
+ return () => electron.ipcRenderer.removeListener(Channels.CLEAR_BROWSING_DATA_OPEN, handler);
524
+ }
525
+ },
526
+ pip: {
527
+ toggle: () => electron.ipcRenderer.invoke(Channels.TAB_TOGGLE_PIP)
439
528
  }
440
529
  };
441
530
  electron.contextBridge.exposeInMainWorld("vessel", api);
@@ -195,6 +195,19 @@
195
195
  }
196
196
  }
197
197
 
198
+ .tab-item.pinned {
199
+ max-width: 40px;
200
+ min-width: 36px;
201
+ padding: 0 10px;
202
+ justify-content: center;
203
+ }
204
+
205
+ .tab-item.pinned .tab-favicon,
206
+ .tab-item.pinned .tab-favicon-fallback {
207
+ width: 14px;
208
+ height: 14px;
209
+ }
210
+
198
211
  .tab-item:hover {
199
212
  background: var(--surface-hover);
200
213
  color: var(--text-secondary);
@@ -206,6 +219,85 @@
206
219
  font-weight: 500;
207
220
  }
208
221
 
222
+ .tab-item.group-blue,
223
+ .tab-group-chip.group-blue { --tab-group-color: #4b8dff; }
224
+ .tab-item.group-green,
225
+ .tab-group-chip.group-green { --tab-group-color: #45b36b; }
226
+ .tab-item.group-yellow,
227
+ .tab-group-chip.group-yellow { --tab-group-color: #d9b441; }
228
+ .tab-item.group-orange,
229
+ .tab-group-chip.group-orange { --tab-group-color: #df8742; }
230
+ .tab-item.group-red,
231
+ .tab-group-chip.group-red { --tab-group-color: #e35d6a; }
232
+ .tab-item.group-purple,
233
+ .tab-group-chip.group-purple { --tab-group-color: #9b73f0; }
234
+ .tab-item.group-gray,
235
+ .tab-group-chip.group-gray { --tab-group-color: #8b95a1; }
236
+
237
+ .tab-item[class*="group-"] {
238
+ box-shadow: inset 0 2px 0 color-mix(in srgb, var(--tab-group-color) 78%, transparent);
239
+ }
240
+
241
+ .tab-group-chip {
242
+ display: inline-flex;
243
+ align-items: center;
244
+ gap: 6px;
245
+ height: 24px;
246
+ max-width: 150px;
247
+ margin-bottom: 3px;
248
+ padding: 0 8px;
249
+ border-radius: 6px;
250
+ color: var(--text-secondary);
251
+ background: color-mix(in srgb, var(--tab-group-color) 18%, var(--bg-secondary));
252
+ border: 1px solid color-mix(in srgb, var(--tab-group-color) 48%, transparent);
253
+ flex-shrink: 0;
254
+ transition:
255
+ background var(--duration-fast) var(--ease-in-out),
256
+ color var(--duration-fast) var(--ease-in-out),
257
+ transform var(--duration-fast) var(--ease-out-expo);
258
+ }
259
+
260
+ .tab-group-chip:hover {
261
+ color: var(--text-primary);
262
+ background: color-mix(in srgb, var(--tab-group-color) 26%, var(--bg-secondary));
263
+ }
264
+
265
+ .tab-group-chip:active {
266
+ transform: scale(0.96);
267
+ }
268
+
269
+ .tab-group-chip.collapsed {
270
+ background: color-mix(in srgb, var(--tab-group-color) 12%, var(--bg-secondary));
271
+ }
272
+
273
+ .tab-group-dot {
274
+ width: 7px;
275
+ height: 7px;
276
+ border-radius: 999px;
277
+ background: var(--tab-group-color);
278
+ flex-shrink: 0;
279
+ }
280
+
281
+ .tab-group-name {
282
+ min-width: 0;
283
+ overflow: hidden;
284
+ text-overflow: ellipsis;
285
+ font-size: 10.5px;
286
+ font-weight: 600;
287
+ }
288
+
289
+ .tab-group-count {
290
+ min-width: 14px;
291
+ height: 14px;
292
+ padding: 0 4px;
293
+ border-radius: 999px;
294
+ background: color-mix(in srgb, var(--tab-group-color) 28%, transparent);
295
+ color: var(--text-muted);
296
+ font-size: 9px;
297
+ font-weight: 700;
298
+ line-height: 14px;
299
+ }
300
+
209
301
  /* Subtle top accent line on active tab */
210
302
  .tab-item.active::before {
211
303
  content: '';
@@ -302,6 +394,42 @@
302
394
  color: var(--text-primary);
303
395
  }
304
396
 
397
+ .tab-audio {
398
+ width: 18px;
399
+ height: 18px;
400
+ display: inline-flex;
401
+ align-items: center;
402
+ justify-content: center;
403
+ border-radius: var(--radius-sm);
404
+ color: var(--accent-primary);
405
+ flex-shrink: 0;
406
+ margin-right: -2px;
407
+ transition:
408
+ background var(--duration-fast) var(--ease-in-out),
409
+ color var(--duration-fast) var(--ease-in-out),
410
+ transform var(--duration-fast) var(--ease-out-expo);
411
+ }
412
+
413
+ .tab-audio:hover {
414
+ background: var(--surface-active);
415
+ color: var(--text-primary);
416
+ }
417
+
418
+ .tab-audio:active {
419
+ transform: scale(0.9);
420
+ }
421
+
422
+ .tab-audio-pinned {
423
+ position: absolute;
424
+ right: 0;
425
+ bottom: 1px;
426
+ width: 14px;
427
+ height: 14px;
428
+ margin: 0;
429
+ background: var(--bg-primary);
430
+ box-shadow: 0 0 0 1px var(--border-subtle);
431
+ }
432
+
305
433
  .tab-loading {
306
434
  width: 8px;
307
435
  height: 8px;
@@ -1526,6 +1654,283 @@
1526
1654
  background: var(--status-warning-bg);
1527
1655
  color: var(--status-warning);
1528
1656
  }
1657
+
1658
+ /* ═══════════════════════════════════════
1659
+ Security indicator
1660
+ ═══════════════════════════════════════ */
1661
+
1662
+ .security-indicator-wrapper {
1663
+ position: relative;
1664
+ display: flex;
1665
+ align-items: center;
1666
+ }
1667
+
1668
+ .security-indicator {
1669
+ display: flex;
1670
+ align-items: center;
1671
+ justify-content: center;
1672
+ width: 24px;
1673
+ height: 24px;
1674
+ border: none;
1675
+ background: transparent;
1676
+ color: #9ca3af;
1677
+ cursor: pointer;
1678
+ border-radius: 4px;
1679
+ transition: background 0.15s;
1680
+ }
1681
+
1682
+ .security-indicator:hover {
1683
+ background: rgba(255, 255, 255, 0.08);
1684
+ }
1685
+
1686
+ .security-indicator.secure {
1687
+ color: #4ade80;
1688
+ }
1689
+
1690
+ .security-indicator.insecure {
1691
+ color: #9ca3af;
1692
+ }
1693
+
1694
+ .security-indicator.error {
1695
+ color: #f87171;
1696
+ }
1697
+
1698
+ .security-popup {
1699
+ position: absolute;
1700
+ top: calc(100% + 6px);
1701
+ left: 0;
1702
+ background: #1e1e24;
1703
+ border: 1px solid rgba(255, 255, 255, 0.08);
1704
+ border-radius: 8px;
1705
+ padding: 12px 16px;
1706
+ min-width: 220px;
1707
+ z-index: 100;
1708
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
1709
+ }
1710
+
1711
+ .security-popup-content {
1712
+ display: flex;
1713
+ flex-direction: column;
1714
+ gap: 8px;
1715
+ }
1716
+
1717
+ .security-popup-text {
1718
+ font-size: 12px;
1719
+ color: #e0e0e0;
1720
+ line-height: 1.5;
1721
+ margin: 0;
1722
+ }
1723
+
1724
+ .security-popup-link {
1725
+ font-size: 12px;
1726
+ color: #60a5fa;
1727
+ background: none;
1728
+ border: none;
1729
+ cursor: pointer;
1730
+ padding: 0;
1731
+ text-align: left;
1732
+ text-decoration: underline;
1733
+ }
1734
+
1735
+ .security-popup-link:hover {
1736
+ color: #93c5fd;
1737
+ }
1738
+
1739
+ .security-popup-actions {
1740
+ display: flex;
1741
+ gap: 8px;
1742
+ margin-top: 4px;
1743
+ }
1744
+
1745
+ .security-popup-action-proceed {
1746
+ font-size: 11px;
1747
+ color: #fbbf24;
1748
+ background: rgba(251, 191, 36, 0.1);
1749
+ border: 1px solid rgba(251, 191, 36, 0.3);
1750
+ border-radius: 4px;
1751
+ cursor: pointer;
1752
+ padding: 4px 8px;
1753
+ }
1754
+
1755
+ .security-popup-action-proceed:hover {
1756
+ background: rgba(251, 191, 36, 0.2);
1757
+ }
1758
+
1759
+ .security-popup-action-back {
1760
+ font-size: 11px;
1761
+ color: #9ca3af;
1762
+ background: rgba(156, 163, 175, 0.1);
1763
+ border: 1px solid rgba(156, 163, 175, 0.2);
1764
+ border-radius: 4px;
1765
+ cursor: pointer;
1766
+ padding: 4px 8px;
1767
+ }
1768
+
1769
+ .security-popup-action-back:hover {
1770
+ background: rgba(156, 163, 175, 0.2);
1771
+ }
1772
+
1773
+ .clear-data-overlay {
1774
+ position: fixed;
1775
+ inset: 0;
1776
+ background: rgba(0, 0, 0, 0.5);
1777
+ display: flex;
1778
+ align-items: center;
1779
+ justify-content: center;
1780
+ z-index: 200;
1781
+ }
1782
+
1783
+ .clear-data-dialog {
1784
+ background: var(--bg-secondary);
1785
+ border: 1px solid var(--border-visible);
1786
+ border-radius: var(--radius-lg);
1787
+ padding: 24px;
1788
+ min-width: 380px;
1789
+ max-width: 440px;
1790
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
1791
+ }
1792
+
1793
+ .clear-data-header {
1794
+ display: flex;
1795
+ align-items: center;
1796
+ justify-content: space-between;
1797
+ margin-bottom: 20px;
1798
+ }
1799
+
1800
+ .clear-data-header h3 {
1801
+ margin: 0;
1802
+ font-size: 15px;
1803
+ font-weight: 600;
1804
+ color: var(--text-primary);
1805
+ }
1806
+
1807
+ .clear-data-close {
1808
+ background: none;
1809
+ border: none;
1810
+ color: var(--text-muted);
1811
+ cursor: pointer;
1812
+ padding: 4px;
1813
+ border-radius: var(--radius-sm);
1814
+ display: flex;
1815
+ align-items: center;
1816
+ justify-content: center;
1817
+ }
1818
+
1819
+ .clear-data-close:hover {
1820
+ color: var(--text-primary);
1821
+ background: var(--surface-hover);
1822
+ }
1823
+
1824
+ .clear-data-range {
1825
+ margin-bottom: 16px;
1826
+ }
1827
+
1828
+ .clear-data-range label {
1829
+ display: block;
1830
+ font-size: 12px;
1831
+ color: var(--text-secondary);
1832
+ margin-bottom: 6px;
1833
+ }
1834
+
1835
+ .clear-data-select {
1836
+ width: 100%;
1837
+ padding: 6px 10px;
1838
+ font-size: 13px;
1839
+ background: var(--bg-tertiary);
1840
+ color: var(--text-primary);
1841
+ border: 1px solid var(--border-visible);
1842
+ border-radius: var(--radius-sm);
1843
+ outline: none;
1844
+ cursor: pointer;
1845
+ appearance: auto;
1846
+ }
1847
+
1848
+ .clear-data-select:focus {
1849
+ border-color: var(--accent-primary);
1850
+ }
1851
+
1852
+ .clear-data-checks {
1853
+ display: flex;
1854
+ flex-direction: column;
1855
+ gap: 10px;
1856
+ margin-bottom: 20px;
1857
+ padding: 12px;
1858
+ background: var(--bg-tertiary);
1859
+ border-radius: var(--radius-md);
1860
+ }
1861
+
1862
+ .clear-data-check {
1863
+ display: flex;
1864
+ align-items: center;
1865
+ gap: 10px;
1866
+ font-size: 13px;
1867
+ color: var(--text-primary);
1868
+ cursor: pointer;
1869
+ }
1870
+
1871
+ .clear-data-check input[type="checkbox"] {
1872
+ accent-color: var(--accent-primary);
1873
+ width: 16px;
1874
+ height: 16px;
1875
+ cursor: pointer;
1876
+ }
1877
+
1878
+ .clear-data-actions {
1879
+ display: flex;
1880
+ justify-content: flex-end;
1881
+ gap: 10px;
1882
+ }
1883
+
1884
+ .clear-data-error {
1885
+ margin: -4px 0 14px;
1886
+ font-size: 12px;
1887
+ color: var(--error);
1888
+ }
1889
+
1890
+ .clear-data-cancel {
1891
+ padding: 7px 16px;
1892
+ font-size: 13px;
1893
+ background: var(--bg-tertiary);
1894
+ color: var(--text-secondary);
1895
+ border: 1px solid var(--border-visible);
1896
+ border-radius: var(--radius-sm);
1897
+ cursor: pointer;
1898
+ }
1899
+
1900
+ .clear-data-cancel:hover {
1901
+ background: var(--bg-elevated);
1902
+ color: var(--text-primary);
1903
+ }
1904
+
1905
+ .clear-data-confirm {
1906
+ padding: 7px 16px;
1907
+ font-size: 13px;
1908
+ background: var(--error);
1909
+ color: #fff;
1910
+ border: none;
1911
+ border-radius: var(--radius-sm);
1912
+ cursor: pointer;
1913
+ font-weight: 500;
1914
+ }
1915
+
1916
+ .clear-data-confirm:hover:not(:disabled) {
1917
+ opacity: 0.9;
1918
+ }
1919
+
1920
+ .clear-data-confirm:disabled {
1921
+ opacity: 0.4;
1922
+ cursor: not-allowed;
1923
+ }
1924
+
1925
+ .clear-data-done {
1926
+ display: flex;
1927
+ align-items: center;
1928
+ justify-content: center;
1929
+ gap: 10px;
1930
+ padding: 20px;
1931
+ font-size: 14px;
1932
+ color: var(--accent-secondary);
1933
+ }
1529
1934
  /* ═══════════════════════════════════════
1530
1935
  Command bar overlay — cinematic entrance
1531
1936
  ═══════════════════════════════════════ */
@@ -2055,6 +2460,7 @@
2055
2460
  }
2056
2461
 
2057
2462
  .bookmark-save-card,
2463
+ .bookmark-export-card,
2058
2464
  .bookmark-folder-section {
2059
2465
  display: flex;
2060
2466
  flex-direction: column;
@@ -2065,6 +2471,19 @@
2065
2471
  border: 1px solid var(--border-glass);
2066
2472
  }
2067
2473
 
2474
+ .bookmark-export-actions {
2475
+ display: flex;
2476
+ gap: 6px;
2477
+ flex-wrap: wrap;
2478
+ }
2479
+
2480
+ .bookmark-export-message {
2481
+ font-size: 11px;
2482
+ color: var(--text-secondary);
2483
+ line-height: 1.4;
2484
+ overflow-wrap: anywhere;
2485
+ }
2486
+
2068
2487
  .bookmark-save-shell {
2069
2488
  display: flex;
2070
2489
  flex-direction: column;
@@ -4546,6 +4965,13 @@
4546
4965
  border-bottom: 1px solid var(--border-subtle);
4547
4966
  }
4548
4967
 
4968
+ .history-panel-actions {
4969
+ display: flex;
4970
+ gap: 6px;
4971
+ flex-wrap: wrap;
4972
+ justify-content: flex-end;
4973
+ }
4974
+
4549
4975
  .history-panel-title {
4550
4976
  font-size: 12px;
4551
4977
  font-weight: 600;