@bendyline/docblocks-react 2.6.2 → 2.7.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 (57) hide show
  1. package/README.md +3 -10
  2. package/THIRD_PARTY_NOTICES.txt +4284 -3651
  3. package/dist/AiDiagrams-LFV4YU6W.js +13 -0
  4. package/dist/AiEditorAssistant-GN2KXKZD.js +786 -0
  5. package/dist/AudioExportDialog-F23QXNPB.js +253 -0
  6. package/dist/DocumentConflictDialog-5LRVIGXS.js +111 -0
  7. package/dist/ExportDialog-IMBVGRYG.js +9 -0
  8. package/dist/{ExportToolbarControls-QYLBRWM7.js → ExportToolbarControls-MUM6HM3K.js} +117 -49
  9. package/dist/{GitToolbarControl-O5AXBC6T.js → GitToolbarControl-B7KG4MFP.js} +6 -6
  10. package/dist/{GitUI-L5T3XHZG.js → GitUI-RCWUZVS6.js} +6 -6
  11. package/dist/PresentationMaker-W2JIBHRN.js +9 -0
  12. package/dist/QuickOpenDialog-2KK4SEBU.js +356 -0
  13. package/dist/Settings-DuXk6baH.d.ts +144 -0
  14. package/dist/ShareDialog-XUA2OVGI.js +292 -0
  15. package/dist/SpeechToolbarControl-OSQS7NVY.js +434 -0
  16. package/dist/TextFromNarration-XYRAB6O2.js +598 -0
  17. package/dist/WorkspaceSearchPanel-BKZJRPMY.js +334 -0
  18. package/dist/chunk-2IYBBFQX.js +201 -0
  19. package/dist/{chunk-LG6HAWCK.js → chunk-56KO2LYN.js} +35 -4
  20. package/dist/chunk-6B7G33D5.js +88 -0
  21. package/dist/chunk-ARATARVJ.js +40 -0
  22. package/dist/{chunk-ODYNOPC3.js → chunk-BCQZTWE5.js} +57 -17
  23. package/dist/{chunk-FMDLZ4ZG.js → chunk-BD54Z5XP.js} +12 -3
  24. package/dist/chunk-EA4BO6E4.js +73 -0
  25. package/dist/chunk-EPOLZNFD.js +518 -0
  26. package/dist/chunk-G4MFB3IO.js +208 -0
  27. package/dist/{chunk-MRUK56JS.js → chunk-GMA4KGGO.js} +7 -3
  28. package/dist/chunk-I44HKDQX.js +314 -0
  29. package/dist/chunk-K4I3NJFL.js +49 -0
  30. package/dist/chunk-KBDZDFPU.js +61 -0
  31. package/dist/{chunk-FNSRCCBC.js → chunk-KWG6UP5O.js} +0 -10
  32. package/dist/chunk-NAH52736.js +1884 -0
  33. package/dist/chunk-RP3DVNTI.js +62 -0
  34. package/dist/chunk-SPUPWCSI.js +111 -0
  35. package/dist/chunk-TBLZBNQF.js +25 -0
  36. package/dist/{chunk-M5Y5WO7Z.js → chunk-UG4G7PJ4.js} +1 -1
  37. package/dist/chunk-UONFWKJ7.js +22 -0
  38. package/dist/chunk-VO2JYYQZ.js +40 -0
  39. package/dist/chunk-W55E6TE2.js +1714 -0
  40. package/dist/chunk-X3DDTJKR.js +574 -0
  41. package/dist/{chunk-EBWYGTN7.js → chunk-X437UAF7.js} +6 -0
  42. package/dist/editor.d.ts +36 -1
  43. package/dist/editor.js +16 -1
  44. package/dist/export/index.d.ts +27 -11
  45. package/dist/export/index.js +11 -7
  46. package/dist/index.d.ts +100 -13
  47. package/dist/index.js +3927 -1638
  48. package/dist/proofing/index.js +11 -1
  49. package/dist/{run-export-I2XOVGG4.js → run-export-47X5FTYZ.js} +3 -3
  50. package/dist/settings/index.d.ts +32 -101
  51. package/dist/settings/index.js +14 -2
  52. package/package.json +9 -9
  53. package/src/styles/docblocks.css +2344 -657
  54. package/dist/ExportDialog-Q4VWI43H.js +0 -9
  55. package/dist/ShareDialog-4OX3UPJ4.js +0 -359
  56. package/dist/chunk-JDJVRDOP.js +0 -92
  57. package/dist/chunk-Q6XNIKDG.js +0 -669
@@ -20,6 +20,13 @@
20
20
  follows whichever appearance the shell in the page resolved to. */
21
21
  :root,
22
22
  .db-shell {
23
+ /* Chrome typeface. `system-ui` first so DocBlocks looks native by default.
24
+ Settings > Appearance > Interface font swaps this for the bundled face
25
+ below; the visual-regression suite forces that, because under the system
26
+ stack the same screenshot renders in a different typeface on every OS. */
27
+ --db-ui-font:
28
+ system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial,
29
+ sans-serif;
23
30
  --db-bg: #ffffff;
24
31
  --db-bg-subtle: #f3eede;
25
32
  --db-bg-hover: #e9e2cb;
@@ -77,6 +84,88 @@
77
84
  --db-git-conflicted: #b22b1b;
78
85
  }
79
86
 
87
+ /* ── Adaptive tokens ──────────────────────────────────────────
88
+ The ONLY place in this stylesheet that branches on form factor. Every
89
+ adaptive rule below CONSUMES a token; it does not re-test a width.
90
+
91
+ There is no PostCSS in this repo, so `@custom-media` is unavailable and CSS
92
+ cannot read a custom property inside a media condition. TypeScript owns the
93
+ numbers (packages/react/src/layout/form-factor.ts) and stamps `data-db-*`
94
+ on <html> and .db-shell; these selectors key off that. Same pattern the
95
+ theme already uses with `[data-theme]`.
96
+
97
+ Bound on :root as well as .db-shell because Squisq portals its menus and
98
+ dialogs onto <body>, outside the shell subtree. */
99
+ :root,
100
+ .db-shell {
101
+ /* Hit targets. Raised wholesale on coarse pointers rather than per rule. */
102
+ --db-target-min: 28px;
103
+ --db-control-size: 24px;
104
+ --db-row-min-height: 26px;
105
+ /* Below 16px iOS Safari zooms the page when an input takes focus. */
106
+ --db-input-font-size: 13px;
107
+
108
+ /* Viewport and safe area. env() resolves to 0px without viewport-fit=cover. */
109
+ --db-shell-block-size: 100dvh;
110
+ --db-safe-top: env(safe-area-inset-top, 0px);
111
+ --db-safe-right: env(safe-area-inset-right, 0px);
112
+ --db-safe-bottom: env(safe-area-inset-bottom, 0px);
113
+ --db-safe-left: env(safe-area-inset-left, 0px);
114
+ /* Written by useKeyboardInset while the on-screen keyboard is up. */
115
+ --db-keyboard-inset: 0px;
116
+
117
+ /* Drawer. --db-drawer-progress is driven directly on the node during a
118
+ swipe so the gesture costs no React renders. */
119
+ /* 15vw of scrim always stays tappable to dismiss -- 58px on a 390px phone.
120
+ At 88vw that strip was only 47px, which is below the 44px target once you
121
+ account for the shadow. */
122
+ --db-drawer-width: min(85vw, 400px);
123
+ --db-drawer-progress: 0;
124
+ --db-drawer-duration: 220ms;
125
+ }
126
+
127
+ [data-db-pointer='coarse'] {
128
+ --db-target-min: 44px;
129
+ --db-control-size: 40px;
130
+ --db-row-min-height: 44px;
131
+ --db-input-font-size: 16px;
132
+ }
133
+
134
+ [data-db-width='medium'],
135
+ [data-db-width='expanded'],
136
+ [data-db-width='wide'] {
137
+ --db-drawer-width: min(60vw, 420px);
138
+ }
139
+
140
+ @media (prefers-reduced-motion: reduce) {
141
+ :root,
142
+ .db-shell {
143
+ --db-drawer-duration: 0ms;
144
+ }
145
+ }
146
+
147
+ /* Interface font: fixed.
148
+ `DocBlocks Fixed UI` is the Roboto variable binary each surface already ships
149
+ for the document theme of that name, redeclared over the full 100-900 range
150
+ so the chrome's 400/500/600/650/700 weights render exactly rather than
151
+ snapping to the nearest static face. Bound on the root, not only the shell,
152
+ because Squisq portals its menus onto <body>. */
153
+ :root[data-db-interface-font='fixed'],
154
+ :root[data-db-interface-font='fixed'] .db-shell {
155
+ --db-ui-font:
156
+ 'DocBlocks Fixed UI', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
157
+ 'Helvetica Neue', Arial, sans-serif;
158
+ /* Squisq's chrome reads `--squisq-ux-font` with a `system-ui` fallback, the
159
+ same bridge shape as the `--squisq-*` colour tokens further down. Setting
160
+ it here carries the fixed face into the editor toolbar, menus and dialogs,
161
+ which is most of what a shell screenshot actually contains.
162
+
163
+ Scoped to fixed mode on purpose: the token is left unset by default so
164
+ Squisq keeps its own chrome font, and DOCUMENT typography is never touched
165
+ — a theme's fonts are content the author chose, not chrome. */
166
+ --squisq-ux-font: var(--db-ui-font);
167
+ }
168
+
80
169
  :root:has(.db-shell[data-theme='dark']),
81
170
  .db-shell[data-theme='dark'] {
82
171
  --db-bg: #1a1812;
@@ -176,7 +265,8 @@
176
265
  position: relative;
177
266
  }
178
267
 
179
- .db-file-explorer--drop-active::after {
268
+ .db-file-explorer--drop-active::after,
269
+ .db-shell-editor-area--drop-active::after {
180
270
  content: 'Drop to import';
181
271
  position: absolute;
182
272
  inset: 0;
@@ -359,8 +449,9 @@
359
449
  }
360
450
 
361
451
  .db-explorer-btn {
362
- width: 24px;
363
- height: 24px;
452
+ position: relative;
453
+ width: var(--db-control-size);
454
+ height: var(--db-control-size);
364
455
  background: none;
365
456
  border: 1px solid transparent;
366
457
  border-radius: 3px;
@@ -457,6 +548,8 @@
457
548
  background: var(--db-bg);
458
549
  color: var(--db-text);
459
550
  font: inherit;
551
+ /* Longhand after the shorthand: keeps iOS from zooming on focus. */
552
+ font-size: var(--db-input-font-size);
460
553
  }
461
554
 
462
555
  .db-transient-move-hint,
@@ -539,7 +632,7 @@
539
632
  min-width: 0;
540
633
  box-sizing: border-box;
541
634
  padding: 3px 6px;
542
- font-size: 13px;
635
+ font-size: var(--db-input-font-size);
543
636
  background: var(--db-bg);
544
637
  color: var(--db-text);
545
638
  border: 1px solid var(--db-input-border);
@@ -677,6 +770,10 @@
677
770
  .db-tree-row {
678
771
  display: flex;
679
772
  align-items: center;
773
+ /* Long-press opens our own context menu; without this iOS shows its text
774
+ selection callout on top of it. */
775
+ -webkit-touch-callout: none;
776
+ min-height: var(--db-row-min-height);
680
777
  padding: 6px 4px;
681
778
  cursor: pointer;
682
779
  white-space: nowrap;
@@ -763,7 +860,7 @@
763
860
  .db-tree-rename-input {
764
861
  flex: 1;
765
862
  padding: 1px 4px;
766
- font-size: 13px;
863
+ font-size: var(--db-input-font-size);
767
864
  background: var(--db-bg);
768
865
  color: var(--db-text);
769
866
  border: 1px solid var(--db-input-border);
@@ -781,6 +878,7 @@
781
878
  }
782
879
 
783
880
  .db-tree-more {
881
+ position: relative;
784
882
  flex-shrink: 0;
785
883
  display: inline-flex;
786
884
  align-items: center;
@@ -807,10 +905,21 @@
807
905
  visibility: visible;
808
906
  }
809
907
 
810
- @media (hover: none), (pointer: coarse) {
811
- .db-tree-more {
812
- visibility: visible;
813
- }
908
+ /* No hover to reveal on: keep the row's overflow control permanently visible.
909
+ Driven by `any-hover`, so an iPad with a Magic Keyboard keeps hover reveals
910
+ while still getting coarse-pointer hit targets. */
911
+ [data-db-hover='none'] .db-tree-more {
912
+ visibility: visible;
913
+ }
914
+
915
+ /* Grow the touchable area without growing the glyph. Both operands are tokens,
916
+ so on a fine pointer the inset resolves to 0 and nothing moves. The same
917
+ trick the sidebar resizer already uses for its 1px drag handle. */
918
+ .db-tree-more::after,
919
+ .db-explorer-btn::after {
920
+ content: '';
921
+ position: absolute;
922
+ inset: calc((var(--db-control-size) - var(--db-target-min)) / 2);
814
923
  }
815
924
 
816
925
  .db-tree-more:hover {
@@ -978,6 +1087,54 @@
978
1087
  font-weight: 500;
979
1088
  }
980
1089
 
1090
+ /* A listed workspace: the select button plus its ⋯ actions button. The row
1091
+ carries the hover and selected backgrounds so they span both. */
1092
+ .db-workspace-dropdown-row {
1093
+ display: flex;
1094
+ align-items: stretch;
1095
+ }
1096
+
1097
+ .db-workspace-dropdown-row:hover {
1098
+ background: var(--db-bg-hover);
1099
+ }
1100
+
1101
+ .db-workspace-dropdown-row--active {
1102
+ background: var(--db-bg-selected);
1103
+ }
1104
+
1105
+ .db-workspace-dropdown-row .db-workspace-dropdown-item {
1106
+ flex: 1 1 auto;
1107
+ min-width: 0;
1108
+ background: none;
1109
+ }
1110
+
1111
+ .db-workspace-dropdown-more {
1112
+ display: flex;
1113
+ align-items: center;
1114
+ justify-content: center;
1115
+ flex: 0 0 28px;
1116
+ padding: 0;
1117
+ border: 0;
1118
+ background: transparent;
1119
+ color: var(--db-text-muted);
1120
+ cursor: pointer;
1121
+ opacity: 0.72;
1122
+ }
1123
+
1124
+ .db-workspace-dropdown-row--active .db-workspace-dropdown-more {
1125
+ color: var(--db-text-on-selected);
1126
+ }
1127
+
1128
+ .db-workspace-dropdown-more:hover,
1129
+ .db-workspace-dropdown-more[aria-expanded='true'] {
1130
+ opacity: 1;
1131
+ }
1132
+
1133
+ .db-workspace-dropdown-more:focus-visible {
1134
+ outline: 2px solid var(--db-focus);
1135
+ outline-offset: -2px;
1136
+ }
1137
+
981
1138
  .db-workspace-type {
982
1139
  font-size: 11px;
983
1140
  color: var(--db-text-placeholder);
@@ -1018,9 +1175,12 @@
1018
1175
  margin: 4px 0;
1019
1176
  }
1020
1177
 
1178
+ /* 300px when there is room. The picker narrows the dropdown to fit inside the
1179
+ sidebar (see WorkspacePicker), and the form follows it down. */
1021
1180
  .db-workspace-create {
1022
1181
  box-sizing: border-box;
1023
- width: min(300px, calc(100vw - 24px));
1182
+ width: 300px;
1183
+ max-width: 100%;
1024
1184
  padding: 10px;
1025
1185
  }
1026
1186
 
@@ -1042,6 +1202,8 @@
1042
1202
  background: var(--db-bg);
1043
1203
  color: var(--db-text);
1044
1204
  font: inherit;
1205
+ /* Longhand after the shorthand: keeps iOS from zooming on focus. */
1206
+ font-size: var(--db-input-font-size);
1045
1207
  }
1046
1208
 
1047
1209
  .db-workspace-create-input:focus-visible {
@@ -1126,6 +1288,14 @@
1126
1288
  display: block;
1127
1289
  }
1128
1290
 
1291
+ /* The logo is black lettering on a pale extruded edge. On espresso the black
1292
+ fill vanished and only the edges showed, so it read as a hollow outline.
1293
+ Inverting makes the letters solid and sinks the edge into the background,
1294
+ and the sepia warms them toward --db-text. */
1295
+ .db-shell[data-theme='dark'] .db-app-menu-logo {
1296
+ filter: invert(1) brightness(0.88) sepia(0.15);
1297
+ }
1298
+
1129
1299
  .db-app-menu-caret {
1130
1300
  width: 10px;
1131
1301
  height: 6px;
@@ -1265,18 +1435,31 @@
1265
1435
  .db-shell {
1266
1436
  display: flex;
1267
1437
  flex-direction: column;
1438
+ /* Removes the 300ms double-tap-zoom delay without disabling pinch-zoom of
1439
+ the document, which would be an accessibility regression. */
1440
+ touch-action: manipulation;
1441
+ /* Pre-dvh engines keep the old behaviour. This is an @supports block rather
1442
+ than a var() fallback on purpose: a var() that resolves to an unsupported
1443
+ unit becomes invalid-at-computed-value-time (`unset`) instead of falling
1444
+ back to the previous declaration, which would collapse the shell. */
1268
1445
  height: 100vh;
1269
1446
  background: var(--db-bg);
1270
1447
  color: var(--db-text);
1271
- font-family:
1272
- system-ui,
1273
- -apple-system,
1274
- BlinkMacSystemFont,
1275
- 'Segoe UI',
1276
- Roboto,
1277
- 'Helvetica Neue',
1278
- Arial,
1279
- sans-serif;
1448
+ font-family: var(--db-ui-font);
1449
+ }
1450
+
1451
+ /* Keep a rubber-band at the end of the tree from scrolling the page behind it. */
1452
+ .db-shell-sidebar,
1453
+ .db-tree {
1454
+ overscroll-behavior: contain;
1455
+ }
1456
+
1457
+ @supports (height: 100dvh) {
1458
+ .db-shell {
1459
+ /* Tracks the shrinking viewport as mobile browser chrome collapses. Hosts
1460
+ with no dynamic chrome (Electron) override the token to 100%. */
1461
+ height: var(--db-shell-block-size);
1462
+ }
1280
1463
  }
1281
1464
 
1282
1465
  .db-shell-topbar {
@@ -1293,6 +1476,45 @@
1293
1476
  font-size: 14px;
1294
1477
  }
1295
1478
 
1479
+ .db-shell-panes {
1480
+ position: relative;
1481
+ display: flex;
1482
+ flex: 1;
1483
+ min-height: 0;
1484
+ overflow: hidden;
1485
+ }
1486
+
1487
+ /* Vertical scrolling stays with the browser; horizontal is the drawer swipe. */
1488
+ [data-db-layout='single-pane'][data-db-pointer='coarse'] .db-shell-panes {
1489
+ touch-action: pan-y;
1490
+ }
1491
+
1492
+ .db-shell-editor-area {
1493
+ flex: 1;
1494
+ overflow: hidden;
1495
+ display: flex;
1496
+ flex-direction: column;
1497
+ position: relative;
1498
+ /* The editor has its own top chrome beside (or behind) the sidebar.
1499
+ Reserve the cutout once on this pane so every document and empty view
1500
+ clears it, including toolbars that wrap onto multiple rows. */
1501
+ padding-top: var(--db-safe-top);
1502
+ /* Lifts everything bottom-anchored -- including Squisq's status bar -- clear
1503
+ of the home indicator and the on-screen keyboard. iOS does not resize the
1504
+ layout viewport for the keyboard, so without this they sit underneath it.
1505
+ Applied to the pane we own: setting `padding-bottom` on
1506
+ `.squisq-status-bar` REPLACES Squisq's own padding rather than adding to
1507
+ it, which silently shrank the bar by 4px and broke its shared border with
1508
+ the sidebar footer. Both insets are 0 on desktop. */
1509
+ padding-bottom: calc(var(--db-safe-bottom) + var(--db-keyboard-inset));
1510
+ padding-right: var(--db-safe-right);
1511
+ }
1512
+
1513
+ [data-db-layout='single-pane'] .db-shell-editor-area {
1514
+ /* With the drawer closed, the editor also owns the viewport's left edge. */
1515
+ padding-left: var(--db-safe-left);
1516
+ }
1517
+
1296
1518
  .db-shell-sidebar {
1297
1519
  width: 260px;
1298
1520
  display: flex;
@@ -1302,6 +1524,62 @@
1302
1524
  position: relative;
1303
1525
  }
1304
1526
 
1527
+ /* ── Sidebar as an overlay drawer ─────────────────────────────
1528
+ Single-pane lifts the sidebar out of the flex row and floats it over the
1529
+ editor. Both panes stay mounted: hiding with `visibility` keeps the layout
1530
+ boxes alive, so getBoundingClientRect still works for scrollIntoView, the
1531
+ editor never relayouts, and opening the drawer costs one compositor
1532
+ transform. `visibility` also removes the pane from the tab order and the
1533
+ a11y tree; `inert` (applied from React) covers pointer hit-testing too.
1534
+
1535
+ Do NOT change this to `display: none` — that unmounts the layout box and
1536
+ reintroduces the reflow this replaced. */
1537
+ [data-db-layout='single-pane'] .db-shell-sidebar {
1538
+ position: absolute;
1539
+ inset-block: 0;
1540
+ inset-inline-start: 0;
1541
+ z-index: 30;
1542
+ background: var(--db-bg);
1543
+ width: var(--db-drawer-width);
1544
+ padding-inline-start: var(--db-safe-left);
1545
+ border-inline-end: 1px solid var(--db-border-strong);
1546
+ box-shadow: 0 0 40px var(--db-shadow);
1547
+ visibility: hidden;
1548
+ transform: translateX(calc((var(--db-drawer-progress) - 1) * 100%));
1549
+ transition:
1550
+ transform var(--db-drawer-duration) ease,
1551
+ visibility 0s linear var(--db-drawer-duration);
1552
+ }
1553
+
1554
+ [data-db-layout='single-pane'][data-db-drawer='open'] .db-shell-sidebar {
1555
+ --db-drawer-progress: 1;
1556
+ visibility: visible;
1557
+ transition-delay: 0s;
1558
+ /* `transform: none`, not `translateX(0)`. ANY non-none transform makes this
1559
+ element the containing block for `position: fixed` descendants, and the
1560
+ modal overlay (.db-dialog-overlay, `position: fixed; inset: 0`) is rendered
1561
+ inside the sidebar rather than portalled to <body>. With a transform here
1562
+ every dialog opened from the app menu is sized and clipped to the drawer
1563
+ instead of the viewport. Removing it once the drawer is open is visually
1564
+ identical, because progress is 1 and translateX(0) moves nothing. */
1565
+ transform: none;
1566
+ }
1567
+
1568
+ .db-shell-scrim {
1569
+ position: absolute;
1570
+ inset: 0;
1571
+ z-index: 25;
1572
+ background: rgba(0, 0, 0, 0.4);
1573
+ opacity: var(--db-drawer-progress);
1574
+ pointer-events: none;
1575
+ transition: opacity var(--db-drawer-duration) ease;
1576
+ }
1577
+
1578
+ [data-db-drawer='open'] .db-shell-scrim {
1579
+ --db-drawer-progress: 1;
1580
+ pointer-events: auto;
1581
+ }
1582
+
1305
1583
  .db-sidebar-collapse-preview {
1306
1584
  position: absolute;
1307
1585
  inset: 0;
@@ -1417,7 +1695,9 @@ body.db-resizing-sidebar * {
1417
1695
  display: flex;
1418
1696
  align-items: center;
1419
1697
  border-bottom: 1px solid var(--db-border-strong);
1420
- padding: 4px;
1698
+ /* Clears the iOS status bar under `apple-mobile-web-app-status-bar-style:
1699
+ black-translucent`; resolves to plain 4px everywhere else. */
1700
+ padding: calc(4px + var(--db-safe-top)) 4px 4px;
1421
1701
  gap: 4px;
1422
1702
  flex-shrink: 0;
1423
1703
  min-height: 40px;
@@ -1457,8 +1737,9 @@ body.db-resizing-sidebar * {
1457
1737
  align-items: center;
1458
1738
  gap: 6px;
1459
1739
  /* Match the status bar's pinned line box + 8px vertical padding + 1px border. */
1460
- height: 25px;
1461
- padding: 0 12px 0 18px;
1740
+ height: calc(25px + var(--db-safe-bottom));
1741
+ /* Clears the iOS home indicator; 0px on every other surface. */
1742
+ padding: 0 12px var(--db-safe-bottom) 18px;
1462
1743
  border-top: 1px solid var(--db-border-strong);
1463
1744
  flex-shrink: 0;
1464
1745
  font-size: 11px;
@@ -1517,11 +1798,6 @@ body.db-resizing-sidebar * {
1517
1798
 
1518
1799
  /* ── Mobile Layout ──────────────────────────────────────────── */
1519
1800
 
1520
- .db-shell--mobile .db-shell-sidebar {
1521
- width: 100%;
1522
- border-right: none;
1523
- }
1524
-
1525
1801
  .db-shell--mobile:has(.db-mobile-first-run) .db-file-explorer {
1526
1802
  flex: 0 0 170px;
1527
1803
  height: 170px;
@@ -1650,7 +1926,18 @@ body.db-resizing-sidebar * {
1650
1926
  /* The compact layout puts Squisq's overflow trigger part-way along the second
1651
1927
  row, wherever the formatting buttons stop. Its desktop right-aligned
1652
1928
  placement would hang the menu off-canvas from there, so anchor the mobile
1653
- popover to the viewport instead. */
1929
+ popover to the full-width toolbar instead. The trigger's own wrapper must
1930
+ not be the containing block: an offset from it moves with the trigger, and
1931
+ once Squisq kept Insert inline the trigger moved right and the menu ran
1932
+ 89px off a 390px screen. */
1933
+ .db-shell--mobile .squisq-toolbar {
1934
+ position: relative;
1935
+ }
1936
+
1937
+ .db-shell--mobile .squisq-toolbar-overflow {
1938
+ position: static;
1939
+ }
1940
+
1654
1941
  .db-shell--mobile .squisq-editor-shell .squisq-toolbar-overflow-menu {
1655
1942
  right: auto !important;
1656
1943
  left: max(4px, env(safe-area-inset-left)) !important;
@@ -1876,6 +2163,25 @@ body.db-resizing-sidebar * {
1876
2163
  background: rgba(0, 0, 0, 0.4);
1877
2164
  }
1878
2165
 
2166
+ /* Palette-style dialogs (quick-open) sit near the top, where the eye already is. */
2167
+ .db-dialog-overlay--top {
2168
+ align-items: flex-start;
2169
+ padding-top: min(12vh, 96px);
2170
+ }
2171
+
2172
+ /* Present to assistive technology, absent from the layout. */
2173
+ .db-visually-hidden {
2174
+ position: absolute;
2175
+ width: 1px;
2176
+ height: 1px;
2177
+ margin: -1px;
2178
+ padding: 0;
2179
+ overflow: hidden;
2180
+ clip: rect(0 0 0 0);
2181
+ white-space: nowrap;
2182
+ border: 0;
2183
+ }
2184
+
1879
2185
  .db-dialog {
1880
2186
  box-sizing: border-box;
1881
2187
  background: var(--db-bg);
@@ -1947,11 +2253,13 @@ body.db-resizing-sidebar * {
1947
2253
  text-decoration: underline;
1948
2254
  }
1949
2255
 
2256
+ /* Spacing, not "·" glyphs, separates the links: a text separator was left
2257
+ orphaned at the start of the line whenever the row wrapped. */
1950
2258
  .db-dialog-links {
1951
2259
  display: flex;
1952
2260
  flex-wrap: wrap;
1953
2261
  align-items: center;
1954
- gap: 6px;
2262
+ gap: 6px 16px;
1955
2263
  }
1956
2264
 
1957
2265
  .db-about-beta {
@@ -1993,10 +2301,6 @@ body.db-resizing-sidebar * {
1993
2301
  user-select: all;
1994
2302
  }
1995
2303
 
1996
- .db-dialog-sep {
1997
- color: var(--db-text-placeholder);
1998
- }
1999
-
2000
2304
  /* ── Settings Dialog ─────────────────────────────────────────── */
2001
2305
 
2002
2306
  .db-settings-fieldset {
@@ -2025,6 +2329,12 @@ body.db-resizing-sidebar * {
2025
2329
  line-height: 1.5;
2026
2330
  }
2027
2331
 
2332
+ /* A status line stays mounted while empty so later changes are announced, but
2333
+ it should not leave a gap. */
2334
+ .db-settings-hint:empty {
2335
+ margin: 0;
2336
+ }
2337
+
2028
2338
  .db-settings-hint code {
2029
2339
  font-size: 11px;
2030
2340
  background: var(--db-bg-subtle);
@@ -2125,7 +2435,7 @@ body.db-resizing-sidebar * {
2125
2435
  width: 100%;
2126
2436
  padding: 6px 8px;
2127
2437
  font: inherit;
2128
- font-size: 13px;
2438
+ font-size: var(--db-input-font-size);
2129
2439
  background: var(--db-bg-subtle);
2130
2440
  color: var(--db-text);
2131
2441
  border: 1px solid var(--db-input-border);
@@ -2139,6 +2449,130 @@ body.db-resizing-sidebar * {
2139
2449
  border-color: var(--db-accent);
2140
2450
  }
2141
2451
 
2452
+ /* Generated catalog files (index.html, catalog.json): shown, never edited */
2453
+
2454
+ .db-generated-file,
2455
+ .db-generated-file-body {
2456
+ flex: 1;
2457
+ min-height: 0;
2458
+ display: flex;
2459
+ flex-direction: column;
2460
+ }
2461
+
2462
+ .db-generated-file-notice {
2463
+ display: flex;
2464
+ flex-wrap: wrap;
2465
+ align-items: center;
2466
+ gap: 8px 12px;
2467
+ padding: 8px 16px;
2468
+ border-bottom: 1px solid var(--db-border);
2469
+ background: var(--db-bg-subtle);
2470
+ color: var(--db-text-muted);
2471
+ font-size: 13px;
2472
+ line-height: 1.4;
2473
+ }
2474
+
2475
+ .db-generated-file-notice-text {
2476
+ flex: 1 1 240px;
2477
+ min-width: 0;
2478
+ }
2479
+
2480
+ .db-generated-file-notice strong {
2481
+ color: var(--db-text);
2482
+ font-weight: 600;
2483
+ }
2484
+
2485
+ .db-generated-file-back {
2486
+ padding: 4px 8px;
2487
+ border: none;
2488
+ border-radius: 4px;
2489
+ background: none;
2490
+ color: var(--db-text-secondary);
2491
+ font: inherit;
2492
+ cursor: pointer;
2493
+ }
2494
+
2495
+ /* Show the page as a browser would, whatever the app theme: a page that
2496
+ paints no background of its own is drawn on white, never on the app's dark
2497
+ surface (its dark text would vanish). `color-scheme: light` keeps the frame
2498
+ opaque-light rather than inheriting the host's dark canvas. Themed pages
2499
+ paint their own background over this. */
2500
+ .db-generated-file-preview {
2501
+ flex: 1;
2502
+ min-height: 0;
2503
+ width: 100%;
2504
+ border: 0;
2505
+ background: #fff;
2506
+ color-scheme: light;
2507
+ }
2508
+
2509
+ /* Workspace settings (`.docblocks/workspace.json`) */
2510
+
2511
+ .db-settings-subfields {
2512
+ display: flex;
2513
+ flex-direction: column;
2514
+ gap: 10px;
2515
+ margin: 4px 0 10px 24px;
2516
+ }
2517
+
2518
+ .db-settings-text {
2519
+ display: flex;
2520
+ flex-direction: column;
2521
+ gap: 4px;
2522
+ color: var(--db-text);
2523
+ font-size: 13px;
2524
+ }
2525
+
2526
+ .db-settings-text-input {
2527
+ box-sizing: border-box;
2528
+ width: 100%;
2529
+ padding: 6px 8px;
2530
+ font: inherit;
2531
+ font-size: var(--db-input-font-size);
2532
+ background: var(--db-bg-subtle);
2533
+ color: var(--db-text);
2534
+ border: 1px solid var(--db-input-border);
2535
+ border-radius: 4px;
2536
+ outline: none;
2537
+ }
2538
+
2539
+ .db-settings-text-input:focus-visible {
2540
+ border-color: var(--db-accent);
2541
+ }
2542
+
2543
+ .db-settings-textarea {
2544
+ min-height: 3.5em;
2545
+ resize: vertical;
2546
+ font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
2547
+ }
2548
+
2549
+ .db-settings-number-input {
2550
+ max-width: 8em;
2551
+ }
2552
+
2553
+ .db-settings-status-row {
2554
+ display: flex;
2555
+ flex-wrap: wrap;
2556
+ align-items: center;
2557
+ justify-content: space-between;
2558
+ gap: 8px 12px;
2559
+ }
2560
+
2561
+ .db-settings-status {
2562
+ margin: 0;
2563
+ font-size: 12px;
2564
+ line-height: 1.5;
2565
+ color: var(--db-text-muted);
2566
+ }
2567
+
2568
+ .db-settings-status--warning {
2569
+ color: var(--db-danger);
2570
+ }
2571
+
2572
+ .db-settings-link-btn {
2573
+ margin-top: 8px;
2574
+ }
2575
+
2142
2576
  .db-font-picker {
2143
2577
  position: relative;
2144
2578
  }
@@ -2206,11 +2640,7 @@ body.db-resizing-sidebar * {
2206
2640
  .db-font-picker-group {
2207
2641
  padding: 10px 10px 4px;
2208
2642
  color: var(--db-text-muted);
2209
- font:
2210
- 600 10px/1.2 system-ui,
2211
- -apple-system,
2212
- 'Segoe UI',
2213
- sans-serif;
2643
+ font: 600 10px/1.2 var(--db-ui-font);
2214
2644
  letter-spacing: 0.065em;
2215
2645
  text-transform: uppercase;
2216
2646
  }
@@ -2279,11 +2709,7 @@ body.db-resizing-sidebar * {
2279
2709
  .db-font-picker-check {
2280
2710
  flex: 0 0 18px;
2281
2711
  color: var(--db-accent-deep);
2282
- font:
2283
- 700 14px/1 system-ui,
2284
- -apple-system,
2285
- 'Segoe UI',
2286
- sans-serif;
2712
+ font: 700 14px/1 var(--db-ui-font);
2287
2713
  text-align: center;
2288
2714
  }
2289
2715
 
@@ -2320,29 +2746,139 @@ body.db-resizing-sidebar * {
2320
2746
  cursor: default;
2321
2747
  }
2322
2748
 
2323
- .db-settings-accent {
2324
- position: relative;
2325
- display: flex;
2326
- align-items: center;
2327
- gap: 8px;
2328
- min-width: 0;
2329
- padding: 7px 8px;
2330
- border: 1px solid transparent;
2331
- border-radius: 6px;
2749
+ /* The quieter of two actions — Disconnect beside a primary Connect. */
2750
+ .db-settings-action--secondary {
2751
+ border-color: var(--db-input-border);
2752
+ background: transparent;
2332
2753
  color: var(--db-text);
2333
- cursor: pointer;
2334
2754
  }
2335
2755
 
2336
- .db-settings-accent:hover {
2337
- background: var(--db-bg-subtle);
2338
- }
2339
-
2340
- .db-settings-accent--selected {
2341
- background: var(--db-accent-soft-08);
2756
+ .db-settings-action--secondary:hover:not(:disabled) {
2342
2757
  border-color: var(--db-accent);
2758
+ background: var(--db-bg-subtle);
2343
2759
  }
2344
2760
 
2345
- .db-settings-accent-input {
2761
+ /* A one-time code the person types into Gezel: easy to read and to select. */
2762
+ .db-settings-ai-code {
2763
+ font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
2764
+ font-size: 15px;
2765
+ letter-spacing: 0.12em;
2766
+ color: var(--db-text);
2767
+ user-select: all;
2768
+ }
2769
+
2770
+ .db-settings-ai-error {
2771
+ color: var(--db-danger);
2772
+ }
2773
+
2774
+ .db-settings-ai-models {
2775
+ margin-top: 8px;
2776
+ }
2777
+
2778
+ .db-settings-ai-model-downloads {
2779
+ margin-top: 10px;
2780
+ padding: 12px;
2781
+ border: 1px solid var(--db-border);
2782
+ border-radius: 6px;
2783
+ background: var(--db-bg-subtle);
2784
+ }
2785
+
2786
+ .db-settings-ai-model-downloads .db-settings-select {
2787
+ margin-top: 0;
2788
+ }
2789
+
2790
+ .db-settings-ai-download-progress {
2791
+ display: grid;
2792
+ gap: 6px;
2793
+ margin-top: 12px;
2794
+ color: var(--db-text-secondary);
2795
+ font-size: 12px;
2796
+ }
2797
+
2798
+ .db-settings-ai-download-progress progress {
2799
+ width: 100%;
2800
+ height: 8px;
2801
+ accent-color: var(--db-accent);
2802
+ }
2803
+
2804
+ /* Speech settings: dictation and narration model rows. */
2805
+ .db-settings-speech-section + .db-settings-speech-section {
2806
+ margin-top: 14px;
2807
+ }
2808
+
2809
+ .db-settings-subheading {
2810
+ margin: 10px 0 2px;
2811
+ color: var(--db-text);
2812
+ font-size: 13px;
2813
+ font-weight: 600;
2814
+ }
2815
+
2816
+ .db-settings-speech-models {
2817
+ display: grid;
2818
+ gap: 8px;
2819
+ margin: 8px 0 0;
2820
+ padding: 0;
2821
+ list-style: none;
2822
+ }
2823
+
2824
+ .db-settings-speech-model {
2825
+ display: flex;
2826
+ align-items: center;
2827
+ justify-content: space-between;
2828
+ gap: 12px;
2829
+ padding: 10px 12px;
2830
+ border: 1px solid var(--db-border);
2831
+ border-radius: 6px;
2832
+ background: var(--db-bg-subtle);
2833
+ }
2834
+
2835
+ .db-settings-speech-model-text {
2836
+ display: grid;
2837
+ gap: 2px;
2838
+ min-width: 0;
2839
+ }
2840
+
2841
+ .db-settings-speech-model-name {
2842
+ color: var(--db-text);
2843
+ font-size: 13px;
2844
+ }
2845
+
2846
+ .db-settings-speech-model .db-settings-hint {
2847
+ margin: 0;
2848
+ }
2849
+
2850
+ .db-settings-speech-model .db-settings-ai-download-progress {
2851
+ min-width: 140px;
2852
+ margin-top: 0;
2853
+ }
2854
+
2855
+ .db-settings-speech-model .db-settings-action {
2856
+ flex-shrink: 0;
2857
+ }
2858
+
2859
+ .db-settings-accent {
2860
+ position: relative;
2861
+ display: flex;
2862
+ align-items: center;
2863
+ gap: 8px;
2864
+ min-width: 0;
2865
+ padding: 7px 8px;
2866
+ border: 1px solid transparent;
2867
+ border-radius: 6px;
2868
+ color: var(--db-text);
2869
+ cursor: pointer;
2870
+ }
2871
+
2872
+ .db-settings-accent:hover {
2873
+ background: var(--db-bg-subtle);
2874
+ }
2875
+
2876
+ .db-settings-accent--selected {
2877
+ background: var(--db-accent-soft-08);
2878
+ border-color: var(--db-accent);
2879
+ }
2880
+
2881
+ .db-settings-accent-input {
2346
2882
  position: absolute;
2347
2883
  width: 1px;
2348
2884
  height: 1px;
@@ -2676,7 +3212,7 @@ body.db-resizing-sidebar * {
2676
3212
  display: block;
2677
3213
  width: 100%;
2678
3214
  padding: 6px 8px;
2679
- font-size: 13px;
3215
+ font-size: var(--db-input-font-size);
2680
3216
  background: var(--db-bg-subtle);
2681
3217
  color: var(--db-text);
2682
3218
  border: 1px solid var(--db-border);
@@ -2701,7 +3237,7 @@ body.db-resizing-sidebar * {
2701
3237
  min-width: 0;
2702
3238
  box-sizing: border-box;
2703
3239
  padding: 6px 8px;
2704
- font-size: 13px;
3240
+ font-size: var(--db-input-font-size);
2705
3241
  background: var(--db-bg-subtle);
2706
3242
  color: var(--db-text);
2707
3243
  border: 1px solid var(--db-border);
@@ -2985,15 +3521,13 @@ body.db-resizing-sidebar * {
2985
3521
  color: var(--db-text-muted);
2986
3522
  }
2987
3523
 
2988
- @media (max-width: 560px) {
2989
- .db-share-qr-heading {
2990
- display: block;
2991
- }
3524
+ [data-db-width='compact'] .db-share-qr-heading {
3525
+ display: block;
3526
+ }
2992
3527
 
2993
- .db-share-qr-actions {
2994
- justify-content: flex-start;
2995
- margin-top: 10px;
2996
- }
3528
+ [data-db-width='compact'] .db-share-qr-actions {
3529
+ justify-content: flex-start;
3530
+ margin-top: 10px;
2997
3531
  }
2998
3532
 
2999
3533
  /* ── Squisq editor chrome separators ─────────────────────────── */
@@ -3021,6 +3555,12 @@ body.db-resizing-sidebar * {
3021
3555
  background: rgba(255, 255, 255, 0.04);
3022
3556
  }
3023
3557
 
3558
+ /* Squisq also assigns this token directly on its dark toolbar. Bind it at
3559
+ that boundary so readable heading glyphs never inherit placeholder ink. */
3560
+ .db-shell[data-theme] .squisq-editor-shell .squisq-toolbar {
3561
+ --squisq-toolbar-icon: var(--db-text-muted);
3562
+ }
3563
+
3024
3564
  .db-shell[data-theme='dark'] .squisq-toolbar-view-tabs {
3025
3565
  background: var(--db-editor-canvas);
3026
3566
  }
@@ -3556,15 +4096,7 @@ body.db-resizing-sidebar * {
3556
4096
  `var(--db-accent-…)` here drops to the squisq fallback (dark slate
3557
4097
  bg + near-white text) because the vars never resolve. */
3558
4098
  html:has(.db-shell) .squisq-tooltip {
3559
- font-family:
3560
- ui-sans-serif,
3561
- system-ui,
3562
- -apple-system,
3563
- 'Segoe UI',
3564
- Roboto,
3565
- 'Helvetica Neue',
3566
- Arial,
3567
- sans-serif;
4099
+ font-family: var(--db-ui-font);
3568
4100
  box-shadow: 0 2px 8px rgba(15, 30, 20, 0.35);
3569
4101
  /* Default (light mode + system-light): dark espresso chip, cream
3570
4102
  text — an inverted floating chip against the cream UI. */
@@ -4024,7 +4556,7 @@ html:has(.db-shell)
4024
4556
  }
4025
4557
 
4026
4558
  html:has(.db-shell) .squisq-use-mode-menu .squisq-use-mode-menu-summary {
4027
- color: var(--db-text-muted);
4559
+ color: var(--db-text-secondary);
4028
4560
  }
4029
4561
 
4030
4562
  html:has(.db-shell) .squisq-use-mode-menu .squisq-use-mode-menu-check {
@@ -4756,15 +5288,14 @@ html:has(.db-shell[data-theme='dark'])
4756
5288
  }
4757
5289
 
4758
5290
  .db-shell[data-theme='light'] .squisq-editor-shell[data-theme='light'] .squisq-status-bar {
5291
+ --squisq-text-muted: var(--db-text-secondary);
4759
5292
  background: var(--db-accent-tint-strong);
4760
5293
  border-top-color: var(--db-border-strong);
4761
5294
  }
4762
5295
 
4763
- /* Status bar "✓ OK" indicator — squisq paints this in saturated emerald
4764
- (#059669 light, #34d399 dark). Re-tone to the sage accent so the
4765
- status indicator harmonizes with the rest of the chrome. */
5296
+ /* The stronger accent keeps small status text readable on the tinted bar. */
4766
5297
  .db-shell .squisq-status-ok {
4767
- color: var(--db-accent);
5298
+ color: var(--db-accent-hover);
4768
5299
  }
4769
5300
 
4770
5301
  .db-shell[data-theme='dark'] .squisq-status-ok {
@@ -5164,6 +5695,82 @@ html:has(.db-shell[data-theme='dark'])
5164
5695
  outline-offset: 2px;
5165
5696
  }
5166
5697
 
5698
+ .db-conflict-columns {
5699
+ display: grid;
5700
+ grid-template-columns: repeat(2, minmax(0, 1fr));
5701
+ gap: 16px;
5702
+ flex: 1;
5703
+ min-height: 300px;
5704
+ }
5705
+
5706
+ .db-conflict-version {
5707
+ display: flex;
5708
+ flex-direction: column;
5709
+ min-width: 0;
5710
+ padding: 16px;
5711
+ border: 1px solid var(--db-border);
5712
+ border-radius: 8px;
5713
+ }
5714
+
5715
+ .db-conflict-version h3 {
5716
+ margin: 0;
5717
+ color: var(--db-text);
5718
+ font-size: 15px;
5719
+ }
5720
+
5721
+ .db-conflict-metadata {
5722
+ margin: 4px 0 12px;
5723
+ color: var(--db-text-muted);
5724
+ font-size: 12px;
5725
+ }
5726
+
5727
+ .db-conflict-preview {
5728
+ box-sizing: border-box;
5729
+ flex: 1;
5730
+ width: 100%;
5731
+ min-height: 160px;
5732
+ padding: 12px;
5733
+ overflow: auto;
5734
+ color: var(--db-text);
5735
+ background: var(--db-bg-elevated, var(--db-bg));
5736
+ border: 1px solid var(--db-border);
5737
+ border-radius: 4px;
5738
+ font:
5739
+ 13px / 1.6 ui-monospace,
5740
+ monospace;
5741
+ resize: none;
5742
+ }
5743
+
5744
+ .db-conflict-consequence {
5745
+ margin: 12px 0;
5746
+ font-size: 12px;
5747
+ }
5748
+
5749
+ .db-conflict-dialog button:not(.db-dialog-close) {
5750
+ min-height: var(--db-target-min, 32px);
5751
+ padding: 7px 12px;
5752
+ color: var(--db-text);
5753
+ background: var(--db-bg);
5754
+ border: 1px solid var(--db-border);
5755
+ border-radius: 5px;
5756
+ cursor: pointer;
5757
+ }
5758
+
5759
+ .db-conflict-dialog button:disabled {
5760
+ opacity: 0.6;
5761
+ cursor: default;
5762
+ }
5763
+
5764
+ .db-conflict-dialog button:focus-visible,
5765
+ .db-conflict-preview:focus-visible {
5766
+ outline: 2px solid var(--db-accent);
5767
+ outline-offset: 2px;
5768
+ }
5769
+
5770
+ [data-db-width='compact'] .db-conflict-columns {
5771
+ grid-template-columns: minmax(0, 1fr);
5772
+ }
5773
+
5167
5774
  /* Browser PWA update notice. It is docked over the right side of Squisq's
5168
5775
  status bar, while extra status-bar padding keeps its contents visible.
5169
5776
  If the status bar is hidden, it becomes a compact floating badge so the
@@ -5315,788 +5922,1868 @@ html:has(.db-shell[data-theme='dark'])
5315
5922
  }
5316
5923
  }
5317
5924
 
5318
- /* ── Git ─────────────────────────────────────────────────────── */
5925
+ /* ── AI editor assistance ───────────────────────────────────── */
5319
5926
 
5320
- /* Dialog size modifiers (shared Dialog component) */
5321
- .db-dialog--wide {
5322
- width: 560px;
5323
- max-width: 100%;
5324
- max-height: min(calc(100dvh - 32px), 660px);
5927
+ .db-ai-toolbar {
5928
+ border-left: 0;
5325
5929
  }
5326
5930
 
5327
- .db-dialog--full {
5328
- width: min(1100px, 94vw);
5329
- height: 82vh;
5330
- display: flex;
5331
- flex-direction: column;
5931
+ .db-ai-toolbar-trigger {
5932
+ color: var(--db-accent-deep);
5332
5933
  }
5333
5934
 
5334
- .db-dialog--full .db-dialog-body {
5335
- flex: 1;
5336
- min-height: 0;
5337
- overflow: auto;
5338
- display: flex;
5339
- flex-direction: column;
5935
+ .db-ai-toolbar-menu {
5936
+ min-width: 220px;
5340
5937
  }
5341
5938
 
5342
- .db-dialog-footer {
5343
- display: flex;
5344
- justify-content: flex-end;
5345
- gap: 8px;
5346
- padding: 12px 20px 16px;
5347
- border-top: 1px solid var(--db-border);
5939
+ /* Read aloud: the speech menu and its inline transport while playing. */
5940
+ .db-speech-toolbar {
5941
+ display: inline-flex;
5942
+ align-items: center;
5943
+ border-left: 0;
5348
5944
  }
5349
5945
 
5350
- /* Buttons used in git dialog footers */
5351
- .db-git-primary-btn {
5352
- padding: 6px 16px;
5353
- border: none;
5354
- border-radius: 5px;
5355
- background: var(--db-accent);
5356
- color: var(--db-text-on-accent);
5357
- font-size: 13px;
5358
- font-weight: 600;
5359
- cursor: pointer;
5946
+ .db-speech-toolbar-menu {
5947
+ min-width: 220px;
5360
5948
  }
5361
5949
 
5362
- .db-git-primary-btn:hover:not(:disabled) {
5363
- background: var(--db-accent-hover);
5950
+ .db-speech-transport {
5951
+ display: inline-flex;
5952
+ align-items: center;
5953
+ gap: 2px;
5364
5954
  }
5365
5955
 
5366
- .db-git-primary-btn:disabled {
5367
- opacity: 0.5;
5368
- cursor: default;
5956
+ .db-speech-transport-label {
5957
+ min-width: 3.5em;
5958
+ padding: 0 6px;
5959
+ color: var(--db-text-secondary);
5960
+ font-size: 12px;
5961
+ font-variant-numeric: tabular-nums;
5962
+ white-space: nowrap;
5369
5963
  }
5370
5964
 
5371
- /* Destructive confirmation (delete, remove workspace). The foreground comes
5372
- from a token rather than a literal because the two themes need opposite ink:
5373
- light's danger is deep red and carries white at ~6.5:1, while dark's is a
5374
- light red where white would fall to ~2.8:1 and fail WCAG AA. */
5375
- .db-git-primary-btn--danger {
5376
- background: var(--db-danger);
5377
- color: var(--db-text-on-danger);
5965
+ .db-ai-toolbar-status {
5966
+ max-width: 280px;
5967
+ padding: 7px 12px;
5968
+ color: var(--db-text-muted);
5969
+ font-size: 11px;
5970
+ line-height: 1.4;
5971
+ white-space: normal;
5378
5972
  }
5379
5973
 
5380
- .db-git-primary-btn--danger:hover:not(:disabled) {
5381
- background: color-mix(in srgb, var(--db-danger) 85%, black);
5974
+ .db-ai-draft-dialog {
5975
+ width: min(680px, 100%);
5382
5976
  }
5383
5977
 
5384
- .db-git-secondary-btn {
5385
- padding: 6px 14px;
5386
- border: 1px solid var(--db-border-strong);
5387
- border-radius: 5px;
5388
- background: transparent;
5389
- color: var(--db-text);
5390
- font-size: 13px;
5391
- cursor: pointer;
5978
+ .db-ai-draft-dialog .db-dialog-footer {
5979
+ flex-wrap: wrap;
5980
+ align-items: center;
5392
5981
  }
5393
5982
 
5394
- .db-git-secondary-btn:hover:not(:disabled) {
5395
- background: var(--db-bg-hover);
5983
+ .db-ai-draft-dialog .db-dialog-header,
5984
+ .db-ai-draft-dialog .db-dialog-footer {
5985
+ flex-shrink: 0;
5396
5986
  }
5397
5987
 
5398
- .db-git-secondary-btn:disabled {
5399
- opacity: 0.5;
5400
- cursor: default;
5988
+ .db-ai-draft-dialog .db-ai-draft-body {
5989
+ display: flex;
5990
+ flex-direction: column;
5991
+ gap: 12px;
5401
5992
  }
5402
5993
 
5403
- /* Status bar row in the sidebar */
5404
- .db-git-statusbar {
5405
- position: relative;
5994
+ .db-ai-draft-body > .db-ai-field,
5995
+ .db-ai-draft-body > .db-ai-selection-preview,
5996
+ .db-ai-draft-body > .db-ai-disclaimer {
5406
5997
  flex-shrink: 0;
5407
- padding: 2px 8px 4px;
5408
- border-bottom: 1px solid var(--db-border);
5998
+ margin: 0;
5409
5999
  }
5410
6000
 
5411
- .db-git-statusbar-chip {
6001
+ /* Let the draft yield space to the prompt, selection and review note. The
6002
+ body still scrolls when a short viewport cannot fit their minimum sizes. */
6003
+ .db-ai-draft-body > .db-ai-draft-field {
5412
6004
  display: flex;
5413
- align-items: center;
5414
- gap: 6px;
5415
- width: 100%;
5416
- padding: 4px 8px;
5417
- border: none;
5418
- border-radius: 4px;
5419
- background: transparent;
5420
- color: var(--db-text-secondary);
5421
- font-size: 12px;
5422
- cursor: pointer;
5423
- overflow: hidden;
6005
+ flex-direction: column;
6006
+ flex: 1 1 auto;
6007
+ min-height: calc(96px + 1.6em + 6px);
5424
6008
  }
5425
6009
 
5426
- .db-git-statusbar-chip:hover {
5427
- background: var(--db-bg-hover);
6010
+ .db-ai-draft-body .db-ai-draft-field .db-ai-draft-output {
6011
+ flex: 1 1 auto;
6012
+ height: min(190px, 28dvh);
6013
+ min-height: 96px;
5428
6014
  }
5429
6015
 
5430
- .db-git-branch-glyph {
5431
- color: var(--db-text-muted);
5432
- flex-shrink: 0;
6016
+ .db-ai-draft-start {
6017
+ display: flex;
6018
+ justify-content: center;
6019
+ padding: 20px 0;
5433
6020
  }
5434
6021
 
5435
- .db-git-statusbar-branch {
5436
- font-weight: 600;
5437
- white-space: nowrap;
5438
- overflow: hidden;
5439
- text-overflow: ellipsis;
6022
+ .db-ai-draft-body .db-ai-selection-preview blockquote {
6023
+ box-sizing: border-box;
6024
+ max-height: min(112px, 16dvh);
5440
6025
  }
5441
6026
 
5442
- .db-git-statusbar-counts {
5443
- color: var(--db-text-muted);
5444
- flex-shrink: 0;
6027
+ .db-ai-draft-dialog .db-ai-draft-footer {
6028
+ flex-direction: column;
6029
+ align-items: stretch;
5445
6030
  }
5446
6031
 
5447
- .db-git-statusbar-dirty {
5448
- color: var(--db-git-modified);
5449
- flex-shrink: 0;
6032
+ .db-ai-draft-actions {
6033
+ display: flex;
6034
+ justify-content: flex-end;
6035
+ flex-wrap: wrap;
6036
+ gap: 8px;
5450
6037
  }
5451
6038
 
5452
- .db-git-statusbar-merge {
5453
- color: var(--db-git-conflicted);
5454
- font-weight: 600;
5455
- flex-shrink: 0;
6039
+ /* Status has its own row, so errors cannot steal space from the actions. */
6040
+ .db-ai-footer-status {
6041
+ min-width: 0;
6042
+ overflow-wrap: anywhere;
5456
6043
  }
5457
6044
 
5458
- .db-git-statusbar-busy {
5459
- color: var(--db-text-muted);
5460
- flex-shrink: 0;
6045
+ .db-ai-footer-status p {
6046
+ margin: 0;
5461
6047
  }
5462
6048
 
5463
- /* The offer to turn Git on for a folder inside a larger repository. It sits
5464
- directly above the sidebar footer and borrows its voice: muted, 11px, no
5465
- icon and no accent — this is a default the user may change, not a fault. */
5466
- .db-git-grant-notice {
5467
- box-sizing: border-box;
5468
- display: flex;
5469
- align-items: center;
6049
+ .db-ai-field {
6050
+ display: grid;
5470
6051
  gap: 6px;
5471
- flex-shrink: 0;
5472
- padding: 6px 12px 6px 18px;
5473
- border-top: 1px solid var(--db-border);
6052
+ margin-bottom: 14px;
6053
+ color: var(--db-text);
6054
+ font-weight: 600;
6055
+ }
6056
+
6057
+ .db-ai-field textarea {
6058
+ box-sizing: border-box;
6059
+ width: 100%;
6060
+ min-height: 72px;
6061
+ padding: 9px 10px;
6062
+ resize: vertical;
6063
+ border: 1px solid var(--db-input-border);
6064
+ border-radius: 5px;
6065
+ outline: none;
6066
+ background: var(--db-bg-subtle);
6067
+ color: var(--db-text);
6068
+ font: 400 var(--db-input-font-size) / 1.5 var(--db-ui-font);
6069
+ }
6070
+
6071
+ .db-ai-field textarea:focus-visible {
6072
+ border-color: var(--db-accent);
6073
+ box-shadow: 0 0 0 1px var(--db-accent);
6074
+ }
6075
+
6076
+ .db-ai-field .db-ai-draft-output {
6077
+ min-height: 190px;
6078
+ font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
6079
+ font-size: 12px;
6080
+ font-weight: 400;
6081
+ }
6082
+
6083
+ .db-ai-selection-preview {
6084
+ margin: 0 0 14px;
5474
6085
  color: var(--db-text-muted);
5475
- font-size: 11px;
5476
- line-height: 1.3;
6086
+ font-size: 12px;
5477
6087
  }
5478
6088
 
5479
- .db-git-grant-notice-text {
5480
- overflow: hidden;
5481
- text-overflow: ellipsis;
5482
- white-space: nowrap;
6089
+ /* A whole-document selection must not push the draft below the dialog. */
6090
+ .db-ai-selection-preview blockquote {
6091
+ max-height: calc(8 * 1.5em + 16px);
6092
+ border: 1px solid var(--db-input-border);
6093
+ border-radius: 5px;
5483
6094
  }
5484
6095
 
5485
- .db-git-grant-notice-action {
5486
- flex-shrink: 0;
5487
- padding: 0;
5488
- border: 0;
5489
- background: transparent;
5490
- color: inherit;
5491
- font: inherit;
5492
- line-height: inherit;
5493
- text-decoration: underline;
5494
- white-space: nowrap;
5495
- cursor: pointer;
6096
+ .db-ai-selection-preview blockquote:focus-visible {
6097
+ outline: 2px solid var(--db-focus);
6098
+ outline-offset: 2px;
5496
6099
  }
5497
6100
 
5498
- .db-git-grant-notice-action:hover {
6101
+ .db-ai-selection-preview blockquote,
6102
+ .db-ai-review-excerpt blockquote {
6103
+ margin: 5px 0 0;
6104
+ padding: 8px 10px;
6105
+ overflow: auto;
6106
+ background: var(--db-bg-subtle);
5499
6107
  color: var(--db-text-secondary);
6108
+ font:
6109
+ 400 12px/1.5 ui-monospace,
6110
+ SFMono-Regular,
6111
+ Consolas,
6112
+ monospace;
6113
+ white-space: pre-wrap;
6114
+ overflow-wrap: anywhere;
5500
6115
  }
5501
6116
 
5502
- .db-git-grant-remember {
6117
+ .db-ai-review-excerpt blockquote {
6118
+ border-left: 3px solid var(--db-border-strong);
6119
+ }
6120
+
6121
+ .db-ai-progress,
6122
+ .db-ai-note,
6123
+ .db-ai-error,
6124
+ .db-ai-disclaimer {
6125
+ font-size: 12px;
6126
+ }
6127
+
6128
+ .db-ai-progress {
5503
6129
  display: flex;
5504
6130
  align-items: center;
5505
- gap: 8px;
5506
- margin: 12px 0;
5507
- font-size: 13px;
5508
- color: var(--db-text);
5509
- cursor: pointer;
6131
+ gap: 7px;
6132
+ color: var(--db-text-secondary);
5510
6133
  }
5511
6134
 
5512
- /* Actions dropdown (mirrors db-ws-settings-dropdown) */
5513
- .db-git-menu {
5514
- position: absolute;
5515
- top: 100%;
5516
- left: 8px;
5517
- right: 8px;
5518
- z-index: 100;
5519
- background: var(--db-bg);
5520
- border: 1px solid var(--db-border);
5521
- border-radius: 6px;
5522
- box-shadow: 0 4px 12px var(--db-shadow);
5523
- padding: 4px 0;
5524
- margin-top: 2px;
6135
+ .db-ai-generation-status {
6136
+ display: grid;
6137
+ gap: 6px;
5525
6138
  }
5526
6139
 
5527
- .db-git-menu-item {
5528
- display: block;
6140
+ .db-ai-generation-status progress {
5529
6141
  width: 100%;
5530
- padding: 7px 14px;
5531
- border: none;
5532
- background: transparent;
5533
- text-align: left;
5534
- font-size: 13px;
5535
- color: var(--db-text);
5536
- cursor: pointer;
6142
+ height: 6px;
6143
+ accent-color: var(--db-accent);
5537
6144
  }
5538
6145
 
5539
- .db-git-menu-item:hover:not(:disabled),
5540
- .db-git-menu-item:focus-visible {
5541
- background: var(--db-bg-hover);
6146
+ .db-ai-error {
6147
+ color: var(--db-danger);
5542
6148
  }
5543
6149
 
5544
- /* Items are arrow-reachable rather than tab stops, so the ring is the only
5545
- cue to which one Enter will fire. */
5546
- .db-git-menu-item:focus-visible {
5547
- outline: 2px solid var(--db-focus);
5548
- outline-offset: -2px;
6150
+ .db-ai-note,
6151
+ .db-ai-disclaimer {
6152
+ color: var(--db-text-muted);
5549
6153
  }
5550
6154
 
5551
- .db-git-menu-item:disabled {
5552
- color: var(--db-text-placeholder);
5553
- cursor: default;
6155
+ .db-ai-spinner {
6156
+ display: inline-block;
6157
+ width: 12px;
6158
+ height: 12px;
6159
+ flex: 0 0 12px;
6160
+ box-sizing: border-box;
6161
+ border: 2px solid var(--db-border-strong);
6162
+ border-top-color: var(--db-accent);
6163
+ border-radius: 50%;
6164
+ animation: db-ai-spin 0.8s linear infinite;
5554
6165
  }
5555
6166
 
5556
- .db-git-menu-divider {
5557
- height: 1px;
5558
- background: var(--db-border);
5559
- margin: 4px 0;
6167
+ @keyframes db-ai-spin {
6168
+ to {
6169
+ transform: rotate(360deg);
6170
+ }
5560
6171
  }
5561
6172
 
5562
- /* aria-live op-result line — visually subtle, announced politely */
5563
- .db-git-inline-status {
5564
- display: block;
5565
- padding: 0 16px;
5566
- font-size: 11px;
5567
- color: var(--db-text-muted);
5568
- min-height: 0;
6173
+ .db-text-from-narration button:not(.db-dialog-close),
6174
+ .db-ai-draft-dialog .db-dialog-footer button,
6175
+ .db-ai-draft-start button,
6176
+ .db-ai-review-panel button {
6177
+ min-height: var(--db-target-min);
6178
+ padding: 6px 10px;
6179
+ border: 1px solid var(--db-input-border);
6180
+ border-radius: 5px;
6181
+ background: var(--db-bg);
6182
+ color: var(--db-text-secondary);
6183
+ font: 600 12px/1.2 var(--db-ui-font);
6184
+ cursor: pointer;
5569
6185
  }
5570
6186
 
5571
- .db-git-inline-status:empty {
5572
- display: none;
6187
+ .db-text-from-narration .db-dialog-footer button:last-child,
6188
+ .db-ai-draft-dialog .db-dialog-footer button:last-child,
6189
+ .db-ai-draft-start button,
6190
+ .db-ai-review-finding-actions button:last-child,
6191
+ .db-ai-review-actions button {
6192
+ border-color: var(--db-accent);
6193
+ background: var(--db-accent);
6194
+ color: var(--db-text-on-accent);
5573
6195
  }
5574
6196
 
5575
- /* File-tree badges */
5576
- .db-git-badge {
5577
- margin-left: auto;
5578
- padding: 0 4px;
5579
- font-size: 10px;
5580
- font-weight: 700;
5581
- flex-shrink: 0;
6197
+ .db-text-from-narration button:not(.db-dialog-close):hover:not(:disabled),
6198
+ .db-ai-draft-dialog .db-dialog-footer button:hover:not(:disabled),
6199
+ .db-ai-draft-start button:hover,
6200
+ .db-ai-review-panel button:hover:not(:disabled) {
6201
+ border-color: var(--db-accent-hover);
6202
+ background: var(--db-bg-hover);
6203
+ color: var(--db-text);
5582
6204
  }
5583
6205
 
5584
- .db-tree-row .db-git-badge {
5585
- margin-left: 4px;
6206
+ .db-text-from-narration button:focus-visible,
6207
+ .db-text-from-narration textarea:focus-visible,
6208
+ .db-ai-draft-dialog .db-dialog-footer button:focus-visible,
6209
+ .db-ai-draft-start button:focus-visible,
6210
+ .db-ai-review-panel button:focus-visible {
6211
+ outline: 2px solid var(--db-focus);
6212
+ outline-offset: 2px;
5586
6213
  }
5587
6214
 
5588
- .db-git-badge--modified {
5589
- color: var(--db-git-modified);
6215
+ .db-text-from-narration button:disabled,
6216
+ .db-ai-draft-dialog .db-dialog-footer button:disabled,
6217
+ .db-ai-review-panel button:disabled {
6218
+ opacity: 0.5;
6219
+ cursor: default;
5590
6220
  }
5591
6221
 
5592
- .db-git-badge--added {
5593
- color: var(--db-git-added);
6222
+ .db-ai-review-panel {
6223
+ position: relative;
6224
+ z-index: 5;
6225
+ width: min(360px, 38vw);
6226
+ min-width: 280px;
6227
+ min-height: 0;
6228
+ flex: 0 0 auto;
6229
+ box-sizing: border-box;
6230
+ overflow-y: auto;
6231
+ border-left: 1px solid var(--db-border-strong);
6232
+ background: var(--db-bg);
6233
+ color: var(--db-text-secondary);
6234
+ font: 13px/1.45 var(--db-ui-font);
5594
6235
  }
5595
6236
 
5596
- .db-git-badge--untracked {
5597
- color: var(--db-git-untracked);
6237
+ [data-db-width='compact'] .db-ai-review-panel {
6238
+ position: absolute;
6239
+ inset: 0;
6240
+ width: 100%;
6241
+ min-width: 0;
6242
+ border-left: 0;
5598
6243
  }
5599
6244
 
5600
- .db-git-badge--renamed {
5601
- color: var(--db-git-renamed);
6245
+ .db-ai-review-header {
6246
+ position: sticky;
6247
+ top: 0;
6248
+ z-index: 1;
6249
+ display: flex;
6250
+ align-items: flex-start;
6251
+ justify-content: space-between;
6252
+ gap: 12px;
6253
+ padding: 14px 14px 10px;
6254
+ border-bottom: 1px solid var(--db-border);
6255
+ background: var(--db-bg);
5602
6256
  }
5603
6257
 
5604
- .db-git-badge--deleted {
5605
- color: var(--db-git-deleted);
6258
+ .db-ai-review-header h2 {
6259
+ margin: 0;
6260
+ color: var(--db-text);
6261
+ font-size: 15px;
6262
+ line-height: 1.3;
5606
6263
  }
5607
6264
 
5608
- .db-git-badge--conflicted {
5609
- color: var(--db-git-conflicted);
6265
+ .db-ai-review-count {
6266
+ color: var(--db-text-muted);
6267
+ font-size: 11px;
5610
6268
  }
5611
6269
 
5612
- .db-git-badge--dir {
5613
- color: var(--db-git-modified);
6270
+ .db-ai-review-close {
6271
+ width: var(--db-target-min);
6272
+ padding: 0 !important;
6273
+ border-color: transparent !important;
6274
+ background: transparent !important;
6275
+ font-size: 20px !important;
6276
+ line-height: 1 !important;
5614
6277
  }
5615
6278
 
5616
- .db-tree-context-divider {
5617
- height: 1px;
5618
- background: var(--db-border);
5619
- margin: 4px 0;
6279
+ .db-ai-review-actions {
6280
+ padding: 10px 14px 0;
5620
6281
  }
5621
6282
 
5622
- /* Toolbar control */
5623
- .db-git-toolbar-trigger {
5624
- position: relative;
6283
+ .db-ai-review-empty,
6284
+ .db-ai-review-stale {
6285
+ margin: 12px 14px;
6286
+ padding: 10px;
6287
+ border: 1px solid var(--db-border);
6288
+ border-radius: 5px;
6289
+ background: var(--db-bg-subtle);
6290
+ color: var(--db-text-muted);
5625
6291
  }
5626
6292
 
5627
- .db-git-toolbar-dot {
5628
- position: absolute;
5629
- top: 3px;
5630
- right: 3px;
5631
- width: 7px;
5632
- height: 7px;
5633
- border-radius: 50%;
5634
- background: var(--db-git-modified);
6293
+ .db-ai-review-stale {
6294
+ border-color: var(--db-accent);
6295
+ color: var(--db-text-secondary);
5635
6296
  }
5636
6297
 
5637
- /* Dialog internals — file lists (commit + conflicts) */
5638
- .db-git-file-list {
5639
- margin: 8px 0;
5640
- padding: 0;
6298
+ .db-ai-review-list {
6299
+ display: grid;
6300
+ gap: 10px;
6301
+ margin: 12px 0 0;
6302
+ padding: 0 14px;
5641
6303
  list-style: none;
5642
- max-height: 260px;
5643
- overflow-y: auto;
6304
+ }
6305
+
6306
+ .db-ai-review-finding {
6307
+ padding: 12px;
5644
6308
  border: 1px solid var(--db-border);
5645
- border-radius: 5px;
6309
+ border-radius: 6px;
6310
+ background: var(--db-bg);
6311
+ box-shadow: 0 1px 2px var(--db-shadow);
5646
6312
  }
5647
6313
 
5648
- .db-git-file-row {
6314
+ .db-ai-review-finding-meta {
5649
6315
  display: flex;
5650
6316
  align-items: center;
5651
- gap: 8px;
5652
- width: 100%;
5653
- padding: 6px 10px;
5654
- border: none;
5655
- background: transparent;
5656
- font-size: 12.5px;
5657
- color: var(--db-text);
5658
- text-align: left;
5659
- }
5660
-
5661
- .db-git-file-row + .db-git-file-row {
5662
- border-top: 1px solid var(--db-border);
6317
+ gap: 7px;
6318
+ color: var(--db-text-muted);
6319
+ font-size: 11px;
5663
6320
  }
5664
6321
 
5665
- button.db-git-file-row {
5666
- cursor: pointer;
6322
+ .db-ai-review-severity {
6323
+ padding: 2px 5px;
6324
+ border: 1px solid var(--db-border);
6325
+ border-radius: 3px;
6326
+ text-transform: uppercase;
6327
+ letter-spacing: 0.04em;
5667
6328
  }
5668
6329
 
5669
- button.db-git-file-row:hover {
5670
- background: var(--db-bg-hover);
6330
+ .db-ai-review-severity--warning {
6331
+ border-color: var(--db-danger);
6332
+ color: var(--db-danger);
5671
6333
  }
5672
6334
 
5673
- .db-git-file-kind {
5674
- margin-left: auto;
5675
- font-size: 10.5px;
5676
- color: var(--db-text-muted);
5677
- flex-shrink: 0;
6335
+ .db-ai-review-severity--suggestion {
6336
+ border-color: var(--db-accent);
6337
+ color: var(--db-accent-deep);
5678
6338
  }
5679
6339
 
5680
- .db-git-commit-message {
5681
- width: 100%;
5682
- min-height: 72px;
5683
- padding: 8px 10px;
5684
- border: 1px solid var(--db-input-border);
5685
- border-radius: 5px;
5686
- background: var(--db-bg);
6340
+ .db-ai-review-finding h3 {
6341
+ margin: 8px 0 5px;
5687
6342
  color: var(--db-text);
5688
6343
  font-size: 13px;
5689
- font-family: inherit;
5690
- resize: vertical;
5691
- box-sizing: border-box;
5692
6344
  }
5693
6345
 
5694
- /* Generic form rows in git dialogs */
5695
- .db-git-form-row {
5696
- display: flex;
5697
- align-items: center;
5698
- gap: 8px;
5699
- margin: 10px 0;
6346
+ .db-ai-review-finding p {
6347
+ margin: 0 0 8px;
5700
6348
  }
5701
6349
 
5702
- .db-git-form-label {
5703
- font-size: 12.5px;
5704
- color: var(--db-text-secondary);
5705
- flex-shrink: 0;
6350
+ .db-ai-review-excerpt {
6351
+ margin-top: 10px;
6352
+ color: var(--db-text-muted);
6353
+ font-size: 11px;
5706
6354
  }
5707
6355
 
5708
- .db-git-form-input {
5709
- flex: 1;
5710
- padding: 6px 10px;
5711
- border: 1px solid var(--db-input-border);
5712
- border-radius: 5px;
5713
- background: var(--db-bg);
5714
- color: var(--db-text);
5715
- font-size: 13px;
5716
- box-sizing: border-box;
6356
+ .db-ai-review-excerpt--replacement blockquote {
6357
+ border-left-color: var(--db-accent);
6358
+ background: var(--db-accent-soft-08);
5717
6359
  }
5718
6360
 
5719
- .db-git-form-error,
5720
- .db-export-error {
5721
- margin: 8px 0 0;
5722
- color: var(--db-danger);
5723
- font-size: 12.5px;
6361
+ .db-ai-review-finding-actions {
6362
+ display: flex;
6363
+ justify-content: flex-end;
6364
+ gap: 7px;
6365
+ margin-top: 10px;
5724
6366
  }
5725
6367
 
5726
- .db-git-hint {
5727
- color: var(--db-text-muted);
5728
- font-size: 12px;
6368
+ .db-settings-ai-knowledge-list {
6369
+ list-style: none;
6370
+ margin: 0;
6371
+ padding: 0;
5729
6372
  }
5730
6373
 
5731
- /* Branches dialog */
5732
- .db-git-branch-list {
5733
- margin: 8px 0;
5734
- padding: 0;
5735
- list-style: none;
5736
- max-height: 280px;
5737
- overflow-y: auto;
6374
+ .db-settings-ai-knowledge-list > li {
6375
+ border-top: 1px solid var(--db-border);
6376
+ padding-block: 12px;
6377
+ overflow-wrap: anywhere;
5738
6378
  }
5739
6379
 
5740
- .db-git-branch-row {
6380
+ .db-settings-ai-knowledge-actions {
5741
6381
  display: flex;
6382
+ flex-wrap: wrap;
5742
6383
  align-items: center;
5743
6384
  gap: 8px;
5744
- width: 100%;
5745
- padding: 7px 10px;
5746
- border: none;
5747
- border-radius: 4px;
5748
- background: transparent;
5749
- font-size: 13px;
5750
- color: var(--db-text);
5751
- text-align: left;
5752
- cursor: pointer;
5753
6385
  }
5754
6386
 
5755
- .db-git-branch-row:hover {
5756
- background: var(--db-bg-hover);
6387
+ .db-settings-ai-knowledge progress {
6388
+ max-width: 100%;
5757
6389
  }
5758
6390
 
5759
- .db-git-branch-row--current {
5760
- font-weight: 600;
5761
- color: var(--db-accent);
5762
- cursor: default;
6391
+ .db-ai-review-disclaimer {
6392
+ margin: 14px;
6393
+ color: var(--db-text-muted);
6394
+ font-size: 11px;
5763
6395
  }
5764
6396
 
5765
- .db-git-branch-row--current:hover {
5766
- background: transparent;
6397
+ /* AI diagrams: the Illustrate panel cards and the Insert diagram dialog. */
6398
+ .db-ai-illustrate-kind {
6399
+ border-color: var(--db-accent);
6400
+ color: var(--db-accent-deep);
5767
6401
  }
5768
6402
 
5769
- /* History dialog */
5770
- .db-git-history-list {
5771
- margin: 8px 0;
5772
- padding: 0;
5773
- list-style: none;
6403
+ .db-ai-illustrate-actions {
6404
+ flex-wrap: wrap;
6405
+ align-items: center;
5774
6406
  }
5775
6407
 
5776
- .db-git-history-item {
5777
- padding: 8px 10px;
5778
- border-bottom: 1px solid var(--db-border);
5779
- cursor: pointer;
6408
+ .db-ai-illustrate-actions select,
6409
+ .db-ai-field--inline select {
6410
+ min-height: var(--db-target-min);
6411
+ border: 1px solid var(--db-border-strong);
6412
+ border-radius: 5px;
6413
+ background: var(--db-bg);
6414
+ color: var(--db-text);
6415
+ font: inherit;
5780
6416
  }
5781
6417
 
5782
- .db-git-history-item:hover {
5783
- background: var(--db-bg-hover);
6418
+ .db-ai-illustrate-footer {
6419
+ position: sticky;
6420
+ bottom: 0;
6421
+ padding-bottom: 10px;
6422
+ background: var(--db-bg);
5784
6423
  }
5785
6424
 
5786
- .db-git-history-meta {
5787
- margin-top: 2px;
5788
- font-size: 11.5px;
5789
- color: var(--db-text-muted);
6425
+ .db-ai-field--inline {
6426
+ display: flex;
6427
+ align-items: center;
6428
+ gap: 10px;
5790
6429
  }
5791
6430
 
5792
- .db-git-history-files {
5793
- margin: 6px 0 0;
5794
- padding: 0;
5795
- list-style: none;
6431
+ .db-ai-diagram-preview {
6432
+ margin: 10px 0 6px;
6433
+ max-height: 340px;
6434
+ overflow: auto;
6435
+ border: 1px solid var(--db-border);
6436
+ border-radius: 6px;
6437
+ background: var(--db-bg-subtle);
5796
6438
  }
5797
6439
 
5798
- .db-git-history-file {
5799
- display: flex;
5800
- align-items: center;
5801
- gap: 8px;
5802
- width: 100%;
5803
- padding: 4px 8px;
5804
- border: none;
5805
- background: transparent;
5806
- font-size: 12px;
6440
+ .db-ai-diagram-dialog .db-ai-diagram-preview {
6441
+ max-height: 420px;
6442
+ }
6443
+
6444
+ .db-ai-diagram-source {
6445
+ max-height: 220px;
6446
+ overflow: auto;
6447
+ margin: 6px 0 0;
6448
+ padding: 8px;
6449
+ border: 1px solid var(--db-border);
6450
+ border-radius: 5px;
6451
+ background: var(--db-bg-subtle);
5807
6452
  color: var(--db-text-secondary);
5808
- text-align: left;
5809
- cursor: pointer;
5810
- border-radius: 4px;
6453
+ font:
6454
+ 11px/1.4 ui-monospace,
6455
+ SFMono-Regular,
6456
+ Consolas,
6457
+ monospace;
6458
+ white-space: pre;
5811
6459
  }
5812
6460
 
5813
- .db-git-history-file:hover {
5814
- background: var(--db-bg-hover);
6461
+ .db-ai-link-button {
6462
+ padding: 0;
6463
+ border: 0;
6464
+ background: none;
6465
+ color: var(--db-accent-deep);
6466
+ font: inherit;
6467
+ text-decoration: underline;
6468
+ cursor: pointer;
5815
6469
  }
5816
6470
 
5817
- /* Diff dialog */
5818
- .db-git-diff-host {
5819
- flex: 1;
5820
- min-height: 320px;
5821
- border: 1px solid var(--db-border);
5822
- border-radius: 5px;
5823
- overflow: hidden;
6471
+ @media (prefers-reduced-motion: reduce) {
6472
+ .db-ai-spinner {
6473
+ animation: none;
6474
+ }
5824
6475
  }
5825
6476
 
5826
- .db-git-diff-loading {
5827
- padding: 24px;
5828
- text-align: center;
5829
- color: var(--db-text-muted);
6477
+ /* ── Git ─────────────────────────────────────────────────────── */
6478
+
6479
+ /* Dialog size modifiers (shared Dialog component) */
6480
+ .db-dialog--wide {
6481
+ width: 560px;
6482
+ max-width: 100%;
6483
+ max-height: min(calc(100dvh - 32px), 660px);
5830
6484
  }
5831
6485
 
5832
- .db-git-diff-labels {
6486
+ .db-dialog--full {
6487
+ width: min(1100px, 94vw);
6488
+ height: 82vh;
5833
6489
  display: flex;
5834
- gap: 12px;
5835
- margin-bottom: 6px;
5836
- font-size: 12px;
5837
- color: var(--db-text-muted);
6490
+ flex-direction: column;
5838
6491
  }
5839
6492
 
5840
- .db-git-diff-labels > span {
6493
+ .db-dialog--full .db-dialog-body {
5841
6494
  flex: 1;
6495
+ min-height: 0;
6496
+ overflow: auto;
6497
+ display: flex;
6498
+ flex-direction: column;
5842
6499
  }
5843
6500
 
5844
- /* Clone progress */
5845
- .db-git-progress {
5846
- margin: 12px 0 4px;
6501
+ .db-dialog-footer {
6502
+ display: flex;
6503
+ justify-content: flex-end;
6504
+ gap: 8px;
6505
+ padding: 12px 20px 16px;
6506
+ border-top: 1px solid var(--db-border);
5847
6507
  }
5848
6508
 
5849
- .db-git-progress-bar {
5850
- height: 6px;
5851
- border-radius: 3px;
5852
- background: var(--db-accent-soft-15);
5853
- overflow: hidden;
5854
- position: relative;
6509
+ /* Buttons used in git dialog footers */
6510
+ .db-git-primary-btn {
6511
+ padding: 6px 16px;
6512
+ border: none;
6513
+ border-radius: 5px;
6514
+ background: var(--db-accent);
6515
+ color: var(--db-text-on-accent);
6516
+ font-size: 13px;
6517
+ font-weight: 600;
6518
+ cursor: pointer;
5855
6519
  }
5856
6520
 
5857
- .db-git-progress-bar > span {
5858
- display: block;
5859
- height: 100%;
5860
- background: var(--db-accent);
5861
- transition: width 0.2s;
6521
+ .db-git-primary-btn:hover:not(:disabled) {
6522
+ background: var(--db-accent-hover);
5862
6523
  }
5863
6524
 
5864
- .db-git-progress-text {
5865
- margin-top: 6px;
5866
- font-size: 12px;
5867
- color: var(--db-text-muted);
6525
+ .db-git-primary-btn:disabled {
6526
+ opacity: 0.5;
6527
+ cursor: default;
5868
6528
  }
5869
6529
 
5870
- @media (prefers-reduced-motion: reduce) {
5871
- .db-workspace-picker-caret,
5872
- .db-app-menu-caret,
5873
- .db-ws-settings-btn,
5874
- .db-shell-sidebar-resizer,
5875
- .db-sidebar-collapse-preview,
5876
- .db-export-chip,
5877
- .db-git-progress-bar > span {
5878
- transition: none;
5879
- }
6530
+ /* Destructive confirmation (delete, remove workspace). The foreground comes
6531
+ from a token rather than a literal because the two themes need opposite ink:
6532
+ light's danger is deep red and carries white at ~6.5:1, while dark's is a
6533
+ light red where white would fall to ~2.8:1 and fail WCAG AA. */
6534
+ .db-git-primary-btn--danger {
6535
+ background: var(--db-danger);
6536
+ color: var(--db-text-on-danger);
6537
+ }
5880
6538
 
5881
- .db-welcome-gateway,
5882
- .db-save-toast {
5883
- animation: none;
5884
- }
6539
+ .db-git-primary-btn--danger:hover:not(:disabled) {
6540
+ background: color-mix(in srgb, var(--db-danger) 85%, black);
5885
6541
  }
5886
6542
 
5887
- /* History dialog internals added by the expanded-row layout */
5888
- .db-git-history-toggle {
5889
- display: block;
5890
- width: 100%;
5891
- padding: 0;
5892
- border: none;
6543
+ .db-git-secondary-btn {
6544
+ padding: 6px 14px;
6545
+ border: 1px solid var(--db-border-strong);
6546
+ border-radius: 5px;
5893
6547
  background: transparent;
5894
- color: inherit;
5895
- font: inherit;
5896
- text-align: left;
6548
+ color: var(--db-text);
6549
+ font-size: 13px;
5897
6550
  cursor: pointer;
5898
6551
  }
5899
6552
 
5900
- .db-git-history-subject {
5901
- display: block;
5902
- font-size: 13px;
5903
- color: var(--db-text);
6553
+ .db-git-secondary-btn:hover:not(:disabled) {
6554
+ background: var(--db-bg-hover);
5904
6555
  }
5905
6556
 
5906
- .db-git-history-body {
5907
- margin: 6px 0 0;
5908
- padding: 8px 10px;
6557
+ .db-git-secondary-btn:disabled {
6558
+ opacity: 0.5;
6559
+ cursor: default;
6560
+ }
6561
+
6562
+ /* Status bar row in the sidebar */
6563
+ .db-git-statusbar {
6564
+ position: relative;
6565
+ flex-shrink: 0;
6566
+ padding: 2px 8px 4px;
6567
+ border-bottom: 1px solid var(--db-border);
6568
+ }
6569
+
6570
+ .db-git-statusbar-chip {
6571
+ display: flex;
6572
+ align-items: center;
6573
+ gap: 6px;
6574
+ width: 100%;
6575
+ padding: 4px 8px;
6576
+ border: none;
5909
6577
  border-radius: 4px;
5910
- background: var(--db-bg-subtle);
6578
+ background: transparent;
5911
6579
  color: var(--db-text-secondary);
5912
6580
  font-size: 12px;
5913
- white-space: pre-wrap;
5914
- font-family: inherit;
6581
+ cursor: pointer;
6582
+ overflow: hidden;
5915
6583
  }
5916
6584
 
5917
- /* ---------------------------------------------------------------------------
5918
- Window Controls Overlay — installed web app (PWA) custom titlebar.
5919
-
5920
- When the manifest's `display_override: ["window-controls-overlay", ...]`
5921
- is active, the OS caption buttons float over the first shell row and this
5922
- block turns that row into the titlebar: draggable empty space, insets for
5923
- the caption buttons, and every interactive descendant opted back out.
6585
+ .db-git-statusbar-chip:hover {
6586
+ background: var(--db-bg-hover);
6587
+ }
5924
6588
 
5925
- Shares its drag/inset structure with the Electron build in
5926
- packages/desktop/renderer/titlebar.css. Its compact vertical metrics are
5927
- intentionally PWA-specific because Electron uses a 42px overlay while this
5928
- mode follows the OS-provided caption height (32px on Windows). Electron is
5929
- scoped under `.db-desktop-root` and reports `display-mode: browser`, so this
5930
- media query can never double-apply there. The media query is live: toggling
5931
- the overlay chevron flips it with no JS. */
5932
- @media (display-mode: window-controls-overlay) {
5933
- .db-shell {
5934
- --db-wco-titlebar-height: env(titlebar-area-height, 32px);
5935
- }
6589
+ .db-git-branch-glyph {
6590
+ color: var(--db-text-muted);
6591
+ flex-shrink: 0;
6592
+ }
5936
6593
 
5937
- /* The first shell row replaces the native titlebar. Empty space can drag
5938
- the window; every interactive descendant opts back out below. */
5939
- .db-shell .db-shell-sidebar-header,
5940
- .db-shell .squisq-editor-header {
5941
- app-region: drag;
5942
- -webkit-app-region: drag;
5943
- box-sizing: border-box;
5944
- height: var(--db-wco-titlebar-height);
5945
- min-height: var(--db-wco-titlebar-height);
5946
- }
6594
+ .db-git-statusbar-branch {
6595
+ font-weight: 600;
6596
+ white-space: nowrap;
6597
+ overflow: hidden;
6598
+ text-overflow: ellipsis;
6599
+ }
5947
6600
 
5948
- .db-shell .squisq-toolbar {
5949
- app-region: drag;
5950
- -webkit-app-region: drag;
5951
- box-sizing: border-box;
5952
- height: 100%;
5953
- min-height: 0;
5954
- }
6601
+ .db-git-statusbar-counts {
6602
+ color: var(--db-text-muted);
6603
+ flex-shrink: 0;
6604
+ }
5955
6605
 
5956
- /* The flexible actions lane owns the otherwise-empty gap between Squisq's
5957
- formatting controls and the fixed document controls. Mark the child
5958
- explicitly because its overflow clipping can prevent the toolbar's drag
5959
- region from reaching those pixels. Controls opt out below. */
5960
- .db-shell .squisq-toolbar-actions {
5961
- app-region: drag;
5962
- -webkit-app-region: drag;
5963
- cursor: grab;
5964
- }
6606
+ .db-git-statusbar-dirty {
6607
+ color: var(--db-git-modified);
6608
+ flex-shrink: 0;
6609
+ }
5965
6610
 
5966
- .db-shell .db-shell-sidebar-header {
5967
- padding-block: 0;
5968
- padding-left: max(4px, calc(env(titlebar-area-x, 0px) + 4px));
5969
- cursor: grab;
5970
- }
6611
+ .db-git-statusbar-merge {
6612
+ color: var(--db-git-conflicted);
6613
+ font-weight: 600;
6614
+ flex-shrink: 0;
6615
+ }
5971
6616
 
5972
- /* Keep the shell controls inside the compact native caption band. These
5973
- overrides apply only to an installed app using Window Controls Overlay;
5974
- the regular browser toolbar keeps its roomier metrics. */
5975
- .db-shell .db-app-menu-btn,
5976
- .db-shell .db-workspace-picker-btn {
5977
- padding-block: 3px;
5978
- }
6617
+ .db-git-statusbar-busy {
6618
+ color: var(--db-text-muted);
6619
+ flex-shrink: 0;
6620
+ }
5979
6621
 
5980
- .db-shell .squisq-toolbar-view-tab {
5981
- padding-top: 4px;
5982
- padding-bottom: 2px;
5983
- }
6622
+ /* The offer to turn Git on for a folder inside a larger repository. It sits
6623
+ directly above the sidebar footer and borrows its voice: muted, 11px, no
6624
+ icon and no accent — this is a default the user may change, not a fault. */
6625
+ .db-git-grant-notice {
6626
+ box-sizing: border-box;
6627
+ display: flex;
6628
+ align-items: center;
6629
+ gap: 6px;
6630
+ flex-shrink: 0;
6631
+ padding: 6px 12px 6px 18px;
6632
+ border-top: 1px solid var(--db-border);
6633
+ color: var(--db-text-muted);
6634
+ font-size: 11px;
6635
+ line-height: 1.3;
6636
+ }
5984
6637
 
5985
- /* Keep the compact labels on the same visual center as the action glyphs.
5986
- Move only the text; the tab hit area and active underline stay anchored
5987
- to the titlebar edges. */
5988
- .db-shell .squisq-toolbar-view-tab-label {
5989
- transform: translateY(1px);
5990
- }
6638
+ .db-git-grant-notice-text {
6639
+ overflow: hidden;
6640
+ text-overflow: ellipsis;
6641
+ white-space: nowrap;
6642
+ }
5991
6643
 
5992
- .db-shell .squisq-use-mode-trigger {
5993
- padding-bottom: 10px;
5994
- }
6644
+ .db-git-grant-notice-action {
6645
+ flex-shrink: 0;
6646
+ padding: 0;
6647
+ border: 0;
6648
+ background: transparent;
6649
+ color: inherit;
6650
+ font: inherit;
6651
+ line-height: inherit;
6652
+ text-decoration: underline;
6653
+ white-space: nowrap;
6654
+ cursor: pointer;
6655
+ }
5995
6656
 
5996
- /* The 32px caption row leaves little room around Squisq's 28px action
5997
- buttons. Keep the selected background clear of the header's 1px bottom
5998
- divider without moving the glyphs off their shared center line. */
5999
- .db-shell .squisq-toolbar-actions .squisq-toolbar-button {
6000
- box-sizing: border-box;
6001
- height: 26px;
6002
- }
6657
+ .db-git-grant-notice-action:hover {
6658
+ color: var(--db-text-secondary);
6659
+ }
6003
6660
 
6004
- /* Squisq's overflow measurement deliberately tolerates a 2px overhang.
6005
- Reserve one pixel beyond that tolerance so the final Insert control
6006
- moves into More actions instead of being clipped by the caption inset. */
6007
- .db-shell .squisq-toolbar-actions {
6008
- margin-right: 3px;
6009
- }
6661
+ .db-git-grant-remember {
6662
+ display: flex;
6663
+ align-items: center;
6664
+ gap: 8px;
6665
+ margin: 12px 0;
6666
+ font-size: 13px;
6667
+ color: var(--db-text);
6668
+ cursor: pointer;
6669
+ }
6010
6670
 
6011
- .db-shell .squisq-toolbar-button[aria-label='Insert image'] {
6671
+ /* Actions dropdown (mirrors db-ws-settings-dropdown) */
6672
+ .db-git-menu {
6673
+ position: absolute;
6674
+ top: 100%;
6675
+ left: 8px;
6676
+ right: 8px;
6677
+ z-index: 100;
6678
+ background: var(--db-bg);
6679
+ border: 1px solid var(--db-border);
6680
+ border-radius: 6px;
6681
+ box-shadow: 0 4px 12px var(--db-shadow);
6682
+ padding: 4px 0;
6683
+ margin-top: 2px;
6684
+ }
6685
+
6686
+ .db-git-menu-item {
6687
+ display: block;
6688
+ width: 100%;
6689
+ padding: 7px 14px;
6690
+ border: none;
6691
+ background: transparent;
6692
+ text-align: left;
6693
+ font-size: 13px;
6694
+ color: var(--db-text);
6695
+ cursor: pointer;
6696
+ }
6697
+
6698
+ .db-git-menu-item:hover:not(:disabled),
6699
+ .db-git-menu-item:focus-visible {
6700
+ background: var(--db-bg-hover);
6701
+ }
6702
+
6703
+ /* Items are arrow-reachable rather than tab stops, so the ring is the only
6704
+ cue to which one Enter will fire. */
6705
+ .db-git-menu-item:focus-visible {
6706
+ outline: 2px solid var(--db-focus);
6707
+ outline-offset: -2px;
6708
+ }
6709
+
6710
+ .db-git-menu-item:disabled {
6711
+ color: var(--db-text-placeholder);
6712
+ cursor: default;
6713
+ }
6714
+
6715
+ .db-git-menu-divider {
6716
+ height: 1px;
6717
+ background: var(--db-border);
6718
+ margin: 4px 0;
6719
+ }
6720
+
6721
+ /* aria-live op-result line — visually subtle, announced politely */
6722
+ .db-git-inline-status {
6723
+ display: block;
6724
+ padding: 0 16px;
6725
+ font-size: 11px;
6726
+ color: var(--db-text-muted);
6727
+ min-height: 0;
6728
+ }
6729
+
6730
+ .db-git-inline-status:empty {
6731
+ display: none;
6732
+ }
6733
+
6734
+ /* File-tree badges */
6735
+ .db-git-badge {
6736
+ margin-left: auto;
6737
+ padding: 0 4px;
6738
+ font-size: 10px;
6739
+ font-weight: 700;
6740
+ flex-shrink: 0;
6741
+ }
6742
+
6743
+ .db-tree-row .db-git-badge {
6744
+ margin-left: 4px;
6745
+ }
6746
+
6747
+ .db-git-badge--modified {
6748
+ color: var(--db-git-modified);
6749
+ }
6750
+
6751
+ .db-git-badge--added {
6752
+ color: var(--db-git-added);
6753
+ }
6754
+
6755
+ .db-git-badge--untracked {
6756
+ color: var(--db-git-untracked);
6757
+ }
6758
+
6759
+ .db-git-badge--renamed {
6760
+ color: var(--db-git-renamed);
6761
+ }
6762
+
6763
+ .db-git-badge--deleted {
6764
+ color: var(--db-git-deleted);
6765
+ }
6766
+
6767
+ .db-git-badge--conflicted {
6768
+ color: var(--db-git-conflicted);
6769
+ }
6770
+
6771
+ .db-git-badge--dir {
6772
+ color: var(--db-git-modified);
6773
+ }
6774
+
6775
+ .db-tree-context-divider {
6776
+ height: 1px;
6777
+ background: var(--db-border);
6778
+ margin: 4px 0;
6779
+ }
6780
+
6781
+ /* Toolbar control */
6782
+ .db-git-toolbar-trigger {
6783
+ position: relative;
6784
+ }
6785
+
6786
+ .db-git-toolbar-dot {
6787
+ position: absolute;
6788
+ top: 3px;
6789
+ right: 3px;
6790
+ width: 7px;
6791
+ height: 7px;
6792
+ border-radius: 50%;
6793
+ background: var(--db-git-modified);
6794
+ }
6795
+
6796
+ /* Dialog internals — file lists (commit + conflicts) */
6797
+ .db-git-file-list {
6798
+ margin: 8px 0;
6799
+ padding: 0;
6800
+ list-style: none;
6801
+ max-height: 260px;
6802
+ overflow-y: auto;
6803
+ border: 1px solid var(--db-border);
6804
+ border-radius: 5px;
6805
+ }
6806
+
6807
+ .db-git-file-row {
6808
+ display: flex;
6809
+ align-items: center;
6810
+ gap: 8px;
6811
+ width: 100%;
6812
+ padding: 6px 10px;
6813
+ border: none;
6814
+ background: transparent;
6815
+ font-size: 12.5px;
6816
+ color: var(--db-text);
6817
+ text-align: left;
6818
+ }
6819
+
6820
+ .db-git-file-row + .db-git-file-row {
6821
+ border-top: 1px solid var(--db-border);
6822
+ }
6823
+
6824
+ button.db-git-file-row {
6825
+ cursor: pointer;
6826
+ }
6827
+
6828
+ button.db-git-file-row:hover {
6829
+ background: var(--db-bg-hover);
6830
+ }
6831
+
6832
+ .db-git-file-kind {
6833
+ margin-left: auto;
6834
+ font-size: 10.5px;
6835
+ color: var(--db-text-muted);
6836
+ flex-shrink: 0;
6837
+ }
6838
+
6839
+ .db-git-commit-message {
6840
+ width: 100%;
6841
+ min-height: 72px;
6842
+ padding: 8px 10px;
6843
+ border: 1px solid var(--db-input-border);
6844
+ border-radius: 5px;
6845
+ background: var(--db-bg);
6846
+ color: var(--db-text);
6847
+ font-size: var(--db-input-font-size);
6848
+ font-family: inherit;
6849
+ resize: vertical;
6850
+ box-sizing: border-box;
6851
+ }
6852
+
6853
+ /* Generic form rows in git dialogs */
6854
+ .db-git-form-row {
6855
+ display: flex;
6856
+ align-items: center;
6857
+ gap: 8px;
6858
+ margin: 10px 0;
6859
+ }
6860
+
6861
+ .db-git-form-label {
6862
+ font-size: 12.5px;
6863
+ color: var(--db-text-secondary);
6864
+ flex-shrink: 0;
6865
+ }
6866
+
6867
+ .db-git-form-input {
6868
+ flex: 1;
6869
+ padding: 6px 10px;
6870
+ border: 1px solid var(--db-input-border);
6871
+ border-radius: 5px;
6872
+ background: var(--db-bg);
6873
+ color: var(--db-text);
6874
+ font-size: var(--db-input-font-size);
6875
+ box-sizing: border-box;
6876
+ }
6877
+
6878
+ /* New document dialog: label/field pairs in two aligned columns */
6879
+ .db-new-document-fields {
6880
+ display: grid;
6881
+ grid-template-columns: auto minmax(0, 1fr);
6882
+ align-items: center;
6883
+ gap: 10px 8px;
6884
+ margin: 10px 0;
6885
+ }
6886
+
6887
+ .db-git-form-error,
6888
+ .db-export-error {
6889
+ margin: 8px 0 0;
6890
+ color: var(--db-danger);
6891
+ font-size: 12.5px;
6892
+ }
6893
+
6894
+ .db-git-hint {
6895
+ color: var(--db-text-muted);
6896
+ font-size: 12px;
6897
+ }
6898
+
6899
+ /* Branches dialog */
6900
+ .db-git-branch-list {
6901
+ margin: 8px 0;
6902
+ padding: 0;
6903
+ list-style: none;
6904
+ max-height: 280px;
6905
+ overflow-y: auto;
6906
+ }
6907
+
6908
+ .db-git-branch-row {
6909
+ display: flex;
6910
+ align-items: center;
6911
+ gap: 8px;
6912
+ width: 100%;
6913
+ padding: 7px 10px;
6914
+ border: none;
6915
+ border-radius: 4px;
6916
+ background: transparent;
6917
+ font-size: 13px;
6918
+ color: var(--db-text);
6919
+ text-align: left;
6920
+ cursor: pointer;
6921
+ }
6922
+
6923
+ .db-git-branch-row:hover {
6924
+ background: var(--db-bg-hover);
6925
+ }
6926
+
6927
+ .db-git-branch-row--current {
6928
+ font-weight: 600;
6929
+ color: var(--db-accent);
6930
+ cursor: default;
6931
+ }
6932
+
6933
+ .db-git-branch-row--current:hover {
6934
+ background: transparent;
6935
+ }
6936
+
6937
+ /* History dialog */
6938
+ .db-git-history-list {
6939
+ margin: 8px 0;
6940
+ padding: 0;
6941
+ list-style: none;
6942
+ }
6943
+
6944
+ .db-git-history-item {
6945
+ padding: 8px 10px;
6946
+ border-bottom: 1px solid var(--db-border);
6947
+ cursor: pointer;
6948
+ }
6949
+
6950
+ .db-git-history-item:hover {
6951
+ background: var(--db-bg-hover);
6952
+ }
6953
+
6954
+ .db-git-history-meta {
6955
+ margin-top: 2px;
6956
+ font-size: 11.5px;
6957
+ color: var(--db-text-muted);
6958
+ }
6959
+
6960
+ .db-git-history-files {
6961
+ margin: 6px 0 0;
6962
+ padding: 0;
6963
+ list-style: none;
6964
+ }
6965
+
6966
+ .db-git-history-file {
6967
+ display: flex;
6968
+ align-items: center;
6969
+ gap: 8px;
6970
+ width: 100%;
6971
+ padding: 4px 8px;
6972
+ border: none;
6973
+ background: transparent;
6974
+ font-size: 12px;
6975
+ color: var(--db-text-secondary);
6976
+ text-align: left;
6977
+ cursor: pointer;
6978
+ border-radius: 4px;
6979
+ }
6980
+
6981
+ .db-git-history-file:hover {
6982
+ background: var(--db-bg-hover);
6983
+ }
6984
+
6985
+ /* Diff dialog */
6986
+ .db-git-diff-host {
6987
+ flex: 1;
6988
+ min-height: 320px;
6989
+ border: 1px solid var(--db-border);
6990
+ border-radius: 5px;
6991
+ overflow: hidden;
6992
+ }
6993
+
6994
+ .db-git-diff-loading {
6995
+ padding: 24px;
6996
+ text-align: center;
6997
+ color: var(--db-text-muted);
6998
+ }
6999
+
7000
+ .db-git-diff-labels {
7001
+ display: flex;
7002
+ gap: 12px;
7003
+ margin-bottom: 6px;
7004
+ font-size: 12px;
7005
+ color: var(--db-text-muted);
7006
+ }
7007
+
7008
+ .db-git-diff-labels > span {
7009
+ flex: 1;
7010
+ }
7011
+
7012
+ /* Clone progress */
7013
+ .db-git-progress {
7014
+ margin: 12px 0 4px;
7015
+ }
7016
+
7017
+ .db-git-progress-bar {
7018
+ height: 6px;
7019
+ border-radius: 3px;
7020
+ background: var(--db-accent-soft-15);
7021
+ overflow: hidden;
7022
+ position: relative;
7023
+ }
7024
+
7025
+ .db-git-progress-bar > span {
7026
+ display: block;
7027
+ height: 100%;
7028
+ background: var(--db-accent);
7029
+ transition: width 0.2s;
7030
+ }
7031
+
7032
+ .db-git-progress-text {
7033
+ margin-top: 6px;
7034
+ font-size: 12px;
7035
+ color: var(--db-text-muted);
7036
+ }
7037
+
7038
+ @media (prefers-reduced-motion: reduce) {
7039
+ .db-workspace-picker-caret,
7040
+ .db-app-menu-caret,
7041
+ .db-ws-settings-btn,
7042
+ .db-shell-sidebar-resizer,
7043
+ .db-sidebar-collapse-preview,
7044
+ .db-export-chip,
7045
+ .db-git-progress-bar > span {
7046
+ transition: none;
7047
+ }
7048
+
7049
+ .db-welcome-gateway,
7050
+ .db-save-toast {
7051
+ animation: none;
7052
+ }
7053
+ }
7054
+
7055
+ /* History dialog internals added by the expanded-row layout */
7056
+ .db-git-history-toggle {
7057
+ display: block;
7058
+ width: 100%;
7059
+ padding: 0;
7060
+ border: none;
7061
+ background: transparent;
7062
+ color: inherit;
7063
+ font: inherit;
7064
+ text-align: left;
7065
+ cursor: pointer;
7066
+ }
7067
+
7068
+ .db-git-history-subject {
7069
+ display: block;
7070
+ font-size: 13px;
7071
+ color: var(--db-text);
7072
+ }
7073
+
7074
+ .db-git-history-body {
7075
+ margin: 6px 0 0;
7076
+ padding: 8px 10px;
7077
+ border-radius: 4px;
7078
+ background: var(--db-bg-subtle);
7079
+ color: var(--db-text-secondary);
7080
+ font-size: 12px;
7081
+ white-space: pre-wrap;
7082
+ font-family: inherit;
7083
+ }
7084
+
7085
+ /* ---------------------------------------------------------------------------
7086
+ Window Controls Overlay — installed web app (PWA) custom titlebar.
7087
+
7088
+ When the manifest's `display_override: ["window-controls-overlay", ...]`
7089
+ is active, the OS caption buttons float over the first shell row and this
7090
+ block turns that row into the titlebar: draggable empty space, insets for
7091
+ the caption buttons, and every interactive descendant opted back out.
7092
+
7093
+ Shares its drag/inset structure with the Electron build in
7094
+ packages/desktop/renderer/titlebar.css. Its compact vertical metrics are
7095
+ intentionally PWA-specific because Electron uses a 42px overlay while this
7096
+ mode follows the OS-provided caption height (32px on Windows). Electron is
7097
+ scoped under `.db-desktop-root` and reports `display-mode: browser`, so this
7098
+ media query can never double-apply there. The media query is live: toggling
7099
+ the overlay chevron flips it with no JS. */
7100
+ @media (display-mode: window-controls-overlay) {
7101
+ .db-shell {
7102
+ --db-wco-titlebar-height: env(titlebar-area-height, 32px);
7103
+ }
7104
+
7105
+ /* The first shell row replaces the native titlebar. Empty space can drag
7106
+ the window; every interactive descendant opts back out below. */
7107
+ .db-shell .db-shell-sidebar-header,
7108
+ .db-shell .squisq-editor-header {
7109
+ app-region: drag;
7110
+ -webkit-app-region: drag;
7111
+ box-sizing: border-box;
7112
+ height: var(--db-wco-titlebar-height);
7113
+ min-height: var(--db-wco-titlebar-height);
7114
+ }
7115
+
7116
+ .db-shell .squisq-toolbar {
7117
+ app-region: drag;
7118
+ -webkit-app-region: drag;
7119
+ box-sizing: border-box;
7120
+ height: 100%;
7121
+ min-height: 0;
7122
+ }
7123
+
7124
+ /* The flexible actions lane owns the otherwise-empty gap between Squisq's
7125
+ formatting controls and the fixed document controls. Mark the child
7126
+ explicitly because its overflow clipping can prevent the toolbar's drag
7127
+ region from reaching those pixels. Controls opt out below. */
7128
+ .db-shell .squisq-toolbar-actions {
7129
+ app-region: drag;
7130
+ -webkit-app-region: drag;
7131
+ cursor: grab;
7132
+ }
7133
+
7134
+ .db-shell .db-shell-sidebar-header {
7135
+ padding-block: 0;
7136
+ padding-left: max(4px, calc(env(titlebar-area-x, 0px) + 4px));
7137
+ cursor: grab;
7138
+ }
7139
+
7140
+ /* Keep the shell controls inside the compact native caption band. These
7141
+ overrides apply only to an installed app using Window Controls Overlay;
7142
+ the regular browser toolbar keeps its roomier metrics. */
7143
+ .db-shell .db-app-menu-btn,
7144
+ .db-shell .db-workspace-picker-btn {
7145
+ padding-block: 3px;
7146
+ }
7147
+
7148
+ .db-shell .squisq-toolbar-view-tab {
7149
+ padding-top: 4px;
7150
+ padding-bottom: 2px;
7151
+ }
7152
+
7153
+ /* Keep the compact labels on the same visual center as the action glyphs.
7154
+ Move only the text; the tab hit area and active underline stay anchored
7155
+ to the titlebar edges. */
7156
+ .db-shell .squisq-toolbar-view-tab-label {
7157
+ transform: translateY(1px);
7158
+ }
7159
+
7160
+ .db-shell .squisq-use-mode-trigger {
7161
+ padding-bottom: 10px;
7162
+ }
7163
+
7164
+ /* The 32px caption row leaves little room around Squisq's 28px action
7165
+ buttons. Keep the selected background clear of the header's 1px bottom
7166
+ divider without moving the glyphs off their shared center line. */
7167
+ .db-shell .squisq-toolbar-actions .squisq-toolbar-button {
7168
+ box-sizing: border-box;
7169
+ height: 26px;
7170
+ }
7171
+
7172
+ /* Squisq's overflow measurement deliberately tolerates a 2px overhang.
7173
+ Reserve one pixel beyond that tolerance so the rightmost control moves
7174
+ into More actions instead of being clipped by the caption inset. */
7175
+ .db-shell .squisq-toolbar-actions {
7176
+ margin-right: 3px;
7177
+ }
7178
+
7179
+ .db-shell .squisq-toolbar-button[aria-label='Insert image'] {
6012
7180
  height: 28px;
6013
7181
  }
6014
7182
 
6015
- .db-shell .squisq-editor-header--image {
6016
- padding-block: 0;
6017
- }
7183
+ .db-shell .squisq-editor-header--image {
7184
+ padding-block: 0;
7185
+ }
7186
+
7187
+ /* Make the draggable header space beside the workspace gear discoverable,
7188
+ matching the Electron titlebar without introducing another control. The
7189
+ 12px dotted content and its 8px right padding form one drag region. */
7190
+ .db-shell .db-window-drag-grip {
7191
+ box-sizing: border-box;
7192
+ width: 20px;
7193
+ height: 20px;
7194
+ flex: 0 0 20px;
7195
+ padding-right: 8px;
7196
+ background-image: radial-gradient(circle, var(--db-text-muted) 1px, transparent 1.25px);
7197
+ background-clip: content-box;
7198
+ background-origin: content-box;
7199
+ background-position: center;
7200
+ background-size: 4px 4px;
7201
+ opacity: 0.72;
7202
+ app-region: drag;
7203
+ -webkit-app-region: drag;
7204
+ }
7205
+
7206
+ /* Let the workspace menu size itself to its contents and cross the sidebar
7207
+ boundary above the editor. The explorer still clips its own contents. */
7208
+ .db-shell .db-shell-sidebar {
7209
+ overflow: visible;
7210
+ }
7211
+
7212
+ .db-shell .db-workspace-dropdown {
7213
+ box-sizing: border-box;
7214
+ width: max-content;
7215
+ }
7216
+
7217
+ /* The caption buttons normally occupy the right edge. Derive that inset
7218
+ from the overlay safe area rather than assuming a fixed width, so
7219
+ scaling, RTL controls, and OS variants stay clear. The compact sidebar
7220
+ header is full-width, so it needs the same reservation. */
7221
+ .db-shell.db-shell--mobile .db-shell-sidebar-header,
7222
+ .db-shell .squisq-toolbar,
7223
+ .db-shell .squisq-editor-header--image {
7224
+ padding-right: max(
7225
+ 12px,
7226
+ calc(100vw - env(titlebar-area-x, 0px) - env(titlebar-area-width, 100vw) + 8px)
7227
+ );
7228
+ }
7229
+
7230
+ /* In compact mode there is no sidebar to absorb left-side controls such as
7231
+ macOS traffic lights, so the editor toolbar also observes the left inset. */
7232
+ .db-shell.db-shell--mobile .squisq-toolbar,
7233
+ .db-shell.db-shell--mobile .squisq-editor-header--image {
7234
+ padding-left: env(titlebar-area-x, 0px);
7235
+ }
7236
+
7237
+ .db-shell
7238
+ :is(
7239
+ button,
7240
+ a,
7241
+ input,
7242
+ select,
7243
+ textarea,
7244
+ [contenteditable='true'],
7245
+ [role='button'],
7246
+ [role='tab']
7247
+ ) {
7248
+ app-region: no-drag;
7249
+ -webkit-app-region: no-drag;
7250
+ }
7251
+
7252
+ /* Folder and empty states do not render Squisq's toolbar. Preserve a top
7253
+ drag strip in those states and keep folder content below it. */
7254
+ .db-shell .db-shell-empty::before,
7255
+ .db-shell .db-folder-view::before {
7256
+ content: '';
7257
+ position: absolute;
7258
+ top: 0;
7259
+ left: env(titlebar-area-x, 0px);
7260
+ width: env(titlebar-area-width, 100%);
7261
+ height: var(--db-wco-titlebar-height);
7262
+ app-region: drag;
7263
+ -webkit-app-region: drag;
7264
+ }
7265
+
7266
+ .db-shell .db-folder-view {
7267
+ box-sizing: border-box;
7268
+ padding-top: calc(24px + var(--db-wco-titlebar-height));
7269
+ }
7270
+ }
7271
+
7272
+ /* Transcript review shares the shell's dialog and theme tokens. */
7273
+ .db-text-from-narration {
7274
+ font-family: var(--db-ui-font);
7275
+ }
7276
+ .db-text-from-narration .db-dialog-body {
7277
+ display: flex;
7278
+ flex-direction: column;
7279
+ gap: 12px;
7280
+ }
7281
+ .db-text-from-narration p {
7282
+ margin: 0;
7283
+ }
7284
+ .db-narration-actions {
7285
+ display: flex;
7286
+ flex-wrap: wrap;
7287
+ gap: 8px;
7288
+ }
7289
+ .db-narration-transcript {
7290
+ display: flex;
7291
+ flex-direction: column;
7292
+ gap: 6px;
7293
+ }
7294
+ .db-narration-transcript textarea {
7295
+ width: 100%;
7296
+ box-sizing: border-box;
7297
+ min-height: 160px;
7298
+ resize: vertical;
7299
+ font: inherit;
7300
+ line-height: 1.5;
7301
+ color: var(--db-text);
7302
+ background: var(--db-bg);
7303
+ border: 1px solid var(--db-border);
7304
+ border-radius: 6px;
7305
+ padding: 10px;
7306
+ }
7307
+ .db-narration-note {
7308
+ color: var(--db-text-secondary);
7309
+ font-size: 12px;
7310
+ line-height: 1.5;
7311
+ }
7312
+ .db-narration-status {
7313
+ display: flex;
7314
+ flex-direction: column;
7315
+ gap: 6px;
7316
+ }
7317
+ .db-narration-rewrite {
7318
+ display: flex;
7319
+ flex-direction: column;
7320
+ align-items: flex-start;
7321
+ gap: 6px;
7322
+ }
7323
+
7324
+ /* Presentation review uses the same source and timeline as the saved player. */
7325
+ .db-presentation-workspace {
7326
+ display: grid;
7327
+ flex: 1;
7328
+ min-height: 0;
7329
+ grid-template-columns: minmax(140px, 24%) minmax(0, 1fr);
7330
+ gap: 18px;
7331
+ align-items: stretch;
7332
+ }
7333
+ .db-presentation-beats {
7334
+ display: flex;
7335
+ flex-direction: column;
7336
+ gap: 8px;
7337
+ min-width: 0;
7338
+ min-height: 0;
7339
+ padding: 8px;
7340
+ border: 1px solid var(--db-border);
7341
+ border-radius: 8px;
7342
+ background: var(--db-bg-subtle);
7343
+ overflow-y: auto;
7344
+ }
7345
+ .db-presentation-beats button {
7346
+ display: flex;
7347
+ flex-direction: column;
7348
+ align-items: flex-start;
7349
+ flex: 0 0 auto;
7350
+ gap: 8px;
7351
+ min-width: 0;
7352
+ max-width: 100%;
7353
+ text-align: left;
7354
+ min-height: var(--db-target-min);
7355
+ padding: 12px;
7356
+ border: 1px solid var(--db-input-border);
7357
+ border-radius: 6px;
7358
+ color: var(--db-text);
7359
+ background: var(--db-bg);
7360
+ cursor: pointer;
7361
+ font: inherit;
7362
+ overflow: hidden;
7363
+ }
7364
+ .db-presentation-beat-title {
7365
+ display: -webkit-box;
7366
+ -webkit-box-orient: vertical;
7367
+ -webkit-line-clamp: 3;
7368
+ overflow: hidden;
7369
+ overflow-wrap: anywhere;
7370
+ line-height: 1.5;
7371
+ }
7372
+ .db-presentation-beats button:hover {
7373
+ background: var(--db-bg-hover);
7374
+ }
7375
+ .db-presentation-beats button:focus-visible {
7376
+ outline: 2px solid var(--db-focus);
7377
+ outline-offset: 2px;
7378
+ }
7379
+ .db-presentation-beats button[aria-current='step'] {
7380
+ border-color: var(--db-accent);
7381
+ background: var(--db-bg-hover);
7382
+ box-shadow: inset 3px 0 0 var(--db-accent);
7383
+ }
7384
+ .db-presentation-detail {
7385
+ min-width: 0;
7386
+ display: flex;
7387
+ flex-direction: column;
7388
+ gap: 12px;
7389
+ overflow-y: auto;
7390
+ }
7391
+ .db-presentation-preview {
7392
+ flex-shrink: 0;
7393
+ box-sizing: border-box;
7394
+ width: 100%;
7395
+ height: clamp(120px, 23vh, 240px);
7396
+ overflow: hidden;
7397
+ border: 1px solid var(--db-input-border);
7398
+ border-radius: 8px;
7399
+ }
7400
+ .db-presentation-preview > * {
7401
+ width: 100%;
7402
+ height: 100%;
7403
+ }
7404
+ .db-presentation-fields {
7405
+ display: flex;
7406
+ flex-shrink: 0;
7407
+ flex-wrap: wrap;
7408
+ gap: 12px;
7409
+ }
7410
+ .db-presentation-preferences {
7411
+ align-items: flex-end;
7412
+ }
7413
+ .db-presentation-beats small {
7414
+ display: block;
7415
+ max-width: 100%;
7416
+ padding: 2px 6px;
7417
+ border-radius: 4px;
7418
+ background: var(--db-bg-subtle);
7419
+ color: var(--db-text-muted);
7420
+ overflow-wrap: anywhere;
7421
+ }
7422
+ .db-presentation label.db-presentation-toggle {
7423
+ display: flex;
7424
+ flex-direction: row;
7425
+ align-items: center;
7426
+ gap: 0.6rem;
7427
+ box-sizing: border-box;
7428
+ width: auto;
7429
+ max-width: 100%;
7430
+ min-height: var(--db-target-min);
7431
+ padding: 8px 0;
7432
+ }
7433
+ .db-presentation input[type='checkbox'] {
7434
+ width: 1.1rem;
7435
+ height: 1.1rem;
7436
+ min-height: 0;
7437
+ padding: 0;
7438
+ margin: 0;
7439
+ flex: 0 0 auto;
7440
+ }
7441
+ .db-presentation-fields label {
7442
+ width: min(100%, 320px);
7443
+ }
7444
+ .db-presentation-source {
7445
+ flex-shrink: 0;
7446
+ padding: 12px;
7447
+ border: 1px solid var(--db-input-border);
7448
+ border-radius: 6px;
7449
+ }
7450
+ .db-presentation-source-label {
7451
+ display: flex;
7452
+ flex-wrap: wrap;
7453
+ align-items: baseline;
7454
+ gap: 8px;
7455
+ }
7456
+ .db-presentation-source-label h3 {
7457
+ margin: 0;
7458
+ font-size: inherit;
7459
+ }
7460
+ .db-presentation-source-label span {
7461
+ color: var(--db-text-secondary);
7462
+ font-size: 12px;
7463
+ }
7464
+ .db-presentation-source p {
7465
+ margin: 8px 0 0;
7466
+ max-height: 150px;
7467
+ overflow-y: auto;
7468
+ white-space: pre-wrap;
7469
+ line-height: 1.5;
7470
+ }
7471
+ .db-presentation-wording summary {
7472
+ cursor: pointer;
7473
+ min-height: var(--db-target-min);
7474
+ align-content: center;
7475
+ }
7476
+ .db-presentation-wording label + label {
7477
+ margin-top: 12px;
7478
+ }
7479
+ .db-presentation label {
7480
+ display: flex;
7481
+ flex-direction: column;
7482
+ gap: 5px;
7483
+ font-weight: 600;
7484
+ }
7485
+ .db-presentation input,
7486
+ .db-presentation select,
7487
+ .db-presentation textarea {
7488
+ box-sizing: border-box;
7489
+ width: 100%;
7490
+ min-height: var(--db-target-min);
7491
+ padding: 8px;
7492
+ border: 1px solid var(--db-input-border);
7493
+ border-radius: 5px;
7494
+ background: var(--db-bg);
7495
+ color: var(--db-text);
7496
+ font: inherit;
7497
+ }
7498
+ .db-presentation [role='alert'] {
7499
+ color: var(--db-danger);
7500
+ }
7501
+ .db-presentation details p {
7502
+ font-size: 13px;
7503
+ line-height: 1.6;
7504
+ color: var(--db-text-secondary);
7505
+ }
7506
+ :root[data-db-width='compact'] .db-presentation-workspace {
7507
+ grid-template-columns: minmax(0, 1fr);
7508
+ grid-template-rows: minmax(0, 140px) minmax(0, 1fr);
7509
+ }
7510
+ :root[data-db-width='compact'] .db-presentation-beats {
7511
+ max-height: 140px;
7512
+ }
7513
+
7514
+ /* ── Workspace search and quick-open ───────────────────────────── */
7515
+
7516
+ /* The sidebar shows the file tree or workspace search. The hidden view stays
7517
+ mounted so it keeps its expanded folders or its results. */
7518
+ .db-file-explorer.db-sidebar-view--hidden,
7519
+ .db-search-panel[hidden] {
7520
+ display: none;
7521
+ }
7522
+
7523
+ /* Query matches in quick-open and search results. */
7524
+ .db-search-match {
7525
+ padding: 0;
7526
+ border-radius: 2px;
7527
+ background: var(--db-accent-soft-25);
7528
+ color: inherit;
7529
+ }
7530
+
7531
+ .db-quick-open .db-quick-open-body {
7532
+ display: flex;
7533
+ flex-direction: column;
7534
+ min-height: 0;
7535
+ padding: 0;
7536
+ }
7537
+
7538
+ .db-quick-open-input {
7539
+ box-sizing: border-box;
7540
+ width: 100%;
7541
+ margin: 0;
7542
+ padding: 12px 14px;
7543
+ border: none;
7544
+ border-bottom: 1px solid var(--db-border);
7545
+ border-radius: 8px 8px 0 0;
7546
+ background: transparent;
7547
+ color: var(--db-text);
7548
+ font: inherit;
7549
+ font-size: max(15px, var(--db-input-font-size));
7550
+ outline: none;
7551
+ }
7552
+
7553
+ .db-quick-open-input:focus-visible {
7554
+ box-shadow: inset 0 -2px 0 var(--db-focus);
7555
+ }
6018
7556
 
6019
- /* Make the draggable header space beside the workspace gear discoverable,
6020
- matching the Electron titlebar without introducing another control. The
6021
- 12px dotted content and its 8px right padding form one drag region. */
6022
- .db-shell .db-window-drag-grip {
6023
- box-sizing: border-box;
6024
- width: 20px;
6025
- height: 20px;
6026
- flex: 0 0 20px;
6027
- padding-right: 8px;
6028
- background-image: radial-gradient(circle, var(--db-text-muted) 1px, transparent 1.25px);
6029
- background-clip: content-box;
6030
- background-origin: content-box;
6031
- background-position: center;
6032
- background-size: 4px 4px;
6033
- opacity: 0.72;
6034
- app-region: drag;
6035
- -webkit-app-region: drag;
6036
- }
7557
+ .db-quick-open-list {
7558
+ max-height: min(60vh, 480px);
7559
+ margin: 0;
7560
+ padding: 4px;
7561
+ overflow-y: auto;
7562
+ list-style: none;
7563
+ }
6037
7564
 
6038
- /* Let the workspace menu size itself to its contents and cross the sidebar
6039
- boundary above the editor. The explorer still clips its own contents. */
6040
- .db-shell .db-shell-sidebar {
6041
- overflow: visible;
6042
- }
7565
+ .db-quick-open-list:empty {
7566
+ display: none;
7567
+ }
6043
7568
 
6044
- .db-shell .db-workspace-dropdown {
6045
- box-sizing: border-box;
6046
- width: max-content;
6047
- }
7569
+ .db-quick-open-option {
7570
+ display: flex;
7571
+ align-items: baseline;
7572
+ gap: 8px;
7573
+ min-width: 0;
7574
+ min-height: var(--db-row-min-height);
7575
+ padding: 6px 10px;
7576
+ border-radius: 4px;
7577
+ color: var(--db-text);
7578
+ cursor: pointer;
7579
+ user-select: none;
7580
+ }
6048
7581
 
6049
- /* The caption buttons normally occupy the right edge. Derive that inset
6050
- from the overlay safe area rather than assuming a fixed width, so
6051
- scaling, RTL controls, and OS variants stay clear. The compact sidebar
6052
- header is full-width, so it needs the same reservation. */
6053
- .db-shell.db-shell--mobile .db-shell-sidebar-header,
6054
- .db-shell .squisq-toolbar,
6055
- .db-shell .squisq-editor-header--image {
6056
- padding-right: max(
6057
- 12px,
6058
- calc(100vw - env(titlebar-area-x, 0px) - env(titlebar-area-width, 100vw) + 8px)
6059
- );
6060
- }
7582
+ .db-quick-open-option--active {
7583
+ background: var(--db-bg-hover);
7584
+ }
6061
7585
 
6062
- /* In compact mode there is no sidebar to absorb left-side controls such as
6063
- macOS traffic lights, so the editor toolbar also observes the left inset. */
6064
- .db-shell.db-shell--mobile .squisq-toolbar,
6065
- .db-shell.db-shell--mobile .squisq-editor-header--image {
6066
- padding-left: env(titlebar-area-x, 0px);
6067
- }
7586
+ .db-quick-open-name,
7587
+ .db-quick-open-title,
7588
+ .db-quick-open-folder {
7589
+ min-width: 0;
7590
+ overflow: hidden;
7591
+ text-overflow: ellipsis;
7592
+ white-space: nowrap;
7593
+ }
6068
7594
 
6069
- .db-shell
6070
- :is(
6071
- button,
6072
- a,
6073
- input,
6074
- select,
6075
- textarea,
6076
- [contenteditable='true'],
6077
- [role='button'],
6078
- [role='tab']
6079
- ) {
6080
- app-region: no-drag;
6081
- -webkit-app-region: no-drag;
6082
- }
7595
+ .db-quick-open-name {
7596
+ flex: 0 1 auto;
7597
+ font-weight: 600;
7598
+ }
6083
7599
 
6084
- /* Folder and empty states do not render Squisq's toolbar. Preserve a top
6085
- drag strip in those states and keep folder content below it. */
6086
- .db-shell .db-shell-empty::before,
6087
- .db-shell .db-folder-view::before {
6088
- content: '';
6089
- position: absolute;
6090
- top: 0;
6091
- left: env(titlebar-area-x, 0px);
6092
- width: env(titlebar-area-width, 100%);
6093
- height: var(--db-wco-titlebar-height);
6094
- app-region: drag;
6095
- -webkit-app-region: drag;
6096
- }
7600
+ .db-quick-open-title {
7601
+ flex: 0 2 auto;
7602
+ color: var(--db-text-secondary);
7603
+ }
6097
7604
 
6098
- .db-shell .db-folder-view {
6099
- box-sizing: border-box;
6100
- padding-top: calc(24px + var(--db-wco-titlebar-height));
6101
- }
7605
+ .db-quick-open-folder {
7606
+ flex: 1 3 auto;
7607
+ margin-left: auto;
7608
+ color: var(--db-text-muted);
7609
+ font-size: 12px;
7610
+ text-align: right;
7611
+ }
7612
+
7613
+ .db-quick-open .db-quick-open-status {
7614
+ margin: 0;
7615
+ padding: 8px 14px;
7616
+ border-top: 1px solid var(--db-border);
7617
+ color: var(--db-text-muted);
7618
+ font-size: 12px;
7619
+ }
7620
+
7621
+ .db-quick-open .db-quick-open-status:empty {
7622
+ display: none;
7623
+ }
7624
+
7625
+ .db-search-panel {
7626
+ display: flex;
7627
+ flex-direction: column;
7628
+ height: 100%;
7629
+ min-height: 0;
7630
+ overflow: hidden;
7631
+ font-size: 13px;
7632
+ }
7633
+
7634
+ .db-search-form {
7635
+ display: flex;
7636
+ align-items: center;
7637
+ gap: 4px;
7638
+ padding: 8px;
7639
+ }
7640
+
7641
+ .db-search-input {
7642
+ box-sizing: border-box;
7643
+ flex: 1 1 auto;
7644
+ min-width: 0;
7645
+ min-height: var(--db-target-min);
7646
+ padding: 4px 8px;
7647
+ border: 1px solid var(--db-border-strong);
7648
+ border-radius: 4px;
7649
+ background: var(--db-bg);
7650
+ color: var(--db-text);
7651
+ font: inherit;
7652
+ font-size: var(--db-input-font-size);
7653
+ }
7654
+
7655
+ .db-search-input:focus-visible {
7656
+ outline: 2px solid var(--db-focus);
7657
+ outline-offset: -1px;
7658
+ }
7659
+
7660
+ .db-search-toggle {
7661
+ min-width: var(--db-target-min);
7662
+ min-height: var(--db-target-min);
7663
+ padding: 0 6px;
7664
+ border: 1px solid transparent;
7665
+ border-radius: 4px;
7666
+ background: none;
7667
+ color: var(--db-text-muted);
7668
+ font: inherit;
7669
+ font-size: 12px;
7670
+ font-weight: 600;
7671
+ cursor: pointer;
7672
+ }
7673
+
7674
+ .db-search-toggle--word {
7675
+ text-decoration: underline;
7676
+ text-underline-offset: 3px;
7677
+ }
7678
+
7679
+ .db-search-toggle:hover {
7680
+ background: var(--db-bg-hover);
7681
+ color: var(--db-text);
7682
+ }
7683
+
7684
+ .db-search-toggle[aria-pressed='true'] {
7685
+ background: var(--db-bg-selected);
7686
+ color: var(--db-text-on-selected);
7687
+ }
7688
+
7689
+ .db-search-toggle:focus-visible {
7690
+ outline: 2px solid var(--db-focus);
7691
+ outline-offset: 1px;
7692
+ }
7693
+
7694
+ .db-search-status,
7695
+ .db-search-more {
7696
+ margin: 0;
7697
+ padding: 0 10px 6px;
7698
+ color: var(--db-text-muted);
7699
+ font-size: 12px;
7700
+ }
7701
+
7702
+ .db-search-status:empty {
7703
+ display: none;
7704
+ }
7705
+
7706
+ .db-search-results {
7707
+ flex: 1 1 auto;
7708
+ min-height: 0;
7709
+ padding: 0 4px 8px;
7710
+ overflow-y: auto;
7711
+ }
7712
+
7713
+ .db-search-document,
7714
+ .db-search-line {
7715
+ display: flex;
7716
+ align-items: baseline;
7717
+ gap: 6px;
7718
+ min-height: var(--db-row-min-height);
7719
+ padding: 4px 6px;
7720
+ overflow: hidden;
7721
+ border-radius: 4px;
7722
+ color: var(--db-text);
7723
+ white-space: nowrap;
7724
+ cursor: pointer;
7725
+ user-select: none;
7726
+ }
7727
+
7728
+ .db-search-document:hover,
7729
+ .db-search-line:hover {
7730
+ background: var(--db-bg-hover);
7731
+ }
7732
+
7733
+ .db-search-document:focus-visible,
7734
+ .db-search-line:focus-visible {
7735
+ outline: 2px solid var(--db-focus);
7736
+ outline-offset: -2px;
7737
+ }
7738
+
7739
+ .db-search-chevron {
7740
+ flex: 0 0 auto;
7741
+ width: 12px;
7742
+ color: var(--db-text-muted);
7743
+ text-align: center;
7744
+ }
7745
+
7746
+ .db-search-document-title,
7747
+ .db-search-document-path,
7748
+ .db-search-snippet {
7749
+ min-width: 0;
7750
+ overflow: hidden;
7751
+ text-overflow: ellipsis;
7752
+ }
7753
+
7754
+ .db-search-document-title {
7755
+ flex: 0 1 auto;
7756
+ font-weight: 600;
7757
+ }
7758
+
7759
+ .db-search-document-path {
7760
+ flex: 1 1 auto;
7761
+ color: var(--db-text-muted);
7762
+ font-size: 12px;
7763
+ }
7764
+
7765
+ .db-search-count {
7766
+ flex: 0 0 auto;
7767
+ padding: 0 6px;
7768
+ border-radius: 8px;
7769
+ background: var(--db-bg-subtle);
7770
+ color: var(--db-text-secondary);
7771
+ font-size: 11px;
7772
+ }
7773
+
7774
+ .db-search-line {
7775
+ padding-left: 24px;
7776
+ }
7777
+
7778
+ .db-search-line-number {
7779
+ flex: 0 0 auto;
7780
+ min-width: 2.5em;
7781
+ color: var(--db-text-muted);
7782
+ font-size: 11px;
7783
+ font-variant-numeric: tabular-nums;
7784
+ text-align: right;
7785
+ }
7786
+
7787
+ .db-search-snippet {
7788
+ flex: 1 1 auto;
6102
7789
  }