@bendyline/docblocks-react 2.6.1 → 2.7.0

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 (54) hide show
  1. package/README.md +3 -10
  2. package/THIRD_PARTY_NOTICES.txt +4284 -3651
  3. package/dist/AiDiagrams-XWOM3YZX.js +13 -0
  4. package/dist/AiEditorAssistant-M4LI2CRY.js +771 -0
  5. package/dist/AudioExportDialog-F23QXNPB.js +253 -0
  6. package/dist/DocumentConflictDialog-5LRVIGXS.js +111 -0
  7. package/dist/ExportDialog-L6FG6W3H.js +9 -0
  8. package/dist/{ExportToolbarControls-QYLBRWM7.js → ExportToolbarControls-BRCPZ7H3.js} +108 -42
  9. package/dist/{GitUI-L5T3XHZG.js → GitUI-LZW3IUXO.js} +5 -5
  10. package/dist/PresentationMaker-622NHMIN.js +9 -0
  11. package/dist/QuickOpenDialog-2KK4SEBU.js +356 -0
  12. package/dist/Settings-DuXk6baH.d.ts +144 -0
  13. package/dist/{ShareDialog-4OX3UPJ4.js → ShareDialog-N7GPM4SB.js} +10 -59
  14. package/dist/SpeechToolbarControl-UZQKGQWD.js +434 -0
  15. package/dist/TextFromNarration-XYRAB6O2.js +598 -0
  16. package/dist/WorkspaceSearchPanel-OUQQ5DOM.js +328 -0
  17. package/dist/chunk-2IYBBFQX.js +201 -0
  18. package/dist/{chunk-LG6HAWCK.js → chunk-56KO2LYN.js} +35 -4
  19. package/dist/chunk-5OZBGIIT.js +1826 -0
  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-EA4BO6E4.js +73 -0
  24. package/dist/chunk-G4MFB3IO.js +208 -0
  25. package/dist/chunk-I44HKDQX.js +314 -0
  26. package/dist/chunk-K4I3NJFL.js +49 -0
  27. package/dist/chunk-KBDZDFPU.js +61 -0
  28. package/dist/{chunk-FNSRCCBC.js → chunk-KWG6UP5O.js} +0 -10
  29. package/dist/chunk-MMOTEQK6.js +518 -0
  30. package/dist/chunk-OINKNX26.js +574 -0
  31. package/dist/chunk-Q5ZVP5LV.js +1711 -0
  32. package/dist/chunk-RP3DVNTI.js +62 -0
  33. package/dist/{chunk-FMDLZ4ZG.js → chunk-SGQKTKDX.js} +2 -2
  34. package/dist/chunk-TBLZBNQF.js +25 -0
  35. package/dist/{chunk-M5Y5WO7Z.js → chunk-UG4G7PJ4.js} +1 -1
  36. package/dist/chunk-UONFWKJ7.js +22 -0
  37. package/dist/chunk-VO2JYYQZ.js +40 -0
  38. package/dist/{chunk-EBWYGTN7.js → chunk-X437UAF7.js} +6 -0
  39. package/dist/chunk-YS4HVWIO.js +63 -0
  40. package/dist/editor.d.ts +36 -1
  41. package/dist/editor.js +16 -1
  42. package/dist/export/index.d.ts +27 -11
  43. package/dist/export/index.js +11 -7
  44. package/dist/index.d.ts +100 -13
  45. package/dist/index.js +3916 -1633
  46. package/dist/{run-export-I2XOVGG4.js → run-export-47X5FTYZ.js} +3 -3
  47. package/dist/settings/index.d.ts +32 -101
  48. package/dist/settings/index.js +14 -2
  49. package/package.json +9 -9
  50. package/src/styles/docblocks.css +2337 -650
  51. package/dist/ExportDialog-Q4VWI43H.js +0 -9
  52. package/dist/chunk-JDJVRDOP.js +0 -92
  53. package/dist/chunk-Q6XNIKDG.js +0 -669
  54. package/dist/{GitToolbarControl-O5AXBC6T.js → GitToolbarControl-J4UYZDV6.js} +3 -3
@@ -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;
@@ -1670,19 +1957,30 @@ body.db-resizing-sidebar * {
1670
1957
  caption buttons; see packages/desktop/renderer/titlebar.css. */
1671
1958
  .db-shell--desktop-toolbar-wrapped:not(.db-shell--mobile) {
1672
1959
  --db-toolbar-wrapped-row: 44px;
1960
+ /* Squisq's toolbar keeps this inline-end padding so the second row's last
1961
+ control never touches the pane edge. The tab row is a flex item, so a
1962
+ 100% basis would stop at the content box and leave a toolbar-coloured
1963
+ strip beyond the tabs; it has to cover the padding too. */
1964
+ --db-toolbar-wrapped-inline-end: 12px;
1673
1965
  }
1674
1966
 
1675
1967
  .db-shell--desktop-toolbar-wrapped:not(.db-shell--mobile) .squisq-toolbar {
1676
1968
  min-height: calc(var(--db-toolbar-wrapped-row) * 2);
1677
1969
  flex-wrap: wrap;
1678
1970
  align-content: stretch;
1971
+ padding-right: var(--db-toolbar-wrapped-inline-end);
1679
1972
  }
1680
1973
 
1974
+ /* The tab row spans the whole toolbar, padding included, so its surface runs
1975
+ edge to edge and its right-hand divider (which separated it from the
1976
+ formatting controls when they shared a row) has nothing left to divide. */
1681
1977
  .db-shell--desktop-toolbar-wrapped:not(.db-shell--mobile) .squisq-toolbar-view-tabs {
1682
1978
  box-sizing: border-box;
1683
- flex: 0 0 100%;
1684
- width: 100%;
1979
+ flex: 0 0 auto;
1980
+ width: calc(100% + var(--db-toolbar-wrapped-inline-end));
1981
+ margin-right: calc(-1 * var(--db-toolbar-wrapped-inline-end));
1685
1982
  height: var(--db-toolbar-wrapped-row);
1983
+ border-right: 0;
1686
1984
  }
1687
1985
 
1688
1986
  .db-mobile-back {
@@ -1865,6 +2163,25 @@ body.db-resizing-sidebar * {
1865
2163
  background: rgba(0, 0, 0, 0.4);
1866
2164
  }
1867
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
+
1868
2185
  .db-dialog {
1869
2186
  box-sizing: border-box;
1870
2187
  background: var(--db-bg);
@@ -1936,11 +2253,13 @@ body.db-resizing-sidebar * {
1936
2253
  text-decoration: underline;
1937
2254
  }
1938
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. */
1939
2258
  .db-dialog-links {
1940
2259
  display: flex;
1941
2260
  flex-wrap: wrap;
1942
2261
  align-items: center;
1943
- gap: 6px;
2262
+ gap: 6px 16px;
1944
2263
  }
1945
2264
 
1946
2265
  .db-about-beta {
@@ -1982,10 +2301,6 @@ body.db-resizing-sidebar * {
1982
2301
  user-select: all;
1983
2302
  }
1984
2303
 
1985
- .db-dialog-sep {
1986
- color: var(--db-text-placeholder);
1987
- }
1988
-
1989
2304
  /* ── Settings Dialog ─────────────────────────────────────────── */
1990
2305
 
1991
2306
  .db-settings-fieldset {
@@ -2114,7 +2429,7 @@ body.db-resizing-sidebar * {
2114
2429
  width: 100%;
2115
2430
  padding: 6px 8px;
2116
2431
  font: inherit;
2117
- font-size: 13px;
2432
+ font-size: var(--db-input-font-size);
2118
2433
  background: var(--db-bg-subtle);
2119
2434
  color: var(--db-text);
2120
2435
  border: 1px solid var(--db-input-border);
@@ -2128,6 +2443,130 @@ body.db-resizing-sidebar * {
2128
2443
  border-color: var(--db-accent);
2129
2444
  }
2130
2445
 
2446
+ /* Generated catalog files (index.html, catalog.json): shown, never edited */
2447
+
2448
+ .db-generated-file,
2449
+ .db-generated-file-body {
2450
+ flex: 1;
2451
+ min-height: 0;
2452
+ display: flex;
2453
+ flex-direction: column;
2454
+ }
2455
+
2456
+ .db-generated-file-notice {
2457
+ display: flex;
2458
+ flex-wrap: wrap;
2459
+ align-items: center;
2460
+ gap: 8px 12px;
2461
+ padding: 8px 16px;
2462
+ border-bottom: 1px solid var(--db-border);
2463
+ background: var(--db-bg-subtle);
2464
+ color: var(--db-text-muted);
2465
+ font-size: 13px;
2466
+ line-height: 1.4;
2467
+ }
2468
+
2469
+ .db-generated-file-notice-text {
2470
+ flex: 1 1 240px;
2471
+ min-width: 0;
2472
+ }
2473
+
2474
+ .db-generated-file-notice strong {
2475
+ color: var(--db-text);
2476
+ font-weight: 600;
2477
+ }
2478
+
2479
+ .db-generated-file-back {
2480
+ padding: 4px 8px;
2481
+ border: none;
2482
+ border-radius: 4px;
2483
+ background: none;
2484
+ color: var(--db-text-secondary);
2485
+ font: inherit;
2486
+ cursor: pointer;
2487
+ }
2488
+
2489
+ /* Show the page as a browser would, whatever the app theme: a page that
2490
+ paints no background of its own is drawn on white, never on the app's dark
2491
+ surface (its dark text would vanish). `color-scheme: light` keeps the frame
2492
+ opaque-light rather than inheriting the host's dark canvas. Themed pages
2493
+ paint their own background over this. */
2494
+ .db-generated-file-preview {
2495
+ flex: 1;
2496
+ min-height: 0;
2497
+ width: 100%;
2498
+ border: 0;
2499
+ background: #fff;
2500
+ color-scheme: light;
2501
+ }
2502
+
2503
+ /* Workspace settings (`.docblocks/workspace.json`) */
2504
+
2505
+ .db-settings-subfields {
2506
+ display: flex;
2507
+ flex-direction: column;
2508
+ gap: 10px;
2509
+ margin: 4px 0 10px 24px;
2510
+ }
2511
+
2512
+ .db-settings-text {
2513
+ display: flex;
2514
+ flex-direction: column;
2515
+ gap: 4px;
2516
+ color: var(--db-text);
2517
+ font-size: 13px;
2518
+ }
2519
+
2520
+ .db-settings-text-input {
2521
+ box-sizing: border-box;
2522
+ width: 100%;
2523
+ padding: 6px 8px;
2524
+ font: inherit;
2525
+ font-size: var(--db-input-font-size);
2526
+ background: var(--db-bg-subtle);
2527
+ color: var(--db-text);
2528
+ border: 1px solid var(--db-input-border);
2529
+ border-radius: 4px;
2530
+ outline: none;
2531
+ }
2532
+
2533
+ .db-settings-text-input:focus-visible {
2534
+ border-color: var(--db-accent);
2535
+ }
2536
+
2537
+ .db-settings-textarea {
2538
+ min-height: 3.5em;
2539
+ resize: vertical;
2540
+ font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
2541
+ }
2542
+
2543
+ .db-settings-number-input {
2544
+ max-width: 8em;
2545
+ }
2546
+
2547
+ .db-settings-status-row {
2548
+ display: flex;
2549
+ flex-wrap: wrap;
2550
+ align-items: center;
2551
+ justify-content: space-between;
2552
+ gap: 8px 12px;
2553
+ }
2554
+
2555
+ .db-settings-status {
2556
+ margin: 0;
2557
+ font-size: 12px;
2558
+ line-height: 1.5;
2559
+ color: var(--db-text-muted);
2560
+ }
2561
+
2562
+ .db-settings-status--warning {
2563
+ color: var(--db-danger);
2564
+ }
2565
+
2566
+ .db-settings-link-btn {
2567
+ margin-top: 8px;
2568
+ }
2569
+
2131
2570
  .db-font-picker {
2132
2571
  position: relative;
2133
2572
  }
@@ -2195,11 +2634,7 @@ body.db-resizing-sidebar * {
2195
2634
  .db-font-picker-group {
2196
2635
  padding: 10px 10px 4px;
2197
2636
  color: var(--db-text-muted);
2198
- font:
2199
- 600 10px/1.2 system-ui,
2200
- -apple-system,
2201
- 'Segoe UI',
2202
- sans-serif;
2637
+ font: 600 10px/1.2 var(--db-ui-font);
2203
2638
  letter-spacing: 0.065em;
2204
2639
  text-transform: uppercase;
2205
2640
  }
@@ -2268,11 +2703,7 @@ body.db-resizing-sidebar * {
2268
2703
  .db-font-picker-check {
2269
2704
  flex: 0 0 18px;
2270
2705
  color: var(--db-accent-deep);
2271
- font:
2272
- 700 14px/1 system-ui,
2273
- -apple-system,
2274
- 'Segoe UI',
2275
- sans-serif;
2706
+ font: 700 14px/1 var(--db-ui-font);
2276
2707
  text-align: center;
2277
2708
  }
2278
2709
 
@@ -2309,26 +2740,136 @@ body.db-resizing-sidebar * {
2309
2740
  cursor: default;
2310
2741
  }
2311
2742
 
2312
- .db-settings-accent {
2313
- position: relative;
2314
- display: flex;
2315
- align-items: center;
2316
- gap: 8px;
2317
- min-width: 0;
2318
- padding: 7px 8px;
2319
- border: 1px solid transparent;
2320
- border-radius: 6px;
2743
+ /* The quieter of two actions — Disconnect beside a primary Connect. */
2744
+ .db-settings-action--secondary {
2745
+ border-color: var(--db-input-border);
2746
+ background: transparent;
2321
2747
  color: var(--db-text);
2322
- cursor: pointer;
2323
2748
  }
2324
2749
 
2325
- .db-settings-accent:hover {
2750
+ .db-settings-action--secondary:hover:not(:disabled) {
2751
+ border-color: var(--db-accent);
2326
2752
  background: var(--db-bg-subtle);
2327
2753
  }
2328
2754
 
2329
- .db-settings-accent--selected {
2330
- background: var(--db-accent-soft-08);
2331
- border-color: var(--db-accent);
2755
+ /* A one-time code the person types into Gezel: easy to read and to select. */
2756
+ .db-settings-ai-code {
2757
+ font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
2758
+ font-size: 15px;
2759
+ letter-spacing: 0.12em;
2760
+ color: var(--db-text);
2761
+ user-select: all;
2762
+ }
2763
+
2764
+ .db-settings-ai-error {
2765
+ color: var(--db-danger);
2766
+ }
2767
+
2768
+ .db-settings-ai-models {
2769
+ margin-top: 8px;
2770
+ }
2771
+
2772
+ .db-settings-ai-model-downloads {
2773
+ margin-top: 10px;
2774
+ padding: 12px;
2775
+ border: 1px solid var(--db-border);
2776
+ border-radius: 6px;
2777
+ background: var(--db-bg-subtle);
2778
+ }
2779
+
2780
+ .db-settings-ai-model-downloads .db-settings-select {
2781
+ margin-top: 0;
2782
+ }
2783
+
2784
+ .db-settings-ai-download-progress {
2785
+ display: grid;
2786
+ gap: 6px;
2787
+ margin-top: 12px;
2788
+ color: var(--db-text-secondary);
2789
+ font-size: 12px;
2790
+ }
2791
+
2792
+ .db-settings-ai-download-progress progress {
2793
+ width: 100%;
2794
+ height: 8px;
2795
+ accent-color: var(--db-accent);
2796
+ }
2797
+
2798
+ /* Speech settings: dictation and narration model rows. */
2799
+ .db-settings-speech-section + .db-settings-speech-section {
2800
+ margin-top: 14px;
2801
+ }
2802
+
2803
+ .db-settings-subheading {
2804
+ margin: 10px 0 2px;
2805
+ color: var(--db-text);
2806
+ font-size: 13px;
2807
+ font-weight: 600;
2808
+ }
2809
+
2810
+ .db-settings-speech-models {
2811
+ display: grid;
2812
+ gap: 8px;
2813
+ margin: 8px 0 0;
2814
+ padding: 0;
2815
+ list-style: none;
2816
+ }
2817
+
2818
+ .db-settings-speech-model {
2819
+ display: flex;
2820
+ align-items: center;
2821
+ justify-content: space-between;
2822
+ gap: 12px;
2823
+ padding: 10px 12px;
2824
+ border: 1px solid var(--db-border);
2825
+ border-radius: 6px;
2826
+ background: var(--db-bg-subtle);
2827
+ }
2828
+
2829
+ .db-settings-speech-model-text {
2830
+ display: grid;
2831
+ gap: 2px;
2832
+ min-width: 0;
2833
+ }
2834
+
2835
+ .db-settings-speech-model-name {
2836
+ color: var(--db-text);
2837
+ font-size: 13px;
2838
+ }
2839
+
2840
+ .db-settings-speech-model .db-settings-hint {
2841
+ margin: 0;
2842
+ }
2843
+
2844
+ .db-settings-speech-model .db-settings-ai-download-progress {
2845
+ min-width: 140px;
2846
+ margin-top: 0;
2847
+ }
2848
+
2849
+ .db-settings-speech-model .db-settings-action {
2850
+ flex-shrink: 0;
2851
+ }
2852
+
2853
+ .db-settings-accent {
2854
+ position: relative;
2855
+ display: flex;
2856
+ align-items: center;
2857
+ gap: 8px;
2858
+ min-width: 0;
2859
+ padding: 7px 8px;
2860
+ border: 1px solid transparent;
2861
+ border-radius: 6px;
2862
+ color: var(--db-text);
2863
+ cursor: pointer;
2864
+ }
2865
+
2866
+ .db-settings-accent:hover {
2867
+ background: var(--db-bg-subtle);
2868
+ }
2869
+
2870
+ .db-settings-accent--selected {
2871
+ background: var(--db-accent-soft-08);
2872
+ border-color: var(--db-accent);
2332
2873
  }
2333
2874
 
2334
2875
  .db-settings-accent-input {
@@ -2665,7 +3206,7 @@ body.db-resizing-sidebar * {
2665
3206
  display: block;
2666
3207
  width: 100%;
2667
3208
  padding: 6px 8px;
2668
- font-size: 13px;
3209
+ font-size: var(--db-input-font-size);
2669
3210
  background: var(--db-bg-subtle);
2670
3211
  color: var(--db-text);
2671
3212
  border: 1px solid var(--db-border);
@@ -2690,7 +3231,7 @@ body.db-resizing-sidebar * {
2690
3231
  min-width: 0;
2691
3232
  box-sizing: border-box;
2692
3233
  padding: 6px 8px;
2693
- font-size: 13px;
3234
+ font-size: var(--db-input-font-size);
2694
3235
  background: var(--db-bg-subtle);
2695
3236
  color: var(--db-text);
2696
3237
  border: 1px solid var(--db-border);
@@ -2974,15 +3515,13 @@ body.db-resizing-sidebar * {
2974
3515
  color: var(--db-text-muted);
2975
3516
  }
2976
3517
 
2977
- @media (max-width: 560px) {
2978
- .db-share-qr-heading {
2979
- display: block;
2980
- }
3518
+ [data-db-width='compact'] .db-share-qr-heading {
3519
+ display: block;
3520
+ }
2981
3521
 
2982
- .db-share-qr-actions {
2983
- justify-content: flex-start;
2984
- margin-top: 10px;
2985
- }
3522
+ [data-db-width='compact'] .db-share-qr-actions {
3523
+ justify-content: flex-start;
3524
+ margin-top: 10px;
2986
3525
  }
2987
3526
 
2988
3527
  /* ── Squisq editor chrome separators ─────────────────────────── */
@@ -3545,15 +4084,7 @@ body.db-resizing-sidebar * {
3545
4084
  `var(--db-accent-…)` here drops to the squisq fallback (dark slate
3546
4085
  bg + near-white text) because the vars never resolve. */
3547
4086
  html:has(.db-shell) .squisq-tooltip {
3548
- font-family:
3549
- ui-sans-serif,
3550
- system-ui,
3551
- -apple-system,
3552
- 'Segoe UI',
3553
- Roboto,
3554
- 'Helvetica Neue',
3555
- Arial,
3556
- sans-serif;
4087
+ font-family: var(--db-ui-font);
3557
4088
  box-shadow: 0 2px 8px rgba(15, 30, 20, 0.35);
3558
4089
  /* Default (light mode + system-light): dark espresso chip, cream
3559
4090
  text — an inverted floating chip against the cream UI. */
@@ -5153,6 +5684,82 @@ html:has(.db-shell[data-theme='dark'])
5153
5684
  outline-offset: 2px;
5154
5685
  }
5155
5686
 
5687
+ .db-conflict-columns {
5688
+ display: grid;
5689
+ grid-template-columns: repeat(2, minmax(0, 1fr));
5690
+ gap: 16px;
5691
+ flex: 1;
5692
+ min-height: 300px;
5693
+ }
5694
+
5695
+ .db-conflict-version {
5696
+ display: flex;
5697
+ flex-direction: column;
5698
+ min-width: 0;
5699
+ padding: 16px;
5700
+ border: 1px solid var(--db-border);
5701
+ border-radius: 8px;
5702
+ }
5703
+
5704
+ .db-conflict-version h3 {
5705
+ margin: 0;
5706
+ color: var(--db-text);
5707
+ font-size: 15px;
5708
+ }
5709
+
5710
+ .db-conflict-metadata {
5711
+ margin: 4px 0 12px;
5712
+ color: var(--db-text-muted);
5713
+ font-size: 12px;
5714
+ }
5715
+
5716
+ .db-conflict-preview {
5717
+ box-sizing: border-box;
5718
+ flex: 1;
5719
+ width: 100%;
5720
+ min-height: 160px;
5721
+ padding: 12px;
5722
+ overflow: auto;
5723
+ color: var(--db-text);
5724
+ background: var(--db-bg-elevated, var(--db-bg));
5725
+ border: 1px solid var(--db-border);
5726
+ border-radius: 4px;
5727
+ font:
5728
+ 13px / 1.6 ui-monospace,
5729
+ monospace;
5730
+ resize: none;
5731
+ }
5732
+
5733
+ .db-conflict-consequence {
5734
+ margin: 12px 0;
5735
+ font-size: 12px;
5736
+ }
5737
+
5738
+ .db-conflict-dialog button:not(.db-dialog-close) {
5739
+ min-height: var(--db-target-min, 32px);
5740
+ padding: 7px 12px;
5741
+ color: var(--db-text);
5742
+ background: var(--db-bg);
5743
+ border: 1px solid var(--db-border);
5744
+ border-radius: 5px;
5745
+ cursor: pointer;
5746
+ }
5747
+
5748
+ .db-conflict-dialog button:disabled {
5749
+ opacity: 0.6;
5750
+ cursor: default;
5751
+ }
5752
+
5753
+ .db-conflict-dialog button:focus-visible,
5754
+ .db-conflict-preview:focus-visible {
5755
+ outline: 2px solid var(--db-accent);
5756
+ outline-offset: 2px;
5757
+ }
5758
+
5759
+ [data-db-width='compact'] .db-conflict-columns {
5760
+ grid-template-columns: minmax(0, 1fr);
5761
+ }
5762
+
5156
5763
  /* Browser PWA update notice. It is docked over the right side of Squisq's
5157
5764
  status bar, while extra status-bar padding keeps its contents visible.
5158
5765
  If the status bar is hidden, it becomes a compact floating badge so the
@@ -5304,788 +5911,1868 @@ html:has(.db-shell[data-theme='dark'])
5304
5911
  }
5305
5912
  }
5306
5913
 
5307
- /* ── Git ─────────────────────────────────────────────────────── */
5914
+ /* ── AI editor assistance ───────────────────────────────────── */
5308
5915
 
5309
- /* Dialog size modifiers (shared Dialog component) */
5310
- .db-dialog--wide {
5311
- width: 560px;
5312
- max-width: 100%;
5313
- max-height: min(calc(100dvh - 32px), 660px);
5916
+ .db-ai-toolbar {
5917
+ border-left: 0;
5314
5918
  }
5315
5919
 
5316
- .db-dialog--full {
5317
- width: min(1100px, 94vw);
5318
- height: 82vh;
5319
- display: flex;
5320
- flex-direction: column;
5920
+ .db-ai-toolbar-trigger {
5921
+ color: var(--db-accent-deep);
5321
5922
  }
5322
5923
 
5323
- .db-dialog--full .db-dialog-body {
5324
- flex: 1;
5325
- min-height: 0;
5326
- overflow: auto;
5327
- display: flex;
5328
- flex-direction: column;
5924
+ .db-ai-toolbar-menu {
5925
+ min-width: 220px;
5329
5926
  }
5330
5927
 
5331
- .db-dialog-footer {
5332
- display: flex;
5333
- justify-content: flex-end;
5334
- gap: 8px;
5335
- padding: 12px 20px 16px;
5336
- border-top: 1px solid var(--db-border);
5928
+ /* Read aloud: the speech menu and its inline transport while playing. */
5929
+ .db-speech-toolbar {
5930
+ display: inline-flex;
5931
+ align-items: center;
5932
+ border-left: 0;
5337
5933
  }
5338
5934
 
5339
- /* Buttons used in git dialog footers */
5340
- .db-git-primary-btn {
5341
- padding: 6px 16px;
5342
- border: none;
5343
- border-radius: 5px;
5344
- background: var(--db-accent);
5345
- color: var(--db-text-on-accent);
5346
- font-size: 13px;
5347
- font-weight: 600;
5348
- cursor: pointer;
5935
+ .db-speech-toolbar-menu {
5936
+ min-width: 220px;
5349
5937
  }
5350
5938
 
5351
- .db-git-primary-btn:hover:not(:disabled) {
5352
- background: var(--db-accent-hover);
5939
+ .db-speech-transport {
5940
+ display: inline-flex;
5941
+ align-items: center;
5942
+ gap: 2px;
5353
5943
  }
5354
5944
 
5355
- .db-git-primary-btn:disabled {
5356
- opacity: 0.5;
5357
- cursor: default;
5945
+ .db-speech-transport-label {
5946
+ min-width: 3.5em;
5947
+ padding: 0 6px;
5948
+ color: var(--db-text-secondary);
5949
+ font-size: 12px;
5950
+ font-variant-numeric: tabular-nums;
5951
+ white-space: nowrap;
5358
5952
  }
5359
5953
 
5360
- /* Destructive confirmation (delete, remove workspace). The foreground comes
5361
- from a token rather than a literal because the two themes need opposite ink:
5362
- light's danger is deep red and carries white at ~6.5:1, while dark's is a
5363
- light red where white would fall to ~2.8:1 and fail WCAG AA. */
5364
- .db-git-primary-btn--danger {
5365
- background: var(--db-danger);
5366
- color: var(--db-text-on-danger);
5954
+ .db-ai-toolbar-status {
5955
+ max-width: 280px;
5956
+ padding: 7px 12px;
5957
+ color: var(--db-text-muted);
5958
+ font-size: 11px;
5959
+ line-height: 1.4;
5960
+ white-space: normal;
5367
5961
  }
5368
5962
 
5369
- .db-git-primary-btn--danger:hover:not(:disabled) {
5370
- background: color-mix(in srgb, var(--db-danger) 85%, black);
5963
+ .db-ai-draft-dialog {
5964
+ width: min(680px, 100%);
5371
5965
  }
5372
5966
 
5373
- .db-git-secondary-btn {
5374
- padding: 6px 14px;
5375
- border: 1px solid var(--db-border-strong);
5376
- border-radius: 5px;
5377
- background: transparent;
5378
- color: var(--db-text);
5379
- font-size: 13px;
5380
- cursor: pointer;
5967
+ .db-ai-draft-dialog .db-dialog-footer {
5968
+ flex-wrap: wrap;
5969
+ align-items: center;
5381
5970
  }
5382
5971
 
5383
- .db-git-secondary-btn:hover:not(:disabled) {
5384
- background: var(--db-bg-hover);
5972
+ .db-ai-draft-dialog .db-dialog-header,
5973
+ .db-ai-draft-dialog .db-dialog-footer {
5974
+ flex-shrink: 0;
5385
5975
  }
5386
5976
 
5387
- .db-git-secondary-btn:disabled {
5388
- opacity: 0.5;
5389
- cursor: default;
5977
+ .db-ai-draft-dialog .db-ai-draft-body {
5978
+ display: flex;
5979
+ flex-direction: column;
5980
+ gap: 12px;
5390
5981
  }
5391
5982
 
5392
- /* Status bar row in the sidebar */
5393
- .db-git-statusbar {
5394
- position: relative;
5983
+ .db-ai-draft-body > .db-ai-field,
5984
+ .db-ai-draft-body > .db-ai-selection-preview,
5985
+ .db-ai-draft-body > .db-ai-disclaimer {
5395
5986
  flex-shrink: 0;
5396
- padding: 2px 8px 4px;
5397
- border-bottom: 1px solid var(--db-border);
5987
+ margin: 0;
5398
5988
  }
5399
5989
 
5400
- .db-git-statusbar-chip {
5990
+ /* Let the draft yield space to the prompt, selection and review note. The
5991
+ body still scrolls when a short viewport cannot fit their minimum sizes. */
5992
+ .db-ai-draft-body > .db-ai-draft-field {
5401
5993
  display: flex;
5402
- align-items: center;
5403
- gap: 6px;
5404
- width: 100%;
5405
- padding: 4px 8px;
5406
- border: none;
5407
- border-radius: 4px;
5408
- background: transparent;
5409
- color: var(--db-text-secondary);
5410
- font-size: 12px;
5411
- cursor: pointer;
5412
- overflow: hidden;
5994
+ flex-direction: column;
5995
+ flex: 1 1 auto;
5996
+ min-height: calc(96px + 1.6em + 6px);
5413
5997
  }
5414
5998
 
5415
- .db-git-statusbar-chip:hover {
5416
- background: var(--db-bg-hover);
5999
+ .db-ai-draft-body .db-ai-draft-field .db-ai-draft-output {
6000
+ flex: 1 1 auto;
6001
+ height: min(190px, 28dvh);
6002
+ min-height: 96px;
5417
6003
  }
5418
6004
 
5419
- .db-git-branch-glyph {
5420
- color: var(--db-text-muted);
5421
- flex-shrink: 0;
6005
+ .db-ai-draft-start {
6006
+ display: flex;
6007
+ justify-content: center;
6008
+ padding: 20px 0;
5422
6009
  }
5423
6010
 
5424
- .db-git-statusbar-branch {
5425
- font-weight: 600;
5426
- white-space: nowrap;
5427
- overflow: hidden;
5428
- text-overflow: ellipsis;
6011
+ .db-ai-draft-body .db-ai-selection-preview blockquote {
6012
+ box-sizing: border-box;
6013
+ max-height: min(112px, 16dvh);
5429
6014
  }
5430
6015
 
5431
- .db-git-statusbar-counts {
5432
- color: var(--db-text-muted);
5433
- flex-shrink: 0;
6016
+ .db-ai-draft-dialog .db-ai-draft-footer {
6017
+ flex-direction: column;
6018
+ align-items: stretch;
5434
6019
  }
5435
6020
 
5436
- .db-git-statusbar-dirty {
5437
- color: var(--db-git-modified);
5438
- flex-shrink: 0;
6021
+ .db-ai-draft-actions {
6022
+ display: flex;
6023
+ justify-content: flex-end;
6024
+ flex-wrap: wrap;
6025
+ gap: 8px;
5439
6026
  }
5440
6027
 
5441
- .db-git-statusbar-merge {
5442
- color: var(--db-git-conflicted);
5443
- font-weight: 600;
5444
- flex-shrink: 0;
6028
+ /* Status has its own row, so errors cannot steal space from the actions. */
6029
+ .db-ai-footer-status {
6030
+ min-width: 0;
6031
+ overflow-wrap: anywhere;
5445
6032
  }
5446
6033
 
5447
- .db-git-statusbar-busy {
5448
- color: var(--db-text-muted);
5449
- flex-shrink: 0;
6034
+ .db-ai-footer-status p {
6035
+ margin: 0;
5450
6036
  }
5451
6037
 
5452
- /* The offer to turn Git on for a folder inside a larger repository. It sits
5453
- directly above the sidebar footer and borrows its voice: muted, 11px, no
5454
- icon and no accent — this is a default the user may change, not a fault. */
5455
- .db-git-grant-notice {
5456
- box-sizing: border-box;
5457
- display: flex;
5458
- align-items: center;
6038
+ .db-ai-field {
6039
+ display: grid;
5459
6040
  gap: 6px;
5460
- flex-shrink: 0;
5461
- padding: 6px 12px 6px 18px;
5462
- border-top: 1px solid var(--db-border);
6041
+ margin-bottom: 14px;
6042
+ color: var(--db-text);
6043
+ font-weight: 600;
6044
+ }
6045
+
6046
+ .db-ai-field textarea {
6047
+ box-sizing: border-box;
6048
+ width: 100%;
6049
+ min-height: 72px;
6050
+ padding: 9px 10px;
6051
+ resize: vertical;
6052
+ border: 1px solid var(--db-input-border);
6053
+ border-radius: 5px;
6054
+ outline: none;
6055
+ background: var(--db-bg-subtle);
6056
+ color: var(--db-text);
6057
+ font: 400 var(--db-input-font-size) / 1.5 var(--db-ui-font);
6058
+ }
6059
+
6060
+ .db-ai-field textarea:focus-visible {
6061
+ border-color: var(--db-accent);
6062
+ box-shadow: 0 0 0 1px var(--db-accent);
6063
+ }
6064
+
6065
+ .db-ai-field .db-ai-draft-output {
6066
+ min-height: 190px;
6067
+ font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
6068
+ font-size: 12px;
6069
+ font-weight: 400;
6070
+ }
6071
+
6072
+ .db-ai-selection-preview {
6073
+ margin: 0 0 14px;
5463
6074
  color: var(--db-text-muted);
5464
- font-size: 11px;
5465
- line-height: 1.3;
6075
+ font-size: 12px;
5466
6076
  }
5467
6077
 
5468
- .db-git-grant-notice-text {
5469
- overflow: hidden;
5470
- text-overflow: ellipsis;
5471
- white-space: nowrap;
6078
+ /* A whole-document selection must not push the draft below the dialog. */
6079
+ .db-ai-selection-preview blockquote {
6080
+ max-height: calc(8 * 1.5em + 16px);
6081
+ border: 1px solid var(--db-input-border);
6082
+ border-radius: 5px;
5472
6083
  }
5473
6084
 
5474
- .db-git-grant-notice-action {
5475
- flex-shrink: 0;
5476
- padding: 0;
5477
- border: 0;
5478
- background: transparent;
5479
- color: inherit;
5480
- font: inherit;
5481
- line-height: inherit;
5482
- text-decoration: underline;
5483
- white-space: nowrap;
5484
- cursor: pointer;
6085
+ .db-ai-selection-preview blockquote:focus-visible {
6086
+ outline: 2px solid var(--db-focus);
6087
+ outline-offset: 2px;
5485
6088
  }
5486
6089
 
5487
- .db-git-grant-notice-action:hover {
6090
+ .db-ai-selection-preview blockquote,
6091
+ .db-ai-review-excerpt blockquote {
6092
+ margin: 5px 0 0;
6093
+ padding: 8px 10px;
6094
+ overflow: auto;
6095
+ background: var(--db-bg-subtle);
5488
6096
  color: var(--db-text-secondary);
6097
+ font:
6098
+ 400 12px/1.5 ui-monospace,
6099
+ SFMono-Regular,
6100
+ Consolas,
6101
+ monospace;
6102
+ white-space: pre-wrap;
6103
+ overflow-wrap: anywhere;
5489
6104
  }
5490
6105
 
5491
- .db-git-grant-remember {
6106
+ .db-ai-review-excerpt blockquote {
6107
+ border-left: 3px solid var(--db-border-strong);
6108
+ }
6109
+
6110
+ .db-ai-progress,
6111
+ .db-ai-note,
6112
+ .db-ai-error,
6113
+ .db-ai-disclaimer {
6114
+ font-size: 12px;
6115
+ }
6116
+
6117
+ .db-ai-progress {
5492
6118
  display: flex;
5493
6119
  align-items: center;
5494
- gap: 8px;
5495
- margin: 12px 0;
5496
- font-size: 13px;
5497
- color: var(--db-text);
5498
- cursor: pointer;
6120
+ gap: 7px;
6121
+ color: var(--db-text-secondary);
5499
6122
  }
5500
6123
 
5501
- /* Actions dropdown (mirrors db-ws-settings-dropdown) */
5502
- .db-git-menu {
5503
- position: absolute;
5504
- top: 100%;
5505
- left: 8px;
5506
- right: 8px;
5507
- z-index: 100;
5508
- background: var(--db-bg);
5509
- border: 1px solid var(--db-border);
5510
- border-radius: 6px;
5511
- box-shadow: 0 4px 12px var(--db-shadow);
5512
- padding: 4px 0;
5513
- margin-top: 2px;
6124
+ .db-ai-generation-status {
6125
+ display: grid;
6126
+ gap: 6px;
5514
6127
  }
5515
6128
 
5516
- .db-git-menu-item {
5517
- display: block;
6129
+ .db-ai-generation-status progress {
5518
6130
  width: 100%;
5519
- padding: 7px 14px;
5520
- border: none;
5521
- background: transparent;
5522
- text-align: left;
5523
- font-size: 13px;
5524
- color: var(--db-text);
5525
- cursor: pointer;
6131
+ height: 6px;
6132
+ accent-color: var(--db-accent);
5526
6133
  }
5527
6134
 
5528
- .db-git-menu-item:hover:not(:disabled),
5529
- .db-git-menu-item:focus-visible {
5530
- background: var(--db-bg-hover);
6135
+ .db-ai-error {
6136
+ color: var(--db-danger);
5531
6137
  }
5532
6138
 
5533
- /* Items are arrow-reachable rather than tab stops, so the ring is the only
5534
- cue to which one Enter will fire. */
5535
- .db-git-menu-item:focus-visible {
5536
- outline: 2px solid var(--db-focus);
5537
- outline-offset: -2px;
6139
+ .db-ai-note,
6140
+ .db-ai-disclaimer {
6141
+ color: var(--db-text-muted);
5538
6142
  }
5539
6143
 
5540
- .db-git-menu-item:disabled {
5541
- color: var(--db-text-placeholder);
5542
- cursor: default;
6144
+ .db-ai-spinner {
6145
+ display: inline-block;
6146
+ width: 12px;
6147
+ height: 12px;
6148
+ flex: 0 0 12px;
6149
+ box-sizing: border-box;
6150
+ border: 2px solid var(--db-border-strong);
6151
+ border-top-color: var(--db-accent);
6152
+ border-radius: 50%;
6153
+ animation: db-ai-spin 0.8s linear infinite;
5543
6154
  }
5544
6155
 
5545
- .db-git-menu-divider {
5546
- height: 1px;
5547
- background: var(--db-border);
5548
- margin: 4px 0;
6156
+ @keyframes db-ai-spin {
6157
+ to {
6158
+ transform: rotate(360deg);
6159
+ }
5549
6160
  }
5550
6161
 
5551
- /* aria-live op-result line — visually subtle, announced politely */
5552
- .db-git-inline-status {
5553
- display: block;
5554
- padding: 0 16px;
5555
- font-size: 11px;
5556
- color: var(--db-text-muted);
5557
- min-height: 0;
6162
+ .db-text-from-narration button:not(.db-dialog-close),
6163
+ .db-ai-draft-dialog .db-dialog-footer button,
6164
+ .db-ai-draft-start button,
6165
+ .db-ai-review-panel button {
6166
+ min-height: var(--db-target-min);
6167
+ padding: 6px 10px;
6168
+ border: 1px solid var(--db-input-border);
6169
+ border-radius: 5px;
6170
+ background: var(--db-bg);
6171
+ color: var(--db-text-secondary);
6172
+ font: 600 12px/1.2 var(--db-ui-font);
6173
+ cursor: pointer;
5558
6174
  }
5559
6175
 
5560
- .db-git-inline-status:empty {
5561
- display: none;
6176
+ .db-text-from-narration .db-dialog-footer button:last-child,
6177
+ .db-ai-draft-dialog .db-dialog-footer button:last-child,
6178
+ .db-ai-draft-start button,
6179
+ .db-ai-review-finding-actions button:last-child,
6180
+ .db-ai-review-actions button {
6181
+ border-color: var(--db-accent);
6182
+ background: var(--db-accent);
6183
+ color: var(--db-text-on-accent);
5562
6184
  }
5563
6185
 
5564
- /* File-tree badges */
5565
- .db-git-badge {
5566
- margin-left: auto;
5567
- padding: 0 4px;
5568
- font-size: 10px;
5569
- font-weight: 700;
5570
- flex-shrink: 0;
6186
+ .db-text-from-narration button:not(.db-dialog-close):hover:not(:disabled),
6187
+ .db-ai-draft-dialog .db-dialog-footer button:hover:not(:disabled),
6188
+ .db-ai-draft-start button:hover,
6189
+ .db-ai-review-panel button:hover:not(:disabled) {
6190
+ border-color: var(--db-accent-hover);
6191
+ background: var(--db-bg-hover);
6192
+ color: var(--db-text);
5571
6193
  }
5572
6194
 
5573
- .db-tree-row .db-git-badge {
5574
- margin-left: 4px;
6195
+ .db-text-from-narration button:focus-visible,
6196
+ .db-text-from-narration textarea:focus-visible,
6197
+ .db-ai-draft-dialog .db-dialog-footer button:focus-visible,
6198
+ .db-ai-draft-start button:focus-visible,
6199
+ .db-ai-review-panel button:focus-visible {
6200
+ outline: 2px solid var(--db-focus);
6201
+ outline-offset: 2px;
5575
6202
  }
5576
6203
 
5577
- .db-git-badge--modified {
5578
- color: var(--db-git-modified);
6204
+ .db-text-from-narration button:disabled,
6205
+ .db-ai-draft-dialog .db-dialog-footer button:disabled,
6206
+ .db-ai-review-panel button:disabled {
6207
+ opacity: 0.5;
6208
+ cursor: default;
5579
6209
  }
5580
6210
 
5581
- .db-git-badge--added {
5582
- color: var(--db-git-added);
6211
+ .db-ai-review-panel {
6212
+ position: relative;
6213
+ z-index: 5;
6214
+ width: min(360px, 38vw);
6215
+ min-width: 280px;
6216
+ min-height: 0;
6217
+ flex: 0 0 auto;
6218
+ box-sizing: border-box;
6219
+ overflow-y: auto;
6220
+ border-left: 1px solid var(--db-border-strong);
6221
+ background: var(--db-bg);
6222
+ color: var(--db-text-secondary);
6223
+ font: 13px/1.45 var(--db-ui-font);
5583
6224
  }
5584
6225
 
5585
- .db-git-badge--untracked {
5586
- color: var(--db-git-untracked);
6226
+ [data-db-width='compact'] .db-ai-review-panel {
6227
+ position: absolute;
6228
+ inset: 0;
6229
+ width: 100%;
6230
+ min-width: 0;
6231
+ border-left: 0;
5587
6232
  }
5588
6233
 
5589
- .db-git-badge--renamed {
5590
- color: var(--db-git-renamed);
6234
+ .db-ai-review-header {
6235
+ position: sticky;
6236
+ top: 0;
6237
+ z-index: 1;
6238
+ display: flex;
6239
+ align-items: flex-start;
6240
+ justify-content: space-between;
6241
+ gap: 12px;
6242
+ padding: 14px 14px 10px;
6243
+ border-bottom: 1px solid var(--db-border);
6244
+ background: var(--db-bg);
5591
6245
  }
5592
6246
 
5593
- .db-git-badge--deleted {
5594
- color: var(--db-git-deleted);
6247
+ .db-ai-review-header h2 {
6248
+ margin: 0;
6249
+ color: var(--db-text);
6250
+ font-size: 15px;
6251
+ line-height: 1.3;
5595
6252
  }
5596
6253
 
5597
- .db-git-badge--conflicted {
5598
- color: var(--db-git-conflicted);
6254
+ .db-ai-review-count {
6255
+ color: var(--db-text-muted);
6256
+ font-size: 11px;
5599
6257
  }
5600
6258
 
5601
- .db-git-badge--dir {
5602
- color: var(--db-git-modified);
6259
+ .db-ai-review-close {
6260
+ width: var(--db-target-min);
6261
+ padding: 0 !important;
6262
+ border-color: transparent !important;
6263
+ background: transparent !important;
6264
+ font-size: 20px !important;
6265
+ line-height: 1 !important;
5603
6266
  }
5604
6267
 
5605
- .db-tree-context-divider {
5606
- height: 1px;
5607
- background: var(--db-border);
5608
- margin: 4px 0;
6268
+ .db-ai-review-actions {
6269
+ padding: 10px 14px 0;
5609
6270
  }
5610
6271
 
5611
- /* Toolbar control */
5612
- .db-git-toolbar-trigger {
5613
- position: relative;
6272
+ .db-ai-review-empty,
6273
+ .db-ai-review-stale {
6274
+ margin: 12px 14px;
6275
+ padding: 10px;
6276
+ border: 1px solid var(--db-border);
6277
+ border-radius: 5px;
6278
+ background: var(--db-bg-subtle);
6279
+ color: var(--db-text-muted);
5614
6280
  }
5615
6281
 
5616
- .db-git-toolbar-dot {
5617
- position: absolute;
5618
- top: 3px;
5619
- right: 3px;
5620
- width: 7px;
5621
- height: 7px;
5622
- border-radius: 50%;
5623
- background: var(--db-git-modified);
6282
+ .db-ai-review-stale {
6283
+ border-color: var(--db-accent);
6284
+ color: var(--db-text-secondary);
5624
6285
  }
5625
6286
 
5626
- /* Dialog internals — file lists (commit + conflicts) */
5627
- .db-git-file-list {
5628
- margin: 8px 0;
5629
- padding: 0;
6287
+ .db-ai-review-list {
6288
+ display: grid;
6289
+ gap: 10px;
6290
+ margin: 12px 0 0;
6291
+ padding: 0 14px;
5630
6292
  list-style: none;
5631
- max-height: 260px;
5632
- overflow-y: auto;
6293
+ }
6294
+
6295
+ .db-ai-review-finding {
6296
+ padding: 12px;
5633
6297
  border: 1px solid var(--db-border);
5634
- border-radius: 5px;
6298
+ border-radius: 6px;
6299
+ background: var(--db-bg);
6300
+ box-shadow: 0 1px 2px var(--db-shadow);
5635
6301
  }
5636
6302
 
5637
- .db-git-file-row {
6303
+ .db-ai-review-finding-meta {
5638
6304
  display: flex;
5639
6305
  align-items: center;
5640
- gap: 8px;
5641
- width: 100%;
5642
- padding: 6px 10px;
5643
- border: none;
5644
- background: transparent;
5645
- font-size: 12.5px;
5646
- color: var(--db-text);
5647
- text-align: left;
5648
- }
5649
-
5650
- .db-git-file-row + .db-git-file-row {
5651
- border-top: 1px solid var(--db-border);
6306
+ gap: 7px;
6307
+ color: var(--db-text-muted);
6308
+ font-size: 11px;
5652
6309
  }
5653
6310
 
5654
- button.db-git-file-row {
5655
- cursor: pointer;
6311
+ .db-ai-review-severity {
6312
+ padding: 2px 5px;
6313
+ border: 1px solid var(--db-border);
6314
+ border-radius: 3px;
6315
+ text-transform: uppercase;
6316
+ letter-spacing: 0.04em;
5656
6317
  }
5657
6318
 
5658
- button.db-git-file-row:hover {
5659
- background: var(--db-bg-hover);
6319
+ .db-ai-review-severity--warning {
6320
+ border-color: var(--db-danger);
6321
+ color: var(--db-danger);
5660
6322
  }
5661
6323
 
5662
- .db-git-file-kind {
5663
- margin-left: auto;
5664
- font-size: 10.5px;
5665
- color: var(--db-text-muted);
5666
- flex-shrink: 0;
6324
+ .db-ai-review-severity--suggestion {
6325
+ border-color: var(--db-accent);
6326
+ color: var(--db-accent-deep);
5667
6327
  }
5668
6328
 
5669
- .db-git-commit-message {
5670
- width: 100%;
5671
- min-height: 72px;
5672
- padding: 8px 10px;
5673
- border: 1px solid var(--db-input-border);
5674
- border-radius: 5px;
5675
- background: var(--db-bg);
6329
+ .db-ai-review-finding h3 {
6330
+ margin: 8px 0 5px;
5676
6331
  color: var(--db-text);
5677
6332
  font-size: 13px;
5678
- font-family: inherit;
5679
- resize: vertical;
5680
- box-sizing: border-box;
5681
6333
  }
5682
6334
 
5683
- /* Generic form rows in git dialogs */
5684
- .db-git-form-row {
5685
- display: flex;
5686
- align-items: center;
5687
- gap: 8px;
5688
- margin: 10px 0;
6335
+ .db-ai-review-finding p {
6336
+ margin: 0 0 8px;
5689
6337
  }
5690
6338
 
5691
- .db-git-form-label {
5692
- font-size: 12.5px;
5693
- color: var(--db-text-secondary);
5694
- flex-shrink: 0;
6339
+ .db-ai-review-excerpt {
6340
+ margin-top: 10px;
6341
+ color: var(--db-text-muted);
6342
+ font-size: 11px;
5695
6343
  }
5696
6344
 
5697
- .db-git-form-input {
5698
- flex: 1;
5699
- padding: 6px 10px;
5700
- border: 1px solid var(--db-input-border);
5701
- border-radius: 5px;
5702
- background: var(--db-bg);
5703
- color: var(--db-text);
5704
- font-size: 13px;
5705
- box-sizing: border-box;
6345
+ .db-ai-review-excerpt--replacement blockquote {
6346
+ border-left-color: var(--db-accent);
6347
+ background: var(--db-accent-soft-08);
5706
6348
  }
5707
6349
 
5708
- .db-git-form-error,
5709
- .db-export-error {
5710
- margin: 8px 0 0;
5711
- color: var(--db-danger);
5712
- font-size: 12.5px;
6350
+ .db-ai-review-finding-actions {
6351
+ display: flex;
6352
+ justify-content: flex-end;
6353
+ gap: 7px;
6354
+ margin-top: 10px;
5713
6355
  }
5714
6356
 
5715
- .db-git-hint {
5716
- color: var(--db-text-muted);
5717
- font-size: 12px;
6357
+ .db-settings-ai-knowledge-list {
6358
+ list-style: none;
6359
+ margin: 0;
6360
+ padding: 0;
5718
6361
  }
5719
6362
 
5720
- /* Branches dialog */
5721
- .db-git-branch-list {
5722
- margin: 8px 0;
5723
- padding: 0;
5724
- list-style: none;
5725
- max-height: 280px;
5726
- overflow-y: auto;
6363
+ .db-settings-ai-knowledge-list > li {
6364
+ border-top: 1px solid var(--db-border);
6365
+ padding-block: 12px;
6366
+ overflow-wrap: anywhere;
5727
6367
  }
5728
6368
 
5729
- .db-git-branch-row {
6369
+ .db-settings-ai-knowledge-actions {
5730
6370
  display: flex;
6371
+ flex-wrap: wrap;
5731
6372
  align-items: center;
5732
6373
  gap: 8px;
5733
- width: 100%;
5734
- padding: 7px 10px;
5735
- border: none;
5736
- border-radius: 4px;
5737
- background: transparent;
5738
- font-size: 13px;
5739
- color: var(--db-text);
5740
- text-align: left;
5741
- cursor: pointer;
5742
6374
  }
5743
6375
 
5744
- .db-git-branch-row:hover {
5745
- background: var(--db-bg-hover);
6376
+ .db-settings-ai-knowledge progress {
6377
+ max-width: 100%;
5746
6378
  }
5747
6379
 
5748
- .db-git-branch-row--current {
5749
- font-weight: 600;
5750
- color: var(--db-accent);
5751
- cursor: default;
6380
+ .db-ai-review-disclaimer {
6381
+ margin: 14px;
6382
+ color: var(--db-text-muted);
6383
+ font-size: 11px;
5752
6384
  }
5753
6385
 
5754
- .db-git-branch-row--current:hover {
5755
- background: transparent;
6386
+ /* AI diagrams: the Illustrate panel cards and the Insert diagram dialog. */
6387
+ .db-ai-illustrate-kind {
6388
+ border-color: var(--db-accent);
6389
+ color: var(--db-accent-deep);
5756
6390
  }
5757
6391
 
5758
- /* History dialog */
5759
- .db-git-history-list {
5760
- margin: 8px 0;
5761
- padding: 0;
5762
- list-style: none;
6392
+ .db-ai-illustrate-actions {
6393
+ flex-wrap: wrap;
6394
+ align-items: center;
5763
6395
  }
5764
6396
 
5765
- .db-git-history-item {
5766
- padding: 8px 10px;
5767
- border-bottom: 1px solid var(--db-border);
5768
- cursor: pointer;
6397
+ .db-ai-illustrate-actions select,
6398
+ .db-ai-field--inline select {
6399
+ min-height: var(--db-target-min);
6400
+ border: 1px solid var(--db-border-strong);
6401
+ border-radius: 5px;
6402
+ background: var(--db-bg);
6403
+ color: var(--db-text);
6404
+ font: inherit;
5769
6405
  }
5770
6406
 
5771
- .db-git-history-item:hover {
5772
- background: var(--db-bg-hover);
6407
+ .db-ai-illustrate-footer {
6408
+ position: sticky;
6409
+ bottom: 0;
6410
+ padding-bottom: 10px;
6411
+ background: var(--db-bg);
5773
6412
  }
5774
6413
 
5775
- .db-git-history-meta {
5776
- margin-top: 2px;
5777
- font-size: 11.5px;
5778
- color: var(--db-text-muted);
6414
+ .db-ai-field--inline {
6415
+ display: flex;
6416
+ align-items: center;
6417
+ gap: 10px;
5779
6418
  }
5780
6419
 
5781
- .db-git-history-files {
5782
- margin: 6px 0 0;
5783
- padding: 0;
5784
- list-style: none;
6420
+ .db-ai-diagram-preview {
6421
+ margin: 10px 0 6px;
6422
+ max-height: 340px;
6423
+ overflow: auto;
6424
+ border: 1px solid var(--db-border);
6425
+ border-radius: 6px;
6426
+ background: var(--db-bg-subtle);
5785
6427
  }
5786
6428
 
5787
- .db-git-history-file {
5788
- display: flex;
5789
- align-items: center;
5790
- gap: 8px;
5791
- width: 100%;
5792
- padding: 4px 8px;
5793
- border: none;
5794
- background: transparent;
5795
- font-size: 12px;
6429
+ .db-ai-diagram-dialog .db-ai-diagram-preview {
6430
+ max-height: 420px;
6431
+ }
6432
+
6433
+ .db-ai-diagram-source {
6434
+ max-height: 220px;
6435
+ overflow: auto;
6436
+ margin: 6px 0 0;
6437
+ padding: 8px;
6438
+ border: 1px solid var(--db-border);
6439
+ border-radius: 5px;
6440
+ background: var(--db-bg-subtle);
5796
6441
  color: var(--db-text-secondary);
5797
- text-align: left;
5798
- cursor: pointer;
5799
- border-radius: 4px;
6442
+ font:
6443
+ 11px/1.4 ui-monospace,
6444
+ SFMono-Regular,
6445
+ Consolas,
6446
+ monospace;
6447
+ white-space: pre;
5800
6448
  }
5801
6449
 
5802
- .db-git-history-file:hover {
5803
- background: var(--db-bg-hover);
6450
+ .db-ai-link-button {
6451
+ padding: 0;
6452
+ border: 0;
6453
+ background: none;
6454
+ color: var(--db-accent-deep);
6455
+ font: inherit;
6456
+ text-decoration: underline;
6457
+ cursor: pointer;
5804
6458
  }
5805
6459
 
5806
- /* Diff dialog */
5807
- .db-git-diff-host {
5808
- flex: 1;
5809
- min-height: 320px;
5810
- border: 1px solid var(--db-border);
5811
- border-radius: 5px;
5812
- overflow: hidden;
6460
+ @media (prefers-reduced-motion: reduce) {
6461
+ .db-ai-spinner {
6462
+ animation: none;
6463
+ }
5813
6464
  }
5814
6465
 
5815
- .db-git-diff-loading {
5816
- padding: 24px;
5817
- text-align: center;
5818
- color: var(--db-text-muted);
6466
+ /* ── Git ─────────────────────────────────────────────────────── */
6467
+
6468
+ /* Dialog size modifiers (shared Dialog component) */
6469
+ .db-dialog--wide {
6470
+ width: 560px;
6471
+ max-width: 100%;
6472
+ max-height: min(calc(100dvh - 32px), 660px);
5819
6473
  }
5820
6474
 
5821
- .db-git-diff-labels {
6475
+ .db-dialog--full {
6476
+ width: min(1100px, 94vw);
6477
+ height: 82vh;
5822
6478
  display: flex;
5823
- gap: 12px;
5824
- margin-bottom: 6px;
5825
- font-size: 12px;
5826
- color: var(--db-text-muted);
6479
+ flex-direction: column;
5827
6480
  }
5828
6481
 
5829
- .db-git-diff-labels > span {
6482
+ .db-dialog--full .db-dialog-body {
5830
6483
  flex: 1;
6484
+ min-height: 0;
6485
+ overflow: auto;
6486
+ display: flex;
6487
+ flex-direction: column;
5831
6488
  }
5832
6489
 
5833
- /* Clone progress */
5834
- .db-git-progress {
5835
- margin: 12px 0 4px;
6490
+ .db-dialog-footer {
6491
+ display: flex;
6492
+ justify-content: flex-end;
6493
+ gap: 8px;
6494
+ padding: 12px 20px 16px;
6495
+ border-top: 1px solid var(--db-border);
5836
6496
  }
5837
6497
 
5838
- .db-git-progress-bar {
5839
- height: 6px;
5840
- border-radius: 3px;
5841
- background: var(--db-accent-soft-15);
5842
- overflow: hidden;
5843
- position: relative;
6498
+ /* Buttons used in git dialog footers */
6499
+ .db-git-primary-btn {
6500
+ padding: 6px 16px;
6501
+ border: none;
6502
+ border-radius: 5px;
6503
+ background: var(--db-accent);
6504
+ color: var(--db-text-on-accent);
6505
+ font-size: 13px;
6506
+ font-weight: 600;
6507
+ cursor: pointer;
5844
6508
  }
5845
6509
 
5846
- .db-git-progress-bar > span {
5847
- display: block;
5848
- height: 100%;
5849
- background: var(--db-accent);
5850
- transition: width 0.2s;
6510
+ .db-git-primary-btn:hover:not(:disabled) {
6511
+ background: var(--db-accent-hover);
5851
6512
  }
5852
6513
 
5853
- .db-git-progress-text {
5854
- margin-top: 6px;
5855
- font-size: 12px;
5856
- color: var(--db-text-muted);
6514
+ .db-git-primary-btn:disabled {
6515
+ opacity: 0.5;
6516
+ cursor: default;
5857
6517
  }
5858
6518
 
5859
- @media (prefers-reduced-motion: reduce) {
5860
- .db-workspace-picker-caret,
5861
- .db-app-menu-caret,
5862
- .db-ws-settings-btn,
5863
- .db-shell-sidebar-resizer,
5864
- .db-sidebar-collapse-preview,
5865
- .db-export-chip,
5866
- .db-git-progress-bar > span {
5867
- transition: none;
5868
- }
6519
+ /* Destructive confirmation (delete, remove workspace). The foreground comes
6520
+ from a token rather than a literal because the two themes need opposite ink:
6521
+ light's danger is deep red and carries white at ~6.5:1, while dark's is a
6522
+ light red where white would fall to ~2.8:1 and fail WCAG AA. */
6523
+ .db-git-primary-btn--danger {
6524
+ background: var(--db-danger);
6525
+ color: var(--db-text-on-danger);
6526
+ }
5869
6527
 
5870
- .db-welcome-gateway,
5871
- .db-save-toast {
5872
- animation: none;
5873
- }
6528
+ .db-git-primary-btn--danger:hover:not(:disabled) {
6529
+ background: color-mix(in srgb, var(--db-danger) 85%, black);
5874
6530
  }
5875
6531
 
5876
- /* History dialog internals added by the expanded-row layout */
5877
- .db-git-history-toggle {
5878
- display: block;
5879
- width: 100%;
5880
- padding: 0;
5881
- border: none;
6532
+ .db-git-secondary-btn {
6533
+ padding: 6px 14px;
6534
+ border: 1px solid var(--db-border-strong);
6535
+ border-radius: 5px;
5882
6536
  background: transparent;
5883
- color: inherit;
5884
- font: inherit;
5885
- text-align: left;
6537
+ color: var(--db-text);
6538
+ font-size: 13px;
5886
6539
  cursor: pointer;
5887
6540
  }
5888
6541
 
5889
- .db-git-history-subject {
5890
- display: block;
5891
- font-size: 13px;
5892
- color: var(--db-text);
6542
+ .db-git-secondary-btn:hover:not(:disabled) {
6543
+ background: var(--db-bg-hover);
5893
6544
  }
5894
6545
 
5895
- .db-git-history-body {
5896
- margin: 6px 0 0;
5897
- padding: 8px 10px;
6546
+ .db-git-secondary-btn:disabled {
6547
+ opacity: 0.5;
6548
+ cursor: default;
6549
+ }
6550
+
6551
+ /* Status bar row in the sidebar */
6552
+ .db-git-statusbar {
6553
+ position: relative;
6554
+ flex-shrink: 0;
6555
+ padding: 2px 8px 4px;
6556
+ border-bottom: 1px solid var(--db-border);
6557
+ }
6558
+
6559
+ .db-git-statusbar-chip {
6560
+ display: flex;
6561
+ align-items: center;
6562
+ gap: 6px;
6563
+ width: 100%;
6564
+ padding: 4px 8px;
6565
+ border: none;
5898
6566
  border-radius: 4px;
5899
- background: var(--db-bg-subtle);
6567
+ background: transparent;
5900
6568
  color: var(--db-text-secondary);
5901
6569
  font-size: 12px;
5902
- white-space: pre-wrap;
5903
- font-family: inherit;
6570
+ cursor: pointer;
6571
+ overflow: hidden;
5904
6572
  }
5905
6573
 
5906
- /* ---------------------------------------------------------------------------
5907
- Window Controls Overlay — installed web app (PWA) custom titlebar.
6574
+ .db-git-statusbar-chip:hover {
6575
+ background: var(--db-bg-hover);
6576
+ }
5908
6577
 
5909
- When the manifest's `display_override: ["window-controls-overlay", ...]`
5910
- is active, the OS caption buttons float over the first shell row and this
5911
- block turns that row into the titlebar: draggable empty space, insets for
5912
- the caption buttons, and every interactive descendant opted back out.
6578
+ .db-git-branch-glyph {
6579
+ color: var(--db-text-muted);
6580
+ flex-shrink: 0;
6581
+ }
5913
6582
 
5914
- Shares its drag/inset structure with the Electron build in
5915
- packages/desktop/renderer/titlebar.css. Its compact vertical metrics are
5916
- intentionally PWA-specific because Electron uses a 42px overlay while this
5917
- mode follows the OS-provided caption height (32px on Windows). Electron is
5918
- scoped under `.db-desktop-root` and reports `display-mode: browser`, so this
5919
- media query can never double-apply there. The media query is live: toggling
5920
- the overlay chevron flips it with no JS. */
5921
- @media (display-mode: window-controls-overlay) {
5922
- .db-shell {
5923
- --db-wco-titlebar-height: env(titlebar-area-height, 32px);
5924
- }
6583
+ .db-git-statusbar-branch {
6584
+ font-weight: 600;
6585
+ white-space: nowrap;
6586
+ overflow: hidden;
6587
+ text-overflow: ellipsis;
6588
+ }
5925
6589
 
5926
- /* The first shell row replaces the native titlebar. Empty space can drag
5927
- the window; every interactive descendant opts back out below. */
5928
- .db-shell .db-shell-sidebar-header,
5929
- .db-shell .squisq-editor-header {
5930
- app-region: drag;
5931
- -webkit-app-region: drag;
5932
- box-sizing: border-box;
5933
- height: var(--db-wco-titlebar-height);
5934
- min-height: var(--db-wco-titlebar-height);
5935
- }
6590
+ .db-git-statusbar-counts {
6591
+ color: var(--db-text-muted);
6592
+ flex-shrink: 0;
6593
+ }
5936
6594
 
5937
- .db-shell .squisq-toolbar {
5938
- app-region: drag;
5939
- -webkit-app-region: drag;
5940
- box-sizing: border-box;
5941
- height: 100%;
5942
- min-height: 0;
5943
- }
6595
+ .db-git-statusbar-dirty {
6596
+ color: var(--db-git-modified);
6597
+ flex-shrink: 0;
6598
+ }
5944
6599
 
5945
- /* The flexible actions lane owns the otherwise-empty gap between Squisq's
5946
- formatting controls and the fixed document controls. Mark the child
5947
- explicitly because its overflow clipping can prevent the toolbar's drag
5948
- region from reaching those pixels. Controls opt out below. */
5949
- .db-shell .squisq-toolbar-actions {
5950
- app-region: drag;
5951
- -webkit-app-region: drag;
5952
- cursor: grab;
5953
- }
6600
+ .db-git-statusbar-merge {
6601
+ color: var(--db-git-conflicted);
6602
+ font-weight: 600;
6603
+ flex-shrink: 0;
6604
+ }
5954
6605
 
5955
- .db-shell .db-shell-sidebar-header {
5956
- padding-block: 0;
5957
- padding-left: max(4px, calc(env(titlebar-area-x, 0px) + 4px));
5958
- cursor: grab;
5959
- }
6606
+ .db-git-statusbar-busy {
6607
+ color: var(--db-text-muted);
6608
+ flex-shrink: 0;
6609
+ }
5960
6610
 
5961
- /* Keep the shell controls inside the compact native caption band. These
5962
- overrides apply only to an installed app using Window Controls Overlay;
5963
- the regular browser toolbar keeps its roomier metrics. */
5964
- .db-shell .db-app-menu-btn,
5965
- .db-shell .db-workspace-picker-btn {
5966
- padding-block: 3px;
5967
- }
6611
+ /* The offer to turn Git on for a folder inside a larger repository. It sits
6612
+ directly above the sidebar footer and borrows its voice: muted, 11px, no
6613
+ icon and no accent — this is a default the user may change, not a fault. */
6614
+ .db-git-grant-notice {
6615
+ box-sizing: border-box;
6616
+ display: flex;
6617
+ align-items: center;
6618
+ gap: 6px;
6619
+ flex-shrink: 0;
6620
+ padding: 6px 12px 6px 18px;
6621
+ border-top: 1px solid var(--db-border);
6622
+ color: var(--db-text-muted);
6623
+ font-size: 11px;
6624
+ line-height: 1.3;
6625
+ }
5968
6626
 
5969
- .db-shell .squisq-toolbar-view-tab {
5970
- padding-top: 4px;
5971
- padding-bottom: 2px;
5972
- }
6627
+ .db-git-grant-notice-text {
6628
+ overflow: hidden;
6629
+ text-overflow: ellipsis;
6630
+ white-space: nowrap;
6631
+ }
5973
6632
 
5974
- /* Keep the compact labels on the same visual center as the action glyphs.
5975
- Move only the text; the tab hit area and active underline stay anchored
5976
- to the titlebar edges. */
5977
- .db-shell .squisq-toolbar-view-tab-label {
5978
- transform: translateY(1px);
5979
- }
6633
+ .db-git-grant-notice-action {
6634
+ flex-shrink: 0;
6635
+ padding: 0;
6636
+ border: 0;
6637
+ background: transparent;
6638
+ color: inherit;
6639
+ font: inherit;
6640
+ line-height: inherit;
6641
+ text-decoration: underline;
6642
+ white-space: nowrap;
6643
+ cursor: pointer;
6644
+ }
5980
6645
 
5981
- .db-shell .squisq-use-mode-trigger {
5982
- padding-bottom: 10px;
5983
- }
6646
+ .db-git-grant-notice-action:hover {
6647
+ color: var(--db-text-secondary);
6648
+ }
5984
6649
 
5985
- /* The 32px caption row leaves little room around Squisq's 28px action
5986
- buttons. Keep the selected background clear of the header's 1px bottom
5987
- divider without moving the glyphs off their shared center line. */
5988
- .db-shell .squisq-toolbar-actions .squisq-toolbar-button {
5989
- box-sizing: border-box;
5990
- height: 26px;
5991
- }
6650
+ .db-git-grant-remember {
6651
+ display: flex;
6652
+ align-items: center;
6653
+ gap: 8px;
6654
+ margin: 12px 0;
6655
+ font-size: 13px;
6656
+ color: var(--db-text);
6657
+ cursor: pointer;
6658
+ }
5992
6659
 
5993
- /* Squisq's overflow measurement deliberately tolerates a 2px overhang.
5994
- Reserve one pixel beyond that tolerance so the final Insert control
5995
- moves into More actions instead of being clipped by the caption inset. */
5996
- .db-shell .squisq-toolbar-actions {
5997
- margin-right: 3px;
5998
- }
6660
+ /* Actions dropdown (mirrors db-ws-settings-dropdown) */
6661
+ .db-git-menu {
6662
+ position: absolute;
6663
+ top: 100%;
6664
+ left: 8px;
6665
+ right: 8px;
6666
+ z-index: 100;
6667
+ background: var(--db-bg);
6668
+ border: 1px solid var(--db-border);
6669
+ border-radius: 6px;
6670
+ box-shadow: 0 4px 12px var(--db-shadow);
6671
+ padding: 4px 0;
6672
+ margin-top: 2px;
6673
+ }
5999
6674
 
6000
- .db-shell .squisq-toolbar-button[aria-label='Insert image'] {
6675
+ .db-git-menu-item {
6676
+ display: block;
6677
+ width: 100%;
6678
+ padding: 7px 14px;
6679
+ border: none;
6680
+ background: transparent;
6681
+ text-align: left;
6682
+ font-size: 13px;
6683
+ color: var(--db-text);
6684
+ cursor: pointer;
6685
+ }
6686
+
6687
+ .db-git-menu-item:hover:not(:disabled),
6688
+ .db-git-menu-item:focus-visible {
6689
+ background: var(--db-bg-hover);
6690
+ }
6691
+
6692
+ /* Items are arrow-reachable rather than tab stops, so the ring is the only
6693
+ cue to which one Enter will fire. */
6694
+ .db-git-menu-item:focus-visible {
6695
+ outline: 2px solid var(--db-focus);
6696
+ outline-offset: -2px;
6697
+ }
6698
+
6699
+ .db-git-menu-item:disabled {
6700
+ color: var(--db-text-placeholder);
6701
+ cursor: default;
6702
+ }
6703
+
6704
+ .db-git-menu-divider {
6705
+ height: 1px;
6706
+ background: var(--db-border);
6707
+ margin: 4px 0;
6708
+ }
6709
+
6710
+ /* aria-live op-result line — visually subtle, announced politely */
6711
+ .db-git-inline-status {
6712
+ display: block;
6713
+ padding: 0 16px;
6714
+ font-size: 11px;
6715
+ color: var(--db-text-muted);
6716
+ min-height: 0;
6717
+ }
6718
+
6719
+ .db-git-inline-status:empty {
6720
+ display: none;
6721
+ }
6722
+
6723
+ /* File-tree badges */
6724
+ .db-git-badge {
6725
+ margin-left: auto;
6726
+ padding: 0 4px;
6727
+ font-size: 10px;
6728
+ font-weight: 700;
6729
+ flex-shrink: 0;
6730
+ }
6731
+
6732
+ .db-tree-row .db-git-badge {
6733
+ margin-left: 4px;
6734
+ }
6735
+
6736
+ .db-git-badge--modified {
6737
+ color: var(--db-git-modified);
6738
+ }
6739
+
6740
+ .db-git-badge--added {
6741
+ color: var(--db-git-added);
6742
+ }
6743
+
6744
+ .db-git-badge--untracked {
6745
+ color: var(--db-git-untracked);
6746
+ }
6747
+
6748
+ .db-git-badge--renamed {
6749
+ color: var(--db-git-renamed);
6750
+ }
6751
+
6752
+ .db-git-badge--deleted {
6753
+ color: var(--db-git-deleted);
6754
+ }
6755
+
6756
+ .db-git-badge--conflicted {
6757
+ color: var(--db-git-conflicted);
6758
+ }
6759
+
6760
+ .db-git-badge--dir {
6761
+ color: var(--db-git-modified);
6762
+ }
6763
+
6764
+ .db-tree-context-divider {
6765
+ height: 1px;
6766
+ background: var(--db-border);
6767
+ margin: 4px 0;
6768
+ }
6769
+
6770
+ /* Toolbar control */
6771
+ .db-git-toolbar-trigger {
6772
+ position: relative;
6773
+ }
6774
+
6775
+ .db-git-toolbar-dot {
6776
+ position: absolute;
6777
+ top: 3px;
6778
+ right: 3px;
6779
+ width: 7px;
6780
+ height: 7px;
6781
+ border-radius: 50%;
6782
+ background: var(--db-git-modified);
6783
+ }
6784
+
6785
+ /* Dialog internals — file lists (commit + conflicts) */
6786
+ .db-git-file-list {
6787
+ margin: 8px 0;
6788
+ padding: 0;
6789
+ list-style: none;
6790
+ max-height: 260px;
6791
+ overflow-y: auto;
6792
+ border: 1px solid var(--db-border);
6793
+ border-radius: 5px;
6794
+ }
6795
+
6796
+ .db-git-file-row {
6797
+ display: flex;
6798
+ align-items: center;
6799
+ gap: 8px;
6800
+ width: 100%;
6801
+ padding: 6px 10px;
6802
+ border: none;
6803
+ background: transparent;
6804
+ font-size: 12.5px;
6805
+ color: var(--db-text);
6806
+ text-align: left;
6807
+ }
6808
+
6809
+ .db-git-file-row + .db-git-file-row {
6810
+ border-top: 1px solid var(--db-border);
6811
+ }
6812
+
6813
+ button.db-git-file-row {
6814
+ cursor: pointer;
6815
+ }
6816
+
6817
+ button.db-git-file-row:hover {
6818
+ background: var(--db-bg-hover);
6819
+ }
6820
+
6821
+ .db-git-file-kind {
6822
+ margin-left: auto;
6823
+ font-size: 10.5px;
6824
+ color: var(--db-text-muted);
6825
+ flex-shrink: 0;
6826
+ }
6827
+
6828
+ .db-git-commit-message {
6829
+ width: 100%;
6830
+ min-height: 72px;
6831
+ padding: 8px 10px;
6832
+ border: 1px solid var(--db-input-border);
6833
+ border-radius: 5px;
6834
+ background: var(--db-bg);
6835
+ color: var(--db-text);
6836
+ font-size: var(--db-input-font-size);
6837
+ font-family: inherit;
6838
+ resize: vertical;
6839
+ box-sizing: border-box;
6840
+ }
6841
+
6842
+ /* Generic form rows in git dialogs */
6843
+ .db-git-form-row {
6844
+ display: flex;
6845
+ align-items: center;
6846
+ gap: 8px;
6847
+ margin: 10px 0;
6848
+ }
6849
+
6850
+ .db-git-form-label {
6851
+ font-size: 12.5px;
6852
+ color: var(--db-text-secondary);
6853
+ flex-shrink: 0;
6854
+ }
6855
+
6856
+ .db-git-form-input {
6857
+ flex: 1;
6858
+ padding: 6px 10px;
6859
+ border: 1px solid var(--db-input-border);
6860
+ border-radius: 5px;
6861
+ background: var(--db-bg);
6862
+ color: var(--db-text);
6863
+ font-size: var(--db-input-font-size);
6864
+ box-sizing: border-box;
6865
+ }
6866
+
6867
+ /* New document dialog: label/field pairs in two aligned columns */
6868
+ .db-new-document-fields {
6869
+ display: grid;
6870
+ grid-template-columns: auto minmax(0, 1fr);
6871
+ align-items: center;
6872
+ gap: 10px 8px;
6873
+ margin: 10px 0;
6874
+ }
6875
+
6876
+ .db-git-form-error,
6877
+ .db-export-error {
6878
+ margin: 8px 0 0;
6879
+ color: var(--db-danger);
6880
+ font-size: 12.5px;
6881
+ }
6882
+
6883
+ .db-git-hint {
6884
+ color: var(--db-text-muted);
6885
+ font-size: 12px;
6886
+ }
6887
+
6888
+ /* Branches dialog */
6889
+ .db-git-branch-list {
6890
+ margin: 8px 0;
6891
+ padding: 0;
6892
+ list-style: none;
6893
+ max-height: 280px;
6894
+ overflow-y: auto;
6895
+ }
6896
+
6897
+ .db-git-branch-row {
6898
+ display: flex;
6899
+ align-items: center;
6900
+ gap: 8px;
6901
+ width: 100%;
6902
+ padding: 7px 10px;
6903
+ border: none;
6904
+ border-radius: 4px;
6905
+ background: transparent;
6906
+ font-size: 13px;
6907
+ color: var(--db-text);
6908
+ text-align: left;
6909
+ cursor: pointer;
6910
+ }
6911
+
6912
+ .db-git-branch-row:hover {
6913
+ background: var(--db-bg-hover);
6914
+ }
6915
+
6916
+ .db-git-branch-row--current {
6917
+ font-weight: 600;
6918
+ color: var(--db-accent);
6919
+ cursor: default;
6920
+ }
6921
+
6922
+ .db-git-branch-row--current:hover {
6923
+ background: transparent;
6924
+ }
6925
+
6926
+ /* History dialog */
6927
+ .db-git-history-list {
6928
+ margin: 8px 0;
6929
+ padding: 0;
6930
+ list-style: none;
6931
+ }
6932
+
6933
+ .db-git-history-item {
6934
+ padding: 8px 10px;
6935
+ border-bottom: 1px solid var(--db-border);
6936
+ cursor: pointer;
6937
+ }
6938
+
6939
+ .db-git-history-item:hover {
6940
+ background: var(--db-bg-hover);
6941
+ }
6942
+
6943
+ .db-git-history-meta {
6944
+ margin-top: 2px;
6945
+ font-size: 11.5px;
6946
+ color: var(--db-text-muted);
6947
+ }
6948
+
6949
+ .db-git-history-files {
6950
+ margin: 6px 0 0;
6951
+ padding: 0;
6952
+ list-style: none;
6953
+ }
6954
+
6955
+ .db-git-history-file {
6956
+ display: flex;
6957
+ align-items: center;
6958
+ gap: 8px;
6959
+ width: 100%;
6960
+ padding: 4px 8px;
6961
+ border: none;
6962
+ background: transparent;
6963
+ font-size: 12px;
6964
+ color: var(--db-text-secondary);
6965
+ text-align: left;
6966
+ cursor: pointer;
6967
+ border-radius: 4px;
6968
+ }
6969
+
6970
+ .db-git-history-file:hover {
6971
+ background: var(--db-bg-hover);
6972
+ }
6973
+
6974
+ /* Diff dialog */
6975
+ .db-git-diff-host {
6976
+ flex: 1;
6977
+ min-height: 320px;
6978
+ border: 1px solid var(--db-border);
6979
+ border-radius: 5px;
6980
+ overflow: hidden;
6981
+ }
6982
+
6983
+ .db-git-diff-loading {
6984
+ padding: 24px;
6985
+ text-align: center;
6986
+ color: var(--db-text-muted);
6987
+ }
6988
+
6989
+ .db-git-diff-labels {
6990
+ display: flex;
6991
+ gap: 12px;
6992
+ margin-bottom: 6px;
6993
+ font-size: 12px;
6994
+ color: var(--db-text-muted);
6995
+ }
6996
+
6997
+ .db-git-diff-labels > span {
6998
+ flex: 1;
6999
+ }
7000
+
7001
+ /* Clone progress */
7002
+ .db-git-progress {
7003
+ margin: 12px 0 4px;
7004
+ }
7005
+
7006
+ .db-git-progress-bar {
7007
+ height: 6px;
7008
+ border-radius: 3px;
7009
+ background: var(--db-accent-soft-15);
7010
+ overflow: hidden;
7011
+ position: relative;
7012
+ }
7013
+
7014
+ .db-git-progress-bar > span {
7015
+ display: block;
7016
+ height: 100%;
7017
+ background: var(--db-accent);
7018
+ transition: width 0.2s;
7019
+ }
7020
+
7021
+ .db-git-progress-text {
7022
+ margin-top: 6px;
7023
+ font-size: 12px;
7024
+ color: var(--db-text-muted);
7025
+ }
7026
+
7027
+ @media (prefers-reduced-motion: reduce) {
7028
+ .db-workspace-picker-caret,
7029
+ .db-app-menu-caret,
7030
+ .db-ws-settings-btn,
7031
+ .db-shell-sidebar-resizer,
7032
+ .db-sidebar-collapse-preview,
7033
+ .db-export-chip,
7034
+ .db-git-progress-bar > span {
7035
+ transition: none;
7036
+ }
7037
+
7038
+ .db-welcome-gateway,
7039
+ .db-save-toast {
7040
+ animation: none;
7041
+ }
7042
+ }
7043
+
7044
+ /* History dialog internals added by the expanded-row layout */
7045
+ .db-git-history-toggle {
7046
+ display: block;
7047
+ width: 100%;
7048
+ padding: 0;
7049
+ border: none;
7050
+ background: transparent;
7051
+ color: inherit;
7052
+ font: inherit;
7053
+ text-align: left;
7054
+ cursor: pointer;
7055
+ }
7056
+
7057
+ .db-git-history-subject {
7058
+ display: block;
7059
+ font-size: 13px;
7060
+ color: var(--db-text);
7061
+ }
7062
+
7063
+ .db-git-history-body {
7064
+ margin: 6px 0 0;
7065
+ padding: 8px 10px;
7066
+ border-radius: 4px;
7067
+ background: var(--db-bg-subtle);
7068
+ color: var(--db-text-secondary);
7069
+ font-size: 12px;
7070
+ white-space: pre-wrap;
7071
+ font-family: inherit;
7072
+ }
7073
+
7074
+ /* ---------------------------------------------------------------------------
7075
+ Window Controls Overlay — installed web app (PWA) custom titlebar.
7076
+
7077
+ When the manifest's `display_override: ["window-controls-overlay", ...]`
7078
+ is active, the OS caption buttons float over the first shell row and this
7079
+ block turns that row into the titlebar: draggable empty space, insets for
7080
+ the caption buttons, and every interactive descendant opted back out.
7081
+
7082
+ Shares its drag/inset structure with the Electron build in
7083
+ packages/desktop/renderer/titlebar.css. Its compact vertical metrics are
7084
+ intentionally PWA-specific because Electron uses a 42px overlay while this
7085
+ mode follows the OS-provided caption height (32px on Windows). Electron is
7086
+ scoped under `.db-desktop-root` and reports `display-mode: browser`, so this
7087
+ media query can never double-apply there. The media query is live: toggling
7088
+ the overlay chevron flips it with no JS. */
7089
+ @media (display-mode: window-controls-overlay) {
7090
+ .db-shell {
7091
+ --db-wco-titlebar-height: env(titlebar-area-height, 32px);
7092
+ }
7093
+
7094
+ /* The first shell row replaces the native titlebar. Empty space can drag
7095
+ the window; every interactive descendant opts back out below. */
7096
+ .db-shell .db-shell-sidebar-header,
7097
+ .db-shell .squisq-editor-header {
7098
+ app-region: drag;
7099
+ -webkit-app-region: drag;
7100
+ box-sizing: border-box;
7101
+ height: var(--db-wco-titlebar-height);
7102
+ min-height: var(--db-wco-titlebar-height);
7103
+ }
7104
+
7105
+ .db-shell .squisq-toolbar {
7106
+ app-region: drag;
7107
+ -webkit-app-region: drag;
7108
+ box-sizing: border-box;
7109
+ height: 100%;
7110
+ min-height: 0;
7111
+ }
7112
+
7113
+ /* The flexible actions lane owns the otherwise-empty gap between Squisq's
7114
+ formatting controls and the fixed document controls. Mark the child
7115
+ explicitly because its overflow clipping can prevent the toolbar's drag
7116
+ region from reaching those pixels. Controls opt out below. */
7117
+ .db-shell .squisq-toolbar-actions {
7118
+ app-region: drag;
7119
+ -webkit-app-region: drag;
7120
+ cursor: grab;
7121
+ }
7122
+
7123
+ .db-shell .db-shell-sidebar-header {
7124
+ padding-block: 0;
7125
+ padding-left: max(4px, calc(env(titlebar-area-x, 0px) + 4px));
7126
+ cursor: grab;
7127
+ }
7128
+
7129
+ /* Keep the shell controls inside the compact native caption band. These
7130
+ overrides apply only to an installed app using Window Controls Overlay;
7131
+ the regular browser toolbar keeps its roomier metrics. */
7132
+ .db-shell .db-app-menu-btn,
7133
+ .db-shell .db-workspace-picker-btn {
7134
+ padding-block: 3px;
7135
+ }
7136
+
7137
+ .db-shell .squisq-toolbar-view-tab {
7138
+ padding-top: 4px;
7139
+ padding-bottom: 2px;
7140
+ }
7141
+
7142
+ /* Keep the compact labels on the same visual center as the action glyphs.
7143
+ Move only the text; the tab hit area and active underline stay anchored
7144
+ to the titlebar edges. */
7145
+ .db-shell .squisq-toolbar-view-tab-label {
7146
+ transform: translateY(1px);
7147
+ }
7148
+
7149
+ .db-shell .squisq-use-mode-trigger {
7150
+ padding-bottom: 10px;
7151
+ }
7152
+
7153
+ /* The 32px caption row leaves little room around Squisq's 28px action
7154
+ buttons. Keep the selected background clear of the header's 1px bottom
7155
+ divider without moving the glyphs off their shared center line. */
7156
+ .db-shell .squisq-toolbar-actions .squisq-toolbar-button {
7157
+ box-sizing: border-box;
7158
+ height: 26px;
7159
+ }
7160
+
7161
+ /* Squisq's overflow measurement deliberately tolerates a 2px overhang.
7162
+ Reserve one pixel beyond that tolerance so the rightmost control moves
7163
+ into More actions instead of being clipped by the caption inset. */
7164
+ .db-shell .squisq-toolbar-actions {
7165
+ margin-right: 3px;
7166
+ }
7167
+
7168
+ .db-shell .squisq-toolbar-button[aria-label='Insert image'] {
6001
7169
  height: 28px;
6002
7170
  }
6003
7171
 
6004
- .db-shell .squisq-editor-header--image {
6005
- padding-block: 0;
6006
- }
7172
+ .db-shell .squisq-editor-header--image {
7173
+ padding-block: 0;
7174
+ }
7175
+
7176
+ /* Make the draggable header space beside the workspace gear discoverable,
7177
+ matching the Electron titlebar without introducing another control. The
7178
+ 12px dotted content and its 8px right padding form one drag region. */
7179
+ .db-shell .db-window-drag-grip {
7180
+ box-sizing: border-box;
7181
+ width: 20px;
7182
+ height: 20px;
7183
+ flex: 0 0 20px;
7184
+ padding-right: 8px;
7185
+ background-image: radial-gradient(circle, var(--db-text-muted) 1px, transparent 1.25px);
7186
+ background-clip: content-box;
7187
+ background-origin: content-box;
7188
+ background-position: center;
7189
+ background-size: 4px 4px;
7190
+ opacity: 0.72;
7191
+ app-region: drag;
7192
+ -webkit-app-region: drag;
7193
+ }
7194
+
7195
+ /* Let the workspace menu size itself to its contents and cross the sidebar
7196
+ boundary above the editor. The explorer still clips its own contents. */
7197
+ .db-shell .db-shell-sidebar {
7198
+ overflow: visible;
7199
+ }
7200
+
7201
+ .db-shell .db-workspace-dropdown {
7202
+ box-sizing: border-box;
7203
+ width: max-content;
7204
+ }
7205
+
7206
+ /* The caption buttons normally occupy the right edge. Derive that inset
7207
+ from the overlay safe area rather than assuming a fixed width, so
7208
+ scaling, RTL controls, and OS variants stay clear. The compact sidebar
7209
+ header is full-width, so it needs the same reservation. */
7210
+ .db-shell.db-shell--mobile .db-shell-sidebar-header,
7211
+ .db-shell .squisq-toolbar,
7212
+ .db-shell .squisq-editor-header--image {
7213
+ padding-right: max(
7214
+ 12px,
7215
+ calc(100vw - env(titlebar-area-x, 0px) - env(titlebar-area-width, 100vw) + 8px)
7216
+ );
7217
+ }
7218
+
7219
+ /* In compact mode there is no sidebar to absorb left-side controls such as
7220
+ macOS traffic lights, so the editor toolbar also observes the left inset. */
7221
+ .db-shell.db-shell--mobile .squisq-toolbar,
7222
+ .db-shell.db-shell--mobile .squisq-editor-header--image {
7223
+ padding-left: env(titlebar-area-x, 0px);
7224
+ }
7225
+
7226
+ .db-shell
7227
+ :is(
7228
+ button,
7229
+ a,
7230
+ input,
7231
+ select,
7232
+ textarea,
7233
+ [contenteditable='true'],
7234
+ [role='button'],
7235
+ [role='tab']
7236
+ ) {
7237
+ app-region: no-drag;
7238
+ -webkit-app-region: no-drag;
7239
+ }
7240
+
7241
+ /* Folder and empty states do not render Squisq's toolbar. Preserve a top
7242
+ drag strip in those states and keep folder content below it. */
7243
+ .db-shell .db-shell-empty::before,
7244
+ .db-shell .db-folder-view::before {
7245
+ content: '';
7246
+ position: absolute;
7247
+ top: 0;
7248
+ left: env(titlebar-area-x, 0px);
7249
+ width: env(titlebar-area-width, 100%);
7250
+ height: var(--db-wco-titlebar-height);
7251
+ app-region: drag;
7252
+ -webkit-app-region: drag;
7253
+ }
7254
+
7255
+ .db-shell .db-folder-view {
7256
+ box-sizing: border-box;
7257
+ padding-top: calc(24px + var(--db-wco-titlebar-height));
7258
+ }
7259
+ }
7260
+
7261
+ /* Transcript review shares the shell's dialog and theme tokens. */
7262
+ .db-text-from-narration {
7263
+ font-family: var(--db-ui-font);
7264
+ }
7265
+ .db-text-from-narration .db-dialog-body {
7266
+ display: flex;
7267
+ flex-direction: column;
7268
+ gap: 12px;
7269
+ }
7270
+ .db-text-from-narration p {
7271
+ margin: 0;
7272
+ }
7273
+ .db-narration-actions {
7274
+ display: flex;
7275
+ flex-wrap: wrap;
7276
+ gap: 8px;
7277
+ }
7278
+ .db-narration-transcript {
7279
+ display: flex;
7280
+ flex-direction: column;
7281
+ gap: 6px;
7282
+ }
7283
+ .db-narration-transcript textarea {
7284
+ width: 100%;
7285
+ box-sizing: border-box;
7286
+ min-height: 160px;
7287
+ resize: vertical;
7288
+ font: inherit;
7289
+ line-height: 1.5;
7290
+ color: var(--db-text);
7291
+ background: var(--db-bg);
7292
+ border: 1px solid var(--db-border);
7293
+ border-radius: 6px;
7294
+ padding: 10px;
7295
+ }
7296
+ .db-narration-note {
7297
+ color: var(--db-text-secondary);
7298
+ font-size: 12px;
7299
+ line-height: 1.5;
7300
+ }
7301
+ .db-narration-status {
7302
+ display: flex;
7303
+ flex-direction: column;
7304
+ gap: 6px;
7305
+ }
7306
+ .db-narration-rewrite {
7307
+ display: flex;
7308
+ flex-direction: column;
7309
+ align-items: flex-start;
7310
+ gap: 6px;
7311
+ }
7312
+
7313
+ /* Presentation review uses the same source and timeline as the saved player. */
7314
+ .db-presentation-workspace {
7315
+ display: grid;
7316
+ flex: 1;
7317
+ min-height: 0;
7318
+ grid-template-columns: minmax(140px, 24%) minmax(0, 1fr);
7319
+ gap: 18px;
7320
+ align-items: stretch;
7321
+ }
7322
+ .db-presentation-beats {
7323
+ display: flex;
7324
+ flex-direction: column;
7325
+ gap: 8px;
7326
+ min-width: 0;
7327
+ min-height: 0;
7328
+ padding: 8px;
7329
+ border: 1px solid var(--db-border);
7330
+ border-radius: 8px;
7331
+ background: var(--db-bg-subtle);
7332
+ overflow-y: auto;
7333
+ }
7334
+ .db-presentation-beats button {
7335
+ display: flex;
7336
+ flex-direction: column;
7337
+ align-items: flex-start;
7338
+ flex: 0 0 auto;
7339
+ gap: 8px;
7340
+ min-width: 0;
7341
+ max-width: 100%;
7342
+ text-align: left;
7343
+ min-height: var(--db-target-min);
7344
+ padding: 12px;
7345
+ border: 1px solid var(--db-input-border);
7346
+ border-radius: 6px;
7347
+ color: var(--db-text);
7348
+ background: var(--db-bg);
7349
+ cursor: pointer;
7350
+ font: inherit;
7351
+ overflow: hidden;
7352
+ }
7353
+ .db-presentation-beat-title {
7354
+ display: -webkit-box;
7355
+ -webkit-box-orient: vertical;
7356
+ -webkit-line-clamp: 3;
7357
+ overflow: hidden;
7358
+ overflow-wrap: anywhere;
7359
+ line-height: 1.5;
7360
+ }
7361
+ .db-presentation-beats button:hover {
7362
+ background: var(--db-bg-hover);
7363
+ }
7364
+ .db-presentation-beats button:focus-visible {
7365
+ outline: 2px solid var(--db-focus);
7366
+ outline-offset: 2px;
7367
+ }
7368
+ .db-presentation-beats button[aria-current='step'] {
7369
+ border-color: var(--db-accent);
7370
+ background: var(--db-bg-hover);
7371
+ box-shadow: inset 3px 0 0 var(--db-accent);
7372
+ }
7373
+ .db-presentation-detail {
7374
+ min-width: 0;
7375
+ display: flex;
7376
+ flex-direction: column;
7377
+ gap: 12px;
7378
+ overflow-y: auto;
7379
+ }
7380
+ .db-presentation-preview {
7381
+ flex-shrink: 0;
7382
+ box-sizing: border-box;
7383
+ width: 100%;
7384
+ height: clamp(120px, 23vh, 240px);
7385
+ overflow: hidden;
7386
+ border: 1px solid var(--db-input-border);
7387
+ border-radius: 8px;
7388
+ }
7389
+ .db-presentation-preview > * {
7390
+ width: 100%;
7391
+ height: 100%;
7392
+ }
7393
+ .db-presentation-fields {
7394
+ display: flex;
7395
+ flex-shrink: 0;
7396
+ flex-wrap: wrap;
7397
+ gap: 12px;
7398
+ }
7399
+ .db-presentation-preferences {
7400
+ align-items: flex-end;
7401
+ }
7402
+ .db-presentation-beats small {
7403
+ display: block;
7404
+ max-width: 100%;
7405
+ padding: 2px 6px;
7406
+ border-radius: 4px;
7407
+ background: var(--db-bg-subtle);
7408
+ color: var(--db-text-muted);
7409
+ overflow-wrap: anywhere;
7410
+ }
7411
+ .db-presentation label.db-presentation-toggle {
7412
+ display: flex;
7413
+ flex-direction: row;
7414
+ align-items: center;
7415
+ gap: 0.6rem;
7416
+ box-sizing: border-box;
7417
+ width: auto;
7418
+ max-width: 100%;
7419
+ min-height: var(--db-target-min);
7420
+ padding: 8px 0;
7421
+ }
7422
+ .db-presentation input[type='checkbox'] {
7423
+ width: 1.1rem;
7424
+ height: 1.1rem;
7425
+ min-height: 0;
7426
+ padding: 0;
7427
+ margin: 0;
7428
+ flex: 0 0 auto;
7429
+ }
7430
+ .db-presentation-fields label {
7431
+ width: min(100%, 320px);
7432
+ }
7433
+ .db-presentation-source {
7434
+ flex-shrink: 0;
7435
+ padding: 12px;
7436
+ border: 1px solid var(--db-input-border);
7437
+ border-radius: 6px;
7438
+ }
7439
+ .db-presentation-source-label {
7440
+ display: flex;
7441
+ flex-wrap: wrap;
7442
+ align-items: baseline;
7443
+ gap: 8px;
7444
+ }
7445
+ .db-presentation-source-label h3 {
7446
+ margin: 0;
7447
+ font-size: inherit;
7448
+ }
7449
+ .db-presentation-source-label span {
7450
+ color: var(--db-text-secondary);
7451
+ font-size: 12px;
7452
+ }
7453
+ .db-presentation-source p {
7454
+ margin: 8px 0 0;
7455
+ max-height: 150px;
7456
+ overflow-y: auto;
7457
+ white-space: pre-wrap;
7458
+ line-height: 1.5;
7459
+ }
7460
+ .db-presentation-wording summary {
7461
+ cursor: pointer;
7462
+ min-height: var(--db-target-min);
7463
+ align-content: center;
7464
+ }
7465
+ .db-presentation-wording label + label {
7466
+ margin-top: 12px;
7467
+ }
7468
+ .db-presentation label {
7469
+ display: flex;
7470
+ flex-direction: column;
7471
+ gap: 5px;
7472
+ font-weight: 600;
7473
+ }
7474
+ .db-presentation input,
7475
+ .db-presentation select,
7476
+ .db-presentation textarea {
7477
+ box-sizing: border-box;
7478
+ width: 100%;
7479
+ min-height: var(--db-target-min);
7480
+ padding: 8px;
7481
+ border: 1px solid var(--db-input-border);
7482
+ border-radius: 5px;
7483
+ background: var(--db-bg);
7484
+ color: var(--db-text);
7485
+ font: inherit;
7486
+ }
7487
+ .db-presentation [role='alert'] {
7488
+ color: var(--db-danger);
7489
+ }
7490
+ .db-presentation details p {
7491
+ font-size: 13px;
7492
+ line-height: 1.6;
7493
+ color: var(--db-text-secondary);
7494
+ }
7495
+ :root[data-db-width='compact'] .db-presentation-workspace {
7496
+ grid-template-columns: minmax(0, 1fr);
7497
+ grid-template-rows: minmax(0, 140px) minmax(0, 1fr);
7498
+ }
7499
+ :root[data-db-width='compact'] .db-presentation-beats {
7500
+ max-height: 140px;
7501
+ }
7502
+
7503
+ /* ── Workspace search and quick-open ───────────────────────────── */
7504
+
7505
+ /* The sidebar shows the file tree or workspace search. The hidden view stays
7506
+ mounted so it keeps its expanded folders or its results. */
7507
+ .db-file-explorer.db-sidebar-view--hidden,
7508
+ .db-search-panel[hidden] {
7509
+ display: none;
7510
+ }
7511
+
7512
+ /* Query matches in quick-open and search results. */
7513
+ .db-search-match {
7514
+ padding: 0;
7515
+ border-radius: 2px;
7516
+ background: var(--db-accent-soft-25);
7517
+ color: inherit;
7518
+ }
7519
+
7520
+ .db-quick-open .db-quick-open-body {
7521
+ display: flex;
7522
+ flex-direction: column;
7523
+ min-height: 0;
7524
+ padding: 0;
7525
+ }
7526
+
7527
+ .db-quick-open-input {
7528
+ box-sizing: border-box;
7529
+ width: 100%;
7530
+ margin: 0;
7531
+ padding: 12px 14px;
7532
+ border: none;
7533
+ border-bottom: 1px solid var(--db-border);
7534
+ border-radius: 8px 8px 0 0;
7535
+ background: transparent;
7536
+ color: var(--db-text);
7537
+ font: inherit;
7538
+ font-size: max(15px, var(--db-input-font-size));
7539
+ outline: none;
7540
+ }
7541
+
7542
+ .db-quick-open-input:focus-visible {
7543
+ box-shadow: inset 0 -2px 0 var(--db-focus);
7544
+ }
6007
7545
 
6008
- /* Make the draggable header space beside the workspace gear discoverable,
6009
- matching the Electron titlebar without introducing another control. The
6010
- 12px dotted content and its 8px right padding form one drag region. */
6011
- .db-shell .db-window-drag-grip {
6012
- box-sizing: border-box;
6013
- width: 20px;
6014
- height: 20px;
6015
- flex: 0 0 20px;
6016
- padding-right: 8px;
6017
- background-image: radial-gradient(circle, var(--db-text-muted) 1px, transparent 1.25px);
6018
- background-clip: content-box;
6019
- background-origin: content-box;
6020
- background-position: center;
6021
- background-size: 4px 4px;
6022
- opacity: 0.72;
6023
- app-region: drag;
6024
- -webkit-app-region: drag;
6025
- }
7546
+ .db-quick-open-list {
7547
+ max-height: min(60vh, 480px);
7548
+ margin: 0;
7549
+ padding: 4px;
7550
+ overflow-y: auto;
7551
+ list-style: none;
7552
+ }
6026
7553
 
6027
- /* Let the workspace menu size itself to its contents and cross the sidebar
6028
- boundary above the editor. The explorer still clips its own contents. */
6029
- .db-shell .db-shell-sidebar {
6030
- overflow: visible;
6031
- }
7554
+ .db-quick-open-list:empty {
7555
+ display: none;
7556
+ }
6032
7557
 
6033
- .db-shell .db-workspace-dropdown {
6034
- box-sizing: border-box;
6035
- width: max-content;
6036
- }
7558
+ .db-quick-open-option {
7559
+ display: flex;
7560
+ align-items: baseline;
7561
+ gap: 8px;
7562
+ min-width: 0;
7563
+ min-height: var(--db-row-min-height);
7564
+ padding: 6px 10px;
7565
+ border-radius: 4px;
7566
+ color: var(--db-text);
7567
+ cursor: pointer;
7568
+ user-select: none;
7569
+ }
6037
7570
 
6038
- /* The caption buttons normally occupy the right edge. Derive that inset
6039
- from the overlay safe area rather than assuming a fixed width, so
6040
- scaling, RTL controls, and OS variants stay clear. The compact sidebar
6041
- header is full-width, so it needs the same reservation. */
6042
- .db-shell.db-shell--mobile .db-shell-sidebar-header,
6043
- .db-shell .squisq-toolbar,
6044
- .db-shell .squisq-editor-header--image {
6045
- padding-right: max(
6046
- 12px,
6047
- calc(100vw - env(titlebar-area-x, 0px) - env(titlebar-area-width, 100vw) + 8px)
6048
- );
6049
- }
7571
+ .db-quick-open-option--active {
7572
+ background: var(--db-bg-hover);
7573
+ }
6050
7574
 
6051
- /* In compact mode there is no sidebar to absorb left-side controls such as
6052
- macOS traffic lights, so the editor toolbar also observes the left inset. */
6053
- .db-shell.db-shell--mobile .squisq-toolbar,
6054
- .db-shell.db-shell--mobile .squisq-editor-header--image {
6055
- padding-left: env(titlebar-area-x, 0px);
6056
- }
7575
+ .db-quick-open-name,
7576
+ .db-quick-open-title,
7577
+ .db-quick-open-folder {
7578
+ min-width: 0;
7579
+ overflow: hidden;
7580
+ text-overflow: ellipsis;
7581
+ white-space: nowrap;
7582
+ }
6057
7583
 
6058
- .db-shell
6059
- :is(
6060
- button,
6061
- a,
6062
- input,
6063
- select,
6064
- textarea,
6065
- [contenteditable='true'],
6066
- [role='button'],
6067
- [role='tab']
6068
- ) {
6069
- app-region: no-drag;
6070
- -webkit-app-region: no-drag;
6071
- }
7584
+ .db-quick-open-name {
7585
+ flex: 0 1 auto;
7586
+ font-weight: 600;
7587
+ }
6072
7588
 
6073
- /* Folder and empty states do not render Squisq's toolbar. Preserve a top
6074
- drag strip in those states and keep folder content below it. */
6075
- .db-shell .db-shell-empty::before,
6076
- .db-shell .db-folder-view::before {
6077
- content: '';
6078
- position: absolute;
6079
- top: 0;
6080
- left: env(titlebar-area-x, 0px);
6081
- width: env(titlebar-area-width, 100%);
6082
- height: var(--db-wco-titlebar-height);
6083
- app-region: drag;
6084
- -webkit-app-region: drag;
6085
- }
7589
+ .db-quick-open-title {
7590
+ flex: 0 2 auto;
7591
+ color: var(--db-text-secondary);
7592
+ }
6086
7593
 
6087
- .db-shell .db-folder-view {
6088
- box-sizing: border-box;
6089
- padding-top: calc(24px + var(--db-wco-titlebar-height));
6090
- }
7594
+ .db-quick-open-folder {
7595
+ flex: 1 3 auto;
7596
+ margin-left: auto;
7597
+ color: var(--db-text-muted);
7598
+ font-size: 12px;
7599
+ text-align: right;
7600
+ }
7601
+
7602
+ .db-quick-open .db-quick-open-status {
7603
+ margin: 0;
7604
+ padding: 8px 14px;
7605
+ border-top: 1px solid var(--db-border);
7606
+ color: var(--db-text-muted);
7607
+ font-size: 12px;
7608
+ }
7609
+
7610
+ .db-quick-open .db-quick-open-status:empty {
7611
+ display: none;
7612
+ }
7613
+
7614
+ .db-search-panel {
7615
+ display: flex;
7616
+ flex-direction: column;
7617
+ height: 100%;
7618
+ min-height: 0;
7619
+ overflow: hidden;
7620
+ font-size: 13px;
7621
+ }
7622
+
7623
+ .db-search-form {
7624
+ display: flex;
7625
+ align-items: center;
7626
+ gap: 4px;
7627
+ padding: 8px;
7628
+ }
7629
+
7630
+ .db-search-input {
7631
+ box-sizing: border-box;
7632
+ flex: 1 1 auto;
7633
+ min-width: 0;
7634
+ min-height: var(--db-target-min);
7635
+ padding: 4px 8px;
7636
+ border: 1px solid var(--db-border-strong);
7637
+ border-radius: 4px;
7638
+ background: var(--db-bg);
7639
+ color: var(--db-text);
7640
+ font: inherit;
7641
+ font-size: var(--db-input-font-size);
7642
+ }
7643
+
7644
+ .db-search-input:focus-visible {
7645
+ outline: 2px solid var(--db-focus);
7646
+ outline-offset: -1px;
7647
+ }
7648
+
7649
+ .db-search-toggle {
7650
+ min-width: var(--db-target-min);
7651
+ min-height: var(--db-target-min);
7652
+ padding: 0 6px;
7653
+ border: 1px solid transparent;
7654
+ border-radius: 4px;
7655
+ background: none;
7656
+ color: var(--db-text-muted);
7657
+ font: inherit;
7658
+ font-size: 12px;
7659
+ font-weight: 600;
7660
+ cursor: pointer;
7661
+ }
7662
+
7663
+ .db-search-toggle--word {
7664
+ text-decoration: underline;
7665
+ text-underline-offset: 3px;
7666
+ }
7667
+
7668
+ .db-search-toggle:hover {
7669
+ background: var(--db-bg-hover);
7670
+ color: var(--db-text);
7671
+ }
7672
+
7673
+ .db-search-toggle[aria-pressed='true'] {
7674
+ background: var(--db-bg-selected);
7675
+ color: var(--db-text-on-selected);
7676
+ }
7677
+
7678
+ .db-search-toggle:focus-visible {
7679
+ outline: 2px solid var(--db-focus);
7680
+ outline-offset: 1px;
7681
+ }
7682
+
7683
+ .db-search-status,
7684
+ .db-search-more {
7685
+ margin: 0;
7686
+ padding: 0 10px 6px;
7687
+ color: var(--db-text-muted);
7688
+ font-size: 12px;
7689
+ }
7690
+
7691
+ .db-search-status:empty {
7692
+ display: none;
7693
+ }
7694
+
7695
+ .db-search-results {
7696
+ flex: 1 1 auto;
7697
+ min-height: 0;
7698
+ padding: 0 4px 8px;
7699
+ overflow-y: auto;
7700
+ }
7701
+
7702
+ .db-search-document,
7703
+ .db-search-line {
7704
+ display: flex;
7705
+ align-items: baseline;
7706
+ gap: 6px;
7707
+ min-height: var(--db-row-min-height);
7708
+ padding: 4px 6px;
7709
+ overflow: hidden;
7710
+ border-radius: 4px;
7711
+ color: var(--db-text);
7712
+ white-space: nowrap;
7713
+ cursor: pointer;
7714
+ user-select: none;
7715
+ }
7716
+
7717
+ .db-search-document:hover,
7718
+ .db-search-line:hover {
7719
+ background: var(--db-bg-hover);
7720
+ }
7721
+
7722
+ .db-search-document:focus-visible,
7723
+ .db-search-line:focus-visible {
7724
+ outline: 2px solid var(--db-focus);
7725
+ outline-offset: -2px;
7726
+ }
7727
+
7728
+ .db-search-chevron {
7729
+ flex: 0 0 auto;
7730
+ width: 12px;
7731
+ color: var(--db-text-muted);
7732
+ text-align: center;
7733
+ }
7734
+
7735
+ .db-search-document-title,
7736
+ .db-search-document-path,
7737
+ .db-search-snippet {
7738
+ min-width: 0;
7739
+ overflow: hidden;
7740
+ text-overflow: ellipsis;
7741
+ }
7742
+
7743
+ .db-search-document-title {
7744
+ flex: 0 1 auto;
7745
+ font-weight: 600;
7746
+ }
7747
+
7748
+ .db-search-document-path {
7749
+ flex: 1 1 auto;
7750
+ color: var(--db-text-muted);
7751
+ font-size: 12px;
7752
+ }
7753
+
7754
+ .db-search-count {
7755
+ flex: 0 0 auto;
7756
+ padding: 0 6px;
7757
+ border-radius: 8px;
7758
+ background: var(--db-bg-subtle);
7759
+ color: var(--db-text-secondary);
7760
+ font-size: 11px;
7761
+ }
7762
+
7763
+ .db-search-line {
7764
+ padding-left: 24px;
7765
+ }
7766
+
7767
+ .db-search-line-number {
7768
+ flex: 0 0 auto;
7769
+ min-width: 2.5em;
7770
+ color: var(--db-text-muted);
7771
+ font-size: 11px;
7772
+ font-variant-numeric: tabular-nums;
7773
+ text-align: right;
7774
+ }
7775
+
7776
+ .db-search-snippet {
7777
+ flex: 1 1 auto;
6091
7778
  }