@ssebastien/tcmd 0.1.4 → 0.1.7

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 (105) hide show
  1. package/README.md +169 -58
  2. package/desktop/dist/index.html +13 -0
  3. package/desktop/dist/main.js +20298 -0
  4. package/desktop/dist/style.css +1515 -0
  5. package/desktop/frontend/index.html +13 -0
  6. package/package.json +17 -5
  7. package/public/fonts/OFL.txt +93 -0
  8. package/public/licenses/LUCIDE.txt +43 -0
  9. package/public/main.js +5066 -1888
  10. package/public/style.css +660 -46
  11. package/scripts/build-desktop.js +31 -0
  12. package/src/js/tcmd/components/App.html +56 -6
  13. package/src/js/tcmd/components/App.js +233 -58
  14. package/src/js/tcmd/components/App.xml +27 -22
  15. package/src/js/tcmd/components/BookmarkList.html +4 -5
  16. package/src/js/tcmd/components/BookmarkList.js +14 -40
  17. package/src/js/tcmd/components/BookmarkList.xml +1 -2
  18. package/src/js/tcmd/components/BookmarkRow.html +2 -1
  19. package/src/js/tcmd/components/BookmarkRow.js +14 -9
  20. package/src/js/tcmd/components/BookmarkRow.xml +1 -1
  21. package/src/js/tcmd/components/CommandArgRow.html +18 -7
  22. package/src/js/tcmd/components/CommandArgRow.js +100 -44
  23. package/src/js/tcmd/components/CommandArgRow.xml +39 -15
  24. package/src/js/tcmd/components/CommandBar.html +1 -1
  25. package/src/js/tcmd/components/CommandBar.js +31 -25
  26. package/src/js/tcmd/components/CommandBar.xml +2 -2
  27. package/src/js/tcmd/components/CommandItem.js +24 -25
  28. package/src/js/tcmd/components/CommandItem.xml +2 -2
  29. package/src/js/tcmd/components/CommandPanel.html +13 -13
  30. package/src/js/tcmd/components/CommandPanel.js +57 -33
  31. package/src/js/tcmd/components/CommandPanel.xml +30 -20
  32. package/src/js/tcmd/components/Confirm.html +2 -2
  33. package/src/js/tcmd/components/EntryDetail.js +21 -7
  34. package/src/js/tcmd/components/FilePicker.html +10 -0
  35. package/src/js/tcmd/components/FilePicker.js +43 -0
  36. package/src/js/tcmd/components/FilePicker.xml +13 -0
  37. package/src/js/tcmd/components/FilePickerRow.html +6 -0
  38. package/src/js/tcmd/components/FilePickerRow.js +27 -0
  39. package/src/js/tcmd/components/FilePickerRow.xml +10 -0
  40. package/src/js/tcmd/components/FilePreview.html +1 -2
  41. package/src/js/tcmd/components/FilePreview.js +40 -4
  42. package/src/js/tcmd/components/FilePreview.xml +17 -10
  43. package/src/js/tcmd/components/FileRow.html +1 -0
  44. package/src/js/tcmd/components/FileRow.js +60 -9
  45. package/src/js/tcmd/components/Frame.js +57 -31
  46. package/src/js/tcmd/components/Help.html +12 -4
  47. package/src/js/tcmd/components/Help.js +198 -47
  48. package/src/js/tcmd/components/Help.xml +13 -4
  49. package/src/js/tcmd/components/HelpRow.html +8 -0
  50. package/src/js/tcmd/components/HelpRow.xml +7 -0
  51. package/src/js/tcmd/components/OverlayList.html +8 -0
  52. package/src/js/tcmd/components/OverlayList.js +69 -0
  53. package/src/js/tcmd/components/OverlayList.xml +13 -0
  54. package/src/js/tcmd/components/OverlayRow.html +5 -0
  55. package/src/js/tcmd/components/OverlayRow.js +47 -0
  56. package/src/js/tcmd/components/OverlayRow.xml +9 -0
  57. package/src/js/tcmd/components/format.js +4 -23
  58. package/src/js/tcmd/components/icons.js +137 -0
  59. package/src/js/tcmd/components/index.js +8 -3
  60. package/src/js/tcmd/components/rows.js +149 -25
  61. package/src/js/tcmd/core/base64.js +64 -0
  62. package/src/js/tcmd/core/bookmarks.js +45 -8
  63. package/src/js/tcmd/core/commands.js +612 -136
  64. package/src/js/tcmd/core/concurrency.js +59 -0
  65. package/src/js/tcmd/core/decompress.js +117 -0
  66. package/src/js/tcmd/core/directory.js +81 -5
  67. package/src/js/tcmd/core/format.js +36 -0
  68. package/src/js/tcmd/core/fs.js +410 -53
  69. package/src/js/tcmd/core/journal.js +93 -0
  70. package/src/js/tcmd/core/keymap.js +39 -3
  71. package/src/js/tcmd/core/operations.js +735 -63
  72. package/src/js/tcmd/core/os.js +29 -3
  73. package/src/js/tcmd/core/pane.js +4 -2
  74. package/src/js/tcmd/core/panel.js +179 -93
  75. package/src/js/tcmd/core/path.js +30 -3
  76. package/src/js/tcmd/core/permissions.js +107 -0
  77. package/src/js/tcmd/core/picker.js +156 -0
  78. package/src/js/tcmd/core/preview.js +102 -0
  79. package/src/js/tcmd/core/session.js +286 -116
  80. package/src/js/tcmd/core/watch.js +153 -0
  81. package/src/js/tcmd/desktop/backend/api.js +165 -0
  82. package/src/js/tcmd/desktop/backend/fs.js +626 -0
  83. package/src/js/tcmd/desktop/backend/main.ts +9 -0
  84. package/src/js/tcmd/desktop/bookmarks.js +23 -0
  85. package/src/js/tcmd/desktop/fs.js +91 -0
  86. package/src/js/tcmd/desktop/main.js +194 -0
  87. package/src/js/tcmd/desktop/os.js +33 -0
  88. package/src/js/tcmd/tui/app.js +111 -74
  89. package/src/js/tcmd/tui/catalogue.js +232 -23
  90. package/src/js/tcmd/tui/index.js +18 -4
  91. package/src/js/tcmd/tui/opentui.js +33 -0
  92. package/src/js/tcmd/tui/syntax.js +91 -0
  93. package/src/js/tcmd/tui/theme.js +27 -2
  94. package/src/js/tcmd/vendor/bzip2.js +276 -0
  95. package/src/js/tcmd/web/app.js +114 -56
  96. package/src/js/tcmd/web/catalogue.js +41 -4
  97. package/src/js/tcmd/web/effects.js +94 -14
  98. package/src/js/tcmd/web/header.html +1 -1
  99. package/src/js/tcmd/web/http.js +13 -0
  100. package/src/js/tcmd/web/index.js +2 -2
  101. package/src/js/tcmd/web/opfs.js +297 -30
  102. package/src/js/tcmd/web/seed.js +1 -1
  103. package/src/js/tcmd/web/server.js +118 -17
  104. package/src/js/tcmd/web/theme.js +3 -0
  105. package/tinyjs.json +16 -0
@@ -0,0 +1,1515 @@
1
+ /* Project: TinyCommand
2
+ * Author: Sebastien Pierre
3
+ * License: BSD
4
+ * Created: 2026-09-27
5
+ *
6
+ * Styling for the web view (`public/index.html`). The class names are the
7
+ * contract between the shared components and `web/theme.js`; layout only, the
8
+ * component logic never reads styles.
9
+ */
10
+
11
+ /* Palette mirrors tui/theme.js DARK: night-blue surfaces, gold accents,
12
+ saturated orange marks. */
13
+ @font-face {
14
+ font-family: "M+1Code Nerd Font Mono";
15
+ src: url("./fonts/M+1CodeNerdFontMono-Regular.ttf") format("truetype");
16
+ font-style: normal;
17
+ font-weight: 400;
18
+ font-display: swap;
19
+ }
20
+
21
+ :root {
22
+ --font-ui: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
23
+ --font-mono: "M+1Code Nerd Font Mono", ui-monospace, "SFMono-Regular", "SF Mono", Menlo, Consolas, monospace;
24
+ --bg: #0d1526;
25
+ --bg-panel: #111b31;
26
+ --bg-raised: #18233d;
27
+ --bg-cursor: #274a9e;
28
+ --bg-cursor-inactive: #1b2a51;
29
+ --bg-marked: #4a2a0c;
30
+ /* The command panel's argument value fields. */
31
+ --bg-field: #1b2a51;
32
+ --border: #33508f;
33
+ /* The active pane's border/header rule: the explorer's Tiny blue, the
34
+ commander's gold accent (kept in sync with tui/theme.js). */
35
+ --pane-active-explorer: #4088ff;
36
+ --pane-active-commander: #ffc233;
37
+ --text: #e6ecff;
38
+ --text-dim: #8fa3d9;
39
+ --scrollbar-track: transparent;
40
+ --scrollbar-thumb: #22345e;
41
+ --accent: #ffc233;
42
+ --accent-soft: #2b3f78;
43
+ --dir: #5c8cff;
44
+ --link: #4fc3ff;
45
+ --dev: #b48eff;
46
+ --exec: #5fd67a;
47
+ --readonly: #7d8ab8;
48
+ --mark: #ff7a1a;
49
+ --error: #ff4d5e;
50
+ --warning: #ffb020;
51
+ --tip: #a78bfa;
52
+ /* Brand identity bar gradients (kept in sync with tui/theme.js):
53
+ Tiny stays blue, Cmd gold→saturated orange. */
54
+ --brand-tiny-from: #4088ff;
55
+ --brand-tiny-to: #7cd0ff;
56
+ --brand-cmd-from: #ffc233;
57
+ --brand-cmd-to: #ff7a1a;
58
+ }
59
+
60
+ * {
61
+ box-sizing: border-box;
62
+ }
63
+
64
+ /* Every scrollable surface gets a visible, thin bar only while overflowing.
65
+ The WebKit rules keep Chromium/Electron and Safari consistent with Firefox. */
66
+ :is(.desktop-toolbar, .file-list, .preview-text, .preview-card, .panel-ops, .panel-args, .panel-args-scroll, .bookmark-rows, .overlay-rows, .help-columns) {
67
+ scrollbar-width: thin;
68
+ scrollbar-color: var(--scrollbar-thumb) var(--scrollbar-track);
69
+ }
70
+
71
+ :is(.desktop-toolbar, .file-list, .preview-text, .preview-card, .panel-ops, .panel-args, .panel-args-scroll, .bookmark-rows, .overlay-rows, .help-columns)::-webkit-scrollbar {
72
+ width: 0.65rem;
73
+ height: 0.65rem;
74
+ }
75
+
76
+ :is(.desktop-toolbar, .file-list, .preview-text, .preview-card, .panel-ops, .panel-args, .panel-args-scroll, .bookmark-rows, .overlay-rows, .help-columns)::-webkit-scrollbar-track {
77
+ background: var(--scrollbar-track);
78
+ }
79
+
80
+ :is(.desktop-toolbar, .file-list, .preview-text, .preview-card, .panel-ops, .panel-args, .panel-args-scroll, .bookmark-rows, .overlay-rows, .help-columns)::-webkit-scrollbar-thumb {
81
+ background: var(--scrollbar-thumb);
82
+ border: 2px solid var(--scrollbar-track);
83
+ border-radius: 999px;
84
+ }
85
+
86
+ :is(.desktop-toolbar, .file-list, .preview-text, .preview-card, .panel-ops, .panel-args, .panel-args-scroll, .bookmark-rows, .overlay-rows, .help-columns)::-webkit-scrollbar-thumb:hover {
87
+ background: var(--accent);
88
+ }
89
+
90
+ html,
91
+ body,
92
+ #app {
93
+ height: 100%;
94
+ margin: 0;
95
+ }
96
+
97
+ body {
98
+ background: var(--bg);
99
+ color: var(--text);
100
+ font: 13px/1.45 var(--font-ui);
101
+ }
102
+
103
+ /* File and path content keeps a fixed-width face; the surrounding controls use
104
+ the native system UI font above. */
105
+ .file-row,
106
+ .breadcrumbs,
107
+ .entry-detail,
108
+ .summary,
109
+ .preview-text,
110
+ .panel-picker-path,
111
+ .panel-row[data-type="entry"] .panel-name,
112
+ .panel-row[data-type="parent"] .panel-name,
113
+ .panel-list-box,
114
+ .bookmark-path {
115
+ font-family: var(--font-mono);
116
+ }
117
+
118
+ .app {
119
+ display: flex;
120
+ flex-direction: column;
121
+ height: 100%;
122
+ outline: none;
123
+ }
124
+
125
+ /* Header --------------------------------------------------------------- */
126
+
127
+ .app-header {
128
+ display: flex;
129
+ align-items: baseline;
130
+ flex: none;
131
+ padding: 0.1rem 0.6rem;
132
+ border-bottom: 1px solid var(--border);
133
+ background: var(--bg-panel);
134
+ color: var(--text);
135
+ font-weight: 600;
136
+ white-space: nowrap;
137
+ overflow: hidden;
138
+ text-overflow: ellipsis;
139
+ }
140
+
141
+ /* Right-hand trail: the view mode and version, dimmer than the brand. */
142
+ .app-header-status {
143
+ flex: none;
144
+ margin-left: auto;
145
+ padding-left: 0.75rem;
146
+ color: var(--text-dim);
147
+ font-weight: 400;
148
+ }
149
+
150
+ /* The mode word shimmers like the brand: explorer along the Tiny blues,
151
+ commander along the Cmd oranges. Clicking it toggles the view mode. */
152
+ .app-header-mode {
153
+ display: inline-flex;
154
+ align-items: center;
155
+ gap: 0.25rem;
156
+ font-weight: 600;
157
+ cursor: pointer;
158
+ }
159
+
160
+ .header-mode-icon {
161
+ width: 0.8rem;
162
+ height: 0.8rem;
163
+ color: var(--accent);
164
+ }
165
+
166
+ .app-header-mode.mode-explorer {
167
+ background: linear-gradient(90deg, var(--brand-tiny-from), var(--brand-tiny-to));
168
+ -webkit-background-clip: text;
169
+ background-clip: text;
170
+ color: transparent;
171
+ }
172
+
173
+ .app-header-mode.mode-explorer .header-mode-icon {
174
+ color: var(--pane-active-explorer);
175
+ }
176
+
177
+ .app-header-mode.mode-commander {
178
+ background: linear-gradient(90deg, var(--brand-cmd-from), var(--brand-cmd-to));
179
+ -webkit-background-clip: text;
180
+ background-clip: text;
181
+ color: transparent;
182
+ }
183
+
184
+ /* The brand and host give way (ellipsis) instead of pushing the trail off. */
185
+ .app-header > span:not(.app-header-status) {
186
+ min-width: 0;
187
+ overflow: hidden;
188
+ text-overflow: ellipsis;
189
+ }
190
+
191
+ /* Brand: "Tiny" shimmers along a blue gradient, "Cmd" along a brighter
192
+ orange than the mark accent. */
193
+ .app-header .brand-tiny {
194
+ background: linear-gradient(90deg, var(--brand-tiny-from), var(--brand-tiny-to));
195
+ -webkit-background-clip: text;
196
+ background-clip: text;
197
+ color: transparent;
198
+ }
199
+
200
+ .app-header .brand-cmd {
201
+ background: linear-gradient(90deg, var(--brand-cmd-from), var(--brand-cmd-to));
202
+ -webkit-background-clip: text;
203
+ background-clip: text;
204
+ color: transparent;
205
+ }
206
+
207
+ /* Desktop chrome -------------------------------------------------------- */
208
+
209
+ .desktop-toolbar {
210
+ display: flex;
211
+ align-items: center;
212
+ flex: none;
213
+ gap: 0.45rem;
214
+ min-height: 2.55rem;
215
+ padding: 0.3rem 0.55rem;
216
+ border-bottom: 1px solid var(--border);
217
+ background: linear-gradient(180deg, #17243c, var(--bg-panel));
218
+ white-space: nowrap;
219
+ overflow-x: auto;
220
+ }
221
+
222
+ .desktop-toolbar-group {
223
+ display: flex;
224
+ align-items: center;
225
+ gap: 0.35rem;
226
+ flex: none;
227
+ }
228
+
229
+ .desktop-toolbar-spacer {
230
+ flex: 1;
231
+ min-width: 0.5rem;
232
+ }
233
+
234
+ .desktop-toolbar-separator {
235
+ flex: none;
236
+ height: 1.35rem;
237
+ border-left: 1px solid var(--border);
238
+ }
239
+
240
+ .desktop-toolbar-button {
241
+ display: inline-flex;
242
+ align-items: center;
243
+ justify-content: center;
244
+ gap: 0.4rem;
245
+ min-height: 1.9rem;
246
+ padding: 0.2rem 0.55rem;
247
+ border: 1px solid transparent;
248
+ border-radius: 5px;
249
+ background: transparent;
250
+ color: var(--text-dim);
251
+ font: inherit;
252
+ font-size: 12px;
253
+ cursor: pointer;
254
+ }
255
+
256
+ .desktop-toolbar-button:hover {
257
+ border-color: var(--border);
258
+ background: var(--bg-raised);
259
+ color: var(--text);
260
+ }
261
+
262
+ .desktop-toolbar-button.is-primary {
263
+ border-color: var(--accent-soft);
264
+ background: #202f50;
265
+ color: var(--text);
266
+ }
267
+
268
+ .desktop-toolbar-button.is-primary:hover {
269
+ border-color: var(--accent);
270
+ background: #283b62;
271
+ }
272
+
273
+ .ui-icon {
274
+ flex: none;
275
+ fill: none;
276
+ stroke: currentColor;
277
+ stroke-width: 2;
278
+ stroke-linecap: round;
279
+ stroke-linejoin: round;
280
+ }
281
+
282
+ .lucide-defs {
283
+ display: none;
284
+ }
285
+
286
+ .toolbar-icon {
287
+ width: 1rem;
288
+ height: 1rem;
289
+ color: var(--accent);
290
+ }
291
+
292
+ .toolbar-chevron {
293
+ width: 0.75rem;
294
+ height: 0.75rem;
295
+ margin-left: -0.2rem;
296
+ color: var(--text-dim);
297
+ }
298
+
299
+ /* Panes ---------------------------------------------------------------- */
300
+
301
+ .panes {
302
+ display: flex;
303
+ flex: 1;
304
+ min-height: 0;
305
+ gap: 1px;
306
+ background: var(--border);
307
+ }
308
+
309
+ .pane {
310
+ display: flex;
311
+ flex: 1 1 0;
312
+ flex-direction: column;
313
+ min-width: 0;
314
+ min-height: 0;
315
+ background: var(--bg-panel);
316
+ border: 1px solid var(--border);
317
+ }
318
+
319
+ .pane.is-active {
320
+ border-color: var(--pane-active-commander);
321
+ }
322
+
323
+ /* Explorer tints the active pane with the Tiny blue instead of the gold. */
324
+ .app.is-explorer .pane.is-active {
325
+ border-color: var(--pane-active-explorer);
326
+ }
327
+
328
+ /* Explorer mode: the middle (current) column carries the extra width, the
329
+ parent and preview columns stay even. */
330
+ .pane.is-major {
331
+ flex-grow: 1.35;
332
+ }
333
+
334
+ .pane-header {
335
+ display: flex;
336
+ align-items: baseline;
337
+ gap: 0.35rem;
338
+ min-width: 0;
339
+ overflow: hidden;
340
+ white-space: nowrap;
341
+ font-size: 12px;
342
+ flex: none;
343
+ min-height: 1.8rem;
344
+ padding: 0 0.45rem;
345
+ border-bottom: 1px solid var(--border);
346
+ }
347
+
348
+ .pane.is-active .pane-header {
349
+ border-bottom-color: var(--pane-active-commander);
350
+ }
351
+
352
+ .app.is-explorer .pane.is-active .pane-header {
353
+ border-bottom-color: var(--pane-active-explorer);
354
+ }
355
+
356
+ .pane-header > div {
357
+ min-width: 0;
358
+ flex: 1;
359
+ }
360
+
361
+ .pane > [data-slot="list"] {
362
+ display: flex;
363
+ flex: 1;
364
+ min-height: 0;
365
+ }
366
+
367
+ /* Breadcrumbs ---------------------------------------------------------- */
368
+
369
+ .breadcrumbs {
370
+ flex: none;
371
+ display: flex;
372
+ align-items: center;
373
+ gap: 0.15rem;
374
+ padding: 0.3rem 0.1rem;
375
+ overflow: hidden;
376
+ white-space: nowrap;
377
+ font-size: 12px;
378
+ }
379
+
380
+ .crumb {
381
+ color: var(--text-dim);
382
+ text-decoration: none;
383
+ }
384
+
385
+ .crumb:hover {
386
+ color: var(--accent);
387
+ }
388
+
389
+ .crumb.is-root {
390
+ color: var(--text-dim);
391
+ }
392
+
393
+ .crumb .crumb-sep {
394
+ color: var(--border);
395
+ }
396
+
397
+ .crumb-sep:empty {
398
+ display: none;
399
+ }
400
+
401
+ /* File list ------------------------------------------------------------ */
402
+
403
+ .file-list {
404
+ flex: 1;
405
+ min-height: 0;
406
+ overflow: auto;
407
+ margin: 0;
408
+ padding: 0.15rem 0;
409
+ }
410
+
411
+ .file-list ul {
412
+ list-style: none;
413
+ padding: 0;
414
+ margin: 0;
415
+ }
416
+
417
+ .file-list p {
418
+ color: var(--text-dim);
419
+ white-space: pre;
420
+ }
421
+
422
+ .file-row {
423
+ display: grid;
424
+ grid-template-columns: 1.1rem 1rem minmax(0, 1fr) auto;
425
+ gap: 0.4rem;
426
+ align-items: center;
427
+ padding: 0 0.35rem;
428
+ white-space: nowrap;
429
+ cursor: pointer;
430
+ }
431
+
432
+ .file-row:hover {
433
+ background: var(--bg-raised);
434
+ }
435
+
436
+ .file-row.is-current {
437
+ background: var(--bg-cursor);
438
+ }
439
+
440
+ .file-row.is-current[data-active="false"] {
441
+ background: var(--bg-cursor-inactive);
442
+ }
443
+
444
+ .file-row[data-marked="true"]:not(.is-current) {
445
+ background: var(--bg-marked);
446
+ }
447
+
448
+ .marker {
449
+ color: var(--accent);
450
+ white-space: pre;
451
+ }
452
+
453
+ .file-row[data-marked="true"] .marker {
454
+ color: var(--mark);
455
+ }
456
+
457
+ .file-row-icon {
458
+ width: 1rem;
459
+ height: 1rem;
460
+ color: var(--text-dim);
461
+ }
462
+
463
+ .file-row[data-kind="dir"] .file-row-icon {
464
+ color: var(--dir);
465
+ }
466
+
467
+ .file-row[data-kind="link"] .file-row-icon {
468
+ color: var(--link);
469
+ }
470
+
471
+ .file-row[data-kind="dev"] .file-row-icon {
472
+ color: var(--dev);
473
+ }
474
+
475
+ .name {
476
+ overflow: hidden;
477
+ text-overflow: ellipsis;
478
+ }
479
+
480
+ .name.is-dir {
481
+ color: var(--dir);
482
+ font-weight: 600;
483
+ }
484
+
485
+ .name.is-exec {
486
+ color: var(--exec);
487
+ }
488
+
489
+ .name.is-readonly {
490
+ color: var(--readonly);
491
+ }
492
+
493
+ .file-row[data-kind="link"] .name {
494
+ color: var(--link);
495
+ }
496
+
497
+ .file-row[data-kind="dev"] .name {
498
+ color: var(--dev);
499
+ }
500
+
501
+ .file-row.is-current .name {
502
+ color: var(--text);
503
+ }
504
+
505
+ .file-row[data-marked="true"] .name {
506
+ color: var(--mark);
507
+ }
508
+
509
+ .size {
510
+ color: var(--text-dim);
511
+ font-variant-numeric: tabular-nums;
512
+ }
513
+
514
+ /* Entry detail ---------------------------------------------------------- */
515
+
516
+ .entry-detail {
517
+ border-top: 1px solid var(--border);
518
+ padding: 0.2rem 0.45rem 0;
519
+ }
520
+
521
+ .entry-detail-line {
522
+ display: flex;
523
+ min-width: 0;
524
+ white-space: pre;
525
+ overflow: hidden;
526
+ }
527
+
528
+ .entry-detail-line > span {
529
+ flex: none;
530
+ }
531
+
532
+ .entry-detail-line .entry-detail-spacer {
533
+ flex: 1;
534
+ min-width: 1ch;
535
+ }
536
+
537
+ .entry-detail-sep {
538
+ color: var(--text-dim);
539
+ }
540
+
541
+ .entry-detail-type.is-directory {
542
+ color: var(--dir);
543
+ }
544
+
545
+ .entry-detail-type.is-symlink {
546
+ color: var(--link);
547
+ }
548
+
549
+ .entry-detail-type.is-device {
550
+ color: var(--dev);
551
+ }
552
+
553
+ .entry-detail-type.is-exec {
554
+ color: var(--exec);
555
+ }
556
+
557
+ .entry-detail-type.is-readonly {
558
+ color: var(--readonly);
559
+ }
560
+
561
+ .entry-detail-mode {
562
+ color: var(--accent);
563
+ }
564
+
565
+ .entry-detail-marked {
566
+ color: var(--mark);
567
+ }
568
+
569
+ /* Summary -------------------------------------------------------------- */
570
+
571
+ .summary {
572
+ flex: none;
573
+ padding: 0.25rem 0.45rem;
574
+ color: var(--text-dim);
575
+ white-space: pre;
576
+ overflow: hidden;
577
+ text-overflow: ellipsis;
578
+ }
579
+
580
+ /* Filter bar ----------------------------------------------------------- */
581
+
582
+ .filter-bar {
583
+ flex: none;
584
+ display: flex;
585
+ align-items: center;
586
+ gap: 0.4rem;
587
+ padding: 0.2rem 0.1rem;
588
+ color: var(--text-dim);
589
+ font-size: 11px;
590
+ }
591
+
592
+ .filter-prompt {
593
+ flex: none;
594
+ color: var(--text-dim);
595
+ }
596
+
597
+ .filter-label {
598
+ flex: 1;
599
+ min-width: 0;
600
+ overflow: hidden;
601
+ text-overflow: ellipsis;
602
+ white-space: nowrap;
603
+ color: var(--accent);
604
+ }
605
+
606
+ .filter-alert {
607
+ flex: none;
608
+ color: var(--error);
609
+ }
610
+
611
+ .filter-input {
612
+ flex: 1;
613
+ min-width: 0;
614
+ background: transparent;
615
+ border: none;
616
+ outline: none;
617
+ color: var(--text);
618
+ font: inherit;
619
+ font-size: 12px;
620
+ }
621
+
622
+ /* Preview -------------------------------------------------------------- */
623
+
624
+ [data-slot="inspector"] {
625
+ display: flex;
626
+ flex: 1 1 0;
627
+ min-width: 0;
628
+ min-height: 0;
629
+ }
630
+
631
+ /* The maximized inspector (`⇧V`): the preview fills the whole pane row. */
632
+ .preview-max {
633
+ display: flex;
634
+ flex: 1 1 0;
635
+ min-width: 0;
636
+ min-height: 0;
637
+ }
638
+
639
+ .preview {
640
+ display: flex;
641
+ flex: 1;
642
+ flex-direction: column;
643
+ min-width: 0;
644
+ min-height: 0;
645
+ padding: 0.35rem 0.5rem;
646
+ background: var(--bg);
647
+ border: 1px solid var(--border);
648
+ }
649
+
650
+ .preview > header {
651
+ color: var(--text);
652
+ border-bottom: 1px solid var(--border);
653
+ padding-bottom: 0.3rem;
654
+ white-space: nowrap;
655
+ overflow: hidden;
656
+ text-overflow: ellipsis;
657
+ }
658
+
659
+ /* The inspector's directory column: breadcrumbs over the listing, laid out
660
+ like a pane header so a previewed directory reads as a pane. */
661
+ .preview > .pane-header {
662
+ flex: none;
663
+ border-bottom: 1px solid var(--border);
664
+ padding-left: 0;
665
+ padding-right: 0;
666
+ }
667
+
668
+ .preview-list {
669
+ display: flex;
670
+ flex: 1;
671
+ min-height: 0;
672
+ }
673
+
674
+ .preview-text,
675
+ .preview-card {
676
+ flex: 1;
677
+ min-height: 0;
678
+ margin: 0;
679
+ overflow: auto;
680
+ white-space: pre-wrap;
681
+ overflow-wrap: anywhere;
682
+ font: inherit;
683
+ font-size: 12px;
684
+ }
685
+
686
+ .preview-card {
687
+ color: var(--text-dim);
688
+ }
689
+
690
+ /* Command bar ---------------------------------------------------------- */
691
+
692
+ .command-bar {
693
+ flex: none;
694
+ display: flex;
695
+ align-items: center;
696
+ justify-content: space-between;
697
+ gap: 0.75rem;
698
+ min-height: 1.9rem;
699
+ padding: 0.25rem 0.6rem;
700
+ border-top: 1px solid var(--border);
701
+ background: var(--bg-panel);
702
+ overflow: hidden;
703
+ }
704
+
705
+ .command-bar-keys {
706
+ display: flex;
707
+ flex-wrap: nowrap;
708
+ gap: 0.45rem;
709
+ min-width: 0;
710
+ overflow: hidden;
711
+ }
712
+
713
+ .command-key {
714
+ background: var(--bg-raised);
715
+ border: 1px solid var(--border);
716
+ border-radius: 4px;
717
+ color: var(--text-dim);
718
+ cursor: pointer;
719
+ font: inherit;
720
+ font-size: 11px;
721
+ padding: 0.05rem 0.4rem;
722
+ white-space: nowrap;
723
+ }
724
+
725
+ .command-key:hover {
726
+ color: var(--text);
727
+ border-color: var(--accent-soft);
728
+ }
729
+
730
+ .command-key:disabled {
731
+ background: transparent;
732
+ border-color: transparent;
733
+ cursor: default;
734
+ }
735
+
736
+ button:focus-visible,
737
+ input:focus-visible {
738
+ outline: 1px solid var(--accent);
739
+ outline-offset: 2px;
740
+ }
741
+
742
+ .command-bar .is-error {
743
+ color: var(--error);
744
+ }
745
+
746
+ .command-bar [data-kind="warning"] {
747
+ color: var(--warning);
748
+ }
749
+
750
+ .command-bar [data-kind="tip"] {
751
+ color: var(--tip);
752
+ }
753
+
754
+ /* Confirm -------------------------------------------------------------- */
755
+
756
+ .confirm {
757
+ position: fixed;
758
+ inset: 0;
759
+ z-index: 20;
760
+ display: flex;
761
+ align-items: center;
762
+ justify-content: center;
763
+ background: rgb(0 0 0 / 45%);
764
+ }
765
+
766
+ .confirm p {
767
+ max-width: min(560px, 90vw);
768
+ margin: 0;
769
+ padding: 0.6rem 0.9rem;
770
+ background: var(--bg-panel);
771
+ border: 1px solid var(--error);
772
+ border-radius: 6px;
773
+ pointer-events: auto;
774
+ }
775
+
776
+ /* Modal presentations -------------------------------------------------- */
777
+
778
+ .command-panel,
779
+ .bookmark-list,
780
+ .help,
781
+ .viewer {
782
+ position: fixed;
783
+ inset: 0;
784
+ z-index: 15;
785
+ display: flex;
786
+ align-items: center;
787
+ justify-content: center;
788
+ padding: 1rem;
789
+ background: rgb(0 0 0 / 45%);
790
+ }
791
+
792
+ .help {
793
+ z-index: 30;
794
+ }
795
+
796
+ .command-dialog,
797
+ .bookmark-dialog,
798
+ .help-dialog {
799
+ display: flex;
800
+ flex-direction: column;
801
+ width: min(900px, 95vw);
802
+ max-height: 85vh;
803
+ min-height: 0;
804
+ padding: 0.6rem;
805
+ border: 1px solid var(--accent);
806
+ border-radius: 6px;
807
+ background: var(--bg-panel);
808
+ }
809
+
810
+ .command-dialog {
811
+ position: relative;
812
+ height: 72vh;
813
+ }
814
+
815
+ .bookmark-dialog,
816
+ .help-dialog {
817
+ width: min(640px, 95vw);
818
+ }
819
+
820
+ .panel-title,
821
+ .help-dialog > header,
822
+ .bookmark-dialog h2 {
823
+ color: var(--text);
824
+ font: inherit;
825
+ font-weight: 600;
826
+ margin: 0 0 0.4rem;
827
+ }
828
+
829
+ /* The dialog's close action sits in the top border like a close button: the
830
+ panel background masks the border run underneath it. */
831
+ .panel-close {
832
+ position: absolute;
833
+ top: -0.55rem;
834
+ right: 0.9rem;
835
+ z-index: 2;
836
+ padding: 0 0.3rem;
837
+ border: none;
838
+ border-radius: 3px;
839
+ background: var(--bg-panel);
840
+ color: var(--text-dim);
841
+ font: inherit;
842
+ line-height: 1.1;
843
+ cursor: pointer;
844
+ }
845
+
846
+ .panel-close:hover,
847
+ .panel-close:focus-visible {
848
+ color: var(--text);
849
+ background: var(--accent-soft);
850
+ }
851
+
852
+ .panel-query-line,
853
+ .panel-value-line,
854
+ .bookmark-dialog > header {
855
+ display: flex;
856
+ align-items: center;
857
+ gap: 0.5rem;
858
+ padding: 0.3rem 0;
859
+ }
860
+
861
+ /* The left pane: the `:` filter over the grouped command list. */
862
+ .panel-command-column {
863
+ display: flex;
864
+ flex-direction: column;
865
+ min-height: 0;
866
+ }
867
+
868
+ .panel-query,
869
+ .panel-value {
870
+ background: transparent;
871
+ border: none;
872
+ color: var(--text);
873
+ font: inherit;
874
+ min-width: 2ch;
875
+ }
876
+
877
+ /* The right pane's header: the selected command's name. */
878
+ .panel-command-name {
879
+ margin: 0;
880
+ padding: 0.3rem 0.6rem;
881
+ color: var(--text);
882
+ font-weight: 600;
883
+ }
884
+
885
+ /* The argument pane's rows: an aligned label + boxed value field for an
886
+ argument, and a bordered list of selected paths under a selection. */
887
+ .panel-row[data-type="arg"] .panel-name {
888
+ white-space: pre;
889
+ color: var(--text-dim);
890
+ }
891
+
892
+ .panel-row[data-type="arg"].is-focused .panel-name {
893
+ color: var(--accent);
894
+ }
895
+
896
+ .panel-row[data-type="group"] {
897
+ padding-top: 0.45rem;
898
+ cursor: default;
899
+ font-size: 0.82em;
900
+ font-weight: 700;
901
+ letter-spacing: 0.06em;
902
+ text-transform: uppercase;
903
+ }
904
+
905
+ .panel-row[data-type="group"][data-group="White"] {
906
+ color: var(--text);
907
+ }
908
+
909
+ .panel-row[data-type="group"][data-group="Amber"] {
910
+ color: var(--warning);
911
+ }
912
+
913
+ .panel-row[data-type="group"][data-group="Red"] {
914
+ color: var(--error);
915
+ }
916
+
917
+ .panel-row[data-type="op"] {
918
+ padding-left: 1.5rem;
919
+ }
920
+
921
+ .panel-row[data-type="run"] {
922
+ justify-content: flex-start;
923
+ margin-top: 0;
924
+ padding-top: 0.25rem;
925
+ padding-bottom: 0.25rem;
926
+ }
927
+
928
+ .panel-preview {
929
+ flex: 0 1 auto;
930
+ max-height: 20vh;
931
+ margin: 0;
932
+ padding: 0.35rem 0.6rem;
933
+ border-top: 1px solid var(--border);
934
+ color: var(--text-dim);
935
+ overflow: auto;
936
+ white-space: pre-wrap;
937
+ overflow-wrap: anywhere;
938
+ font: inherit;
939
+ }
940
+
941
+ .panel-run-action {
942
+ flex: none;
943
+ list-style: none;
944
+ margin: 0;
945
+ padding: 0 0.6rem 0.4rem 0;
946
+ }
947
+
948
+ .panel-run-button {
949
+ padding: 0.15rem 0.7rem;
950
+ border: 1px solid var(--text);
951
+ border-radius: 4px;
952
+ background: transparent;
953
+ color: var(--text);
954
+ font: inherit;
955
+ cursor: pointer;
956
+ }
957
+
958
+ .panel-row[data-type="run"].is-focused .panel-run-button {
959
+ background: var(--accent-soft);
960
+ }
961
+
962
+ .panel-row[data-type="run"][data-risk="caution"] .panel-run-button {
963
+ border-color: var(--warning);
964
+ color: var(--warning);
965
+ }
966
+
967
+ .panel-row[data-type="run"][data-risk="destructive"] .panel-run-button {
968
+ border-color: var(--error);
969
+ color: var(--error);
970
+ }
971
+
972
+ .panel-run-error-block {
973
+ margin: 0.25rem 0.6rem 0.35rem 0.5rem;
974
+ padding: 0.25rem 0.5rem;
975
+ border: 1px solid var(--error);
976
+ border-radius: 4px;
977
+ }
978
+
979
+ .panel-run-error-block p {
980
+ margin: 0;
981
+ color: var(--error);
982
+ white-space: pre-wrap;
983
+ overflow-wrap: anywhere;
984
+ }
985
+
986
+ /* The armed command, printed below `[Confirm]` in the action's risk colour. */
987
+ .panel-confirm-command {
988
+ margin: 0;
989
+ padding: 0.15rem 0.6rem 0.4rem 0.5rem;
990
+ white-space: pre-wrap;
991
+ overflow-wrap: anywhere;
992
+ }
993
+
994
+ .panel-confirm-command[data-risk="caution"] {
995
+ color: var(--warning);
996
+ }
997
+
998
+ .panel-confirm-command[data-risk="destructive"] {
999
+ color: var(--error);
1000
+ }
1001
+
1002
+ /* A permission class row: a label and three r/w/x cells. */
1003
+ .panel-perm {
1004
+ display: inline-flex;
1005
+ align-items: baseline;
1006
+ gap: 0.6rem;
1007
+ }
1008
+
1009
+ .panel-perm-class {
1010
+ width: 3.5rem;
1011
+ color: var(--text-dim);
1012
+ }
1013
+
1014
+ .panel-perm-bit {
1015
+ width: 1.4rem;
1016
+ padding: 0;
1017
+ border: none;
1018
+ border-radius: 3px;
1019
+ background: transparent;
1020
+ color: var(--text-dim);
1021
+ font: inherit;
1022
+ font-weight: 600;
1023
+ text-align: center;
1024
+ cursor: pointer;
1025
+ }
1026
+
1027
+ .panel-perm-bit.is-on {
1028
+ color: var(--accent);
1029
+ }
1030
+
1031
+ .panel-perm-bit.is-bit-focused {
1032
+ background: var(--accent-soft);
1033
+ color: var(--text);
1034
+ }
1035
+
1036
+ .panel-field {
1037
+ display: inline-flex;
1038
+ align-items: baseline;
1039
+ flex: 1;
1040
+ min-width: 0;
1041
+ background: var(--bg-field);
1042
+ border-radius: 3px;
1043
+ border: 1px solid var(--border);
1044
+ padding: 0 0.25rem;
1045
+ }
1046
+
1047
+ .panel-field[data-editable="false"] {
1048
+ background: transparent;
1049
+ border-color: transparent;
1050
+ padding-left: 0;
1051
+ }
1052
+
1053
+ .panel-field[data-editable="true"] {
1054
+ border-color: var(--accent-soft);
1055
+ }
1056
+
1057
+ .panel-field[data-editable="false"] .panel-field-bracket {
1058
+ display: none;
1059
+ }
1060
+
1061
+ .panel-field[data-editable="false"] .panel-field-value {
1062
+ color: var(--text-dim);
1063
+ }
1064
+
1065
+ .panel-field-bracket {
1066
+ color: var(--text-dim);
1067
+ }
1068
+
1069
+ .panel-field-value {
1070
+ flex: 1;
1071
+ min-width: 0;
1072
+ overflow: hidden;
1073
+ text-overflow: ellipsis;
1074
+ white-space: pre;
1075
+ color: var(--text);
1076
+ }
1077
+
1078
+ .panel-field .panel-value {
1079
+ flex: 1;
1080
+ min-width: 0;
1081
+ background: transparent;
1082
+ border: none;
1083
+ color: var(--text);
1084
+ font: inherit;
1085
+ }
1086
+
1087
+ .panel-list-indent {
1088
+ white-space: pre;
1089
+ }
1090
+
1091
+ .panel-list-box {
1092
+ display: inline-flex;
1093
+ align-items: baseline;
1094
+ gap: 0.5rem;
1095
+ flex: 1;
1096
+ min-width: 0;
1097
+ border-left: 1px solid var(--border);
1098
+ border-right: 1px solid var(--border);
1099
+ padding: 0 0.4rem;
1100
+ }
1101
+
1102
+ .panel-row.is-list-top .panel-list-box {
1103
+ border-top: 1px solid var(--border);
1104
+ border-top-left-radius: 4px;
1105
+ border-top-right-radius: 4px;
1106
+ }
1107
+
1108
+ .panel-row.is-list-bottom .panel-list-box {
1109
+ border-bottom: 1px solid var(--border);
1110
+ border-bottom-left-radius: 4px;
1111
+ border-bottom-right-radius: 4px;
1112
+ }
1113
+
1114
+ .panel-query,
1115
+ .panel-value,
1116
+ .bookmark-query {
1117
+ flex: 1;
1118
+ min-width: 0;
1119
+ background: transparent;
1120
+ border: none;
1121
+ color: var(--text);
1122
+ font: inherit;
1123
+ }
1124
+
1125
+ .panel-columns {
1126
+ display: grid;
1127
+ grid-template-columns: minmax(0, 2fr) minmax(0, 3fr);
1128
+ flex: 1;
1129
+ min-height: 0;
1130
+ border-top: 1px solid var(--border);
1131
+ border-bottom: 1px solid var(--border);
1132
+ }
1133
+
1134
+ .panel-ops,
1135
+ .panel-args,
1136
+ .bookmark-rows {
1137
+ list-style: none;
1138
+ margin: 0;
1139
+ padding: 0.3rem 0;
1140
+ overflow: auto;
1141
+ min-height: 0;
1142
+ }
1143
+
1144
+ .panel-ops {
1145
+ flex: 1 1 0;
1146
+ }
1147
+
1148
+ /* The argument pane scrolls as a whole so the Run action follows the last
1149
+ field instead of being pinned to the bottom of the column. */
1150
+ .panel-args-scroll {
1151
+ flex: 1 1 0;
1152
+ min-height: 0;
1153
+ overflow: auto;
1154
+ }
1155
+
1156
+ .panel-args {
1157
+ flex: none;
1158
+ overflow: visible;
1159
+ }
1160
+
1161
+ /* The argument column: an empty state (a TinyCmd action binds no arguments)
1162
+ above the rows, with the divider on the column rather than the list so both
1163
+ stay visible. */
1164
+ .panel-args-column {
1165
+ display: flex;
1166
+ flex-direction: column;
1167
+ min-height: 0;
1168
+ border-left: 1px solid var(--border);
1169
+ }
1170
+
1171
+ .panel-args-empty {
1172
+ display: flex;
1173
+ flex-direction: column;
1174
+ gap: 0.1rem;
1175
+ margin: 0.3rem 0;
1176
+ padding: 0 0.6rem;
1177
+ color: var(--text-dim);
1178
+ }
1179
+
1180
+
1181
+
1182
+ /* File picker sub-mode: a nested pane containing its path, filter and entries
1183
+ (which reuse `.panel-row` through the shared arg-row map). */
1184
+ .panel-picker-pane {
1185
+ display: flex;
1186
+ flex: 1 1 0;
1187
+ flex-direction: column;
1188
+ min-height: 0;
1189
+ margin: 0.35rem 0.5rem 0.5rem;
1190
+ border: 1px solid var(--border);
1191
+ border-radius: 4px;
1192
+ overflow: hidden;
1193
+ }
1194
+
1195
+ .panel-picker {
1196
+ display: flex;
1197
+ flex-direction: column;
1198
+ gap: 0.15rem;
1199
+ padding: 0.3rem 0.6rem;
1200
+ border-bottom: 1px solid var(--border);
1201
+ }
1202
+
1203
+ .panel-picker-rows {
1204
+ flex: 1 1 0;
1205
+ }
1206
+
1207
+ .panel-picker-path {
1208
+ flex: 1;
1209
+ min-width: 0;
1210
+ margin: 0;
1211
+ padding: 0;
1212
+ background: transparent;
1213
+ border: none;
1214
+ color: var(--text);
1215
+ font: inherit;
1216
+ }
1217
+
1218
+ .panel-picker-path:focus {
1219
+ outline: none;
1220
+ }
1221
+
1222
+ .panel-picker-line {
1223
+ display: flex;
1224
+ align-items: center;
1225
+ gap: 0.5rem;
1226
+ }
1227
+
1228
+ .panel-picker-icon {
1229
+ width: 1rem;
1230
+ height: 1rem;
1231
+ color: var(--accent);
1232
+ }
1233
+
1234
+ .panel-picker-rows .picker-row {
1235
+ padding-left: 0.6rem;
1236
+ padding-right: 0.6rem;
1237
+ }
1238
+
1239
+ .panel-row,
1240
+ .bookmark-row {
1241
+ display: flex;
1242
+ align-items: baseline;
1243
+ gap: 0.5rem;
1244
+ padding: 0.15rem 0.3rem;
1245
+ white-space: nowrap;
1246
+ cursor: pointer;
1247
+ }
1248
+
1249
+ .bookmark-icon {
1250
+ width: 0.9rem;
1251
+ height: 0.9rem;
1252
+ align-self: center;
1253
+ color: var(--text-dim);
1254
+ }
1255
+
1256
+ /* An argument stacks its label over its value: the marker and label on the
1257
+ first line, the value field aligned under the label on the second. */
1258
+ .panel-row[data-type="arg"] {
1259
+ display: grid;
1260
+ grid-template-columns: minmax(0, 1fr);
1261
+ grid-template-rows: auto auto;
1262
+ row-gap: 0.1rem;
1263
+ align-items: baseline;
1264
+ }
1265
+
1266
+ /* Labels and values start one space in from the pane border. */
1267
+ .panel-args .panel-row[data-type="arg"],
1268
+ .panel-args .panel-row[data-type="perm"],
1269
+ .panel-run-action .panel-row {
1270
+ padding-left: 0.5rem;
1271
+ }
1272
+
1273
+ .panel-row[data-type="arg"] > .panel-marker {
1274
+ display: none;
1275
+ }
1276
+
1277
+ .panel-row[data-type="arg"] > .panel-name {
1278
+ grid-area: 1 / 1;
1279
+ min-width: 0;
1280
+ overflow: hidden;
1281
+ }
1282
+
1283
+ .panel-row[data-type="arg"] > .panel-field {
1284
+ grid-area: 2 / 1;
1285
+ }
1286
+
1287
+ .panel-row.is-focused,
1288
+ .bookmark-row.is-selected {
1289
+ background: var(--accent-soft);
1290
+ }
1291
+
1292
+ .panel-marker,
1293
+ .bookmark-marker {
1294
+ color: var(--accent);
1295
+ white-space: pre;
1296
+ }
1297
+
1298
+ .panel-summary,
1299
+ .bookmark-path {
1300
+ color: var(--text-dim);
1301
+ min-width: 0;
1302
+ overflow: hidden;
1303
+ text-overflow: ellipsis;
1304
+ }
1305
+
1306
+ .panel-op-chevron {
1307
+ width: 0.9rem;
1308
+ height: 0.9rem;
1309
+ flex: none;
1310
+ margin-left: auto;
1311
+ color: var(--text-dim);
1312
+ }
1313
+
1314
+ .panel-row.is-focused .panel-op-chevron {
1315
+ color: var(--accent);
1316
+ }
1317
+
1318
+ .panel-row.is-focused .panel-name {
1319
+ color: var(--accent);
1320
+ }
1321
+
1322
+ .panel-row[data-risk="destructive"] .panel-name {
1323
+ color: var(--error);
1324
+ }
1325
+
1326
+ .panel-row[data-risk="caution"] .panel-name {
1327
+ color: var(--warning);
1328
+ }
1329
+
1330
+ .panel-row[data-selected="true"]:not(.is-focused) .panel-name {
1331
+ color: var(--mark);
1332
+ }
1333
+
1334
+ .command-dialog > footer,
1335
+ .bookmark-dialog > footer,
1336
+ .help-dialog > footer,
1337
+ .bookmark-empty {
1338
+ color: var(--text-dim);
1339
+ padding-top: 0.3rem;
1340
+ }
1341
+
1342
+ /* Shared list overlay (history / trash) --------------------------------- */
1343
+
1344
+ .overlay-list {
1345
+ position: fixed;
1346
+ inset: 0;
1347
+ z-index: 18;
1348
+ display: flex;
1349
+ align-items: center;
1350
+ justify-content: center;
1351
+ padding: 1rem;
1352
+ background: rgb(0 0 0 / 45%);
1353
+ }
1354
+
1355
+ .overlay-dialog {
1356
+ display: flex;
1357
+ flex-direction: column;
1358
+ width: min(640px, 95vw);
1359
+ max-height: 85vh;
1360
+ min-height: 0;
1361
+ padding: 0.6rem;
1362
+ border: 1px solid var(--accent);
1363
+ border-radius: 6px;
1364
+ background: var(--bg-panel);
1365
+ }
1366
+
1367
+ .overlay-dialog h2 {
1368
+ color: var(--text);
1369
+ font: inherit;
1370
+ font-weight: 600;
1371
+ margin: 0 0 0.4rem;
1372
+ }
1373
+
1374
+ .overlay-rows {
1375
+ list-style: none;
1376
+ margin: 0;
1377
+ padding: 0.3rem 0;
1378
+ overflow: auto;
1379
+ min-height: 0;
1380
+ }
1381
+
1382
+ .overlay-row {
1383
+ display: flex;
1384
+ align-items: baseline;
1385
+ gap: 0.5rem;
1386
+ padding: 0.15rem 0.3rem;
1387
+ white-space: nowrap;
1388
+ cursor: pointer;
1389
+ }
1390
+
1391
+ .overlay-row[data-current="true"] {
1392
+ background: var(--accent-soft);
1393
+ }
1394
+
1395
+ .overlay-marker {
1396
+ color: var(--accent);
1397
+ white-space: pre;
1398
+ }
1399
+
1400
+ .overlay-text {
1401
+ color: var(--text);
1402
+ min-width: 0;
1403
+ overflow: hidden;
1404
+ text-overflow: ellipsis;
1405
+ }
1406
+
1407
+ .overlay-row[data-dim="true"] .overlay-text {
1408
+ color: var(--text-dim);
1409
+ }
1410
+
1411
+ .overlay-row[data-current="true"] .overlay-text {
1412
+ color: var(--accent);
1413
+ }
1414
+
1415
+ .overlay-meta {
1416
+ margin-left: auto;
1417
+ color: var(--text-dim);
1418
+ min-width: 0;
1419
+ overflow: hidden;
1420
+ text-overflow: ellipsis;
1421
+ }
1422
+
1423
+ .overlay-dialog > footer,
1424
+ .overlay-empty {
1425
+ color: var(--text-dim);
1426
+ padding-top: 0.3rem;
1427
+ }
1428
+
1429
+ .help-columns {
1430
+ display: flex;
1431
+ gap: 1.5rem;
1432
+ flex: 1;
1433
+ min-height: 0;
1434
+ overflow: auto;
1435
+ }
1436
+
1437
+ .help-column {
1438
+ flex: 1;
1439
+ min-width: 0;
1440
+ }
1441
+
1442
+ .help-block {
1443
+ min-height: 1.2em;
1444
+ }
1445
+
1446
+ .help-section {
1447
+ color: var(--text);
1448
+ font-weight: 700;
1449
+ letter-spacing: 0.04em;
1450
+ }
1451
+
1452
+ .help-entry {
1453
+ display: inline-flex;
1454
+ align-items: center;
1455
+ gap: 0.35rem;
1456
+ max-width: 100%;
1457
+ min-height: 1.55rem;
1458
+ padding: 0 0.4rem;
1459
+ border: 1px solid var(--border);
1460
+ border-radius: 4px;
1461
+ background: var(--bg-raised);
1462
+ white-space: nowrap;
1463
+ }
1464
+
1465
+ .help-icon {
1466
+ width: 0.9rem;
1467
+ height: 0.9rem;
1468
+ color: var(--accent);
1469
+ }
1470
+
1471
+ .help-title {
1472
+ color: var(--text);
1473
+ }
1474
+
1475
+ .help-entry .help-title {
1476
+ overflow: hidden;
1477
+ text-overflow: ellipsis;
1478
+ }
1479
+
1480
+ .help-key {
1481
+ color: var(--accent);
1482
+ }
1483
+
1484
+ .help-entry .help-key {
1485
+ flex: none;
1486
+ padding-left: 0.35rem;
1487
+ border-left: 1px solid var(--border);
1488
+ font: 11px/1.5 var(--font-mono);
1489
+ }
1490
+
1491
+ .help-bracket {
1492
+ color: var(--text-dim);
1493
+ }
1494
+
1495
+ .help-footer {
1496
+ border-top: 1px solid var(--accent);
1497
+ padding-top: 0.3rem;
1498
+ }
1499
+
1500
+ .viewer > .preview {
1501
+ flex: none;
1502
+ width: 90%;
1503
+ height: 90%;
1504
+ }
1505
+
1506
+ .resize-hint {
1507
+ flex: 1;
1508
+ display: flex;
1509
+ flex-direction: column;
1510
+ align-items: center;
1511
+ justify-content: center;
1512
+ color: var(--text-dim);
1513
+ }
1514
+
1515
+ /* EOF */