flexdesk 0.16.1 → 0.17.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.
- package/CHANGELOG.md +93 -0
- package/LICENSE +0 -0
- package/README.md +2217 -42
- package/THIRD_PARTY_LICENSES.md +0 -0
- package/css/base.css +1834 -75
- package/css/flexdesk.css +3146 -164
- package/css/overrides.css +16 -0
- package/css/reset.css +0 -0
- package/css/tokens.css +0 -0
- package/dist/canvas.js +6 -239
- package/dist/canvas.js.map +3 -3
- package/dist/charts.js +709 -18
- package/dist/charts.js.map +4 -4
- package/dist/chunk-3PHCPZHT.js +0 -0
- package/dist/chunk-3PHCPZHT.js.map +0 -0
- package/dist/chunk-4A7SJC3T.js +503 -0
- package/dist/chunk-4A7SJC3T.js.map +7 -0
- package/dist/{chunk-6JSOVNID.js → chunk-CVMCZZX2.js} +635 -10
- package/dist/chunk-CVMCZZX2.js.map +7 -0
- package/dist/chunk-D3COLZZ2.js +1311 -0
- package/dist/chunk-D3COLZZ2.js.map +7 -0
- package/dist/chunk-FOOS3T5L.js +0 -0
- package/dist/chunk-FOOS3T5L.js.map +0 -0
- package/dist/{chunk-SN4LSOAR.js → chunk-GOQLR5WR.js} +452 -2
- package/dist/chunk-GOQLR5WR.js.map +7 -0
- package/dist/{chunk-FL5KFNQH.js → chunk-HNU6MM2B.js} +52 -17
- package/dist/chunk-HNU6MM2B.js.map +7 -0
- package/dist/chunk-HYJYYEPK.js +375 -0
- package/dist/chunk-HYJYYEPK.js.map +7 -0
- package/dist/chunk-JKZLNKG6.js +2041 -0
- package/dist/chunk-JKZLNKG6.js.map +7 -0
- package/dist/chunk-JYWURG5T.js +0 -0
- package/dist/chunk-JYWURG5T.js.map +0 -0
- package/dist/{chunk-RQM5Z2MU.js → chunk-MCIXFNVF.js} +633 -311
- package/dist/chunk-MCIXFNVF.js.map +7 -0
- package/dist/chunk-N7HC3ADV.js +30 -0
- package/dist/chunk-N7HC3ADV.js.map +7 -0
- package/dist/{chunk-FBGP5KN5.js → chunk-Q36EPT2R.js} +3268 -203
- package/dist/chunk-Q36EPT2R.js.map +7 -0
- package/dist/chunk-QWQJUDPD.js +610 -0
- package/dist/chunk-QWQJUDPD.js.map +7 -0
- package/dist/{chunk-NLTOY57M.js → chunk-UURZ37SD.js} +28 -48
- package/dist/chunk-UURZ37SD.js.map +7 -0
- package/dist/{chunk-B5Q53LAJ.js → chunk-UWO43BZU.js} +2 -2
- package/dist/chunk-UWO43BZU.js.map +7 -0
- package/dist/chunk-WVFGV5FT.js +0 -0
- package/dist/chunk-WVFGV5FT.js.map +0 -0
- package/dist/core.js +170 -118
- package/dist/core.js.map +2 -2
- package/dist/editor.js +156 -70
- package/dist/editor.js.map +2 -2
- package/dist/flexdesk.css +3146 -164
- package/dist/flow.js +2789 -306
- package/dist/flow.js.map +4 -4
- package/dist/host.js +109 -3
- package/dist/host.js.map +3 -3
- package/dist/reset.css +0 -0
- package/dist/tile_registry-6WZPTUZV.js +0 -0
- package/dist/tile_registry-6WZPTUZV.js.map +0 -0
- package/dist/tiles.js +657 -234
- package/dist/tiles.js.map +4 -4
- package/dist/tokens.css +0 -0
- package/dist/widgets.js +3252 -2124
- package/dist/widgets.js.map +4 -4
- package/dist/wm.js +1227 -347
- package/dist/wm.js.map +4 -4
- package/package.json +3 -1
- package/src/canvas/canvas_adapter.js +5 -0
- package/src/canvas/edge_router.js +0 -0
- package/src/canvas/graph/connector_router.js +0 -0
- package/src/canvas/graph/history_service.js +0 -0
- package/src/canvas/graph/node_platform.js +0 -0
- package/src/canvas/index.js +1 -0
- package/src/canvas/layered_layout.js +244 -0
- package/src/charts/chart_types.js +0 -0
- package/src/charts/data_series_plot_window.js +0 -0
- package/src/charts/downsample.js +2 -2
- package/src/charts/plot_config.js +53 -29
- package/src/charts/plot_config_editor.js +627 -0
- package/src/charts/plot_grid.js +449 -0
- package/src/charts/plot_popout_window.js +103 -317
- package/src/charts/plotly_wrapper.js +22 -2
- package/src/charts/series_transforms.js +206 -0
- package/src/core/event_bus.js +0 -0
- package/src/core/logging.js +1 -1
- package/src/core/settings.js +105 -19
- package/src/core/state_guard.js +93 -51
- package/src/core/state_guard_config.js +85 -74
- package/src/core/state_machine.js +0 -0
- package/src/editor/editor_pane.js +3 -3
- package/src/editor/monaco_editor_factory.js +124 -60
- package/src/editor/monaco_loader.js +103 -28
- package/src/editor/notebook_search.js +0 -0
- package/src/editor/notebook_tab_bar.js +38 -52
- package/src/editor/notebook_undo_manager.js +0 -0
- package/src/editor/split_pane_container.js +6 -3
- package/src/flow/canvas_editor/connections.js +90 -0
- package/src/flow/canvas_editor/editor.js +2351 -153
- package/src/flow/canvas_editor/index.js +2 -1
- package/src/flow/canvas_editor/layout.js +119 -12
- package/src/flow/canvas_editor/strings.js +80 -0
- package/src/flow/kit/always_before.js +0 -0
- package/src/flow/kit/catalogue.js +97 -3
- package/src/flow/kit/chip_input.js +0 -0
- package/src/flow/kit/dom.js +0 -0
- package/src/flow/kit/findings.js +0 -0
- package/src/flow/kit/history.js +0 -0
- package/src/flow/kit/index.js +3 -3
- package/src/flow/kit/keys.js +7 -1
- package/src/flow/kit/logic_graph.js +97 -15
- package/src/flow/kit/references.js +0 -0
- package/src/flow/kit/settings_panel.js +0 -0
- package/src/flow/kit/settings_schema.js +2 -1
- package/src/flow/kit/step_picker.js +0 -0
- package/src/flow/kit/strings.js +3 -1
- package/src/flow/kit/value_picker.js +0 -0
- package/src/flow/kit/widgets.js +86 -109
- package/src/flow/lanes/editor.js +136 -14
- package/src/flow/lanes/index.js +3 -1
- package/src/flow/lanes/layout.js +0 -0
- package/src/flow/lanes/pipeline.js +44 -2
- package/src/flow/lanes/preview.js +0 -0
- package/src/flow/lanes/strings.js +1 -0
- package/src/flow/outline/editor.js +0 -0
- package/src/flow/outline/index.js +0 -0
- package/src/flow/outline/mapping.js +0 -0
- package/src/flow/outline/menu.js +0 -0
- package/src/flow/outline/operations.js +0 -0
- package/src/flow/outline/recognise.js +0 -0
- package/src/flow/outline/strings.js +0 -0
- package/src/help/help_modal.js +168 -42
- package/src/help/help_registry.js +12 -1
- package/src/host/external_links.js +0 -0
- package/src/host/file_picker.js +117 -0
- package/src/host/host.js +10 -2
- package/src/host/photino_host.js +9 -0
- package/src/host/photino_host.md +21 -3
- package/src/host/pywebview_host.js +10 -0
- package/src/tiles/chart_tiles.js +53 -245
- package/src/tiles/config_schema.js +8 -0
- package/src/tiles/figure_tile.js +322 -0
- package/src/tiles/layout_persistence.js +3 -3
- package/src/tiles/list_tiles.js +7 -7
- package/src/tiles/scope_picker.js +0 -0
- package/src/tiles/tile_base.js +1 -1
- package/src/tiles/tile_config_form.js +442 -0
- package/src/tiles/tile_grid.js +2 -0
- package/src/tiles/tile_registry.js +0 -0
- package/src/tiling/bottom_panel_tabs.js +67 -99
- package/src/tiling/command_palette.js +64 -19
- package/src/tiling/content_registry.js +4 -1
- package/src/tiling/desktops.js +11 -1
- package/src/tiling/entity_sources.js +0 -0
- package/src/tiling/keymap.js +403 -128
- package/src/tiling/kind_taxonomy.js +78 -0
- package/src/tiling/landing_table.js +0 -0
- package/src/tiling/loading_overlay.js +0 -0
- package/src/tiling/nav_panel.js +59 -10
- package/src/tiling/page_factory.js +5 -5
- package/src/tiling/panel_availability.js +49 -0
- package/src/tiling/panel_keys.js +0 -0
- package/src/tiling/shell.js +114 -12
- package/src/tiling/tab_strip.js +0 -0
- package/src/tiling/tile_breadcrumb.js +0 -0
- package/src/tiling/tile_renderer.js +105 -9
- package/src/tiling/tile_tab_menu.js +0 -0
- package/src/tiling/tile_tree.js +0 -0
- package/src/tiling/wm.js +562 -30
- package/src/tiling/zoom.js +0 -0
- package/src/ui/base/component_base.js +0 -0
- package/src/ui/base/controller_base.js +0 -0
- package/src/ui/base/page_base.js +0 -0
- package/src/ui/components/about_dialog.js +0 -0
- package/src/ui/components/action_dropdown.js +30 -2
- package/src/ui/components/alert_log.js +0 -0
- package/src/ui/components/alerts_pane.js +0 -0
- package/src/ui/components/attribute_list_editor.js +0 -0
- package/src/ui/components/autocomplete_field.js +0 -0
- package/src/ui/components/cell_editor_host.js +211 -0
- package/src/ui/components/cell_grid.js +648 -0
- package/src/ui/components/cell_selection.js +220 -0
- package/src/ui/components/choice_controls.js +351 -0
- package/src/ui/components/color_field.js +211 -0
- package/src/ui/components/color_list_field.js +210 -0
- package/src/ui/components/column_fit.js +0 -0
- package/src/ui/components/column_groups.js +314 -0
- package/src/ui/components/column_order.js +142 -0
- package/src/ui/components/computing_status_window.js +98 -25
- package/src/ui/components/confirm_dialog.js +81 -38
- package/src/ui/components/context_menu.js +2 -2
- package/src/ui/components/conversation_view.js +440 -0
- package/src/ui/components/crosstab.js +289 -0
- package/src/ui/components/data_table.js +601 -62
- package/src/ui/components/detail_header.js +22 -11
- package/src/ui/components/document_outline.js +397 -0
- package/src/ui/components/drag_reorder.js +0 -0
- package/src/ui/components/fact_table.js +0 -0
- package/src/ui/components/fill_handle.js +322 -0
- package/src/ui/components/gallery_picker.js +19 -8
- package/src/ui/components/header_actions.js +55 -0
- package/src/ui/components/inline_renamer.js +0 -0
- package/src/ui/components/job_progress.js +51 -0
- package/src/ui/components/managed_window.js +27 -4
- package/src/ui/components/menu_bar.js +745 -0
- package/src/ui/components/modal.js +449 -75
- package/src/ui/components/notification_history.js +3 -3
- package/src/ui/components/progress.js +483 -0
- package/src/ui/components/record_list.js +0 -0
- package/src/ui/components/row_activation.js +0 -0
- package/src/ui/components/section_stack.js +298 -0
- package/src/ui/components/series.js +173 -0
- package/src/ui/components/settings_view.js +634 -0
- package/src/ui/components/slide_out_panel.js +43 -6
- package/src/ui/components/slider_field.js +275 -18
- package/src/ui/components/sortable_list.js +0 -0
- package/src/ui/components/staged_edits.js +343 -0
- package/src/ui/components/staged_history.js +172 -0
- package/src/ui/components/table_filter_chips.js +0 -0
- package/src/ui/components/table_state_store.js +0 -0
- package/src/ui/components/table_structure.js +182 -0
- package/src/ui/components/table_values.js +0 -0
- package/src/ui/components/tabs.js +497 -0
- package/src/ui/components/tag_input.js +215 -0
- package/src/ui/components/toast.js +25 -8
- package/src/ui/components/toggle_field.js +175 -0
- package/src/ui/components/tree_view.js +55 -34
- package/src/ui/components/window_taskbar.js +0 -0
- package/src/ui/components/wizard.js +563 -0
- package/src/ui/controllers/window_chrome_controller.js +2 -2
- package/src/ui/notification_center.js +375 -119
- package/src/ui/utils/auto_scrollbars.js +0 -0
- package/src/ui/utils/markdown.js +709 -0
- package/src/ui/utils/native_context_menu.js +0 -0
- package/src/ui/utils/overlay_scrollbar.js +16 -12
- package/src/ui/utils/raf_resize_observer.js +0 -0
- package/src/ui/utils/scroll_lock.js +0 -0
- package/src/ui/utils/strip_scroll.js +55 -0
- package/src/ui/utils/tooltip_service.js +0 -8
- package/dist/chunk-6JSOVNID.js.map +0 -7
- package/dist/chunk-B5Q53LAJ.js.map +0 -7
- package/dist/chunk-FBGP5KN5.js.map +0 -7
- package/dist/chunk-FL5KFNQH.js.map +0 -7
- package/dist/chunk-NLTOY57M.js.map +0 -7
- package/dist/chunk-NNFTETK3.js +0 -633
- package/dist/chunk-NNFTETK3.js.map +0 -7
- package/dist/chunk-O5OHMWBB.js +0 -284
- package/dist/chunk-O5OHMWBB.js.map +0 -7
- package/dist/chunk-RQM5Z2MU.js.map +0 -7
- package/dist/chunk-SN4LSOAR.js.map +0 -7
- package/dist/chunk-W6FBJLPW.js +0 -367
- package/dist/chunk-W6FBJLPW.js.map +0 -7
- package/src/ui/controllers/panel_state_machine.js +0 -634
package/css/base.css
CHANGED
|
@@ -156,6 +156,10 @@
|
|
|
156
156
|
font-size: var(--font-size-sm);
|
|
157
157
|
line-height: 1.5;
|
|
158
158
|
}
|
|
159
|
+
/* Shown: the service adds `visible` once the tooltip is positioned, and removes it to fade out */
|
|
160
|
+
.twm-latex-tooltip.visible {
|
|
161
|
+
opacity: 1;
|
|
162
|
+
}
|
|
159
163
|
/* Tooltip header (first line) styling */
|
|
160
164
|
.twm-latex-tooltip strong {
|
|
161
165
|
display: block;
|
|
@@ -336,6 +340,46 @@
|
|
|
336
340
|
background: var(--accent);
|
|
337
341
|
border-color: var(--accent);
|
|
338
342
|
}
|
|
343
|
+
/* NotificationCenter progress toasts: a bar, a status line, a collapse toggle. */
|
|
344
|
+
.twm-notification__collapse {
|
|
345
|
+
width: 22px;
|
|
346
|
+
height: 22px;
|
|
347
|
+
border: none;
|
|
348
|
+
border-radius: var(--radius-sm);
|
|
349
|
+
background: rgba(255, 255, 255, 0.06);
|
|
350
|
+
color: #999;
|
|
351
|
+
cursor: pointer;
|
|
352
|
+
display: inline-flex;
|
|
353
|
+
align-items: center;
|
|
354
|
+
justify-content: center;
|
|
355
|
+
padding: 0;
|
|
356
|
+
flex-shrink: 0;
|
|
357
|
+
transition: background var(--transition-fast), color var(--transition-fast), transform var(--transition-fast);
|
|
358
|
+
}
|
|
359
|
+
.twm-notification__collapse:hover {
|
|
360
|
+
background: rgba(255, 255, 255, 0.14);
|
|
361
|
+
color: var(--text-bright);
|
|
362
|
+
}
|
|
363
|
+
.twm-notification--collapsed .twm-notification__collapse {
|
|
364
|
+
transform: rotate(-90deg);
|
|
365
|
+
}
|
|
366
|
+
.twm-notification__progress {
|
|
367
|
+
margin-top: var(--space-sm);
|
|
368
|
+
}
|
|
369
|
+
.twm-notification__status {
|
|
370
|
+
margin-top: var(--space-xs);
|
|
371
|
+
font-size: var(--font-size-xs);
|
|
372
|
+
color: var(--text-secondary);
|
|
373
|
+
overflow: hidden;
|
|
374
|
+
text-overflow: ellipsis;
|
|
375
|
+
white-space: nowrap;
|
|
376
|
+
}
|
|
377
|
+
.twm-notification--collapsed .twm-notification__body,
|
|
378
|
+
.twm-notification--collapsed .twm-notification__status,
|
|
379
|
+
.twm-notification--collapsed .twm-notification__description,
|
|
380
|
+
.twm-notification--collapsed .twm-notification__actions {
|
|
381
|
+
display: none;
|
|
382
|
+
}
|
|
339
383
|
/* Notification history (bottom bar bell + popover) */
|
|
340
384
|
.twm-notification-history__trigger {
|
|
341
385
|
display: flex;
|
|
@@ -431,6 +475,10 @@
|
|
|
431
475
|
padding: var(--space-md) 10px;
|
|
432
476
|
font-size: var(--font-size-sm);
|
|
433
477
|
}
|
|
478
|
+
.twm-notification-history__item--success { border-left-color: var(--color-success, #3fb950); }
|
|
479
|
+
.twm-notification-history__item--warn { border-left-color: var(--color-warning, #ff9800); }
|
|
480
|
+
.twm-notification-history__item--error,
|
|
481
|
+
.twm-notification-history__item--fatal { border-left-color: var(--color-danger, #c74e4e); }
|
|
434
482
|
.twm-notification-history__item-header {
|
|
435
483
|
display: flex;
|
|
436
484
|
align-items: center;
|
|
@@ -982,6 +1030,82 @@ body.twm-dt-col-resizing {
|
|
|
982
1030
|
cursor: grab;
|
|
983
1031
|
border: 2px solid var(--surface-0);
|
|
984
1032
|
}
|
|
1033
|
+
/* ══ SLIDER FIELD COMPANIONS ══ number box, readout, reset, enable toggle (STORY-0045) */
|
|
1034
|
+
.twm-slider-field__row {
|
|
1035
|
+
display: flex;
|
|
1036
|
+
align-items: center;
|
|
1037
|
+
gap: var(--space-sm);
|
|
1038
|
+
min-width: 0;
|
|
1039
|
+
}
|
|
1040
|
+
.twm-slider-field__row > .twm-slider-field__input {
|
|
1041
|
+
flex: 1 1 auto;
|
|
1042
|
+
min-width: 0;
|
|
1043
|
+
}
|
|
1044
|
+
.twm-slider-field__toggle {
|
|
1045
|
+
flex: 0 0 auto;
|
|
1046
|
+
margin: 0;
|
|
1047
|
+
cursor: pointer;
|
|
1048
|
+
}
|
|
1049
|
+
.twm-slider-field__readout {
|
|
1050
|
+
flex: 0 0 auto;
|
|
1051
|
+
min-width: 3em;
|
|
1052
|
+
text-align: right;
|
|
1053
|
+
font-size: var(--font-size-sm);
|
|
1054
|
+
font-variant-numeric: tabular-nums;
|
|
1055
|
+
color: var(--text-dim);
|
|
1056
|
+
}
|
|
1057
|
+
.twm-slider-field__number {
|
|
1058
|
+
flex: 0 0 auto;
|
|
1059
|
+
width: 6em;
|
|
1060
|
+
padding: var(--space-xxs) var(--space-xs);
|
|
1061
|
+
font: inherit;
|
|
1062
|
+
font-size: var(--font-size-sm);
|
|
1063
|
+
font-variant-numeric: tabular-nums;
|
|
1064
|
+
text-align: right;
|
|
1065
|
+
color: var(--text-body);
|
|
1066
|
+
background: var(--surface-well);
|
|
1067
|
+
border: 1px solid var(--border-default);
|
|
1068
|
+
border-radius: var(--radius-sm);
|
|
1069
|
+
}
|
|
1070
|
+
.twm-slider-field__number:focus {
|
|
1071
|
+
outline: none;
|
|
1072
|
+
border-color: var(--accent);
|
|
1073
|
+
}
|
|
1074
|
+
.twm-slider-field__reset {
|
|
1075
|
+
flex: 0 0 auto;
|
|
1076
|
+
display: inline-flex;
|
|
1077
|
+
align-items: center;
|
|
1078
|
+
justify-content: center;
|
|
1079
|
+
padding: 0;
|
|
1080
|
+
width: 22px;
|
|
1081
|
+
height: 22px;
|
|
1082
|
+
color: var(--text-dim);
|
|
1083
|
+
background: transparent;
|
|
1084
|
+
border: none;
|
|
1085
|
+
border-radius: var(--radius-sm);
|
|
1086
|
+
cursor: pointer;
|
|
1087
|
+
visibility: hidden;
|
|
1088
|
+
}
|
|
1089
|
+
.twm-slider-field__reset .material-symbols-outlined {
|
|
1090
|
+
font-size: 16px;
|
|
1091
|
+
}
|
|
1092
|
+
.twm-slider-field__reset:hover {
|
|
1093
|
+
color: var(--text-bright);
|
|
1094
|
+
background: var(--state-hover);
|
|
1095
|
+
}
|
|
1096
|
+
.twm-slider-field--modified .twm-slider-field__reset {
|
|
1097
|
+
visibility: visible;
|
|
1098
|
+
}
|
|
1099
|
+
.twm-slider-field--modified .twm-slider-field__number,
|
|
1100
|
+
.twm-slider-field--modified .twm-slider-field__readout {
|
|
1101
|
+
color: var(--accent-bright);
|
|
1102
|
+
}
|
|
1103
|
+
.twm-slider-field--off .twm-slider-field__input,
|
|
1104
|
+
.twm-slider-field--off .twm-slider-field__number,
|
|
1105
|
+
.twm-slider-field--off .twm-slider-field__readout {
|
|
1106
|
+
opacity: 0.45;
|
|
1107
|
+
}
|
|
1108
|
+
/* ══ end SLIDER FIELD COMPANIONS ══ */
|
|
985
1109
|
/* ===== Sortable List Component ===== */
|
|
986
1110
|
.twm-sortable-list {
|
|
987
1111
|
display: flex;
|
|
@@ -2725,6 +2849,231 @@ body.twm-window-maximized .twm-resize-handle {
|
|
|
2725
2849
|
cursor: default;
|
|
2726
2850
|
}
|
|
2727
2851
|
|
|
2852
|
+
/* ─── Progress: ProgressBar, ProgressList, StepProgress ──────────────
|
|
2853
|
+
`src/ui/components/progress.js`. Every width is the fill's inline
|
|
2854
|
+
`style.width`, changed in place; the states are modifier classes. */
|
|
2855
|
+
|
|
2856
|
+
.twm-progress {
|
|
2857
|
+
display: flex;
|
|
2858
|
+
flex-direction: column;
|
|
2859
|
+
gap: var(--space-xs);
|
|
2860
|
+
min-width: 0;
|
|
2861
|
+
}
|
|
2862
|
+
.twm-progress__head {
|
|
2863
|
+
display: flex;
|
|
2864
|
+
align-items: baseline;
|
|
2865
|
+
gap: var(--space-sm);
|
|
2866
|
+
font-size: var(--font-size-sm);
|
|
2867
|
+
color: var(--text-secondary);
|
|
2868
|
+
}
|
|
2869
|
+
.twm-progress__label {
|
|
2870
|
+
flex: 1 1 auto;
|
|
2871
|
+
min-width: 0;
|
|
2872
|
+
overflow: hidden;
|
|
2873
|
+
text-overflow: ellipsis;
|
|
2874
|
+
white-space: nowrap;
|
|
2875
|
+
color: var(--text-primary);
|
|
2876
|
+
}
|
|
2877
|
+
.twm-progress__readout,
|
|
2878
|
+
.twm-progress__elapsed {
|
|
2879
|
+
flex: 0 0 auto;
|
|
2880
|
+
font-variant-numeric: tabular-nums;
|
|
2881
|
+
}
|
|
2882
|
+
.twm-progress__elapsed {
|
|
2883
|
+
color: var(--text-muted);
|
|
2884
|
+
}
|
|
2885
|
+
.twm-progress__cancel {
|
|
2886
|
+
flex: 0 0 auto;
|
|
2887
|
+
background: transparent;
|
|
2888
|
+
border: 1px solid var(--border-default);
|
|
2889
|
+
border-radius: var(--radius-sm);
|
|
2890
|
+
color: var(--text-secondary);
|
|
2891
|
+
font-size: var(--font-size-xs);
|
|
2892
|
+
padding: 0 var(--space-sm);
|
|
2893
|
+
cursor: pointer;
|
|
2894
|
+
}
|
|
2895
|
+
.twm-progress__cancel:hover:not(:disabled) {
|
|
2896
|
+
border-color: var(--color-danger);
|
|
2897
|
+
color: var(--color-danger);
|
|
2898
|
+
}
|
|
2899
|
+
.twm-progress__cancel:disabled {
|
|
2900
|
+
opacity: 0.5;
|
|
2901
|
+
cursor: default;
|
|
2902
|
+
}
|
|
2903
|
+
.twm-progress__track,
|
|
2904
|
+
.twm-progress-list__track {
|
|
2905
|
+
position: relative;
|
|
2906
|
+
height: 6px;
|
|
2907
|
+
overflow: hidden;
|
|
2908
|
+
background: var(--surface-3);
|
|
2909
|
+
border-radius: var(--radius-pill);
|
|
2910
|
+
}
|
|
2911
|
+
.twm-progress__fill,
|
|
2912
|
+
.twm-progress-list__fill {
|
|
2913
|
+
height: 100%;
|
|
2914
|
+
width: 0;
|
|
2915
|
+
background: var(--accent);
|
|
2916
|
+
border-radius: inherit;
|
|
2917
|
+
transition: width var(--transition-normal);
|
|
2918
|
+
}
|
|
2919
|
+
.twm-progress--indeterminate .twm-progress__fill {
|
|
2920
|
+
position: absolute;
|
|
2921
|
+
left: 0;
|
|
2922
|
+
width: 30%;
|
|
2923
|
+
animation: twm-progress-sweep 1.2s ease-in-out infinite;
|
|
2924
|
+
}
|
|
2925
|
+
.twm-progress--done .twm-progress__fill {
|
|
2926
|
+
background: var(--color-success);
|
|
2927
|
+
}
|
|
2928
|
+
.twm-progress--error .twm-progress__fill {
|
|
2929
|
+
background: var(--color-danger);
|
|
2930
|
+
}
|
|
2931
|
+
.twm-progress--cancelled .twm-progress__fill {
|
|
2932
|
+
background: var(--text-dim);
|
|
2933
|
+
}
|
|
2934
|
+
@keyframes twm-progress-sweep {
|
|
2935
|
+
0% { transform: translateX(-100%); }
|
|
2936
|
+
100% { transform: translateX(340%); }
|
|
2937
|
+
}
|
|
2938
|
+
|
|
2939
|
+
.twm-progress-list {
|
|
2940
|
+
display: flex;
|
|
2941
|
+
flex-direction: column;
|
|
2942
|
+
gap: var(--space-sm);
|
|
2943
|
+
min-width: 0;
|
|
2944
|
+
}
|
|
2945
|
+
.twm-progress-list__rows {
|
|
2946
|
+
display: flex;
|
|
2947
|
+
flex-direction: column;
|
|
2948
|
+
gap: var(--space-xs);
|
|
2949
|
+
}
|
|
2950
|
+
.twm-progress-list__row {
|
|
2951
|
+
display: grid;
|
|
2952
|
+
grid-template-columns: auto minmax(6em, 1fr) minmax(4em, 2fr) auto;
|
|
2953
|
+
align-items: center;
|
|
2954
|
+
gap: var(--space-sm);
|
|
2955
|
+
font-size: var(--font-size-sm);
|
|
2956
|
+
color: var(--text-primary);
|
|
2957
|
+
}
|
|
2958
|
+
.twm-progress-list__name {
|
|
2959
|
+
overflow: hidden;
|
|
2960
|
+
text-overflow: ellipsis;
|
|
2961
|
+
white-space: nowrap;
|
|
2962
|
+
}
|
|
2963
|
+
.twm-progress-list__count {
|
|
2964
|
+
color: var(--text-secondary);
|
|
2965
|
+
font-variant-numeric: tabular-nums;
|
|
2966
|
+
white-space: nowrap;
|
|
2967
|
+
}
|
|
2968
|
+
.twm-progress-list__state {
|
|
2969
|
+
width: 8px;
|
|
2970
|
+
height: 8px;
|
|
2971
|
+
border-radius: var(--radius-circle);
|
|
2972
|
+
background: var(--text-dim);
|
|
2973
|
+
}
|
|
2974
|
+
.twm-progress-list__row--running .twm-progress-list__state {
|
|
2975
|
+
background: var(--accent);
|
|
2976
|
+
}
|
|
2977
|
+
.twm-progress-list--pulse .twm-progress-list__row--running .twm-progress-list__state {
|
|
2978
|
+
animation: twm-progress-pulse 1.2s ease-in-out infinite;
|
|
2979
|
+
}
|
|
2980
|
+
.twm-progress-list__row--done .twm-progress-list__state,
|
|
2981
|
+
.twm-progress-list__row--done .twm-progress-list__fill {
|
|
2982
|
+
background: var(--color-success);
|
|
2983
|
+
}
|
|
2984
|
+
.twm-progress-list__row--failed .twm-progress-list__state,
|
|
2985
|
+
.twm-progress-list__row--failed .twm-progress-list__fill {
|
|
2986
|
+
background: var(--color-danger);
|
|
2987
|
+
}
|
|
2988
|
+
.twm-progress-list__row--pending {
|
|
2989
|
+
color: var(--text-muted);
|
|
2990
|
+
}
|
|
2991
|
+
.twm-progress-list__empty,
|
|
2992
|
+
.twm-progress-list__stats {
|
|
2993
|
+
font-size: var(--font-size-xs);
|
|
2994
|
+
color: var(--text-muted);
|
|
2995
|
+
font-variant-numeric: tabular-nums;
|
|
2996
|
+
}
|
|
2997
|
+
@keyframes twm-progress-pulse {
|
|
2998
|
+
0%, 100% { opacity: 1; }
|
|
2999
|
+
50% { opacity: 0.35; }
|
|
3000
|
+
}
|
|
3001
|
+
|
|
3002
|
+
.twm-steps {
|
|
3003
|
+
display: flex;
|
|
3004
|
+
flex-wrap: wrap;
|
|
3005
|
+
gap: var(--space-xs) var(--space-lg);
|
|
3006
|
+
margin: 0;
|
|
3007
|
+
padding: 0;
|
|
3008
|
+
list-style: none;
|
|
3009
|
+
font-size: var(--font-size-sm);
|
|
3010
|
+
}
|
|
3011
|
+
.twm-steps__step {
|
|
3012
|
+
display: inline-flex;
|
|
3013
|
+
align-items: center;
|
|
3014
|
+
gap: var(--space-xs);
|
|
3015
|
+
color: var(--text-muted);
|
|
3016
|
+
}
|
|
3017
|
+
.twm-steps__marker {
|
|
3018
|
+
width: 8px;
|
|
3019
|
+
height: 8px;
|
|
3020
|
+
border-radius: var(--radius-circle);
|
|
3021
|
+
border: 1px solid currentColor;
|
|
3022
|
+
}
|
|
3023
|
+
.twm-steps__step--done {
|
|
3024
|
+
color: var(--text-secondary);
|
|
3025
|
+
}
|
|
3026
|
+
.twm-steps__step--done .twm-steps__marker {
|
|
3027
|
+
background: var(--color-success);
|
|
3028
|
+
border-color: var(--color-success);
|
|
3029
|
+
}
|
|
3030
|
+
.twm-steps__step--active {
|
|
3031
|
+
color: var(--text-primary);
|
|
3032
|
+
font-weight: var(--font-weight-semibold);
|
|
3033
|
+
}
|
|
3034
|
+
.twm-steps__step--active .twm-steps__marker {
|
|
3035
|
+
background: var(--accent);
|
|
3036
|
+
border-color: var(--accent);
|
|
3037
|
+
}
|
|
3038
|
+
.twm-steps__step--error {
|
|
3039
|
+
color: var(--color-danger);
|
|
3040
|
+
}
|
|
3041
|
+
.twm-steps__step--error .twm-steps__marker {
|
|
3042
|
+
background: var(--color-danger);
|
|
3043
|
+
border-color: var(--color-danger);
|
|
3044
|
+
}
|
|
3045
|
+
.twm-steps__pass {
|
|
3046
|
+
font-weight: var(--font-weight-regular);
|
|
3047
|
+
color: var(--text-muted);
|
|
3048
|
+
font-variant-numeric: tabular-nums;
|
|
3049
|
+
}
|
|
3050
|
+
@media (prefers-reduced-motion: reduce) {
|
|
3051
|
+
.twm-progress__fill,
|
|
3052
|
+
.twm-progress-list__fill { transition: none; }
|
|
3053
|
+
.twm-progress--indeterminate .twm-progress__fill,
|
|
3054
|
+
.twm-progress-list--pulse .twm-progress-list__row--running .twm-progress-list__state { animation: none; }
|
|
3055
|
+
}
|
|
3056
|
+
|
|
3057
|
+
/* The bar and phases inside showRunProgressDialog / showComputingWindow,
|
|
3058
|
+
and the message's final state. */
|
|
3059
|
+
.twm-job-progress__steps,
|
|
3060
|
+
.twm-job-progress__bar {
|
|
3061
|
+
align-self: stretch;
|
|
3062
|
+
margin: var(--space-xs) 0;
|
|
3063
|
+
}
|
|
3064
|
+
.twm-run-progress__message.is-ok,
|
|
3065
|
+
.twm-computing-status__message.is-ok {
|
|
3066
|
+
color: var(--color-success);
|
|
3067
|
+
}
|
|
3068
|
+
.twm-run-progress__message.is-err,
|
|
3069
|
+
.twm-computing-status__message.is-err {
|
|
3070
|
+
color: var(--color-danger);
|
|
3071
|
+
}
|
|
3072
|
+
.twm-run-progress__message.is-cancelled,
|
|
3073
|
+
.twm-computing-status__message.is-cancelled {
|
|
3074
|
+
color: var(--text-muted);
|
|
3075
|
+
}
|
|
3076
|
+
|
|
2728
3077
|
/* ═══════════════════════════════════════════════════════════════════════
|
|
2729
3078
|
@flexdesk/tiles — THE TILE GRID'S CHROME
|
|
2730
3079
|
|
|
@@ -3299,6 +3648,14 @@ body.twm-window-maximized .twm-resize-handle {
|
|
|
3299
3648
|
box-sizing: border-box;
|
|
3300
3649
|
transition: background var(--transition-normal), border-color var(--transition-normal);
|
|
3301
3650
|
}
|
|
3651
|
+
/* A `{ separator: true }` entry: a rule between two groups of options. It is
|
|
3652
|
+
not a button, so it takes no focus and the arrow keys pass over it. */
|
|
3653
|
+
.twm-action-dropdown-separator {
|
|
3654
|
+
height: 1px;
|
|
3655
|
+
/* the option above already leaves var(--space-xs) below itself */
|
|
3656
|
+
margin: 0 0 var(--space-xs);
|
|
3657
|
+
background: var(--border-subtle);
|
|
3658
|
+
}
|
|
3302
3659
|
.twm-action-dropdown-option:last-child {
|
|
3303
3660
|
margin-bottom: 0;
|
|
3304
3661
|
}
|
|
@@ -4011,7 +4368,36 @@ button.twm-about-dialog__btn--close:focus {
|
|
|
4011
4368
|
}
|
|
4012
4369
|
/* ─── Badges ──────────────────────────────────────────────────────────── */
|
|
4013
4370
|
|
|
4014
|
-
/*
|
|
4371
|
+
/* A badge beside the title (`createDetailHeader({badges})`, BUG-0015): a
|
|
4372
|
+
* neutral pill from tokens. A caller's own `className` sits on the same
|
|
4373
|
+
* element, after this rule's single class, to recolour it. */
|
|
4374
|
+
.twm-detail-header__badge {
|
|
4375
|
+
display: inline-flex;
|
|
4376
|
+
align-items: center;
|
|
4377
|
+
gap: var(--space-xs);
|
|
4378
|
+
padding: 2px var(--space-md);
|
|
4379
|
+
border-radius: var(--radius-pill);
|
|
4380
|
+
border: 1px solid var(--border-subtle);
|
|
4381
|
+
background: var(--surface-2);
|
|
4382
|
+
color: var(--text-muted);
|
|
4383
|
+
font-size: var(--font-size-xs);
|
|
4384
|
+
font-weight: var(--font-weight-medium);
|
|
4385
|
+
line-height: var(--line-height-tight);
|
|
4386
|
+
white-space: nowrap;
|
|
4387
|
+
flex-shrink: 0;
|
|
4388
|
+
}
|
|
4389
|
+
/* Compounded for the Material Symbols tie — see `.twm-leaf__icon`. */
|
|
4390
|
+
.twm-detail-header__badge-icon,
|
|
4391
|
+
.twm-detail-header__badge-icon.material-symbols-outlined {
|
|
4392
|
+
font-size: 14px;
|
|
4393
|
+
line-height: 1;
|
|
4394
|
+
}
|
|
4395
|
+
|
|
4396
|
+
/* ─── Buttons ─────────────────────────────────────────────────────────── */
|
|
4397
|
+
|
|
4398
|
+
/* An action is a `.twm-btn` (BUG-0015): the shared button look, with
|
|
4399
|
+
* 'primary' wearing `.twm-btn--primary` and 'danger' `.twm-btn--danger`;
|
|
4400
|
+
* 'secondary' is the plain button. Its icon is a `.twm-btn__glyph`. */
|
|
4015
4401
|
|
|
4016
4402
|
/* ─── Subtitle ────────────────────────────────────────────────────────── */
|
|
4017
4403
|
|
|
@@ -4757,7 +5143,7 @@ button.twm-about-dialog__btn--close:focus {
|
|
|
4757
5143
|
font-variation-settings: 'opsz' 20, 'wght' 400;
|
|
4758
5144
|
}
|
|
4759
5145
|
|
|
4760
|
-
.twm-leaf__btn:hover:not(:disabled) { background: var(--state-hover); color: var(--text-primary); }
|
|
5146
|
+
.twm-leaf__btn:hover:not(:disabled):not(.twm-leaf__btn--disabled) { background: var(--state-hover); color: var(--text-primary); }
|
|
4761
5147
|
|
|
4762
5148
|
/* C20. A verb that applies to this kind of pane but not right now — greyed and
|
|
4763
5149
|
* explained by its tooltip, rather than removed. `:disabled` alone would still
|
|
@@ -4768,6 +5154,34 @@ button.twm-about-dialog__btn--close:focus {
|
|
|
4768
5154
|
cursor: default;
|
|
4769
5155
|
}
|
|
4770
5156
|
|
|
5157
|
+
/* C42. A content action that is a toggle, and on: `aria-pressed="true"`. The
|
|
5158
|
+
* selected tint the rest of the shell uses, so "on" reads the same everywhere. */
|
|
5159
|
+
.twm-leaf__btn--pressed {
|
|
5160
|
+
background: var(--state-selected);
|
|
5161
|
+
color: var(--text-primary);
|
|
5162
|
+
}
|
|
5163
|
+
|
|
5164
|
+
/* C42. A content action with a text label: the 18px square is for a glyph, so
|
|
5165
|
+
* a labelled button grows to its text. */
|
|
5166
|
+
.twm-leaf__btn--labelled {
|
|
5167
|
+
width: auto;
|
|
5168
|
+
gap: 2px;
|
|
5169
|
+
padding: 0 4px;
|
|
5170
|
+
}
|
|
5171
|
+
.twm-leaf__btn-label {
|
|
5172
|
+
font-size: 11px;
|
|
5173
|
+
line-height: 1;
|
|
5174
|
+
white-space: nowrap;
|
|
5175
|
+
}
|
|
5176
|
+
|
|
5177
|
+
/* C42. `{separator: true}` between groups of content actions. */
|
|
5178
|
+
.twm-leaf__sep {
|
|
5179
|
+
align-self: stretch;
|
|
5180
|
+
width: 1px;
|
|
5181
|
+
margin: 3px 2px;
|
|
5182
|
+
background: var(--border-subtle);
|
|
5183
|
+
}
|
|
5184
|
+
|
|
4771
5185
|
/* R8. THE SAME STRIP, IN A WINDOW. A pane floated into a managed window takes
|
|
4772
5186
|
* its tabs with it — *"to window includes the tab-strip"* — and the strip in
|
|
4773
5187
|
* the window is the strip from the pane: same component, same vocabulary, same
|
|
@@ -5201,9 +5615,202 @@ button.twm-about-dialog__btn--close:focus {
|
|
|
5201
5615
|
background: var(--border-subtle);
|
|
5202
5616
|
}
|
|
5203
5617
|
|
|
5204
|
-
/*
|
|
5205
|
-
*
|
|
5206
|
-
*
|
|
5618
|
+
/* ══ EDITOR · PANES, SPLIT AND SEARCH (BUG-0025) ═════════════════════
|
|
5619
|
+
*
|
|
5620
|
+
* The same family as the tab bar above: `SplitPaneContainer`, `EditorPane`
|
|
5621
|
+
* and `NotebookSearchBar` set these classes and no FlexDesk stylesheet had a
|
|
5622
|
+
* rule for any of them, so with only FlexDesk CSS a split stacked its panes,
|
|
5623
|
+
* the divider was a zero-width div nobody could grab, and the search bar was
|
|
5624
|
+
* a row of bare inputs and icon names.
|
|
5625
|
+
*
|
|
5626
|
+
* `.split-pane-container*`, `.split-pane`, `.split-pane-divider*`
|
|
5627
|
+
* `editor/split_pane_container.js`
|
|
5628
|
+
* `.editor-pane*`, `.notebook-editor-container`
|
|
5629
|
+
* `editor/editor_pane.js`
|
|
5630
|
+
* `.nb-search-bar*` `editor/notebook_search.js`
|
|
5631
|
+
*
|
|
5632
|
+
* Layout first: the container is a row, each pane a column, and the divider
|
|
5633
|
+
* a fixed-width strip that never shrinks. The pane's flex is also written
|
|
5634
|
+
* inline by `SplitPaneContainer` (the ratio); the rule is the fallback. */
|
|
5635
|
+
.split-pane-container {
|
|
5636
|
+
display: flex;
|
|
5637
|
+
flex-direction: row;
|
|
5638
|
+
flex: 1 1 0;
|
|
5639
|
+
min-width: 0;
|
|
5640
|
+
min-height: 0;
|
|
5641
|
+
overflow: hidden;
|
|
5642
|
+
}
|
|
5643
|
+
.split-pane {
|
|
5644
|
+
display: flex;
|
|
5645
|
+
flex-direction: column;
|
|
5646
|
+
flex: 1 1 0;
|
|
5647
|
+
min-width: 0;
|
|
5648
|
+
min-height: 0;
|
|
5649
|
+
overflow: hidden;
|
|
5650
|
+
}
|
|
5651
|
+
/* 4px drawn, 10px grabbed: the `::before` widens the hit target 3px each side
|
|
5652
|
+
* without moving either pane. */
|
|
5653
|
+
.split-pane-divider {
|
|
5654
|
+
position: relative;
|
|
5655
|
+
z-index: 1;
|
|
5656
|
+
flex: 0 0 4px;
|
|
5657
|
+
width: 4px;
|
|
5658
|
+
background: var(--border-strong);
|
|
5659
|
+
cursor: col-resize;
|
|
5660
|
+
transition: background 0.15s;
|
|
5661
|
+
}
|
|
5662
|
+
.split-pane-divider::before {
|
|
5663
|
+
content: '';
|
|
5664
|
+
position: absolute;
|
|
5665
|
+
inset: 0 -3px;
|
|
5666
|
+
}
|
|
5667
|
+
.split-pane-divider:hover,
|
|
5668
|
+
.split-pane-divider--active {
|
|
5669
|
+
background: var(--accent-bright, #1683c4);
|
|
5670
|
+
}
|
|
5671
|
+
/* A pane is its tab bar over its body. The tab bar's own rule says
|
|
5672
|
+
* `height: 100%` (it fills a tile's strip); here it is a fixed 26px row, the
|
|
5673
|
+
* strip's height, and the body takes the rest. */
|
|
5674
|
+
.editor-pane {
|
|
5675
|
+
display: flex;
|
|
5676
|
+
flex-direction: column;
|
|
5677
|
+
flex: 1 1 0;
|
|
5678
|
+
min-width: 0;
|
|
5679
|
+
min-height: 0;
|
|
5680
|
+
overflow: hidden;
|
|
5681
|
+
}
|
|
5682
|
+
.editor-pane > .tabs.notebook-tabs {
|
|
5683
|
+
flex: 0 0 auto;
|
|
5684
|
+
height: 26px;
|
|
5685
|
+
}
|
|
5686
|
+
/* Which of two panes has focus — only drawn when there ARE two. An inset
|
|
5687
|
+
* shadow rather than a border, so focusing a pane does not move its body.
|
|
5688
|
+
* This and the tab-bar row above need `.editor-pane` to survive
|
|
5689
|
+
* `setPanes()`, which is why `SplitPaneContainer` ADDS `.split-pane` to a
|
|
5690
|
+
* pane instead of replacing its classes with it. */
|
|
5691
|
+
.split-pane-container--split .editor-pane--focused > .tabs.notebook-tabs {
|
|
5692
|
+
box-shadow: inset 0 -1px 0 var(--accent-bright, #1683c4);
|
|
5693
|
+
}
|
|
5694
|
+
/* The body is the positioning anchor; the editor container fills it
|
|
5695
|
+
* absolutely, so its height is the body's whatever its content is and the
|
|
5696
|
+
* scrollbar is its own. */
|
|
5697
|
+
.editor-pane__body {
|
|
5698
|
+
position: relative;
|
|
5699
|
+
flex: 1 1 0;
|
|
5700
|
+
min-height: 0;
|
|
5701
|
+
overflow: hidden;
|
|
5702
|
+
}
|
|
5703
|
+
.notebook-editor-container {
|
|
5704
|
+
position: absolute;
|
|
5705
|
+
inset: 0;
|
|
5706
|
+
overflow-x: hidden;
|
|
5707
|
+
overflow-y: auto;
|
|
5708
|
+
background: var(--surface-0);
|
|
5709
|
+
outline: none;
|
|
5710
|
+
}
|
|
5711
|
+
/* The search bar: mounted at the top of the editor container and sticky
|
|
5712
|
+
* there, hidden until `open()` adds `--open`. */
|
|
5713
|
+
.nb-search-bar {
|
|
5714
|
+
position: sticky;
|
|
5715
|
+
top: 0;
|
|
5716
|
+
z-index: 50;
|
|
5717
|
+
display: none;
|
|
5718
|
+
flex-direction: column;
|
|
5719
|
+
gap: var(--space-xs);
|
|
5720
|
+
padding: var(--space-sm) var(--space-md);
|
|
5721
|
+
background: var(--surface-1);
|
|
5722
|
+
border-bottom: 1px solid var(--border-strong);
|
|
5723
|
+
box-shadow: var(--shadow-md);
|
|
5724
|
+
color: var(--text-primary);
|
|
5725
|
+
font-size: var(--font-size-sm);
|
|
5726
|
+
}
|
|
5727
|
+
.nb-search-bar--open { display: flex; }
|
|
5728
|
+
.nb-search-bar__find-row,
|
|
5729
|
+
.nb-search-bar__replace-row {
|
|
5730
|
+
display: flex;
|
|
5731
|
+
align-items: center;
|
|
5732
|
+
gap: var(--space-xs);
|
|
5733
|
+
}
|
|
5734
|
+
/* Lines the replace input up under the find input: the toggle's width. */
|
|
5735
|
+
.nb-search-bar__spacer {
|
|
5736
|
+
flex: 0 0 26px;
|
|
5737
|
+
width: 26px;
|
|
5738
|
+
}
|
|
5739
|
+
.nb-search-bar__input-wrap {
|
|
5740
|
+
flex: 1 1 auto;
|
|
5741
|
+
min-width: 160px;
|
|
5742
|
+
max-width: 320px;
|
|
5743
|
+
}
|
|
5744
|
+
.nb-search-bar__input {
|
|
5745
|
+
box-sizing: border-box;
|
|
5746
|
+
width: 100%;
|
|
5747
|
+
padding: 3px var(--space-sm);
|
|
5748
|
+
background: var(--surface-3);
|
|
5749
|
+
border: 1px solid var(--border-strong);
|
|
5750
|
+
border-radius: var(--radius-sm);
|
|
5751
|
+
color: var(--text-primary);
|
|
5752
|
+
font: inherit;
|
|
5753
|
+
outline: none;
|
|
5754
|
+
}
|
|
5755
|
+
.nb-search-bar__input:focus { border-color: var(--accent-bright, #1683c4); }
|
|
5756
|
+
.nb-search-bar__match-info {
|
|
5757
|
+
min-width: 64px;
|
|
5758
|
+
color: var(--text-muted);
|
|
5759
|
+
font-size: var(--font-size-xs);
|
|
5760
|
+
text-align: center;
|
|
5761
|
+
white-space: nowrap;
|
|
5762
|
+
user-select: none;
|
|
5763
|
+
}
|
|
5764
|
+
.nb-search-bar__match-info--no-results { color: var(--color-danger, #c74e4e); }
|
|
5765
|
+
.nb-search-bar__btn {
|
|
5766
|
+
display: inline-flex;
|
|
5767
|
+
flex: 0 0 auto;
|
|
5768
|
+
align-items: center;
|
|
5769
|
+
justify-content: center;
|
|
5770
|
+
width: 26px;
|
|
5771
|
+
height: 26px;
|
|
5772
|
+
padding: 0;
|
|
5773
|
+
background: transparent;
|
|
5774
|
+
border: none;
|
|
5775
|
+
border-radius: var(--radius-sm);
|
|
5776
|
+
color: var(--text-secondary);
|
|
5777
|
+
cursor: pointer;
|
|
5778
|
+
font-size: var(--font-size-sm);
|
|
5779
|
+
font-weight: 600;
|
|
5780
|
+
}
|
|
5781
|
+
.nb-search-bar__btn:hover { background: var(--state-hover); }
|
|
5782
|
+
.nb-search-bar__btn:active { background: var(--state-active); }
|
|
5783
|
+
/* The case / word / regex toggles reserve the border `--active` colours. */
|
|
5784
|
+
.nb-search-bar__btn--toggle { border: 1px solid transparent; }
|
|
5785
|
+
.nb-search-bar__btn--active,
|
|
5786
|
+
.nb-search-bar__btn--active:hover {
|
|
5787
|
+
background: var(--state-selected);
|
|
5788
|
+
border-color: var(--accent-bright, #1683c4);
|
|
5789
|
+
color: var(--text-bright);
|
|
5790
|
+
}
|
|
5791
|
+
/* Two classes, for the Material Symbols tie — see `.twm-leaf__icon`. */
|
|
5792
|
+
.nb-search-bar__btn .material-symbols-outlined {
|
|
5793
|
+
font-size: 18px;
|
|
5794
|
+
line-height: 1;
|
|
5795
|
+
}
|
|
5796
|
+
.nb-search-bar__icon-word {
|
|
5797
|
+
font-size: var(--font-size-md);
|
|
5798
|
+
font-weight: 700;
|
|
5799
|
+
text-decoration: underline;
|
|
5800
|
+
text-underline-offset: 2px;
|
|
5801
|
+
}
|
|
5802
|
+
.nb-search-bar__separator {
|
|
5803
|
+
flex: 0 0 1px;
|
|
5804
|
+
width: 1px;
|
|
5805
|
+
height: 18px;
|
|
5806
|
+
margin: 0 2px;
|
|
5807
|
+
background: var(--border-strong);
|
|
5808
|
+
}
|
|
5809
|
+
/* ══ end EDITOR · PANES, SPLIT AND SEARCH ══ */
|
|
5810
|
+
|
|
5811
|
+
/* R1. The containing block an ESCAPED window resolves against — a window
|
|
5812
|
+
* dragged out of its pane is re-parented here for the length of the drag.
|
|
5813
|
+
* `relative` only, for the reason `.twm-leaf` documents: `transform`, `filter`,
|
|
5207
5814
|
* `contain` and `will-change` each create a containing block AND trap
|
|
5208
5815
|
* `position: fixed` descendants, which would clip every dropdown the grid opens
|
|
5209
5816
|
* on purpose. */
|
|
@@ -5432,78 +6039,945 @@ button.twm-about-dialog__btn--close:focus {
|
|
|
5432
6039
|
outline: 1px solid var(--accent-bright, #007acc);
|
|
5433
6040
|
outline-offset: -1px;
|
|
5434
6041
|
}
|
|
5435
|
-
.twm-record-list__empty {
|
|
5436
|
-
margin: 0;
|
|
5437
|
-
padding: 12px 6px;
|
|
5438
|
-
color: var(--text-muted, #888);
|
|
5439
|
-
font-size: var(--ea-font-body, 11px);
|
|
6042
|
+
.twm-record-list__empty {
|
|
6043
|
+
margin: 0;
|
|
6044
|
+
padding: 12px 6px;
|
|
6045
|
+
color: var(--text-muted, #888);
|
|
6046
|
+
font-size: var(--ea-font-body, 11px);
|
|
6047
|
+
}
|
|
6048
|
+
|
|
6049
|
+
/* ── the fact sheet ── */
|
|
6050
|
+
.twm-facts {
|
|
6051
|
+
width: 100%;
|
|
6052
|
+
border-collapse: collapse;
|
|
6053
|
+
table-layout: auto;
|
|
6054
|
+
font-size: var(--font-size-sm, 12px);
|
|
6055
|
+
}
|
|
6056
|
+
.twm-facts thead th {
|
|
6057
|
+
text-align: left;
|
|
6058
|
+
font-size: var(--ea-font-small, 10px);
|
|
6059
|
+
font-weight: 600;
|
|
6060
|
+
letter-spacing: 0.06em;
|
|
6061
|
+
text-transform: uppercase;
|
|
6062
|
+
color: var(--text-dim, #666);
|
|
6063
|
+
white-space: nowrap;
|
|
6064
|
+
border-bottom: 1px solid var(--border-default, #303030);
|
|
6065
|
+
padding: 0 12px 6px 0;
|
|
6066
|
+
}
|
|
6067
|
+
/* Every value WRAPS and keeps its own line breaks: nothing is cut off. */
|
|
6068
|
+
.twm-facts tbody td,
|
|
6069
|
+
.twm-facts tbody th {
|
|
6070
|
+
text-align: left;
|
|
6071
|
+
font-weight: normal;
|
|
6072
|
+
border-bottom: 1px solid var(--border-subtle, #2a2a2a);
|
|
6073
|
+
padding: 6px 12px 6px 0;
|
|
6074
|
+
color: var(--text-primary, #e0e0e0);
|
|
6075
|
+
vertical-align: top;
|
|
6076
|
+
white-space: pre-wrap;
|
|
6077
|
+
overflow-wrap: anywhere;
|
|
6078
|
+
}
|
|
6079
|
+
.twm-facts tbody tr:last-child > td,
|
|
6080
|
+
.twm-facts tbody tr:last-child > th { border-bottom: 0; }
|
|
6081
|
+
.twm-facts tbody th.twm-facts__label {
|
|
6082
|
+
color: var(--text-muted, #888);
|
|
6083
|
+
white-space: nowrap;
|
|
6084
|
+
}
|
|
6085
|
+
.twm-facts.twm-facts--wrap-labels tbody th.twm-facts__label { white-space: normal; }
|
|
6086
|
+
/* `wrap: 'words'` — a value wraps at spaces only, and a long word stays
|
|
6087
|
+
* whole: the sheet grows wider and a sideways scroller around it scrolls.
|
|
6088
|
+
* `wrap: 'none'` — a value keeps its own line breaks and no others. */
|
|
6089
|
+
.twm-facts.twm-facts--wrap-words tbody td,
|
|
6090
|
+
.twm-facts.twm-facts--wrap-words tbody th { overflow-wrap: normal; word-break: normal; }
|
|
6091
|
+
.twm-facts.twm-facts--wrap-none tbody td,
|
|
6092
|
+
.twm-facts.twm-facts--wrap-none tbody th { white-space: pre; overflow-wrap: normal; word-break: normal; }
|
|
6093
|
+
.twm-facts.twm-facts--mono tbody td.twm-facts__value,
|
|
6094
|
+
.twm-facts tbody td.twm-facts__mono { font-family: var(--font-family-mono, monospace); font-size: 0.95em; }
|
|
6095
|
+
.twm-facts .twm-facts__num { font-variant-numeric: tabular-nums; white-space: nowrap; }
|
|
6096
|
+
.twm-facts tbody td.twm-facts__null,
|
|
6097
|
+
.twm-facts tbody td.twm-facts__missing { color: var(--text-dim, #666); font-style: italic; }
|
|
6098
|
+
.twm-facts tbody td.twm-facts__arrow {
|
|
6099
|
+
color: var(--text-dim, #666);
|
|
6100
|
+
white-space: nowrap;
|
|
6101
|
+
width: 1%;
|
|
6102
|
+
}
|
|
6103
|
+
.twm-facts tbody tr.twm-facts__row--changed > td.twm-facts__before { color: var(--text-muted, #888); }
|
|
6104
|
+
.twm-facts tbody tr.twm-facts__row--changed > td.twm-facts__arrow { color: var(--color-warning, #ff9800); }
|
|
6105
|
+
.twm-facts tbody tr.twm-facts__row--same > td { color: var(--text-muted, #888); }
|
|
6106
|
+
.twm-facts tbody tr.twm-facts__row--added > td.twm-facts__after { color: var(--color-success, #3fb950); }
|
|
6107
|
+
.twm-facts tbody tr.twm-facts__row--removed > td.twm-facts__before { color: var(--color-danger, #c74e4e); }
|
|
6108
|
+
.twm-facts tbody td.twm-facts__empty {
|
|
6109
|
+
padding: 12px 0;
|
|
6110
|
+
color: var(--text-muted, #888);
|
|
6111
|
+
white-space: normal;
|
|
6112
|
+
}
|
|
6113
|
+
/* ══ end RECORD LIST & FACT SHEET ══ */
|
|
6114
|
+
|
|
6115
|
+
/* ══ HELP MODAL ══════════════════════════════════════════════════════
|
|
6116
|
+
*
|
|
6117
|
+
* `HelpModal` (src/help/help_modal.js): a centred dialog on a dimmed overlay,
|
|
6118
|
+
* a sidebar of categories, a search box and the content pane, which shows the
|
|
6119
|
+
* index, a topic, search results or an error. Its classes are `help-`, not
|
|
6120
|
+
* `twm-`, prefixed — they are older than this sheet, and an embedder styles
|
|
6121
|
+
* them by those names. `.help-article` holds the provider's rendered HTML, so
|
|
6122
|
+
* it styles plain elements. Every class the modal sets has a rule here, and
|
|
6123
|
+
* every class a rule here names is one it sets (tests/help_modal_css.test.mjs). */
|
|
6124
|
+
.help-modal-overlay {
|
|
6125
|
+
position: fixed;
|
|
6126
|
+
inset: 0;
|
|
6127
|
+
display: flex;
|
|
6128
|
+
align-items: center;
|
|
6129
|
+
justify-content: center;
|
|
6130
|
+
background: rgba(0, 0, 0, 0.7);
|
|
6131
|
+
backdrop-filter: blur(4px);
|
|
6132
|
+
z-index: var(--z-over-windows);
|
|
6133
|
+
}
|
|
6134
|
+
.help-modal {
|
|
6135
|
+
display: flex;
|
|
6136
|
+
flex-direction: column;
|
|
6137
|
+
width: 90%;
|
|
6138
|
+
max-width: 1000px;
|
|
6139
|
+
height: 80vh;
|
|
6140
|
+
max-height: 700px;
|
|
6141
|
+
background: var(--surface-0);
|
|
6142
|
+
color: var(--text-body);
|
|
6143
|
+
border: 1px solid var(--surface-3);
|
|
6144
|
+
border-radius: var(--radius-lg);
|
|
6145
|
+
box-shadow: var(--shadow-lg);
|
|
6146
|
+
overflow: hidden;
|
|
6147
|
+
user-select: text;
|
|
6148
|
+
}
|
|
6149
|
+
.help-modal__header {
|
|
6150
|
+
display: flex;
|
|
6151
|
+
align-items: center;
|
|
6152
|
+
justify-content: space-between;
|
|
6153
|
+
padding: var(--space-lg) var(--space-xl);
|
|
6154
|
+
background: var(--surface-1);
|
|
6155
|
+
border-bottom: 1px solid var(--surface-3);
|
|
6156
|
+
}
|
|
6157
|
+
.help-modal__title {
|
|
6158
|
+
display: flex;
|
|
6159
|
+
align-items: center;
|
|
6160
|
+
gap: var(--space-md);
|
|
6161
|
+
font-size: var(--font-size-xl);
|
|
6162
|
+
font-weight: var(--font-weight-semibold);
|
|
6163
|
+
color: var(--text-primary);
|
|
6164
|
+
}
|
|
6165
|
+
.help-modal__title .material-symbols-outlined {
|
|
6166
|
+
font-size: 20px;
|
|
6167
|
+
color: var(--accent-bright);
|
|
6168
|
+
}
|
|
6169
|
+
.help-modal__close {
|
|
6170
|
+
display: flex;
|
|
6171
|
+
align-items: center;
|
|
6172
|
+
justify-content: center;
|
|
6173
|
+
padding: var(--space-xs);
|
|
6174
|
+
background: transparent;
|
|
6175
|
+
border: none;
|
|
6176
|
+
border-radius: var(--radius-sm);
|
|
6177
|
+
color: var(--text-muted);
|
|
6178
|
+
cursor: pointer;
|
|
6179
|
+
}
|
|
6180
|
+
.help-modal__close:hover {
|
|
6181
|
+
background: var(--state-active);
|
|
6182
|
+
color: var(--text-primary);
|
|
6183
|
+
}
|
|
6184
|
+
.help-modal__search {
|
|
6185
|
+
display: flex;
|
|
6186
|
+
align-items: center;
|
|
6187
|
+
gap: var(--space-md);
|
|
6188
|
+
padding: var(--space-md) var(--space-xl);
|
|
6189
|
+
background: var(--surface-1);
|
|
6190
|
+
border-bottom: 1px solid var(--surface-3);
|
|
6191
|
+
}
|
|
6192
|
+
.help-modal__search .material-symbols-outlined {
|
|
6193
|
+
font-size: 18px;
|
|
6194
|
+
color: var(--text-dim);
|
|
6195
|
+
}
|
|
6196
|
+
.help-search-input {
|
|
6197
|
+
flex: 1;
|
|
6198
|
+
padding: var(--space-sm) 10px;
|
|
6199
|
+
background: var(--surface-0);
|
|
6200
|
+
border: 1px solid var(--surface-3);
|
|
6201
|
+
border-radius: var(--radius-sm);
|
|
6202
|
+
color: var(--text-body);
|
|
6203
|
+
font-size: var(--font-size-md);
|
|
6204
|
+
outline: none;
|
|
6205
|
+
}
|
|
6206
|
+
.help-search-input:focus { border-color: var(--accent-bright); }
|
|
6207
|
+
.help-search-input::placeholder { color: var(--text-dim); }
|
|
6208
|
+
.help-modal__body {
|
|
6209
|
+
display: flex;
|
|
6210
|
+
flex: 1;
|
|
6211
|
+
min-height: 0;
|
|
6212
|
+
overflow: hidden;
|
|
6213
|
+
}
|
|
6214
|
+
.help-modal__sidebar {
|
|
6215
|
+
flex: 0 0 220px;
|
|
6216
|
+
padding: var(--space-md) 0;
|
|
6217
|
+
background: var(--surface-1);
|
|
6218
|
+
border-right: 1px solid var(--surface-3);
|
|
6219
|
+
overflow-y: auto;
|
|
6220
|
+
}
|
|
6221
|
+
.help-sidebar__categories {
|
|
6222
|
+
display: flex;
|
|
6223
|
+
flex-direction: column;
|
|
6224
|
+
}
|
|
6225
|
+
.help-category { margin-bottom: var(--space-xs); }
|
|
6226
|
+
.help-category__header {
|
|
6227
|
+
display: flex;
|
|
6228
|
+
align-items: center;
|
|
6229
|
+
gap: var(--space-md);
|
|
6230
|
+
padding: var(--space-md) var(--space-lg);
|
|
6231
|
+
color: var(--text-muted);
|
|
6232
|
+
font-size: var(--font-size-sm);
|
|
6233
|
+
font-weight: var(--font-weight-semibold);
|
|
6234
|
+
text-transform: uppercase;
|
|
6235
|
+
letter-spacing: 0.5px;
|
|
6236
|
+
cursor: pointer;
|
|
6237
|
+
user-select: none;
|
|
6238
|
+
}
|
|
6239
|
+
.help-category__header:hover { color: var(--text-secondary); }
|
|
6240
|
+
.help-category__header .material-symbols-outlined { font-size: 16px; }
|
|
6241
|
+
.help-category__topics {
|
|
6242
|
+
list-style: none;
|
|
6243
|
+
margin: 0;
|
|
6244
|
+
padding: 0;
|
|
6245
|
+
}
|
|
6246
|
+
.help-category.collapsed .help-category__topics { display: none; }
|
|
6247
|
+
.help-topic-item {
|
|
6248
|
+
padding: var(--space-sm) var(--space-lg) var(--space-sm) 36px;
|
|
6249
|
+
border-left: 2px solid transparent;
|
|
6250
|
+
color: var(--text-secondary);
|
|
6251
|
+
font-size: var(--font-size-md);
|
|
6252
|
+
cursor: pointer;
|
|
6253
|
+
}
|
|
6254
|
+
.help-topic-item:hover {
|
|
6255
|
+
background: var(--state-hover);
|
|
6256
|
+
color: var(--text-primary);
|
|
6257
|
+
}
|
|
6258
|
+
.help-topic-item.active {
|
|
6259
|
+
background: var(--state-selected);
|
|
6260
|
+
border-left-color: var(--accent-bright);
|
|
6261
|
+
color: var(--text-bright);
|
|
6262
|
+
}
|
|
6263
|
+
.help-modal__content {
|
|
6264
|
+
flex: 1;
|
|
6265
|
+
min-width: 0;
|
|
6266
|
+
padding: 20px var(--space-2xl);
|
|
6267
|
+
background: var(--surface-0);
|
|
6268
|
+
overflow-y: auto;
|
|
6269
|
+
}
|
|
6270
|
+
.help-content__loading,
|
|
6271
|
+
.help-content__error {
|
|
6272
|
+
display: flex;
|
|
6273
|
+
flex-direction: column;
|
|
6274
|
+
align-items: center;
|
|
6275
|
+
justify-content: center;
|
|
6276
|
+
gap: var(--space-lg);
|
|
6277
|
+
height: 200px;
|
|
6278
|
+
color: var(--text-muted);
|
|
6279
|
+
font-size: var(--font-size-lg);
|
|
6280
|
+
}
|
|
6281
|
+
.help-content__error { color: var(--color-danger-hover); }
|
|
6282
|
+
.help-content__error .material-symbols-outlined {
|
|
6283
|
+
font-size: 48px;
|
|
6284
|
+
opacity: 0.5;
|
|
6285
|
+
}
|
|
6286
|
+
.help-content__article { max-width: 860px; }
|
|
6287
|
+
.help-content__breadcrumb {
|
|
6288
|
+
display: flex;
|
|
6289
|
+
align-items: center;
|
|
6290
|
+
gap: var(--space-md);
|
|
6291
|
+
margin-bottom: var(--space-xl);
|
|
6292
|
+
padding-bottom: var(--space-lg);
|
|
6293
|
+
border-bottom: 1px solid var(--surface-3);
|
|
6294
|
+
}
|
|
6295
|
+
.help-breadcrumb__home {
|
|
6296
|
+
display: flex;
|
|
6297
|
+
align-items: center;
|
|
6298
|
+
color: var(--text-muted);
|
|
6299
|
+
text-decoration: none;
|
|
6300
|
+
}
|
|
6301
|
+
.help-breadcrumb__home:hover { color: var(--accent-bright); }
|
|
6302
|
+
.help-breadcrumb__home .material-symbols-outlined { font-size: 18px; }
|
|
6303
|
+
.help-breadcrumb__separator { color: var(--text-dim); }
|
|
6304
|
+
.help-breadcrumb__title {
|
|
6305
|
+
color: var(--text-secondary);
|
|
6306
|
+
font-size: var(--font-size-md);
|
|
6307
|
+
}
|
|
6308
|
+
/* A topic's table of contents (a `createDocumentOutline`), between the
|
|
6309
|
+
* breadcrumb and the article; drawn only for two headings or more. */
|
|
6310
|
+
.help-content__toc {
|
|
6311
|
+
margin-bottom: var(--space-xl);
|
|
6312
|
+
padding: var(--space-md) 0;
|
|
6313
|
+
border-left: 2px solid var(--surface-3);
|
|
6314
|
+
font-size: var(--font-size-md);
|
|
6315
|
+
}
|
|
6316
|
+
.help-content__toc[hidden] { display: none; }
|
|
6317
|
+
.help-index h1 {
|
|
6318
|
+
margin: 0 0 var(--space-md);
|
|
6319
|
+
color: var(--text-primary);
|
|
6320
|
+
font-size: 24px;
|
|
6321
|
+
}
|
|
6322
|
+
.help-index > p {
|
|
6323
|
+
margin-bottom: var(--space-2xl);
|
|
6324
|
+
color: var(--text-muted);
|
|
6325
|
+
}
|
|
6326
|
+
.help-index__grid {
|
|
6327
|
+
display: grid;
|
|
6328
|
+
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
|
|
6329
|
+
gap: var(--space-xl);
|
|
6330
|
+
}
|
|
6331
|
+
.help-index__category {
|
|
6332
|
+
padding: var(--space-lg);
|
|
6333
|
+
background: var(--surface-1);
|
|
6334
|
+
border: 1px solid var(--surface-3);
|
|
6335
|
+
border-radius: var(--radius-md);
|
|
6336
|
+
}
|
|
6337
|
+
.help-index__category:hover { border-color: var(--accent-bright); }
|
|
6338
|
+
.help-index__category-header {
|
|
6339
|
+
display: flex;
|
|
6340
|
+
align-items: center;
|
|
6341
|
+
gap: var(--space-md);
|
|
6342
|
+
margin-bottom: var(--space-md);
|
|
6343
|
+
color: var(--accent-bright);
|
|
6344
|
+
font-weight: var(--font-weight-semibold);
|
|
6345
|
+
}
|
|
6346
|
+
.help-index__category-header .material-symbols-outlined { font-size: 18px; }
|
|
6347
|
+
.help-index__topics {
|
|
6348
|
+
list-style: none;
|
|
6349
|
+
margin: 0;
|
|
6350
|
+
padding: 0;
|
|
6351
|
+
}
|
|
6352
|
+
.help-index__topic,
|
|
6353
|
+
.help-index__more {
|
|
6354
|
+
padding: var(--space-xs) 0;
|
|
6355
|
+
color: var(--text-secondary);
|
|
6356
|
+
font-size: var(--font-size-md);
|
|
6357
|
+
}
|
|
6358
|
+
.help-index__topic { cursor: pointer; }
|
|
6359
|
+
.help-index__topic:hover { color: var(--text-primary); }
|
|
6360
|
+
.help-index__more {
|
|
6361
|
+
color: var(--text-dim);
|
|
6362
|
+
font-size: var(--font-size-sm);
|
|
6363
|
+
font-style: italic;
|
|
6364
|
+
}
|
|
6365
|
+
.help-search-results h2 {
|
|
6366
|
+
margin: 0 0 var(--space-md);
|
|
6367
|
+
color: var(--text-primary);
|
|
6368
|
+
font-size: var(--font-size-2xl);
|
|
6369
|
+
}
|
|
6370
|
+
.help-search-count {
|
|
6371
|
+
margin-bottom: var(--space-xl);
|
|
6372
|
+
color: var(--text-muted);
|
|
6373
|
+
font-size: var(--font-size-md);
|
|
6374
|
+
}
|
|
6375
|
+
.help-search-empty {
|
|
6376
|
+
color: var(--text-muted);
|
|
6377
|
+
font-style: italic;
|
|
6378
|
+
}
|
|
6379
|
+
.help-search-list {
|
|
6380
|
+
list-style: none;
|
|
6381
|
+
margin: 0;
|
|
6382
|
+
padding: 0;
|
|
6383
|
+
}
|
|
6384
|
+
.help-search-item {
|
|
6385
|
+
display: flex;
|
|
6386
|
+
justify-content: space-between;
|
|
6387
|
+
align-items: center;
|
|
6388
|
+
gap: var(--space-lg);
|
|
6389
|
+
margin-bottom: var(--space-md);
|
|
6390
|
+
padding: 10px var(--space-lg);
|
|
6391
|
+
background: var(--surface-1);
|
|
6392
|
+
border: 1px solid var(--surface-3);
|
|
6393
|
+
border-radius: var(--radius-sm);
|
|
6394
|
+
cursor: pointer;
|
|
6395
|
+
}
|
|
6396
|
+
.help-search-item:hover { border-color: var(--accent-bright); }
|
|
6397
|
+
.help-search-item__title {
|
|
6398
|
+
color: var(--text-primary);
|
|
6399
|
+
font-size: var(--font-size-lg);
|
|
6400
|
+
}
|
|
6401
|
+
.help-search-item__category {
|
|
6402
|
+
color: var(--text-dim);
|
|
6403
|
+
font-size: var(--font-size-sm);
|
|
6404
|
+
}
|
|
6405
|
+
.help-article {
|
|
6406
|
+
color: var(--text-body);
|
|
6407
|
+
font-size: var(--font-size-lg);
|
|
6408
|
+
line-height: 1.6;
|
|
6409
|
+
}
|
|
6410
|
+
.help-article h1,
|
|
6411
|
+
.help-article h2,
|
|
6412
|
+
.help-article h3 { color: var(--text-primary); }
|
|
6413
|
+
.help-article h1 {
|
|
6414
|
+
margin: 0 0 var(--space-xl);
|
|
6415
|
+
padding-bottom: var(--space-md);
|
|
6416
|
+
border-bottom: 1px solid var(--surface-3);
|
|
6417
|
+
font-size: 24px;
|
|
6418
|
+
}
|
|
6419
|
+
.help-article h2 { margin: var(--space-2xl) 0 var(--space-lg); font-size: 20px; }
|
|
6420
|
+
.help-article h3 { margin: 20px 0 var(--space-md); font-size: var(--font-size-xl); }
|
|
6421
|
+
.help-article h4,
|
|
6422
|
+
.help-article h5,
|
|
6423
|
+
.help-article h6 {
|
|
6424
|
+
margin: var(--space-xl) 0 var(--space-md);
|
|
6425
|
+
color: var(--text-secondary);
|
|
6426
|
+
}
|
|
6427
|
+
.help-article p { margin: 0 0 var(--space-lg); }
|
|
6428
|
+
.help-article a { color: var(--accent-bright); text-decoration: none; }
|
|
6429
|
+
.help-article a:hover { text-decoration: underline; }
|
|
6430
|
+
.help-article strong { color: var(--text-primary); font-weight: var(--font-weight-semibold); }
|
|
6431
|
+
.help-article em { font-style: italic; }
|
|
6432
|
+
.help-article code {
|
|
6433
|
+
padding: 2px 6px;
|
|
6434
|
+
background: var(--surface-2);
|
|
6435
|
+
border-radius: 3px;
|
|
6436
|
+
font-family: var(--font-family-mono);
|
|
6437
|
+
font-size: var(--font-size-md);
|
|
6438
|
+
}
|
|
6439
|
+
.help-article pre {
|
|
6440
|
+
margin: 0 0 var(--space-xl);
|
|
6441
|
+
padding: var(--space-lg) var(--space-xl);
|
|
6442
|
+
background: var(--surface-well);
|
|
6443
|
+
border: 1px solid var(--surface-3);
|
|
6444
|
+
border-radius: var(--radius-sm);
|
|
6445
|
+
overflow-x: auto;
|
|
6446
|
+
}
|
|
6447
|
+
.help-article pre code { padding: 0; background: transparent; }
|
|
6448
|
+
.help-article blockquote {
|
|
6449
|
+
margin: 0 0 var(--space-lg);
|
|
6450
|
+
padding: var(--space-md) var(--space-xl);
|
|
6451
|
+
background: var(--state-selected);
|
|
6452
|
+
border-left: 3px solid var(--accent-bright);
|
|
6453
|
+
color: var(--text-secondary);
|
|
6454
|
+
}
|
|
6455
|
+
.help-article hr {
|
|
6456
|
+
margin: var(--space-2xl) 0;
|
|
6457
|
+
border: none;
|
|
6458
|
+
border-top: 1px solid var(--surface-3);
|
|
6459
|
+
}
|
|
6460
|
+
.help-article img {
|
|
6461
|
+
max-width: 100%;
|
|
6462
|
+
margin: var(--space-lg) 0;
|
|
6463
|
+
border-radius: var(--radius-sm);
|
|
6464
|
+
}
|
|
6465
|
+
.help-article table {
|
|
6466
|
+
width: 100%;
|
|
6467
|
+
margin: var(--space-xl) 0;
|
|
6468
|
+
border-collapse: collapse;
|
|
6469
|
+
font-size: var(--font-size-md);
|
|
6470
|
+
}
|
|
6471
|
+
.help-article th,
|
|
6472
|
+
.help-article td {
|
|
6473
|
+
padding: var(--space-md) var(--space-lg);
|
|
6474
|
+
border: 1px solid var(--surface-3);
|
|
6475
|
+
text-align: left;
|
|
6476
|
+
}
|
|
6477
|
+
.help-article th {
|
|
6478
|
+
background: var(--surface-2);
|
|
6479
|
+
color: var(--text-primary);
|
|
6480
|
+
font-weight: var(--font-weight-semibold);
|
|
6481
|
+
}
|
|
6482
|
+
.help-article tr:nth-child(even) { background: rgba(255, 255, 255, 0.02); }
|
|
6483
|
+
.help-article ul,
|
|
6484
|
+
.help-article ol {
|
|
6485
|
+
margin: var(--space-md) 0 var(--space-xl);
|
|
6486
|
+
padding-left: var(--space-2xl);
|
|
6487
|
+
}
|
|
6488
|
+
.help-article li { margin-bottom: var(--space-xs); line-height: 1.5; }
|
|
6489
|
+
.help-article li p { margin: 0; }
|
|
6490
|
+
.help-article li > ul,
|
|
6491
|
+
.help-article li > ol { margin: var(--space-xs) 0; }
|
|
6492
|
+
@media (max-width: 600px) {
|
|
6493
|
+
.help-modal { width: 95%; height: 90vh; }
|
|
6494
|
+
.help-modal__sidebar { display: none; }
|
|
6495
|
+
.help-modal__content { padding: var(--space-xl); }
|
|
6496
|
+
}
|
|
6497
|
+
/* ══ end HELP MODAL ══ */
|
|
6498
|
+
|
|
6499
|
+
/* ══ MENU BAR ════════════════════════════════════════════════════════
|
|
6500
|
+
*
|
|
6501
|
+
* `MenuBar` (src/ui/components/menu_bar.js, STORY-0030): a row of titles,
|
|
6502
|
+
* each opening a menu that may fly out submenus. Not `.twm-menu-bar`, which
|
|
6503
|
+
* is the older strip of 25px icon buttons and keeps its meaning. A menu is
|
|
6504
|
+
* `position: fixed` (the JS places it), so a bar inside a clipped chrome strip
|
|
6505
|
+
* still drops its menus over the page. Same surface, border and shadow as
|
|
6506
|
+
* `.twm-context-menu`: two menus that look different read as two systems.
|
|
6507
|
+
* tests/menu_bar_css.test.mjs holds every class the bar sets to a rule here,
|
|
6508
|
+
* both ways, and base.css to the same text. */
|
|
6509
|
+
.twm-menubar {
|
|
6510
|
+
display: flex;
|
|
6511
|
+
align-items: stretch;
|
|
6512
|
+
gap: 1px;
|
|
6513
|
+
min-height: 24px;
|
|
6514
|
+
font-size: var(--font-size-md);
|
|
6515
|
+
color: var(--text-body);
|
|
6516
|
+
user-select: none;
|
|
6517
|
+
}
|
|
6518
|
+
.twm-menubar__entry {
|
|
6519
|
+
position: relative;
|
|
6520
|
+
display: flex;
|
|
6521
|
+
}
|
|
6522
|
+
.twm-menubar__title {
|
|
6523
|
+
appearance: none;
|
|
6524
|
+
background: none;
|
|
6525
|
+
border: 0;
|
|
6526
|
+
border-radius: var(--radius-sm);
|
|
6527
|
+
color: inherit;
|
|
6528
|
+
font: inherit;
|
|
6529
|
+
padding: var(--space-xxs) var(--space-md);
|
|
6530
|
+
cursor: default;
|
|
6531
|
+
}
|
|
6532
|
+
.twm-menubar__title:hover,
|
|
6533
|
+
.twm-menubar__title:focus-visible,
|
|
6534
|
+
.twm-menubar__title[aria-expanded="true"] {
|
|
6535
|
+
background: var(--state-active);
|
|
6536
|
+
color: var(--text-bright);
|
|
6537
|
+
outline: none;
|
|
6538
|
+
}
|
|
6539
|
+
.twm-menubar__menu {
|
|
6540
|
+
position: fixed;
|
|
6541
|
+
z-index: var(--z-over-windows);
|
|
6542
|
+
display: flex;
|
|
6543
|
+
flex-direction: column;
|
|
6544
|
+
min-width: 200px;
|
|
6545
|
+
max-height: calc(100vh - 8px);
|
|
6546
|
+
overflow-y: auto;
|
|
6547
|
+
padding: var(--space-xs) 0;
|
|
6548
|
+
background: var(--surface-0);
|
|
6549
|
+
color: var(--text-body);
|
|
6550
|
+
border: 1px solid var(--surface-3);
|
|
6551
|
+
border-radius: var(--radius-md);
|
|
6552
|
+
box-shadow: 0 6px 24px rgba(0, 0, 0, 0.45);
|
|
6553
|
+
}
|
|
6554
|
+
.twm-menubar__cell {
|
|
6555
|
+
display: flex;
|
|
6556
|
+
}
|
|
6557
|
+
.twm-menubar__item {
|
|
6558
|
+
appearance: none;
|
|
6559
|
+
background: none;
|
|
6560
|
+
border: 0;
|
|
6561
|
+
width: 100%;
|
|
6562
|
+
text-align: left;
|
|
6563
|
+
color: inherit;
|
|
6564
|
+
font: inherit;
|
|
6565
|
+
display: flex;
|
|
6566
|
+
align-items: center;
|
|
6567
|
+
gap: var(--space-md);
|
|
6568
|
+
padding: var(--space-xs) var(--space-lg) var(--space-xs) var(--space-xs);
|
|
6569
|
+
cursor: default;
|
|
6570
|
+
white-space: nowrap;
|
|
6571
|
+
}
|
|
6572
|
+
.twm-menubar__item:focus,
|
|
6573
|
+
.twm-menubar__item:hover:not(.twm-menubar__item--disabled),
|
|
6574
|
+
.twm-menubar__item[aria-expanded="true"] {
|
|
6575
|
+
background: var(--state-selected);
|
|
6576
|
+
outline: none;
|
|
6577
|
+
}
|
|
6578
|
+
.twm-menubar__item--submenu {
|
|
6579
|
+
padding-right: var(--space-md);
|
|
6580
|
+
}
|
|
6581
|
+
.twm-menubar__item--disabled {
|
|
6582
|
+
opacity: 0.4;
|
|
6583
|
+
color: var(--text-muted);
|
|
6584
|
+
}
|
|
6585
|
+
.twm-menubar__check {
|
|
6586
|
+
flex: 0 0 16px;
|
|
6587
|
+
text-align: center;
|
|
6588
|
+
}
|
|
6589
|
+
.twm-menubar__item--check[aria-checked="true"] .twm-menubar__check::before { content: "\2713"; }
|
|
6590
|
+
.twm-menubar__item--radio[aria-checked="true"] .twm-menubar__check::before { content: "\2022"; }
|
|
6591
|
+
.twm-menubar__label {
|
|
6592
|
+
flex: 1 1 auto;
|
|
6593
|
+
}
|
|
6594
|
+
.twm-menubar__shortcut {
|
|
6595
|
+
margin-left: var(--space-2xl);
|
|
6596
|
+
color: var(--text-muted);
|
|
6597
|
+
font-size: var(--font-size-sm);
|
|
6598
|
+
}
|
|
6599
|
+
.twm-menubar__arrow::before {
|
|
6600
|
+
content: "\25B8";
|
|
6601
|
+
color: var(--text-muted);
|
|
6602
|
+
}
|
|
6603
|
+
.twm-menubar__separator {
|
|
6604
|
+
height: 1px;
|
|
6605
|
+
margin: var(--space-xs) var(--space-md);
|
|
6606
|
+
background: var(--surface-3);
|
|
6607
|
+
}
|
|
6608
|
+
/* ══ end MENU BAR ══ */
|
|
6609
|
+
|
|
6610
|
+
/* ══ TOGGLE ══════════════════════════════════════════════════════════
|
|
6611
|
+
* ToggleField: a track and a knob drawn over a real checkbox with
|
|
6612
|
+
* role="switch". The input sits on top of the track, transparent, so the
|
|
6613
|
+
* pointer and the keyboard reach a native control. Tokens only: swap
|
|
6614
|
+
* tokens.css and the switch follows.
|
|
6615
|
+
*/
|
|
6616
|
+
.twm-toggle {
|
|
6617
|
+
--twm-toggle-w: 34px;
|
|
6618
|
+
--twm-toggle-h: 18px;
|
|
6619
|
+
--twm-toggle-pad: 2px;
|
|
6620
|
+
display: inline-flex;
|
|
6621
|
+
align-items: center;
|
|
6622
|
+
gap: var(--space-sm);
|
|
6623
|
+
color: var(--text-body);
|
|
6624
|
+
font-size: var(--font-size-sm);
|
|
6625
|
+
line-height: var(--line-height-tight);
|
|
6626
|
+
cursor: pointer;
|
|
6627
|
+
user-select: none;
|
|
6628
|
+
vertical-align: middle;
|
|
6629
|
+
}
|
|
6630
|
+
.twm-toggle--compact {
|
|
6631
|
+
--twm-toggle-w: 26px;
|
|
6632
|
+
--twm-toggle-h: 14px;
|
|
6633
|
+
gap: var(--space-xs);
|
|
6634
|
+
font-size: var(--font-size-xs);
|
|
6635
|
+
}
|
|
6636
|
+
.twm-toggle__control {
|
|
6637
|
+
position: relative;
|
|
6638
|
+
display: inline-flex;
|
|
6639
|
+
flex: none;
|
|
6640
|
+
width: var(--twm-toggle-w);
|
|
6641
|
+
height: var(--twm-toggle-h);
|
|
6642
|
+
}
|
|
6643
|
+
.twm-toggle__input {
|
|
6644
|
+
position: absolute;
|
|
6645
|
+
inset: 0;
|
|
6646
|
+
width: 100%;
|
|
6647
|
+
height: 100%;
|
|
6648
|
+
margin: 0;
|
|
6649
|
+
opacity: 0;
|
|
6650
|
+
cursor: inherit;
|
|
6651
|
+
z-index: 1;
|
|
6652
|
+
}
|
|
6653
|
+
.twm-toggle__track {
|
|
6654
|
+
position: relative;
|
|
6655
|
+
display: block;
|
|
6656
|
+
width: 100%;
|
|
6657
|
+
height: 100%;
|
|
6658
|
+
box-sizing: border-box;
|
|
6659
|
+
border: 1px solid var(--border-strong);
|
|
6660
|
+
border-radius: var(--radius-pill);
|
|
6661
|
+
background: var(--surface-3);
|
|
6662
|
+
transition: background-color var(--transition-fast), border-color var(--transition-fast);
|
|
6663
|
+
}
|
|
6664
|
+
.twm-toggle__knob {
|
|
6665
|
+
position: absolute;
|
|
6666
|
+
top: var(--twm-toggle-pad);
|
|
6667
|
+
left: var(--twm-toggle-pad);
|
|
6668
|
+
width: calc(var(--twm-toggle-h) - 2 * var(--twm-toggle-pad) - 2px);
|
|
6669
|
+
height: calc(var(--twm-toggle-h) - 2 * var(--twm-toggle-pad) - 2px);
|
|
6670
|
+
border-radius: var(--radius-circle);
|
|
6671
|
+
background: var(--text-muted);
|
|
6672
|
+
box-shadow: var(--shadow-sm);
|
|
6673
|
+
transition: transform var(--transition-fast), background-color var(--transition-fast);
|
|
6674
|
+
}
|
|
6675
|
+
.twm-toggle__input:checked + .twm-toggle__track {
|
|
6676
|
+
background: var(--accent);
|
|
6677
|
+
border-color: var(--accent);
|
|
6678
|
+
}
|
|
6679
|
+
.twm-toggle__input:checked + .twm-toggle__track .twm-toggle__knob {
|
|
6680
|
+
transform: translateX(calc(var(--twm-toggle-w) - var(--twm-toggle-h)));
|
|
6681
|
+
background: var(--text-bright);
|
|
6682
|
+
}
|
|
6683
|
+
.twm-toggle:hover .twm-toggle__input:not(:disabled) + .twm-toggle__track {
|
|
6684
|
+
border-color: var(--accent-hover);
|
|
6685
|
+
}
|
|
6686
|
+
.twm-toggle__input:focus-visible + .twm-toggle__track {
|
|
6687
|
+
outline: 2px solid var(--accent-bright);
|
|
6688
|
+
outline-offset: 2px;
|
|
6689
|
+
}
|
|
6690
|
+
.twm-toggle__state {
|
|
6691
|
+
min-width: 2.5em;
|
|
6692
|
+
color: var(--text-muted);
|
|
6693
|
+
}
|
|
6694
|
+
.twm-toggle__label {
|
|
6695
|
+
color: var(--text-body);
|
|
6696
|
+
}
|
|
6697
|
+
.twm-toggle--disabled {
|
|
6698
|
+
cursor: not-allowed;
|
|
6699
|
+
opacity: 0.5;
|
|
6700
|
+
}
|
|
6701
|
+
.twm-modal__toggle {
|
|
6702
|
+
display: flex;
|
|
6703
|
+
align-items: center;
|
|
6704
|
+
min-height: var(--ea-row-h);
|
|
6705
|
+
}
|
|
6706
|
+
/* ══ end TOGGLE ══ */
|
|
6707
|
+
|
|
6708
|
+
/* ══ DOCUMENT OUTLINE (0.17.0) ═══════════════════════════════════════
|
|
6709
|
+
* `createDocumentOutline` (src/ui/components/document_outline.js). No height
|
|
6710
|
+
* of its own: the host that holds it scrolls, if anything does. */
|
|
6711
|
+
.twm-doc-outline { display: block; min-width: 0; }
|
|
6712
|
+
.twm-doc-outline__items {
|
|
6713
|
+
list-style: none;
|
|
6714
|
+
margin: 0;
|
|
6715
|
+
padding: 2px 0;
|
|
6716
|
+
}
|
|
6717
|
+
.twm-doc-outline__item { margin: 0; padding: 0; min-width: 0; }
|
|
6718
|
+
/* One step of indentation per level below the first, set inline per item as
|
|
6719
|
+
* `--twm-doc-outline-depth` (0 for depth 1). */
|
|
6720
|
+
.twm-doc-outline__link {
|
|
6721
|
+
display: flex;
|
|
6722
|
+
align-items: baseline;
|
|
6723
|
+
gap: 6px;
|
|
6724
|
+
width: 100%;
|
|
6725
|
+
min-width: 0;
|
|
6726
|
+
margin: 0;
|
|
6727
|
+
padding: 3px 8px 3px calc(8px + var(--twm-doc-outline-depth, 0) * var(--twm-doc-outline-indent, 12px));
|
|
6728
|
+
border: none;
|
|
6729
|
+
border-left: 2px solid transparent;
|
|
6730
|
+
background: transparent;
|
|
6731
|
+
color: var(--text-secondary, #cccccc);
|
|
6732
|
+
font: inherit;
|
|
6733
|
+
text-align: left;
|
|
6734
|
+
cursor: pointer;
|
|
6735
|
+
}
|
|
6736
|
+
.twm-doc-outline__link:hover { background: var(--state-hover, rgba(255, 255, 255, 0.05)); color: var(--text-primary, #e0e0e0); }
|
|
6737
|
+
.twm-doc-outline__link:focus-visible { outline: 1px solid var(--accent-bright, #007acc); outline-offset: -1px; }
|
|
6738
|
+
.twm-doc-outline__item--level-1 > .twm-doc-outline__link { color: var(--text-primary, #e0e0e0); }
|
|
6739
|
+
.twm-doc-outline__number {
|
|
6740
|
+
flex: 0 0 auto;
|
|
6741
|
+
color: var(--text-muted, #888888);
|
|
6742
|
+
font-variant-numeric: tabular-nums;
|
|
6743
|
+
}
|
|
6744
|
+
.twm-doc-outline__label {
|
|
6745
|
+
flex: 1 1 auto;
|
|
6746
|
+
min-width: 0;
|
|
6747
|
+
overflow: hidden;
|
|
6748
|
+
text-overflow: ellipsis;
|
|
6749
|
+
white-space: nowrap;
|
|
6750
|
+
}
|
|
6751
|
+
.twm-doc-outline__item.twm-doc-outline__item--active > .twm-doc-outline__link {
|
|
6752
|
+
border-left-color: var(--accent-bright, #007acc);
|
|
6753
|
+
background: rgba(0, 122, 204, 0.15);
|
|
6754
|
+
color: var(--text-primary, #e0e0e0);
|
|
6755
|
+
}
|
|
6756
|
+
/* Listed, but nothing in the document answers to it. */
|
|
6757
|
+
.twm-doc-outline__item--unresolved > .twm-doc-outline__link { opacity: 0.6; }
|
|
6758
|
+
.twm-doc-outline__empty {
|
|
6759
|
+
margin: 0;
|
|
6760
|
+
padding: 8px;
|
|
6761
|
+
color: var(--text-muted, #888888);
|
|
6762
|
+
font-style: italic;
|
|
6763
|
+
}
|
|
6764
|
+
/* ══ end DOCUMENT OUTLINE ══ */
|
|
6765
|
+
|
|
6766
|
+
/* ══ TAG INPUT (0.17.0) ═══════════════════════════════════════════════
|
|
6767
|
+
* `createTagInput` (src/ui/components/tag_input.js): removable chips and a
|
|
6768
|
+
* text box on one wrapping line. No height of its own. */
|
|
6769
|
+
.twm-tag-input {
|
|
6770
|
+
display: flex;
|
|
6771
|
+
flex-wrap: wrap;
|
|
6772
|
+
align-items: center;
|
|
6773
|
+
gap: var(--space-xs, 4px);
|
|
6774
|
+
min-width: 0;
|
|
6775
|
+
padding: 3px var(--space-xs, 4px);
|
|
6776
|
+
background: var(--surface-3, #3c3c3c);
|
|
6777
|
+
border: 1px solid var(--border-strong, #383838);
|
|
6778
|
+
border-radius: var(--radius-sm, 4px);
|
|
6779
|
+
cursor: text;
|
|
6780
|
+
}
|
|
6781
|
+
.twm-tag-input:focus-within { border-color: var(--accent-bright, #007acc); }
|
|
6782
|
+
.twm-tag-input--readonly {
|
|
6783
|
+
background: transparent;
|
|
6784
|
+
border-color: transparent;
|
|
6785
|
+
padding-left: 0;
|
|
6786
|
+
padding-right: 0;
|
|
6787
|
+
cursor: default;
|
|
6788
|
+
}
|
|
6789
|
+
.twm-tag-input__chips {
|
|
6790
|
+
display: contents;
|
|
6791
|
+
list-style: none;
|
|
6792
|
+
margin: 0;
|
|
6793
|
+
padding: 0;
|
|
6794
|
+
}
|
|
6795
|
+
.twm-tag-input__chip {
|
|
6796
|
+
display: inline-flex;
|
|
6797
|
+
align-items: center;
|
|
6798
|
+
gap: 2px;
|
|
6799
|
+
max-width: 100%;
|
|
6800
|
+
min-width: 0;
|
|
6801
|
+
padding: 1px var(--space-xs, 4px) 1px var(--space-sm, 6px);
|
|
6802
|
+
background: var(--surface-2, #2d2d2d);
|
|
6803
|
+
border: 1px solid var(--border-strong, #383838);
|
|
6804
|
+
border-radius: var(--radius-pill, 999px);
|
|
6805
|
+
color: var(--text-primary, #e0e0e0);
|
|
6806
|
+
font-size: var(--font-size-sm, 12px);
|
|
6807
|
+
line-height: 18px;
|
|
6808
|
+
}
|
|
6809
|
+
.twm-tag-input--readonly .twm-tag-input__chip { padding-right: var(--space-sm, 6px); }
|
|
6810
|
+
.twm-tag-input__text {
|
|
6811
|
+
min-width: 0;
|
|
6812
|
+
overflow: hidden;
|
|
6813
|
+
text-overflow: ellipsis;
|
|
6814
|
+
white-space: nowrap;
|
|
6815
|
+
}
|
|
6816
|
+
.twm-tag-input__remove {
|
|
6817
|
+
display: inline-flex;
|
|
6818
|
+
align-items: center;
|
|
6819
|
+
justify-content: center;
|
|
6820
|
+
width: 16px;
|
|
6821
|
+
height: 16px;
|
|
6822
|
+
padding: 0;
|
|
6823
|
+
border: none;
|
|
6824
|
+
border-radius: var(--radius-circle, 50%);
|
|
6825
|
+
background: transparent;
|
|
6826
|
+
color: var(--text-muted, #888);
|
|
6827
|
+
font: inherit;
|
|
6828
|
+
line-height: 1;
|
|
6829
|
+
cursor: pointer;
|
|
6830
|
+
}
|
|
6831
|
+
.twm-tag-input__remove:hover,
|
|
6832
|
+
.twm-tag-input__remove:focus-visible {
|
|
6833
|
+
background: var(--state-active, rgba(255, 255, 255, 0.08));
|
|
6834
|
+
color: var(--text-bright, #fff);
|
|
6835
|
+
}
|
|
6836
|
+
.twm-tag-input__input {
|
|
6837
|
+
flex: 1 1 6em;
|
|
6838
|
+
min-width: 4em;
|
|
6839
|
+
padding: 1px 2px;
|
|
6840
|
+
border: none;
|
|
6841
|
+
outline: none;
|
|
6842
|
+
background: transparent;
|
|
6843
|
+
color: var(--text-primary, #e0e0e0);
|
|
6844
|
+
font: inherit;
|
|
6845
|
+
font-size: var(--font-size-sm, 12px);
|
|
6846
|
+
}
|
|
6847
|
+
/* ══ end TAG INPUT ══ */
|
|
6848
|
+
|
|
6849
|
+
/* ══ SECTION STACK ═══════════════════════════════════════════════════════
|
|
6850
|
+
* `createSectionStack` (ui/components/section_stack.js, STORY-0036): titled
|
|
6851
|
+
* sections in a column, built on the tree's `.twm-collapsible-*` primitive.
|
|
6852
|
+
*
|
|
6853
|
+
* THE STACK IS A COLUMN AS TALL AS ITS CONTAINER. A section is as tall as its
|
|
6854
|
+
* content, except the FILL section, which takes what the others leave
|
|
6855
|
+
* (`flex: 1 1 0`) — and only while it is open, so a closed one is a header.
|
|
6856
|
+
* Its body is the one that scrolls: `min-height: 0` on the box and the body is
|
|
6857
|
+
* what lets a flex child shrink below its content, without which a long
|
|
6858
|
+
* conversation grows the section, and the panel, past the window. If the
|
|
6859
|
+
* fixed sections alone outgrow the stack, the stack itself scrolls; the open
|
|
6860
|
+
* fill box then stops at its header's height (`min-height: 26px`, the header
|
|
6861
|
+
* rule's `height`) so its header never lands on the next section's, and only
|
|
6862
|
+
* its body shrinks away.
|
|
6863
|
+
*
|
|
6864
|
+
* `[hidden]` needs its own rule: the box is `display: flex`, and an author
|
|
6865
|
+
* `display` beats the UA's `[hidden] { display: none }`. */
|
|
6866
|
+
.twm-section-stack {
|
|
6867
|
+
display: flex;
|
|
6868
|
+
flex-direction: column;
|
|
6869
|
+
height: 100%;
|
|
6870
|
+
min-height: 0;
|
|
6871
|
+
overflow-x: hidden;
|
|
6872
|
+
overflow-y: auto;
|
|
6873
|
+
}
|
|
6874
|
+
.twm-section-stack > .twm-section-stack__section {
|
|
6875
|
+
display: flex;
|
|
6876
|
+
flex-direction: column;
|
|
6877
|
+
flex: 0 0 auto;
|
|
6878
|
+
min-height: 0;
|
|
6879
|
+
}
|
|
6880
|
+
.twm-section-stack > .twm-section-stack__section[hidden] {
|
|
6881
|
+
display: none;
|
|
6882
|
+
}
|
|
6883
|
+
.twm-section-stack > .twm-section-stack__section--fill.twm-section-stack__section--expanded {
|
|
6884
|
+
flex: 1 1 0;
|
|
6885
|
+
min-height: 26px;
|
|
6886
|
+
}
|
|
6887
|
+
.twm-section-stack__section--fill > .twm-collapsible-content.visible {
|
|
6888
|
+
flex: 1 1 0;
|
|
6889
|
+
min-height: 0;
|
|
6890
|
+
overflow-y: auto;
|
|
6891
|
+
}
|
|
6892
|
+
.twm-section-stack__header {
|
|
6893
|
+
gap: var(--space-xxs);
|
|
6894
|
+
height: 26px;
|
|
6895
|
+
padding: 0 var(--space-xs) 0 0;
|
|
6896
|
+
box-sizing: border-box;
|
|
6897
|
+
flex-shrink: 0;
|
|
6898
|
+
color: var(--text-secondary);
|
|
6899
|
+
}
|
|
6900
|
+
.twm-section-stack__header:hover {
|
|
6901
|
+
background: var(--state-hover);
|
|
6902
|
+
}
|
|
6903
|
+
/* A real button, so Enter and Space toggle without re-implementing them; the
|
|
6904
|
+
* first declarations are the reset that keeps the UA's own button off it. */
|
|
6905
|
+
.twm-section-stack__toggle {
|
|
6906
|
+
appearance: none;
|
|
6907
|
+
background: none;
|
|
6908
|
+
border: 0;
|
|
6909
|
+
color: inherit;
|
|
6910
|
+
font: inherit;
|
|
6911
|
+
text-transform: inherit;
|
|
6912
|
+
text-align: left;
|
|
6913
|
+
cursor: pointer;
|
|
6914
|
+
display: flex;
|
|
6915
|
+
align-items: center;
|
|
6916
|
+
gap: var(--space-xs);
|
|
6917
|
+
flex: 1 1 auto;
|
|
6918
|
+
min-width: 0;
|
|
6919
|
+
height: 100%;
|
|
6920
|
+
padding: 0 0 0 var(--space-xs);
|
|
6921
|
+
}
|
|
6922
|
+
.twm-section-stack__toggle:focus-visible,
|
|
6923
|
+
.twm-section-stack__action:focus-visible {
|
|
6924
|
+
outline: 2px solid var(--accent-bright);
|
|
6925
|
+
outline-offset: -2px;
|
|
5440
6926
|
}
|
|
5441
|
-
|
|
5442
|
-
|
|
5443
|
-
|
|
5444
|
-
|
|
5445
|
-
|
|
5446
|
-
|
|
5447
|
-
|
|
6927
|
+
/* The arrow points down while open (`.twm-collapsible-arrow`) and right while
|
|
6928
|
+
* closed — the class `paint()` sets on it. A fixed, clipped box: without the
|
|
6929
|
+
* icon font the glyph is the word `expand_more`, and that word turned on its
|
|
6930
|
+
* side stood taller than the header and made the whole stack scroll. */
|
|
6931
|
+
.twm-section-stack .twm-collapsible-arrow {
|
|
6932
|
+
flex-shrink: 0;
|
|
6933
|
+
width: 12px;
|
|
6934
|
+
height: 12px;
|
|
6935
|
+
line-height: 12px;
|
|
6936
|
+
overflow: hidden;
|
|
5448
6937
|
}
|
|
5449
|
-
.twm-
|
|
5450
|
-
|
|
5451
|
-
font-size: var(--ea-font-small, 10px);
|
|
5452
|
-
font-weight: 600;
|
|
5453
|
-
letter-spacing: 0.06em;
|
|
5454
|
-
text-transform: uppercase;
|
|
5455
|
-
color: var(--text-dim, #666);
|
|
5456
|
-
white-space: nowrap;
|
|
5457
|
-
border-bottom: 1px solid var(--border-default, #303030);
|
|
5458
|
-
padding: 0 12px 6px 0;
|
|
6938
|
+
.twm-section-stack .twm-collapsible-arrow.collapsed {
|
|
6939
|
+
transform: rotate(-90deg);
|
|
5459
6940
|
}
|
|
5460
|
-
|
|
5461
|
-
|
|
5462
|
-
|
|
5463
|
-
text-align: left;
|
|
5464
|
-
font-weight: normal;
|
|
5465
|
-
border-bottom: 1px solid var(--border-subtle, #2a2a2a);
|
|
5466
|
-
padding: 6px 12px 6px 0;
|
|
5467
|
-
color: var(--text-primary, #e0e0e0);
|
|
5468
|
-
vertical-align: top;
|
|
5469
|
-
white-space: pre-wrap;
|
|
5470
|
-
overflow-wrap: anywhere;
|
|
6941
|
+
.twm-section-stack__icon.material-symbols-outlined {
|
|
6942
|
+
font-size: var(--font-size-md);
|
|
6943
|
+
line-height: 1;
|
|
5471
6944
|
}
|
|
5472
|
-
.twm-
|
|
5473
|
-
|
|
5474
|
-
|
|
5475
|
-
color: var(--text-muted, #888);
|
|
6945
|
+
.twm-section-stack__title {
|
|
6946
|
+
flex: 1 1 auto;
|
|
6947
|
+
min-width: 0;
|
|
5476
6948
|
white-space: nowrap;
|
|
6949
|
+
overflow: hidden;
|
|
6950
|
+
text-overflow: ellipsis;
|
|
5477
6951
|
}
|
|
5478
|
-
.twm-
|
|
5479
|
-
|
|
5480
|
-
|
|
5481
|
-
|
|
5482
|
-
|
|
5483
|
-
.twm-facts.twm-facts--wrap-words tbody th { overflow-wrap: normal; word-break: normal; }
|
|
5484
|
-
.twm-facts.twm-facts--wrap-none tbody td,
|
|
5485
|
-
.twm-facts.twm-facts--wrap-none tbody th { white-space: pre; overflow-wrap: normal; word-break: normal; }
|
|
5486
|
-
.twm-facts.twm-facts--mono tbody td.twm-facts__value,
|
|
5487
|
-
.twm-facts tbody td.twm-facts__mono { font-family: var(--font-family-mono, monospace); font-size: 0.95em; }
|
|
5488
|
-
.twm-facts .twm-facts__num { font-variant-numeric: tabular-nums; white-space: nowrap; }
|
|
5489
|
-
.twm-facts tbody td.twm-facts__null,
|
|
5490
|
-
.twm-facts tbody td.twm-facts__missing { color: var(--text-dim, #666); font-style: italic; }
|
|
5491
|
-
.twm-facts tbody td.twm-facts__arrow {
|
|
5492
|
-
color: var(--text-dim, #666);
|
|
5493
|
-
white-space: nowrap;
|
|
5494
|
-
width: 1%;
|
|
6952
|
+
.twm-section-stack__actions {
|
|
6953
|
+
display: flex;
|
|
6954
|
+
align-items: center;
|
|
6955
|
+
gap: var(--space-xxs);
|
|
6956
|
+
flex-shrink: 0;
|
|
5495
6957
|
}
|
|
5496
|
-
.twm-
|
|
5497
|
-
|
|
5498
|
-
|
|
5499
|
-
|
|
5500
|
-
|
|
5501
|
-
|
|
5502
|
-
|
|
5503
|
-
|
|
5504
|
-
|
|
6958
|
+
.twm-section-stack__action {
|
|
6959
|
+
appearance: none;
|
|
6960
|
+
background: none;
|
|
6961
|
+
border: 0;
|
|
6962
|
+
color: var(--text-muted);
|
|
6963
|
+
cursor: pointer;
|
|
6964
|
+
display: flex;
|
|
6965
|
+
align-items: center;
|
|
6966
|
+
justify-content: center;
|
|
6967
|
+
width: 20px;
|
|
6968
|
+
height: 20px;
|
|
6969
|
+
padding: 0;
|
|
6970
|
+
border-radius: var(--radius-sm);
|
|
5505
6971
|
}
|
|
5506
|
-
|
|
6972
|
+
.twm-section-stack__action:hover {
|
|
6973
|
+
color: var(--text-primary);
|
|
6974
|
+
background: var(--state-active);
|
|
6975
|
+
}
|
|
6976
|
+
.twm-section-stack__action .material-symbols-outlined {
|
|
6977
|
+
font-size: var(--font-size-md);
|
|
6978
|
+
line-height: 1;
|
|
6979
|
+
}
|
|
6980
|
+
/* ══ end SECTION STACK ══ */
|
|
5507
6981
|
|
|
5508
6982
|
/* ══ FLOW · KIT ═══════════════════════════════════════════════════════ */
|
|
5509
6983
|
/* The shared flow-editor kit (36 §3, §3.12): the settings panel and its
|
|
@@ -5731,10 +7205,6 @@ button.twm-about-dialog__btn--close:focus {
|
|
|
5731
7205
|
font-size: var(--font-size-xs);
|
|
5732
7206
|
color: var(--twm-flow-muted);
|
|
5733
7207
|
}
|
|
5734
|
-
.twm-flow-field__kept {
|
|
5735
|
-
font-family: var(--font-family-mono);
|
|
5736
|
-
color: var(--text-secondary);
|
|
5737
|
-
}
|
|
5738
7208
|
.twm-flow-field__refusal {
|
|
5739
7209
|
margin: 0;
|
|
5740
7210
|
padding: 6px 8px;
|
|
@@ -5967,6 +7437,30 @@ button.twm-about-dialog__btn--close:focus {
|
|
|
5967
7437
|
outline-offset: 1px;
|
|
5968
7438
|
}
|
|
5969
7439
|
|
|
7440
|
+
/* ── a column typed by name, while the columns are not known ─────────── */
|
|
7441
|
+
.twm-flow-field__typed {
|
|
7442
|
+
display: flex;
|
|
7443
|
+
flex-direction: column;
|
|
7444
|
+
min-width: 0;
|
|
7445
|
+
}
|
|
7446
|
+
.twm-flow-typedchips:focus-within {
|
|
7447
|
+
border-color: var(--twm-flow-focus);
|
|
7448
|
+
}
|
|
7449
|
+
.twm-flow-input.twm-flow-typedchips__input {
|
|
7450
|
+
flex: 1 1 8em;
|
|
7451
|
+
width: auto;
|
|
7452
|
+
min-width: 6em;
|
|
7453
|
+
height: 18px;
|
|
7454
|
+
padding: 0 2px;
|
|
7455
|
+
border: 0;
|
|
7456
|
+
background: transparent;
|
|
7457
|
+
font-size: var(--font-size-xs);
|
|
7458
|
+
}
|
|
7459
|
+
.twm-flow-input.twm-flow-typedchips__input:focus {
|
|
7460
|
+
outline: none;
|
|
7461
|
+
box-shadow: none;
|
|
7462
|
+
}
|
|
7463
|
+
|
|
5970
7464
|
/* ── choice-cards ───────────────────────────────────────────────────── */
|
|
5971
7465
|
.twm-flow-choices {
|
|
5972
7466
|
display: flex;
|
|
@@ -6475,6 +7969,21 @@ button.twm-about-dialog__btn--close:focus {
|
|
|
6475
7969
|
color: var(--twm-flow-blue-fg);
|
|
6476
7970
|
border-bottom: 1px solid var(--twm-flow-blue-line);
|
|
6477
7971
|
}
|
|
7972
|
+
/* A host policy's offer: its sentence, Accept and Not now, on one line. */
|
|
7973
|
+
.twm-flow-graph__offer {
|
|
7974
|
+
display: flex;
|
|
7975
|
+
flex-wrap: wrap;
|
|
7976
|
+
align-items: center;
|
|
7977
|
+
gap: 6px 8px;
|
|
7978
|
+
padding: 4px 10px;
|
|
7979
|
+
font-size: var(--font-size-xs);
|
|
7980
|
+
background: var(--twm-flow-blue-bg);
|
|
7981
|
+
color: var(--twm-flow-blue-fg);
|
|
7982
|
+
border-bottom: 1px solid var(--twm-flow-blue-line);
|
|
7983
|
+
}
|
|
7984
|
+
.twm-flow-graph__offer-text { margin: 0; flex: 1 1 200px; min-width: 0; line-height: 1.4; }
|
|
7985
|
+
.twm-flow-graph__offer-accept,
|
|
7986
|
+
.twm-flow-graph__offer-dismiss { flex: 0 0 auto; }
|
|
6478
7987
|
|
|
6479
7988
|
/* Three columns; the CANVAS is the one that flexes — `flex: 1 1 0px` AND
|
|
6480
7989
|
* `min-width: 0`, or an open settings panel squeezes the palette instead. */
|
|
@@ -6546,6 +8055,8 @@ button.twm-about-dialog__btn--close:focus {
|
|
|
6546
8055
|
}
|
|
6547
8056
|
.twm-flow-graph__canvas { position: relative; flex: 1 1 0px; min-width: 0; min-height: 0; }
|
|
6548
8057
|
.twm-flow-graph__canvas--drop { outline: 2px dashed var(--twm-flow-focus); outline-offset: -2px; }
|
|
8058
|
+
/* Where a dragged line was let go: what the step picker is anchored to. */
|
|
8059
|
+
.twm-flow-graph__drop-anchor { position: absolute; width: 1px; height: 1px; pointer-events: none; }
|
|
6549
8060
|
.twm-flow-graph__aside {
|
|
6550
8061
|
flex: 0 0 300px;
|
|
6551
8062
|
min-width: 0;
|
|
@@ -6677,6 +8188,168 @@ button.twm-about-dialog__btn--close:focus {
|
|
|
6677
8188
|
.twm-flow-graph__node-run[data-state="skipped"],
|
|
6678
8189
|
.twm-flow-graph__node-run[data-state="cancelled"],
|
|
6679
8190
|
.twm-flow-graph__node-run[data-state="not-reached"] { font-style: italic; }
|
|
8191
|
+
/* A TYPE'S OWN BODY, below its ports (a catalogue type's `render`). It adds
|
|
8192
|
+
* height under the rows and moves nothing above them, so the lines' arithmetic
|
|
8193
|
+
* stands. A type with `size.h` is exactly that tall: its body takes what is
|
|
8194
|
+
* left and clips (the node itself never does: its port dots stand out of it).
|
|
8195
|
+
* An `accent` is a stripe over the header, drawn on top of the box so it takes
|
|
8196
|
+
* no height. */
|
|
8197
|
+
.twm-flow-graph__node-body { box-sizing: border-box; padding: 4px 8px 6px; min-width: 0; }
|
|
8198
|
+
.twm-flow-graph__node--sized { display: flex; flex-direction: column; }
|
|
8199
|
+
.twm-flow-graph__node--sized > .twm-flow-graph__node-head,
|
|
8200
|
+
.twm-flow-graph__node--sized > .twm-flow-graph__node-row { flex: none; }
|
|
8201
|
+
.twm-flow-graph__node--sized > .twm-flow-graph__node-body { flex: 1 1 auto; min-height: 0; overflow: hidden; }
|
|
8202
|
+
/* EDITED ON THE NODE (`renameInPlace`, a type's `inline`). The title's box
|
|
8203
|
+
* takes the title's place in the header, as tall as the name was; the inline
|
|
8204
|
+
* settings sit under the ports, above a type's own body, and add height there
|
|
8205
|
+
* only, so the lines' arithmetic stands. */
|
|
8206
|
+
.twm-flow-graph__node-title-input {
|
|
8207
|
+
flex: 1 1 auto;
|
|
8208
|
+
min-width: 0;
|
|
8209
|
+
box-sizing: border-box;
|
|
8210
|
+
height: 22px;
|
|
8211
|
+
padding: 0 4px;
|
|
8212
|
+
background: var(--surface-1);
|
|
8213
|
+
border: 1px solid var(--twm-flow-focus);
|
|
8214
|
+
border-radius: 2px;
|
|
8215
|
+
color: var(--text-body);
|
|
8216
|
+
font: inherit;
|
|
8217
|
+
cursor: text;
|
|
8218
|
+
user-select: text;
|
|
8219
|
+
}
|
|
8220
|
+
.twm-flow-graph__node-title-input[aria-invalid="true"] { border-color: var(--twm-flow-error); }
|
|
8221
|
+
.twm-flow-graph__node-inline { box-sizing: border-box; display: grid; gap: 4px; padding: 4px 8px 6px; min-width: 0; cursor: default; }
|
|
8222
|
+
.twm-flow-graph__node--sized > .twm-flow-graph__node-inline { flex: none; }
|
|
8223
|
+
.twm-flow-graph__node[data-accent]::before {
|
|
8224
|
+
content: "";
|
|
8225
|
+
position: absolute;
|
|
8226
|
+
top: 0;
|
|
8227
|
+
left: 0;
|
|
8228
|
+
right: 0;
|
|
8229
|
+
height: 3px;
|
|
8230
|
+
border-radius: 3px 3px 0 0;
|
|
8231
|
+
pointer-events: none;
|
|
8232
|
+
}
|
|
8233
|
+
.twm-flow-graph__node[data-accent="violet"]::before { background: var(--twm-flow-violet-fg); }
|
|
8234
|
+
.twm-flow-graph__node[data-accent="teal"]::before { background: var(--twm-flow-teal-fg); }
|
|
8235
|
+
.twm-flow-graph__node[data-accent="amber"]::before { background: var(--twm-flow-amber-fg); }
|
|
8236
|
+
.twm-flow-graph__node[data-accent="grey"]::before { background: var(--twm-flow-grey-fg); }
|
|
8237
|
+
.twm-flow-graph__node[data-accent="blue"]::before { background: var(--twm-flow-blue-fg); }
|
|
8238
|
+
.twm-flow-graph__node[data-accent="indigo"]::before { background: var(--twm-flow-indigo-fg); }
|
|
8239
|
+
|
|
8240
|
+
/* ── a group and a note (`groups`, `notes`) ─────────────────────────── */
|
|
8241
|
+
/* A GROUP IS A FRAME BEHIND ITS NODES (first in the node layer). Its body
|
|
8242
|
+
* takes no pointer, so a press inside it between the nodes is the canvas's
|
|
8243
|
+
* (a marquee, a pan); its title bar is the handle that drags the members. */
|
|
8244
|
+
.twm-flow-graph__group {
|
|
8245
|
+
position: absolute;
|
|
8246
|
+
box-sizing: border-box;
|
|
8247
|
+
border: 1px dashed var(--border-strong);
|
|
8248
|
+
border-radius: 6px;
|
|
8249
|
+
background: rgba(255, 255, 255, 0.03);
|
|
8250
|
+
pointer-events: none;
|
|
8251
|
+
}
|
|
8252
|
+
.twm-flow-graph__group-head {
|
|
8253
|
+
box-sizing: border-box;
|
|
8254
|
+
height: 26px;
|
|
8255
|
+
display: flex;
|
|
8256
|
+
align-items: center;
|
|
8257
|
+
padding: 0 8px;
|
|
8258
|
+
border-radius: 6px 6px 0 0;
|
|
8259
|
+
background: var(--twm-flow-grey-bg);
|
|
8260
|
+
color: var(--twm-flow-grey-fg);
|
|
8261
|
+
font-size: var(--font-size-xs);
|
|
8262
|
+
font-weight: 600;
|
|
8263
|
+
cursor: move;
|
|
8264
|
+
pointer-events: auto;
|
|
8265
|
+
user-select: none;
|
|
8266
|
+
}
|
|
8267
|
+
.twm-flow-graph__group-label { flex: 1 1 auto; min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
|
|
8268
|
+
.twm-flow-graph__group-label--untitled { font-style: italic; font-weight: 400; }
|
|
8269
|
+
.twm-flow-graph__group-input { flex: 1 1 auto; min-width: 0; font: inherit; }
|
|
8270
|
+
.twm-flow-graph__group[data-tone="violet"] { border-color: var(--twm-flow-violet-fg); }
|
|
8271
|
+
.twm-flow-graph__group[data-tone="teal"] { border-color: var(--twm-flow-teal-fg); }
|
|
8272
|
+
.twm-flow-graph__group[data-tone="amber"] { border-color: var(--twm-flow-amber-fg); }
|
|
8273
|
+
.twm-flow-graph__group[data-tone="grey"] { border-color: var(--twm-flow-grey-fg); }
|
|
8274
|
+
.twm-flow-graph__group[data-tone="blue"] { border-color: var(--twm-flow-blue-fg); }
|
|
8275
|
+
.twm-flow-graph__group[data-tone="indigo"] { border-color: var(--twm-flow-indigo-fg); }
|
|
8276
|
+
.twm-flow-graph__group[data-tone="violet"] > .twm-flow-graph__group-head { background: var(--twm-flow-violet-bg); color: var(--twm-flow-violet-fg); }
|
|
8277
|
+
.twm-flow-graph__group[data-tone="teal"] > .twm-flow-graph__group-head { background: var(--twm-flow-teal-bg); color: var(--twm-flow-teal-fg); }
|
|
8278
|
+
.twm-flow-graph__group[data-tone="amber"] > .twm-flow-graph__group-head { background: var(--twm-flow-amber-bg); color: var(--twm-flow-amber-fg); }
|
|
8279
|
+
.twm-flow-graph__group[data-tone="blue"] > .twm-flow-graph__group-head { background: var(--twm-flow-blue-bg); color: var(--twm-flow-blue-fg); }
|
|
8280
|
+
.twm-flow-graph__group[data-tone="indigo"] > .twm-flow-graph__group-head { background: var(--twm-flow-indigo-bg); color: var(--twm-flow-indigo-fg); }
|
|
8281
|
+
/* A NOTE is free text on the canvas, its height its text's unless it has a size. */
|
|
8282
|
+
.twm-flow-graph__note {
|
|
8283
|
+
position: absolute;
|
|
8284
|
+
box-sizing: border-box;
|
|
8285
|
+
padding: 8px 10px;
|
|
8286
|
+
background: var(--twm-flow-amber-bg);
|
|
8287
|
+
border: 1px solid var(--border-strong);
|
|
8288
|
+
border-radius: 4px;
|
|
8289
|
+
color: var(--text-body);
|
|
8290
|
+
font-size: var(--font-size-xs);
|
|
8291
|
+
cursor: move;
|
|
8292
|
+
overflow: hidden;
|
|
8293
|
+
outline: none;
|
|
8294
|
+
}
|
|
8295
|
+
.twm-flow-graph__note:focus-visible { box-shadow: 0 0 0 2px var(--twm-flow-focus); }
|
|
8296
|
+
.twm-flow-graph__note--picked { border-color: var(--twm-flow-focus); box-shadow: 0 0 0 1px var(--twm-flow-focus); }
|
|
8297
|
+
.twm-flow-graph__note-text { margin: 0; white-space: pre-wrap; overflow-wrap: anywhere; }
|
|
8298
|
+
.twm-flow-graph__note-text--empty { color: var(--text-muted); font-style: italic; }
|
|
8299
|
+
.twm-flow-graph__note-input {
|
|
8300
|
+
box-sizing: border-box;
|
|
8301
|
+
width: 100%;
|
|
8302
|
+
min-height: 4em;
|
|
8303
|
+
resize: vertical;
|
|
8304
|
+
font: inherit;
|
|
8305
|
+
cursor: text;
|
|
8306
|
+
}
|
|
8307
|
+
/* LIVE VALUES (`setNodeValues`): a value on the header, before the step's id
|
|
8308
|
+
* tag, and one beside a port. Neither element exists until there is a value. */
|
|
8309
|
+
.twm-flow-graph__node-badge {
|
|
8310
|
+
flex: none;
|
|
8311
|
+
max-width: 40%;
|
|
8312
|
+
padding: 1px 5px;
|
|
8313
|
+
overflow: hidden;
|
|
8314
|
+
text-overflow: ellipsis;
|
|
8315
|
+
white-space: nowrap;
|
|
8316
|
+
font-size: var(--font-size-xs);
|
|
8317
|
+
font-weight: 600;
|
|
8318
|
+
font-variant-numeric: tabular-nums;
|
|
8319
|
+
color: var(--text-body);
|
|
8320
|
+
background: rgba(127, 127, 127, 0.18);
|
|
8321
|
+
border-radius: 2px;
|
|
8322
|
+
}
|
|
8323
|
+
.twm-flow-graph__node-badge[data-tone="violet"] { background: var(--twm-flow-violet-bg); color: var(--twm-flow-violet-fg); }
|
|
8324
|
+
.twm-flow-graph__node-badge[data-tone="teal"] { background: var(--twm-flow-teal-bg); color: var(--twm-flow-teal-fg); }
|
|
8325
|
+
.twm-flow-graph__node-badge[data-tone="amber"] { background: var(--twm-flow-amber-bg); color: var(--twm-flow-amber-fg); }
|
|
8326
|
+
.twm-flow-graph__node-badge[data-tone="grey"] { background: var(--twm-flow-grey-bg); color: var(--twm-flow-grey-fg); }
|
|
8327
|
+
.twm-flow-graph__node-badge[data-tone="blue"] { background: var(--twm-flow-blue-bg); color: var(--twm-flow-blue-fg); }
|
|
8328
|
+
.twm-flow-graph__node-badge[data-tone="indigo"] { background: var(--twm-flow-indigo-bg); color: var(--twm-flow-indigo-fg); }
|
|
8329
|
+
.twm-flow-graph__port-value { color: var(--twm-flow-muted); font-variant-numeric: tabular-nums; white-space: nowrap; }
|
|
8330
|
+
|
|
8331
|
+
/* FOLDED TO ITS HEADER (`collapsible`): everything under the header is hidden,
|
|
8332
|
+
* and the lines meet the header's middle. */
|
|
8333
|
+
.twm-flow-graph__node-fold {
|
|
8334
|
+
flex: none;
|
|
8335
|
+
display: inline-flex;
|
|
8336
|
+
align-items: center;
|
|
8337
|
+
justify-content: center;
|
|
8338
|
+
width: 20px;
|
|
8339
|
+
height: 20px;
|
|
8340
|
+
padding: 0;
|
|
8341
|
+
background: none;
|
|
8342
|
+
border: 0;
|
|
8343
|
+
border-radius: 3px;
|
|
8344
|
+
color: var(--twm-flow-muted);
|
|
8345
|
+
cursor: pointer;
|
|
8346
|
+
}
|
|
8347
|
+
.twm-flow-graph__node-fold .material-symbols-outlined { font-size: 16px; }
|
|
8348
|
+
.twm-flow-graph__node-fold:hover:not(:disabled) { color: var(--text-body); background: rgba(127, 127, 127, 0.18); }
|
|
8349
|
+
.twm-flow-graph__node-fold:focus-visible { outline: 1px solid var(--twm-flow-focus); }
|
|
8350
|
+
.twm-flow-graph__node-fold:disabled { cursor: default; opacity: 0.5; }
|
|
8351
|
+
.twm-flow-graph__node--collapsed > :not(.twm-flow-graph__node-head) { display: none; }
|
|
8352
|
+
.twm-flow-graph__node--collapsed > .twm-flow-graph__node-head { border-bottom: 0; border-radius: 3px; }
|
|
6680
8353
|
|
|
6681
8354
|
/* ── a port ─────────────────────────────────────────────────────────── */
|
|
6682
8355
|
.twm-flow-graph__port {
|
|
@@ -6718,16 +8391,53 @@ button.twm-about-dialog__btn--close:focus {
|
|
|
6718
8391
|
.twm-flow-graph__port--taken .twm-flow-graph__port-dot { border-color: var(--twm-flow-ok); background: var(--twm-flow-ok); }
|
|
6719
8392
|
.twm-flow-graph__port--taken .twm-flow-graph__port-count { color: var(--twm-flow-ok); }
|
|
6720
8393
|
.twm-flow-graph__port--untaken { opacity: 0.5; }
|
|
8394
|
+
/* Under `connections` only the inputs the line may end on are lit. */
|
|
8395
|
+
.twm-flow-graph--linking.twm-flow-graph--connecting .twm-flow-graph__port--in:not(.twm-flow-graph__port--can-drop) .twm-flow-graph__port-dot {
|
|
8396
|
+
background: transparent;
|
|
8397
|
+
box-shadow: none;
|
|
8398
|
+
}
|
|
8399
|
+
.twm-flow-graph__port--can-drop .twm-flow-graph__port-dot {
|
|
8400
|
+
background: var(--twm-flow-focus);
|
|
8401
|
+
box-shadow: 0 0 0 3px rgba(0, 122, 204, 0.35);
|
|
8402
|
+
}
|
|
6721
8403
|
|
|
6722
8404
|
/* ── a line ─────────────────────────────────────────────────────────── */
|
|
6723
|
-
|
|
6724
|
-
|
|
8405
|
+
/* A consumer's `edgeStyle` sets a line's tone and width as the two custom
|
|
8406
|
+
* properties below (unset, the line is drawn as it always was); a picked or
|
|
8407
|
+
* highlighted line still wins over them. */
|
|
8408
|
+
.twm-flow-graph__edge { fill: none; stroke: var(--twm-canvas-edge-stroke, #8fb4d8); stroke-width: var(--twm-canvas-edge-width, 1.6); }
|
|
8409
|
+
.twm-flow-graph__edge--picked { stroke: var(--twm-flow-focus); stroke-width: calc(var(--twm-canvas-edge-width, 1.6) + 0.8); }
|
|
6725
8410
|
/* A loop's body handing back to the loop: DASHED, and routed under both steps
|
|
6726
8411
|
* by the kernel's `returnEdge`, so it reads as "round again", not as one more
|
|
6727
8412
|
* step forward. */
|
|
6728
8413
|
.twm-flow-graph__edge--back { stroke-dasharray: 6 4; }
|
|
6729
8414
|
.twm-flow-graph__edge--taken { stroke: var(--twm-flow-ok); }
|
|
6730
8415
|
.twm-flow-graph__edge--untaken { opacity: 0.35; }
|
|
8416
|
+
/* The line a drag is drawing: dashed, and never what the release lands on. */
|
|
8417
|
+
.twm-flow-graph__edge--draft { stroke: var(--twm-flow-focus); stroke-dasharray: 4 3; pointer-events: none; }
|
|
8418
|
+
/* `edgeStyle`'s dash, and the lines of a hovered step or line (`hoverHighlight`). */
|
|
8419
|
+
.twm-flow-graph__edge--dashed { stroke-dasharray: 6 4; }
|
|
8420
|
+
.twm-flow-graph__edge--highlighted { stroke: var(--twm-flow-focus); stroke-width: calc(var(--twm-canvas-edge-width, 1.6) + 0.8); }
|
|
8421
|
+
/* `edgeStyle`'s marker at the input end: an arrowhead, or the kernel's crow's
|
|
8422
|
+
* foot in the line's own tone. */
|
|
8423
|
+
.twm-flow-graph__edge-arrow { fill: var(--twm-canvas-edge-stroke, #8fb4d8); stroke: none; }
|
|
8424
|
+
.twm-flow-graph__edge-foot line, .twm-flow-graph__edge-foot circle { stroke: var(--twm-canvas-edge-stroke, #8fb4d8); }
|
|
8425
|
+
/* `edgeStyle`'s label, centred on the line's midpoint. Its layer sits in the
|
|
8426
|
+
* node layer and is stacked ABOVE every node, so a step never hides it. */
|
|
8427
|
+
.twm-flow-graph__edge-labels { position: absolute; left: 0; top: 0; z-index: 1; }
|
|
8428
|
+
.twm-flow-graph__edge-label {
|
|
8429
|
+
position: absolute;
|
|
8430
|
+
transform: translate(-50%, -50%);
|
|
8431
|
+
padding: 1px 6px;
|
|
8432
|
+
border: 1px solid var(--twm-canvas-edge-stroke, #8fb4d8);
|
|
8433
|
+
border-radius: 8px;
|
|
8434
|
+
background: var(--surface-2);
|
|
8435
|
+
color: var(--text-body);
|
|
8436
|
+
font-size: var(--font-size-xs);
|
|
8437
|
+
line-height: 1.4;
|
|
8438
|
+
white-space: nowrap;
|
|
8439
|
+
cursor: pointer;
|
|
8440
|
+
}
|
|
6731
8441
|
/* The 14px target a 1.6px line cannot be. It opts back into the pointer the
|
|
6732
8442
|
* edge layer turns off. */
|
|
6733
8443
|
.twm-flow-graph__edge-hit { fill: none; stroke: transparent; stroke-width: 14; pointer-events: stroke; cursor: pointer; }
|
|
@@ -6754,6 +8464,26 @@ button.twm-about-dialog__btn--close:focus {
|
|
|
6754
8464
|
}
|
|
6755
8465
|
.twm-flow-graph__ghost .material-symbols-outlined { font-size: 16px; }
|
|
6756
8466
|
.twm-flow-graph__ghost-label { white-space: nowrap; }
|
|
8467
|
+
/* ── the minimap (`minimap: true`) ──────────────────────────────────── */
|
|
8468
|
+
/* Over the canvas's lower right corner, a sibling of the kernel's surface, so a
|
|
8469
|
+
* press on it starts no pan and no marquee. The steps are drawn as boxes and
|
|
8470
|
+
* the view as a frame; a click centres the view there. */
|
|
8471
|
+
.twm-flow-graph__minimap {
|
|
8472
|
+
position: absolute;
|
|
8473
|
+
right: 12px;
|
|
8474
|
+
bottom: 12px;
|
|
8475
|
+
z-index: 1;
|
|
8476
|
+
line-height: 0;
|
|
8477
|
+
background: var(--surface-1);
|
|
8478
|
+
border: 1px solid var(--border-default);
|
|
8479
|
+
border-radius: 4px;
|
|
8480
|
+
box-shadow: var(--shadow-md);
|
|
8481
|
+
cursor: pointer;
|
|
8482
|
+
opacity: 0.92;
|
|
8483
|
+
}
|
|
8484
|
+
.twm-flow-graph__minimap-map { display: block; }
|
|
8485
|
+
.twm-flow-graph__minimap-node { fill: var(--border-strong); }
|
|
8486
|
+
.twm-flow-graph__minimap-view { fill: none; stroke: var(--twm-flow-focus); stroke-width: 1.5px; }
|
|
6757
8487
|
/* ══ end FLOW · CANVAS ══ */
|
|
6758
8488
|
|
|
6759
8489
|
|
|
@@ -8337,4 +10067,33 @@ button.twm-about-dialog__btn--close:focus {
|
|
|
8337
10067
|
font-size: 16px;
|
|
8338
10068
|
line-height: 1;
|
|
8339
10069
|
}
|
|
10070
|
+
.twm-flow-lanes__menu-item.twm-flow-lanes__menu-item--refused {
|
|
10071
|
+
height: auto;
|
|
10072
|
+
min-height: 28px;
|
|
10073
|
+
padding-top: 4px;
|
|
10074
|
+
padding-bottom: 4px;
|
|
10075
|
+
}
|
|
10076
|
+
.twm-flow-lanes__menu-words {
|
|
10077
|
+
display: flex;
|
|
10078
|
+
flex-direction: column;
|
|
10079
|
+
min-width: 0;
|
|
10080
|
+
}
|
|
10081
|
+
.twm-flow-lanes__menu-label {
|
|
10082
|
+
white-space: nowrap;
|
|
10083
|
+
}
|
|
10084
|
+
.twm-flow-lanes__menu-reason {
|
|
10085
|
+
max-width: 280px;
|
|
10086
|
+
font-size: var(--font-size-xs);
|
|
10087
|
+
white-space: normal;
|
|
10088
|
+
}
|
|
10089
|
+
.twm-flow-lanes__menu-sep {
|
|
10090
|
+
height: 1px;
|
|
10091
|
+
margin: 4px 6px;
|
|
10092
|
+
background: var(--border-subtle);
|
|
10093
|
+
}
|
|
10094
|
+
.twm-flow-lanes__notice {
|
|
10095
|
+
margin-left: 8px;
|
|
10096
|
+
color: var(--twm-flow-warning);
|
|
10097
|
+
font-size: var(--font-size-xs);
|
|
10098
|
+
}
|
|
8340
10099
|
/* ══ end FLOW · LANES ══ */
|