plexora 0.0.1__py3-none-any.whl
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.
- plexora/__init__.py +129 -0
- plexora/__main__.py +15 -0
- plexora/_url.py +105 -0
- plexora/api/__init__.py +55 -0
- plexora/api/dataset.py +398 -0
- plexora/api/http.py +19 -0
- plexora/api/plugin.py +541 -0
- plexora/api/store.py +221 -0
- plexora/cli.py +777 -0
- plexora/client/dist/354_bundle.js +2 -0
- plexora/client/dist/354_bundle.js.LICENSE.txt +20 -0
- plexora/client/dist/418_bundle.js +2 -0
- plexora/client/dist/418_bundle.js.LICENSE.txt +1 -0
- plexora/client/dist/693b935cb1f907814be9c6199a68c217.svg +19 -0
- plexora/client/dist/713c134ff47cd328a5b711526f151082.svg +18 -0
- plexora/client/dist/770_bundle.js +1 -0
- plexora/client/dist/ff743f408972e0e96ca9153ed5ae4c83.svg +23 -0
- plexora/client/dist/vendor_bundle.js +2 -0
- plexora/client/dist/vendor_bundle.js.LICENSE.txt +308 -0
- plexora/client/external/openseadragon-bin-2.4.0/LICENSE.txt +28 -0
- plexora/client/external/openseadragon-bin-2.4.0/canvas-overlay-hd.js +140 -0
- plexora/client/external/openseadragon-bin-2.4.0/changelog.txt +501 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/.gitattributes +17 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/LICENSE.txt +116 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/Photoshop/Toolbar.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/Photoshop/fullpage.psd +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/Photoshop/home.psd +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/Photoshop/next.psd +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/Photoshop/previous.psd +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/Photoshop/rotateleft.psd +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/Photoshop/rotateright.psd +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/Photoshop/zoom.psd +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/README.md +9 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/fullpage_grouphover.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/fullpage_hover.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/fullpage_pressed.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/fullpage_rest.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/home_grouphover.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/home_hover.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/home_pressed.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/home_rest.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/next_grouphover.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/next_hover.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/next_pressed.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/next_rest.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/previous_grouphover.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/previous_hover.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/previous_pressed.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/previous_rest.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/rotateleft_grouphover.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/rotateleft_hover.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/rotateleft_pressed.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/rotateleft_rest.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/rotateright_grouphover.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/rotateright_hover.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/rotateright_pressed.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/rotateright_rest.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/zoomin_grouphover.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/zoomin_hover.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/zoomin_pressed.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/zoomin_rest.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/zoomout_grouphover.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/zoomout_hover.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/zoomout_pressed.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/zoomout_rest.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-scalebar.js +562 -0
- plexora/client/src/css/import.css +474 -0
- plexora/client/src/css/main.css +903 -0
- plexora/client/src/css/openProject.css +363 -0
- plexora/client/src/css/quickView.css +166 -0
- plexora/client/src/css/tokens.css +51 -0
- plexora/client/src/css/viewer.css +1655 -0
- plexora/client/src/img/apple-touch-icon.png +0 -0
- plexora/client/src/img/favicon.ico +0 -0
- plexora/client/src/img/logo.ai +8892 -33
- plexora/client/src/img/logo.svg +1 -0
- plexora/client/src/img/logo_with_text.ai +9011 -34
- plexora/client/src/img/logo_with_text.svg +1 -0
- plexora/client/src/js/main.js +704 -0
- plexora/client/src/js/pluginRegistry.js +108 -0
- plexora/client/src/js/services/appStatus.js +286 -0
- plexora/client/src/js/services/browsePicker.js +73 -0
- plexora/client/src/js/services/dataLayer.js +400 -0
- plexora/client/src/js/services/datasetContext.js +143 -0
- plexora/client/src/js/services/glRenderer.js +143 -0
- plexora/client/src/js/services/importFormValidation.js +257 -0
- plexora/client/src/js/services/numericData.js +100 -0
- plexora/client/src/js/services/passVariablesToFrontend.js +20 -0
- plexora/client/src/js/services/simpleEventHandler.js +25 -0
- plexora/client/src/js/vendor.js +29 -0
- plexora/client/src/js/views/channelList.js +663 -0
- plexora/client/src/js/views/colorSwatchPicker.js +202 -0
- plexora/client/src/js/views/columnClassifier.js +146 -0
- plexora/client/src/js/views/coordinateField.js +133 -0
- plexora/client/src/js/views/dataSourceField.js +276 -0
- plexora/client/src/js/views/imageViewer.js +3306 -0
- plexora/client/src/js/views/miniMap.js +787 -0
- plexora/client/src/js/views/navbarControls.js +178 -0
- plexora/client/src/js/views/openProjectPage.js +239 -0
- plexora/client/src/js/views/projectEdit.js +335 -0
- plexora/client/src/js/views/quickViewLanding.js +136 -0
- plexora/client/src/js/views/rainbow.js +326 -0
- plexora/client/src/js/views/requirementsModal.js +572 -0
- plexora/client/src/js/views/rgbImageViewer.js +115 -0
- plexora/client/src/js/views/searchableSelect.js +411 -0
- plexora/client/src/js/views/segmentationProgress.js +122 -0
- plexora/client/src/js/views/toolLoader.js +747 -0
- plexora/client/src/js/views/viewerControls.js +689 -0
- plexora/client/src/js/views/viewerManager.js +434 -0
- plexora/client/src/js/views/viewerSidebar.js +1117 -0
- plexora/client/src/js/workers/tileDecoder.js +130 -0
- plexora/client/src/shaders/frag.glsl +528 -0
- plexora/client/src/shaders/vert.glsl +12 -0
- plexora/client/templates/base.html +212 -0
- plexora/client/templates/index.html +238 -0
- plexora/client/templates/open_project.html +96 -0
- plexora/client/templates/project_columns.html +86 -0
- plexora/client/templates/project_edit.html +196 -0
- plexora/client/templates/upload.html +118 -0
- plexora/connect.py +528 -0
- plexora/datasource.py +782 -0
- plexora/jupyter.py +406 -0
- plexora/notebook_env.py +232 -0
- plexora/paths.py +486 -0
- plexora/plugins/__init__.py +12 -0
- plexora/plugins/cell_explorer/__init__.py +100 -0
- plexora/plugins/cell_explorer/server/__init__.py +11 -0
- plexora/plugins/cell_explorer/server/routes.py +167 -0
- plexora/plugins/cell_explorer/server/state.py +281 -0
- plexora/plugins/cell_explorer/server/values.py +145 -0
- plexora/plugins/cell_explorer/server/variables.py +367 -0
- plexora/plugins/cell_explorer/static/cellExplorerApi.js +158 -0
- plexora/plugins/cell_explorer/static/cellExplorerColors.js +316 -0
- plexora/plugins/cell_explorer/static/cellExplorerContinuous.js +403 -0
- plexora/plugins/cell_explorer/static/cellExplorerFigureBridge.js +133 -0
- plexora/plugins/cell_explorer/static/cellExplorerLegend.js +188 -0
- plexora/plugins/cell_explorer/static/cellExplorerRoiBridge.js +822 -0
- plexora/plugins/cell_explorer/static/cellExplorerSidebarController.js +826 -0
- plexora/plugins/cell_explorer/static/cellExplorerState.js +372 -0
- plexora/plugins/cell_explorer/static/cell_explorer.css +752 -0
- plexora/plugins/cell_explorer/templates/cell_explorer/panel.html +137 -0
- plexora/plugins/figure_builder/__init__.py +125 -0
- plexora/plugins/figure_builder/server/__init__.py +7 -0
- plexora/plugins/figure_builder/server/compose.py +365 -0
- plexora/plugins/figure_builder/server/export.py +784 -0
- plexora/plugins/figure_builder/server/export_jobs.py +148 -0
- plexora/plugins/figure_builder/server/operations.py +556 -0
- plexora/plugins/figure_builder/server/pixels.py +142 -0
- plexora/plugins/figure_builder/server/provenance.py +174 -0
- plexora/plugins/figure_builder/server/render.py +278 -0
- plexora/plugins/figure_builder/server/repository.py +701 -0
- plexora/plugins/figure_builder/server/routes.py +594 -0
- plexora/plugins/figure_builder/server/schema.py +1023 -0
- plexora/plugins/figure_builder/server/sources.py +120 -0
- plexora/plugins/figure_builder/server/textmetrics.py +155 -0
- plexora/plugins/figure_builder/static/figureActions.js +363 -0
- plexora/plugins/figure_builder/static/figureBuilderApi.js +255 -0
- plexora/plugins/figure_builder/static/figureCanvas.js +2362 -0
- plexora/plugins/figure_builder/static/figureCaptureBoxes.js +369 -0
- plexora/plugins/figure_builder/static/figureCaptureDock.js +466 -0
- plexora/plugins/figure_builder/static/figureCaptureTool.js +1034 -0
- plexora/plugins/figure_builder/static/figureConfirm.js +136 -0
- plexora/plugins/figure_builder/static/figureContextBar.js +1193 -0
- plexora/plugins/figure_builder/static/figureContextMenu.js +253 -0
- plexora/plugins/figure_builder/static/figureDocumentState.js +275 -0
- plexora/plugins/figure_builder/static/figureExportUi.js +174 -0
- plexora/plugins/figure_builder/static/figureLibrary.js +247 -0
- plexora/plugins/figure_builder/static/figureQuickEdit.js +628 -0
- plexora/plugins/figure_builder/static/figureRichText.js +634 -0
- plexora/plugins/figure_builder/static/figureSceneSnapshot.js +361 -0
- plexora/plugins/figure_builder/static/figureSchema.js +218 -0
- plexora/plugins/figure_builder/static/figureSidebarController.js +1159 -0
- plexora/plugins/figure_builder/static/figureTextEditor.js +503 -0
- plexora/plugins/figure_builder/static/figureTextPanel.js +491 -0
- plexora/plugins/figure_builder/static/figureViewOptions.js +273 -0
- plexora/plugins/figure_builder/static/figureWorkspace.js +2030 -0
- plexora/plugins/figure_builder/static/figure_builder.css +3292 -0
- plexora/plugins/figure_builder/templates/figure_builder/library.html +74 -0
- plexora/plugins/figure_builder/templates/figure_builder/workspace.html +27 -0
- plexora/plugins/figure_builder/templates/figure_builder/workspace_body.html +458 -0
- plexora/plugins/gating/__init__.py +76 -0
- plexora/plugins/gating/server/__init__.py +0 -0
- plexora/plugins/gating/server/anndata_gates.py +367 -0
- plexora/plugins/gating/server/database.py +16 -0
- plexora/plugins/gating/server/model.py +320 -0
- plexora/plugins/gating/server/routes.py +235 -0
- plexora/plugins/gating/static/csvGatingList.js +947 -0
- plexora/plugins/gating/static/gating.css +289 -0
- plexora/plugins/gating/static/gatingApi.js +221 -0
- plexora/plugins/gating/static/gatingSidebarController.js +513 -0
- plexora/plugins/gating/templates/gating/legacy.html +26 -0
- plexora/plugins/gating/templates/gating/panel.html +69 -0
- plexora/plugins/roi/__init__.py +95 -0
- plexora/plugins/roi/server/__init__.py +8 -0
- plexora/plugins/roi/server/adapters.py +655 -0
- plexora/plugins/roi/server/geojson.py +267 -0
- plexora/plugins/roi/server/geometry.py +181 -0
- plexora/plugins/roi/server/mapping.py +169 -0
- plexora/plugins/roi/server/operations.py +293 -0
- plexora/plugins/roi/server/repository.py +215 -0
- plexora/plugins/roi/server/routes.py +409 -0
- plexora/plugins/roi/server/schema.py +323 -0
- plexora/plugins/roi/static/roi.css +583 -0
- plexora/plugins/roi/static/roiApi.js +177 -0
- plexora/plugins/roi/static/roiFigureBridge.js +107 -0
- plexora/plugins/roi/static/roiGeometry.js +350 -0
- plexora/plugins/roi/static/roiRenderer.js +278 -0
- plexora/plugins/roi/static/roiSidebarController.js +1038 -0
- plexora/plugins/roi/static/roiState.js +518 -0
- plexora/plugins/roi/static/roiTools.js +993 -0
- plexora/plugins/roi/templates/roi/panel.html +240 -0
- plexora/proxy.py +57 -0
- plexora/server/models/adapters/__init__.py +94 -0
- plexora/server/models/adapters/anndata_adapter.py +388 -0
- plexora/server/models/adapters/base.py +93 -0
- plexora/server/models/adapters/classify.py +192 -0
- plexora/server/models/adapters/csv_adapter.py +105 -0
- plexora/server/models/adapters/inspection.py +265 -0
- plexora/server/models/adapters/spatialdata_adapter.py +248 -0
- plexora/server/models/centroid_tiles.py +305 -0
- plexora/server/models/data_model.py +1659 -0
- plexora/server/models/database_model.py +169 -0
- plexora/server/models/project.py +1270 -0
- plexora/server/plugins.py +199 -0
- plexora/server/routes/browse_routes.py +41 -0
- plexora/server/routes/data_routes.py +294 -0
- plexora/server/routes/import_routes.py +603 -0
- plexora/server/routes/page_routes.py +139 -0
- plexora/server/routes/project_routes.py +438 -0
- plexora/server/routes/quick_view_routes.py +62 -0
- plexora/server/routes/system_routes.py +39 -0
- plexora/server/routes/tool_routes.py +418 -0
- plexora/server/utils/addHEColumns.py +11 -0
- plexora/server/utils/fast_png.py +97 -0
- plexora/server/utils/fullConversion.py +50 -0
- plexora/server/utils/native_dialog.py +168 -0
- plexora/server/utils/pre_normalization.py +47 -0
- plexora/server/utils/segmentation_pyramid.py +598 -0
- plexora/server/utils/smallestenclosingcircle.py +126 -0
- plexora/server/utils/tiffsurgeon.py +372 -0
- plexora/server_cli.py +48 -0
- plexora/test.py +0 -0
- plexora-0.0.1.dist-info/METADATA +341 -0
- plexora-0.0.1.dist-info/RECORD +248 -0
- plexora-0.0.1.dist-info/WHEEL +5 -0
- plexora-0.0.1.dist-info/entry_points.txt +12 -0
- plexora-0.0.1.dist-info/licenses/LICENSE +207 -0
- plexora-0.0.1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,752 @@
|
|
|
1
|
+
/* Cell Explorer's panel.
|
|
2
|
+
*
|
|
3
|
+
* Every selector here is this plugin's own: ids prefixed `cell_explorer_`,
|
|
4
|
+
* classes prefixed `cex-`. Core's tokens and its shared widget classes
|
|
5
|
+
* (.control-label, .sidebar-select, .sidebar-action) are used as-is, and
|
|
6
|
+
* nothing core owns is restyled -- a plugin's stylesheet loads only while its
|
|
7
|
+
* tool is open, so a rule for a core element here disappears the moment this
|
|
8
|
+
* tool is closed. See tests/test_plugin_css_boundary.py.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
#cell_explorer_panel_section {
|
|
12
|
+
display: flex;
|
|
13
|
+
flex-direction: column;
|
|
14
|
+
gap: 8px;
|
|
15
|
+
min-width: 0;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/* `hidden` means hidden, including on the blocks below that set a display of
|
|
19
|
+
their own. The UA rule for [hidden] is a bare element selector, so any class
|
|
20
|
+
here with `display: flex` in it quietly outranks it -- which showed up as a
|
|
21
|
+
colour ramp still sitting under the legend after switching from a numeric
|
|
22
|
+
column to a categorical one. */
|
|
23
|
+
#cell_explorer_panel_section [hidden] {
|
|
24
|
+
display: none;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.cex-empty-state {
|
|
28
|
+
background: rgba(255, 255, 255, 0.04);
|
|
29
|
+
border: 1px dashed var(--border-strong);
|
|
30
|
+
border-radius: var(--radius-sm);
|
|
31
|
+
padding: 12px;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.cex-empty-state p {
|
|
35
|
+
color: var(--text-secondary);
|
|
36
|
+
font-size: 12px;
|
|
37
|
+
margin: 0 0 6px;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.cex-hint {
|
|
41
|
+
color: var(--text-muted);
|
|
42
|
+
font-size: 11px;
|
|
43
|
+
line-height: 1.45;
|
|
44
|
+
margin: 4px 0 0;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/* The one row of controls: colour-by, then the legend's filter and its
|
|
48
|
+
All/None. Every part sets `min-width: 0` because the default `auto` on a flex
|
|
49
|
+
item means "at least as wide as my content", which is how one long column
|
|
50
|
+
name used to push the row past the sidebar and put a scrollbar under it. */
|
|
51
|
+
.cex-toolbar {
|
|
52
|
+
align-items: center;
|
|
53
|
+
display: flex;
|
|
54
|
+
gap: 6px;
|
|
55
|
+
min-width: 0;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/* Both elastic, in the proportion they are worth: the colour-by control shows
|
|
59
|
+
a name people read, the filter is a box people type three letters into. */
|
|
60
|
+
.cex-variable {
|
|
61
|
+
flex: 3 1 90px;
|
|
62
|
+
min-width: 0;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.cex-category-controls {
|
|
66
|
+
align-items: center;
|
|
67
|
+
display: flex;
|
|
68
|
+
flex: 2 1 100px;
|
|
69
|
+
gap: 6px;
|
|
70
|
+
min-width: 0;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.cex-search {
|
|
74
|
+
background: var(--surface-2);
|
|
75
|
+
border: 1px solid var(--border-subtle);
|
|
76
|
+
border-radius: var(--radius-sm);
|
|
77
|
+
color: var(--text-primary);
|
|
78
|
+
font-size: 12px;
|
|
79
|
+
/* Never wider than its share of the row: a long column name must truncate
|
|
80
|
+
rather than force the whole panel to scroll sideways. */
|
|
81
|
+
max-width: 100%;
|
|
82
|
+
min-width: 0;
|
|
83
|
+
padding: 5px 8px;
|
|
84
|
+
width: 100%;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
.cex-status {
|
|
88
|
+
color: var(--text-muted);
|
|
89
|
+
font-size: 11px;
|
|
90
|
+
line-height: 1.45;
|
|
91
|
+
margin: 2px 0;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/* -- kind override ------------------------------------------------------ */
|
|
95
|
+
|
|
96
|
+
.cex-override-options {
|
|
97
|
+
background: var(--surface-2);
|
|
98
|
+
border: 1px solid var(--border-subtle);
|
|
99
|
+
border-radius: var(--radius-sm);
|
|
100
|
+
display: flex;
|
|
101
|
+
overflow: hidden;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
.cex-override-option {
|
|
105
|
+
background: transparent;
|
|
106
|
+
border: 0;
|
|
107
|
+
border-right: 1px solid var(--border-subtle);
|
|
108
|
+
color: var(--text-secondary);
|
|
109
|
+
cursor: pointer;
|
|
110
|
+
flex: 1;
|
|
111
|
+
font-size: 11px;
|
|
112
|
+
padding: 5px 4px;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
.cex-override-option:last-child {
|
|
116
|
+
border-right: 0;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.cex-override-option.is-active {
|
|
120
|
+
background: var(--accent-channel);
|
|
121
|
+
color: #0b1118;
|
|
122
|
+
font-weight: 600;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/* -- categorical legend -------------------------------------------------- */
|
|
126
|
+
|
|
127
|
+
/* One height across the row. Core's controls are each sized for a line of
|
|
128
|
+
their own, and a 32px combobox beside a 25px text field and a 23px pair of
|
|
129
|
+
buttons reads as three things that happened to end up together. Scoped under
|
|
130
|
+
this plugin's own selectors, so it is this row's proportions rather than a
|
|
131
|
+
change to the widgets -- the same arrangement as the legend swatch below. */
|
|
132
|
+
#cell_explorer_variable .marker-combobox-trigger {
|
|
133
|
+
font-size: 12px;
|
|
134
|
+
height: 28px;
|
|
135
|
+
padding: 0 8px;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
.cex-category-controls .cex-search {
|
|
139
|
+
box-sizing: border-box;
|
|
140
|
+
flex: 1 1 40px;
|
|
141
|
+
height: 28px;
|
|
142
|
+
min-width: 0;
|
|
143
|
+
padding: 0 6px;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
.cex-toolbar .cex-legend-actions {
|
|
147
|
+
height: 28px;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
.cex-toolbar .cex-toggle {
|
|
151
|
+
align-items: center;
|
|
152
|
+
display: flex;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/* All / None. A segmented pair rather than two links, because it reports the
|
|
156
|
+
legend's state as well as setting it -- and neither being lit is the ordinary
|
|
157
|
+
answer once one row has been hidden. */
|
|
158
|
+
.cex-legend-actions {
|
|
159
|
+
background: var(--surface-2);
|
|
160
|
+
border: 1px solid var(--border-subtle);
|
|
161
|
+
border-radius: var(--radius-sm);
|
|
162
|
+
display: flex;
|
|
163
|
+
flex: 0 0 auto;
|
|
164
|
+
overflow: hidden;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/* One small two-state button. Used on its own (the Range row's Auto) and in a
|
|
168
|
+
segmented pair (All / None) -- inside a pair the group draws the box, so the
|
|
169
|
+
button gives up its own border rather than doubling it. */
|
|
170
|
+
.cex-toggle {
|
|
171
|
+
background: var(--surface-2);
|
|
172
|
+
border: 1px solid var(--border-subtle);
|
|
173
|
+
border-radius: var(--radius-sm);
|
|
174
|
+
color: var(--text-secondary);
|
|
175
|
+
cursor: pointer;
|
|
176
|
+
flex: 0 0 auto;
|
|
177
|
+
font-size: 11px;
|
|
178
|
+
padding: 4px 9px;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
.cex-legend-actions .cex-toggle {
|
|
182
|
+
background: transparent;
|
|
183
|
+
border: 0;
|
|
184
|
+
border-radius: 0;
|
|
185
|
+
border-right: 1px solid var(--border-subtle);
|
|
186
|
+
padding: 3px 9px;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
.cex-legend-actions .cex-toggle:last-child {
|
|
190
|
+
border-right: 0;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
.cex-toggle:hover:not(.is-active) {
|
|
194
|
+
background: rgba(255, 255, 255, 0.06);
|
|
195
|
+
color: var(--text-primary);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
.cex-toggle:focus-visible {
|
|
199
|
+
/* Inset, or a group's overflow:hidden clips the ring away. */
|
|
200
|
+
outline: 2px solid var(--accent-channel);
|
|
201
|
+
outline-offset: -2px;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
.cex-toggle.is-active {
|
|
205
|
+
background: var(--accent-channel);
|
|
206
|
+
border-color: var(--accent-channel);
|
|
207
|
+
color: #0b1118;
|
|
208
|
+
font-weight: 600;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
.cex-legend {
|
|
212
|
+
display: flex;
|
|
213
|
+
flex-direction: column;
|
|
214
|
+
gap: 2px;
|
|
215
|
+
min-width: 0;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/* Past a dozen categories the list scrolls inside the panel rather than
|
|
219
|
+
pushing the opacity control off the bottom of the sidebar. */
|
|
220
|
+
.cex-legend.cex-legend-scroll {
|
|
221
|
+
max-height: 260px;
|
|
222
|
+
overflow-y: auto;
|
|
223
|
+
padding-right: 4px;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/* The whole row toggles the category, so it is drawn as something clickable
|
|
227
|
+
and its text does not select under a run of clicks. */
|
|
228
|
+
.cex-row {
|
|
229
|
+
align-items: center;
|
|
230
|
+
border-radius: var(--radius-sm);
|
|
231
|
+
cursor: pointer;
|
|
232
|
+
display: flex;
|
|
233
|
+
gap: 8px;
|
|
234
|
+
min-width: 0;
|
|
235
|
+
padding: 2px 4px;
|
|
236
|
+
user-select: none;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/* Except here. The swatch means "change the colour", not "hide this". */
|
|
240
|
+
.cex-row .cex-swatch {
|
|
241
|
+
cursor: default;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
.cex-row:hover {
|
|
245
|
+
background: rgba(255, 255, 255, 0.05);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/* Hidden rows are dimmed AND carry an eye-slash icon, so the state is never
|
|
249
|
+
conveyed by colour alone. */
|
|
250
|
+
.cex-row-hidden .cex-label,
|
|
251
|
+
.cex-row-hidden .cex-count {
|
|
252
|
+
opacity: 0.45;
|
|
253
|
+
text-decoration: line-through;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/* The mount core's ColorSwatchPicker renders its button into. The button is
|
|
257
|
+
core's element and keeps core's look; a legend row is denser than a channel
|
|
258
|
+
row, so the size is brought down here -- scoped under this panel's own id, so
|
|
259
|
+
it is this list's appearance and not a change to the widget. */
|
|
260
|
+
.cex-swatch {
|
|
261
|
+
flex: 0 0 auto;
|
|
262
|
+
line-height: 0;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
#cell_explorer_legend .channel-color-swatch {
|
|
266
|
+
height: 17px;
|
|
267
|
+
width: 17px;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
.cex-label {
|
|
271
|
+
color: var(--text-secondary);
|
|
272
|
+
flex: 1;
|
|
273
|
+
font-size: 12px;
|
|
274
|
+
min-width: 0;
|
|
275
|
+
/* Long annotations truncate with the full text on hover. Allowing them to
|
|
276
|
+
expand would widen the sidebar for every project. */
|
|
277
|
+
overflow: hidden;
|
|
278
|
+
text-overflow: ellipsis;
|
|
279
|
+
white-space: nowrap;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
.cex-count {
|
|
283
|
+
color: var(--text-muted);
|
|
284
|
+
flex: 0 0 auto;
|
|
285
|
+
font-size: 11px;
|
|
286
|
+
font-variant-numeric: tabular-nums;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
.cex-visibility {
|
|
290
|
+
background: none;
|
|
291
|
+
border: 0;
|
|
292
|
+
color: var(--text-muted);
|
|
293
|
+
cursor: pointer;
|
|
294
|
+
flex: 0 0 auto;
|
|
295
|
+
font-size: 11px;
|
|
296
|
+
padding: 2px 4px;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
.cex-visibility:hover {
|
|
300
|
+
color: var(--text-primary);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
.cex-empty {
|
|
304
|
+
color: var(--text-muted);
|
|
305
|
+
font-size: 11px;
|
|
306
|
+
margin: 6px 2px;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/* -- continuous ---------------------------------------------------------- */
|
|
310
|
+
|
|
311
|
+
.cex-continuous {
|
|
312
|
+
display: flex;
|
|
313
|
+
flex-direction: column;
|
|
314
|
+
gap: 10px;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
/* The colour bar with its two handles, the palette button and Auto: one line. */
|
|
318
|
+
.cex-ramp-row {
|
|
319
|
+
align-items: center;
|
|
320
|
+
display: flex;
|
|
321
|
+
gap: 6px;
|
|
322
|
+
min-width: 0;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/* Overlay off: the bar and its numbers dim, and the eye beside them turns into
|
|
326
|
+
an eye-slash -- state in two channels, never in contrast alone. The eye
|
|
327
|
+
itself stays at full strength, since it is the way back. */
|
|
328
|
+
.cex-ramp-wrapper.is-hidden .cex-ramp-track,
|
|
329
|
+
.cex-ramp-wrapper.is-hidden .cex-ramp-scale {
|
|
330
|
+
opacity: 0.4;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/* Sized to sit in a row of small controls rather than in a legend row. */
|
|
334
|
+
.cex-ramp-visibility {
|
|
335
|
+
font-size: 12px;
|
|
336
|
+
padding: 2px 2px;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/* The bar and the two range inputs stacked over it, all in one positioning
|
|
340
|
+
context so the handles land on the colours they set. */
|
|
341
|
+
.cex-ramp-track {
|
|
342
|
+
flex: 1;
|
|
343
|
+
height: 18px;
|
|
344
|
+
min-width: 0;
|
|
345
|
+
position: relative;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
.cex-ramp {
|
|
349
|
+
border: 1px solid var(--border-subtle);
|
|
350
|
+
border-radius: 3px;
|
|
351
|
+
box-sizing: border-box;
|
|
352
|
+
height: 100%;
|
|
353
|
+
width: 100%;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
/* Two <input type="range"> over the same track. That is what buys arrow keys,
|
|
357
|
+
Home/End and a tab stop per end for nothing -- but the upper one covers the
|
|
358
|
+
lower, so the inputs take no pointer events at all and the thumbs take them
|
|
359
|
+
back. Without that, one end of the range is unreachable by mouse. */
|
|
360
|
+
.cex-ramp-handle {
|
|
361
|
+
appearance: none;
|
|
362
|
+
-webkit-appearance: none;
|
|
363
|
+
background: none;
|
|
364
|
+
height: 18px;
|
|
365
|
+
left: 0;
|
|
366
|
+
margin: 0;
|
|
367
|
+
pointer-events: none;
|
|
368
|
+
position: absolute;
|
|
369
|
+
top: 0;
|
|
370
|
+
width: 100%;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
.cex-ramp-handle:focus {
|
|
374
|
+
/* The input covers the whole bar, so a ring around it says nothing about
|
|
375
|
+
which end has focus. The thumb wears it instead, below. */
|
|
376
|
+
outline: none;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
.cex-ramp-handle::-webkit-slider-runnable-track,
|
|
380
|
+
.cex-ramp-handle::-moz-range-track {
|
|
381
|
+
background: none;
|
|
382
|
+
border: 0;
|
|
383
|
+
height: 18px;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
.cex-ramp-handle::-webkit-slider-thumb {
|
|
387
|
+
appearance: none;
|
|
388
|
+
-webkit-appearance: none;
|
|
389
|
+
background: #f4f8ff;
|
|
390
|
+
border: 1px solid #05070a;
|
|
391
|
+
border-radius: 2px;
|
|
392
|
+
box-shadow: 0 0 3px rgba(0, 0, 0, 0.8);
|
|
393
|
+
cursor: ew-resize;
|
|
394
|
+
height: 18px;
|
|
395
|
+
pointer-events: auto;
|
|
396
|
+
width: 8px;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
.cex-ramp-handle::-moz-range-thumb {
|
|
400
|
+
background: #f4f8ff;
|
|
401
|
+
border: 1px solid #05070a;
|
|
402
|
+
border-radius: 2px;
|
|
403
|
+
box-shadow: 0 0 3px rgba(0, 0, 0, 0.8);
|
|
404
|
+
cursor: ew-resize;
|
|
405
|
+
height: 18px;
|
|
406
|
+
pointer-events: auto;
|
|
407
|
+
width: 8px;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
.cex-ramp-handle:focus-visible::-webkit-slider-thumb {
|
|
411
|
+
box-shadow: 0 0 0 2px var(--accent-channel);
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
.cex-ramp-handle:focus-visible::-moz-range-thumb {
|
|
415
|
+
box-shadow: 0 0 0 2px var(--accent-channel);
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
.cex-palette-button {
|
|
419
|
+
background: var(--surface-2);
|
|
420
|
+
border: 1px solid var(--border-subtle);
|
|
421
|
+
border-radius: var(--radius-sm);
|
|
422
|
+
color: var(--text-secondary);
|
|
423
|
+
cursor: pointer;
|
|
424
|
+
flex: 0 0 auto;
|
|
425
|
+
font-size: 11px;
|
|
426
|
+
line-height: 1;
|
|
427
|
+
padding: 4px 7px;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
.cex-palette-button:hover {
|
|
431
|
+
background: rgba(255, 255, 255, 0.06);
|
|
432
|
+
color: var(--text-primary);
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
.cex-palette-button.is-open {
|
|
436
|
+
background: var(--accent-channel);
|
|
437
|
+
border-color: var(--accent-channel);
|
|
438
|
+
color: #0b1118;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
.cex-ramp-scale {
|
|
442
|
+
color: var(--text-secondary);
|
|
443
|
+
display: flex;
|
|
444
|
+
font-size: 11px;
|
|
445
|
+
font-variant-numeric: tabular-nums;
|
|
446
|
+
justify-content: space-between;
|
|
447
|
+
margin-top: 4px;
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
/* The palette list, shown only while its button is open. */
|
|
451
|
+
.cex-palettes {
|
|
452
|
+
background: var(--surface-2);
|
|
453
|
+
border: 1px solid var(--border-subtle);
|
|
454
|
+
border-radius: var(--radius-sm);
|
|
455
|
+
padding: 8px;
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
.cex-palette-row {
|
|
459
|
+
display: flex;
|
|
460
|
+
gap: 6px;
|
|
461
|
+
min-width: 0;
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
.cex-palette {
|
|
465
|
+
border: 1px solid var(--border-subtle);
|
|
466
|
+
border-radius: 3px;
|
|
467
|
+
cursor: pointer;
|
|
468
|
+
flex: 1;
|
|
469
|
+
height: 18px;
|
|
470
|
+
min-width: 0;
|
|
471
|
+
padding: 0;
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
.cex-palette.is-active {
|
|
475
|
+
border-color: var(--accent-channel);
|
|
476
|
+
box-shadow: 0 0 0 1px var(--accent-channel);
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
.cex-custom-row {
|
|
480
|
+
display: flex;
|
|
481
|
+
gap: 12px;
|
|
482
|
+
margin-top: 8px;
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
.cex-custom-end {
|
|
486
|
+
align-items: center;
|
|
487
|
+
color: var(--text-secondary);
|
|
488
|
+
display: inline-flex;
|
|
489
|
+
font-size: 11px;
|
|
490
|
+
gap: 6px;
|
|
491
|
+
margin: 0;
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
.cex-custom-end input {
|
|
495
|
+
background: none;
|
|
496
|
+
border: 1px solid var(--border-subtle);
|
|
497
|
+
border-radius: 3px;
|
|
498
|
+
height: 18px;
|
|
499
|
+
padding: 0;
|
|
500
|
+
width: 24px;
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
/* The opacity row that used to be here has moved to core's Cells section
|
|
504
|
+
(index.html, .cell-layer-opacity). Compositing is the viewer's, so the slider
|
|
505
|
+
is shared by every plugin that colours cells rather than each shipping one. */
|
|
506
|
+
|
|
507
|
+
/* Waiting for the segmentation mask this project draws cells on.
|
|
508
|
+
*
|
|
509
|
+
* Shaped like the two empty states above rather than like a modal: it is one
|
|
510
|
+
* of the panel's states, not something laid over it, and it gives way to the
|
|
511
|
+
* real panel the moment the pyramid lands. */
|
|
512
|
+
.cex-mask-wait {
|
|
513
|
+
padding: 4px 2px 2px;
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
.cex-mask-wait-title {
|
|
517
|
+
color: var(--text-secondary);
|
|
518
|
+
font-size: 12px;
|
|
519
|
+
font-weight: 600;
|
|
520
|
+
margin: 0 0 8px;
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
.cex-mask-wait-track {
|
|
524
|
+
background: rgba(255, 255, 255, 0.08);
|
|
525
|
+
border-radius: 999px;
|
|
526
|
+
height: 4px;
|
|
527
|
+
overflow: hidden;
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
.cex-mask-wait-bar {
|
|
531
|
+
background: var(--accent-channel);
|
|
532
|
+
border-radius: 999px;
|
|
533
|
+
height: 100%;
|
|
534
|
+
transition: width 0.3s ease;
|
|
535
|
+
width: 0;
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
/* A job that reports no percentage. Full width at low opacity says "working"
|
|
539
|
+
without claiming a position it does not know -- a bar frozen at 0 reads as a
|
|
540
|
+
job that has stalled. */
|
|
541
|
+
.cex-mask-wait-bar.is-indeterminate {
|
|
542
|
+
animation: cex-mask-wait-pulse 1.6s ease-in-out infinite;
|
|
543
|
+
opacity: 0.35;
|
|
544
|
+
transition: none;
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
@keyframes cex-mask-wait-pulse {
|
|
548
|
+
0%, 100% { opacity: 0.18; }
|
|
549
|
+
50% { opacity: 0.45; }
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
.cex-mask-wait .cex-hint {
|
|
553
|
+
margin: 8px 0 0;
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
/* The way into the ROI composition feature.
|
|
557
|
+
*
|
|
558
|
+
* Full width and named, sitting under the colour-by line where the eye already
|
|
559
|
+
* is, because this is the only announcement the feature gets. The hint carries
|
|
560
|
+
* as much weight as the button: it is the sentence that explains why anyone
|
|
561
|
+
* would press it. */
|
|
562
|
+
/* The button itself is core's .sidebar-action-fancy -- the shape this app
|
|
563
|
+
already uses for "here is a thing you may not know about", so this feature
|
|
564
|
+
announces itself the same way the others do rather than in a style of its
|
|
565
|
+
own. Only the spacing around it belongs here. */
|
|
566
|
+
.cex-roi-launch {
|
|
567
|
+
margin-bottom: 2px;
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
.cex-roi-launch .sidebar-action-fancy {
|
|
571
|
+
margin-top: 10px;
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
.cex-roi-launch-hint {
|
|
575
|
+
color: var(--text-muted);
|
|
576
|
+
font-size: 11px;
|
|
577
|
+
line-height: 1.35;
|
|
578
|
+
margin: 4px 2px 0;
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
/* The ROI composition card.
|
|
582
|
+
*
|
|
583
|
+
* Floats over the image rather than living in the panel, and is therefore the
|
|
584
|
+
* one thing this stylesheet places on <body> -- see cellExplorerRoiBridge.js.
|
|
585
|
+
* It is positioned in client pixels by JS; everything here is appearance.
|
|
586
|
+
*
|
|
587
|
+
* The tokens are core's, like the rest of this file, so the card matches the
|
|
588
|
+
* sidebar it belongs to and follows any theme change with it. */
|
|
589
|
+
.cex-roi-card {
|
|
590
|
+
background: var(--surface-2);
|
|
591
|
+
border: 1px solid var(--border-strong);
|
|
592
|
+
border-radius: var(--radius-sm);
|
|
593
|
+
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.45);
|
|
594
|
+
display: flex;
|
|
595
|
+
flex-direction: column;
|
|
596
|
+
gap: 6px;
|
|
597
|
+
font-size: 12px;
|
|
598
|
+
max-width: 280px;
|
|
599
|
+
min-width: 220px;
|
|
600
|
+
padding: 10px 12px;
|
|
601
|
+
position: fixed;
|
|
602
|
+
z-index: 1200;
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
/* The first hover of a session, waiting on every cell's position. The card
|
|
606
|
+
itself rather than a spinner somewhere else: it is the answer's frame
|
|
607
|
+
arriving before the answer, so nothing moves when the bars land. */
|
|
608
|
+
.cex-roi-card.is-pending .cex-roi-card-empty {
|
|
609
|
+
opacity: 0.7;
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
/* The card sets a display of its own, which outranks the UA rule for [hidden]
|
|
613
|
+
-- the same trap the panel section hits at the top of this file. */
|
|
614
|
+
.cex-roi-card[hidden],
|
|
615
|
+
.cex-roi-card [hidden] {
|
|
616
|
+
display: none;
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
.cex-roi-card-head {
|
|
620
|
+
align-items: baseline;
|
|
621
|
+
display: flex;
|
|
622
|
+
gap: 8px;
|
|
623
|
+
justify-content: space-between;
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
.cex-roi-card-name {
|
|
627
|
+
color: var(--text-primary);
|
|
628
|
+
font-weight: 600;
|
|
629
|
+
overflow: hidden;
|
|
630
|
+
text-overflow: ellipsis;
|
|
631
|
+
white-space: nowrap;
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
.cex-roi-card-total {
|
|
635
|
+
color: var(--text-secondary);
|
|
636
|
+
flex: none;
|
|
637
|
+
font-variant-numeric: tabular-nums;
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
/* Which variable the bars are OF, said quietly. It is context for the numbers,
|
|
641
|
+
not their heading -- the user chose it a moment ago in the panel. */
|
|
642
|
+
.cex-roi-card-variable {
|
|
643
|
+
color: var(--text-muted);
|
|
644
|
+
font-size: 10px;
|
|
645
|
+
letter-spacing: 0.04em;
|
|
646
|
+
margin-top: -4px;
|
|
647
|
+
overflow: hidden;
|
|
648
|
+
text-overflow: ellipsis;
|
|
649
|
+
text-transform: uppercase;
|
|
650
|
+
white-space: nowrap;
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
.cex-roi-card-bars {
|
|
654
|
+
display: flex;
|
|
655
|
+
flex-direction: column;
|
|
656
|
+
gap: 5px;
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
/* Expanded, the list can outgrow the screen. It scrolls inside the card rather
|
|
660
|
+
than the card growing past the image, so the ranking stays where the pointer
|
|
661
|
+
left it. */
|
|
662
|
+
.cex-roi-card.is-expanded .cex-roi-card-bars {
|
|
663
|
+
max-height: 45vh;
|
|
664
|
+
overflow-y: auto;
|
|
665
|
+
padding-right: 4px;
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
.cex-roi-bar {
|
|
669
|
+
display: flex;
|
|
670
|
+
flex-direction: column;
|
|
671
|
+
gap: 2px;
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
.cex-roi-bar-label {
|
|
675
|
+
color: var(--text-secondary);
|
|
676
|
+
overflow: hidden;
|
|
677
|
+
text-overflow: ellipsis;
|
|
678
|
+
white-space: nowrap;
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
/* The fixed 0-100% track. Its width is the denominator every bar is measured
|
|
682
|
+
against, which is what makes two regions comparable by eye. */
|
|
683
|
+
.cex-roi-bar-track {
|
|
684
|
+
background: rgba(255, 255, 255, 0.06);
|
|
685
|
+
border-radius: 2px;
|
|
686
|
+
height: 10px;
|
|
687
|
+
position: relative;
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
.cex-roi-bar-fill {
|
|
691
|
+
border-radius: 2px;
|
|
692
|
+
height: 100%;
|
|
693
|
+
min-width: 1px;
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
/* Sits just past the end of its own bar. `left` or `right` is set inline from
|
|
697
|
+
the percentage, because the offset is the bar's length -- not something CSS
|
|
698
|
+
can know. */
|
|
699
|
+
.cex-roi-bar-count {
|
|
700
|
+
color: var(--text-secondary);
|
|
701
|
+
font-size: 10px;
|
|
702
|
+
font-variant-numeric: tabular-nums;
|
|
703
|
+
line-height: 10px;
|
|
704
|
+
position: absolute;
|
|
705
|
+
top: 0;
|
|
706
|
+
white-space: nowrap;
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
/* Long enough a bar that the number has to go inside it. */
|
|
710
|
+
.cex-roi-bar-count.is-inside {
|
|
711
|
+
color: rgba(255, 255, 255, 0.92);
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
.cex-roi-bar.is-other .cex-roi-bar-label,
|
|
715
|
+
.cex-roi-bar.is-other .cex-roi-bar-count {
|
|
716
|
+
font-style: italic;
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
.cex-roi-card-empty {
|
|
720
|
+
color: var(--text-muted);
|
|
721
|
+
margin: 0;
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
.cex-roi-card-more {
|
|
725
|
+
align-self: flex-start;
|
|
726
|
+
background: none;
|
|
727
|
+
border: none;
|
|
728
|
+
color: var(--accent-channel);
|
|
729
|
+
cursor: pointer;
|
|
730
|
+
font-size: 11px;
|
|
731
|
+
padding: 2px 0;
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
.cex-roi-card-more:hover {
|
|
735
|
+
text-decoration: underline;
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
/* The exact figures for one bar, on top of the card rather than beside it, so
|
|
739
|
+
revealing them never changes the card's size or its position. */
|
|
740
|
+
.cex-roi-card-tip {
|
|
741
|
+
background: rgba(12, 16, 24, 0.96);
|
|
742
|
+
border: 1px solid var(--border-strong);
|
|
743
|
+
border-radius: 3px;
|
|
744
|
+
color: var(--text-primary);
|
|
745
|
+
font-size: 11px;
|
|
746
|
+
left: 12px;
|
|
747
|
+
padding: 3px 7px;
|
|
748
|
+
pointer-events: none;
|
|
749
|
+
position: absolute;
|
|
750
|
+
right: 12px;
|
|
751
|
+
white-space: nowrap;
|
|
752
|
+
}
|