scitex 2.14.0__py3-none-any.whl → 2.15.2__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.
Files changed (300) hide show
  1. scitex/__init__.py +71 -17
  2. scitex/_env_loader.py +156 -0
  3. scitex/_mcp_resources/__init__.py +37 -0
  4. scitex/_mcp_resources/_cheatsheet.py +135 -0
  5. scitex/_mcp_resources/_figrecipe.py +138 -0
  6. scitex/_mcp_resources/_formats.py +102 -0
  7. scitex/_mcp_resources/_modules.py +337 -0
  8. scitex/_mcp_resources/_session.py +149 -0
  9. scitex/_mcp_tools/__init__.py +4 -0
  10. scitex/_mcp_tools/audio.py +66 -0
  11. scitex/_mcp_tools/diagram.py +11 -95
  12. scitex/_mcp_tools/introspect.py +210 -0
  13. scitex/_mcp_tools/plt.py +260 -305
  14. scitex/_mcp_tools/scholar.py +74 -0
  15. scitex/_mcp_tools/social.py +244 -0
  16. scitex/_mcp_tools/template.py +24 -0
  17. scitex/_mcp_tools/writer.py +21 -204
  18. scitex/ai/_gen_ai/_PARAMS.py +10 -7
  19. scitex/ai/classification/reporters/_SingleClassificationReporter.py +45 -1603
  20. scitex/ai/classification/reporters/_mixins/__init__.py +36 -0
  21. scitex/ai/classification/reporters/_mixins/_constants.py +67 -0
  22. scitex/ai/classification/reporters/_mixins/_cv_summary.py +387 -0
  23. scitex/ai/classification/reporters/_mixins/_feature_importance.py +119 -0
  24. scitex/ai/classification/reporters/_mixins/_metrics.py +275 -0
  25. scitex/ai/classification/reporters/_mixins/_plotting.py +179 -0
  26. scitex/ai/classification/reporters/_mixins/_reports.py +153 -0
  27. scitex/ai/classification/reporters/_mixins/_storage.py +160 -0
  28. scitex/ai/classification/timeseries/_TimeSeriesSlidingWindowSplit.py +30 -1550
  29. scitex/ai/classification/timeseries/_sliding_window_core.py +467 -0
  30. scitex/ai/classification/timeseries/_sliding_window_plotting.py +369 -0
  31. scitex/audio/README.md +40 -36
  32. scitex/audio/__init__.py +129 -61
  33. scitex/audio/_branding.py +185 -0
  34. scitex/audio/_mcp/__init__.py +32 -0
  35. scitex/audio/_mcp/handlers.py +59 -6
  36. scitex/audio/_mcp/speak_handlers.py +238 -0
  37. scitex/audio/_relay.py +225 -0
  38. scitex/audio/_tts.py +18 -10
  39. scitex/audio/engines/base.py +17 -10
  40. scitex/audio/engines/elevenlabs_engine.py +7 -2
  41. scitex/audio/mcp_server.py +228 -75
  42. scitex/canvas/README.md +1 -1
  43. scitex/canvas/editor/_dearpygui/__init__.py +25 -0
  44. scitex/canvas/editor/_dearpygui/_editor.py +147 -0
  45. scitex/canvas/editor/_dearpygui/_handlers.py +476 -0
  46. scitex/canvas/editor/_dearpygui/_panels/__init__.py +17 -0
  47. scitex/canvas/editor/_dearpygui/_panels/_control.py +119 -0
  48. scitex/canvas/editor/_dearpygui/_panels/_element_controls.py +190 -0
  49. scitex/canvas/editor/_dearpygui/_panels/_preview.py +43 -0
  50. scitex/canvas/editor/_dearpygui/_panels/_sections.py +390 -0
  51. scitex/canvas/editor/_dearpygui/_plotting.py +187 -0
  52. scitex/canvas/editor/_dearpygui/_rendering.py +504 -0
  53. scitex/canvas/editor/_dearpygui/_selection.py +295 -0
  54. scitex/canvas/editor/_dearpygui/_state.py +93 -0
  55. scitex/canvas/editor/_dearpygui/_utils.py +61 -0
  56. scitex/canvas/editor/flask_editor/_core/__init__.py +27 -0
  57. scitex/canvas/editor/flask_editor/_core/_bbox_extraction.py +200 -0
  58. scitex/canvas/editor/flask_editor/_core/_editor.py +173 -0
  59. scitex/canvas/editor/flask_editor/_core/_export_helpers.py +353 -0
  60. scitex/canvas/editor/flask_editor/_core/_routes_basic.py +190 -0
  61. scitex/canvas/editor/flask_editor/_core/_routes_export.py +332 -0
  62. scitex/canvas/editor/flask_editor/_core/_routes_panels.py +252 -0
  63. scitex/canvas/editor/flask_editor/_core/_routes_save.py +218 -0
  64. scitex/canvas/editor/flask_editor/_core.py +25 -1684
  65. scitex/canvas/editor/flask_editor/templates/__init__.py +32 -70
  66. scitex/cli/__init__.py +38 -43
  67. scitex/cli/audio.py +76 -27
  68. scitex/cli/capture.py +13 -20
  69. scitex/cli/introspect.py +481 -0
  70. scitex/cli/main.py +200 -109
  71. scitex/cli/mcp.py +60 -34
  72. scitex/cli/plt.py +357 -0
  73. scitex/cli/repro.py +15 -8
  74. scitex/cli/resource.py +15 -8
  75. scitex/cli/scholar/__init__.py +23 -8
  76. scitex/cli/scholar/_crossref_scitex.py +296 -0
  77. scitex/cli/scholar/_fetch.py +25 -3
  78. scitex/cli/social.py +314 -0
  79. scitex/cli/stats.py +15 -8
  80. scitex/cli/template.py +129 -12
  81. scitex/cli/tex.py +15 -8
  82. scitex/cli/writer.py +132 -8
  83. scitex/cloud/__init__.py +41 -2
  84. scitex/config/README.md +1 -1
  85. scitex/config/__init__.py +16 -2
  86. scitex/config/_env_registry.py +256 -0
  87. scitex/context/__init__.py +22 -0
  88. scitex/dev/__init__.py +20 -1
  89. scitex/diagram/__init__.py +42 -19
  90. scitex/diagram/mcp_server.py +13 -125
  91. scitex/gen/__init__.py +50 -14
  92. scitex/gen/_list_packages.py +4 -4
  93. scitex/introspect/__init__.py +82 -0
  94. scitex/introspect/_call_graph.py +303 -0
  95. scitex/introspect/_class_hierarchy.py +163 -0
  96. scitex/introspect/_core.py +41 -0
  97. scitex/introspect/_docstring.py +131 -0
  98. scitex/introspect/_examples.py +113 -0
  99. scitex/introspect/_imports.py +271 -0
  100. scitex/{gen/_inspect_module.py → introspect/_list_api.py} +43 -54
  101. scitex/introspect/_mcp/__init__.py +41 -0
  102. scitex/introspect/_mcp/handlers.py +233 -0
  103. scitex/introspect/_members.py +155 -0
  104. scitex/introspect/_resolve.py +89 -0
  105. scitex/introspect/_signature.py +131 -0
  106. scitex/introspect/_source.py +80 -0
  107. scitex/introspect/_type_hints.py +172 -0
  108. scitex/io/_save.py +1 -2
  109. scitex/io/bundle/README.md +1 -1
  110. scitex/logging/_formatters.py +19 -9
  111. scitex/mcp_server.py +98 -5
  112. scitex/os/__init__.py +4 -0
  113. scitex/{gen → os}/_check_host.py +4 -5
  114. scitex/plt/__init__.py +245 -550
  115. scitex/plt/_subplots/_AxisWrapperMixins/_SeabornMixin/_wrappers.py +5 -10
  116. scitex/plt/docs/EXTERNAL_PACKAGE_BRANDING.md +149 -0
  117. scitex/plt/gallery/README.md +1 -1
  118. scitex/plt/utils/_hitmap/__init__.py +82 -0
  119. scitex/plt/utils/_hitmap/_artist_extraction.py +343 -0
  120. scitex/plt/utils/_hitmap/_color_application.py +346 -0
  121. scitex/plt/utils/_hitmap/_color_conversion.py +121 -0
  122. scitex/plt/utils/_hitmap/_constants.py +40 -0
  123. scitex/plt/utils/_hitmap/_hitmap_core.py +334 -0
  124. scitex/plt/utils/_hitmap/_path_extraction.py +357 -0
  125. scitex/plt/utils/_hitmap/_query.py +113 -0
  126. scitex/plt/utils/_hitmap.py +46 -1616
  127. scitex/plt/utils/_metadata/__init__.py +80 -0
  128. scitex/plt/utils/_metadata/_artists/__init__.py +25 -0
  129. scitex/plt/utils/_metadata/_artists/_base.py +195 -0
  130. scitex/plt/utils/_metadata/_artists/_collections.py +356 -0
  131. scitex/plt/utils/_metadata/_artists/_extract.py +57 -0
  132. scitex/plt/utils/_metadata/_artists/_images.py +80 -0
  133. scitex/plt/utils/_metadata/_artists/_lines.py +261 -0
  134. scitex/plt/utils/_metadata/_artists/_patches.py +247 -0
  135. scitex/plt/utils/_metadata/_artists/_text.py +106 -0
  136. scitex/plt/utils/_metadata/_csv.py +416 -0
  137. scitex/plt/utils/_metadata/_detect.py +225 -0
  138. scitex/plt/utils/_metadata/_legend.py +127 -0
  139. scitex/plt/utils/_metadata/_rounding.py +117 -0
  140. scitex/plt/utils/_metadata/_verification.py +202 -0
  141. scitex/schema/README.md +1 -1
  142. scitex/scholar/__init__.py +8 -0
  143. scitex/scholar/_mcp/crossref_handlers.py +265 -0
  144. scitex/scholar/core/Scholar.py +63 -1700
  145. scitex/scholar/core/_mixins/__init__.py +36 -0
  146. scitex/scholar/core/_mixins/_enrichers.py +270 -0
  147. scitex/scholar/core/_mixins/_library_handlers.py +100 -0
  148. scitex/scholar/core/_mixins/_loaders.py +103 -0
  149. scitex/scholar/core/_mixins/_pdf_download.py +375 -0
  150. scitex/scholar/core/_mixins/_pipeline.py +312 -0
  151. scitex/scholar/core/_mixins/_project_handlers.py +125 -0
  152. scitex/scholar/core/_mixins/_savers.py +69 -0
  153. scitex/scholar/core/_mixins/_search.py +103 -0
  154. scitex/scholar/core/_mixins/_services.py +88 -0
  155. scitex/scholar/core/_mixins/_url_finding.py +105 -0
  156. scitex/scholar/crossref_scitex.py +367 -0
  157. scitex/scholar/docs/EXTERNAL_PACKAGE_BRANDING.md +149 -0
  158. scitex/scholar/examples/00_run_all.sh +120 -0
  159. scitex/scholar/jobs/_executors.py +27 -3
  160. scitex/scholar/pdf_download/ScholarPDFDownloader.py +38 -416
  161. scitex/scholar/pdf_download/_cli.py +154 -0
  162. scitex/scholar/pdf_download/strategies/__init__.py +11 -8
  163. scitex/scholar/pdf_download/strategies/manual_download_fallback.py +80 -3
  164. scitex/scholar/pipelines/ScholarPipelineBibTeX.py +73 -121
  165. scitex/scholar/pipelines/ScholarPipelineParallel.py +80 -138
  166. scitex/scholar/pipelines/ScholarPipelineSingle.py +43 -63
  167. scitex/scholar/pipelines/_single_steps.py +71 -36
  168. scitex/scholar/storage/_LibraryManager.py +97 -1695
  169. scitex/scholar/storage/_mixins/__init__.py +30 -0
  170. scitex/scholar/storage/_mixins/_bibtex_handlers.py +128 -0
  171. scitex/scholar/storage/_mixins/_library_operations.py +218 -0
  172. scitex/scholar/storage/_mixins/_metadata_conversion.py +226 -0
  173. scitex/scholar/storage/_mixins/_paper_saving.py +456 -0
  174. scitex/scholar/storage/_mixins/_resolution.py +376 -0
  175. scitex/scholar/storage/_mixins/_storage_helpers.py +121 -0
  176. scitex/scholar/storage/_mixins/_symlink_handlers.py +226 -0
  177. scitex/scholar/url_finder/.tmp/open_url/KNOWN_RESOLVERS.py +462 -0
  178. scitex/scholar/url_finder/.tmp/open_url/README.md +223 -0
  179. scitex/scholar/url_finder/.tmp/open_url/_DOIToURLResolver.py +694 -0
  180. scitex/scholar/url_finder/.tmp/open_url/_OpenURLResolver.py +1160 -0
  181. scitex/scholar/url_finder/.tmp/open_url/_ResolverLinkFinder.py +344 -0
  182. scitex/scholar/url_finder/.tmp/open_url/__init__.py +24 -0
  183. scitex/security/README.md +3 -3
  184. scitex/session/README.md +1 -1
  185. scitex/session/__init__.py +26 -7
  186. scitex/session/_decorator.py +1 -1
  187. scitex/sh/README.md +1 -1
  188. scitex/sh/__init__.py +7 -4
  189. scitex/social/__init__.py +155 -0
  190. scitex/social/docs/EXTERNAL_PACKAGE_BRANDING.md +149 -0
  191. scitex/stats/_mcp/_handlers/__init__.py +31 -0
  192. scitex/stats/_mcp/_handlers/_corrections.py +113 -0
  193. scitex/stats/_mcp/_handlers/_descriptive.py +78 -0
  194. scitex/stats/_mcp/_handlers/_effect_size.py +106 -0
  195. scitex/stats/_mcp/_handlers/_format.py +94 -0
  196. scitex/stats/_mcp/_handlers/_normality.py +110 -0
  197. scitex/stats/_mcp/_handlers/_posthoc.py +224 -0
  198. scitex/stats/_mcp/_handlers/_power.py +247 -0
  199. scitex/stats/_mcp/_handlers/_recommend.py +102 -0
  200. scitex/stats/_mcp/_handlers/_run_test.py +279 -0
  201. scitex/stats/_mcp/_handlers/_stars.py +48 -0
  202. scitex/stats/_mcp/handlers.py +19 -1171
  203. scitex/stats/auto/_stat_style.py +175 -0
  204. scitex/stats/auto/_style_definitions.py +411 -0
  205. scitex/stats/auto/_styles.py +22 -620
  206. scitex/stats/descriptive/__init__.py +11 -8
  207. scitex/stats/descriptive/_ci.py +39 -0
  208. scitex/stats/power/_power.py +15 -4
  209. scitex/str/__init__.py +2 -1
  210. scitex/str/_title_case.py +63 -0
  211. scitex/template/README.md +1 -1
  212. scitex/template/__init__.py +25 -10
  213. scitex/template/_code_templates.py +147 -0
  214. scitex/template/_mcp/handlers.py +81 -0
  215. scitex/template/_mcp/tool_schemas.py +55 -0
  216. scitex/template/_templates/__init__.py +51 -0
  217. scitex/template/_templates/audio.py +233 -0
  218. scitex/template/_templates/canvas.py +312 -0
  219. scitex/template/_templates/capture.py +268 -0
  220. scitex/template/_templates/config.py +43 -0
  221. scitex/template/_templates/diagram.py +294 -0
  222. scitex/template/_templates/io.py +107 -0
  223. scitex/template/_templates/module.py +53 -0
  224. scitex/template/_templates/plt.py +202 -0
  225. scitex/template/_templates/scholar.py +267 -0
  226. scitex/template/_templates/session.py +130 -0
  227. scitex/template/_templates/session_minimal.py +43 -0
  228. scitex/template/_templates/session_plot.py +67 -0
  229. scitex/template/_templates/session_stats.py +77 -0
  230. scitex/template/_templates/stats.py +323 -0
  231. scitex/template/_templates/writer.py +296 -0
  232. scitex/template/clone_writer_directory.py +5 -5
  233. scitex/ui/_backends/_email.py +10 -2
  234. scitex/ui/_backends/_webhook.py +5 -1
  235. scitex/web/_search_pubmed.py +10 -6
  236. scitex/writer/README.md +1 -1
  237. scitex/writer/_mcp/handlers.py +11 -744
  238. scitex/writer/_mcp/tool_schemas.py +5 -335
  239. scitex-2.15.2.dist-info/METADATA +648 -0
  240. {scitex-2.14.0.dist-info → scitex-2.15.2.dist-info}/RECORD +246 -150
  241. scitex/canvas/editor/flask_editor/templates/_scripts.py +0 -4933
  242. scitex/canvas/editor/flask_editor/templates/_styles.py +0 -1658
  243. scitex/dev/plt/data/mpl/PLOTTING_FUNCTIONS.yaml +0 -90
  244. scitex/dev/plt/data/mpl/PLOTTING_SIGNATURES.yaml +0 -1571
  245. scitex/dev/plt/data/mpl/PLOTTING_SIGNATURES_DETAILED.yaml +0 -6262
  246. scitex/dev/plt/data/mpl/SIGNATURES_FLATTENED.yaml +0 -1274
  247. scitex/dev/plt/data/mpl/dir_ax.txt +0 -459
  248. scitex/diagram/_compile.py +0 -312
  249. scitex/diagram/_diagram.py +0 -355
  250. scitex/diagram/_mcp/__init__.py +0 -4
  251. scitex/diagram/_mcp/handlers.py +0 -400
  252. scitex/diagram/_mcp/tool_schemas.py +0 -157
  253. scitex/diagram/_presets.py +0 -173
  254. scitex/diagram/_schema.py +0 -182
  255. scitex/diagram/_split.py +0 -278
  256. scitex/gen/_ci.py +0 -12
  257. scitex/gen/_title_case.py +0 -89
  258. scitex/plt/_mcp/__init__.py +0 -4
  259. scitex/plt/_mcp/_handlers_annotation.py +0 -102
  260. scitex/plt/_mcp/_handlers_figure.py +0 -195
  261. scitex/plt/_mcp/_handlers_plot.py +0 -252
  262. scitex/plt/_mcp/_handlers_style.py +0 -219
  263. scitex/plt/_mcp/handlers.py +0 -74
  264. scitex/plt/_mcp/tool_schemas.py +0 -497
  265. scitex/plt/mcp_server.py +0 -231
  266. scitex/scholar/data/.gitkeep +0 -0
  267. scitex/scholar/data/README.md +0 -44
  268. scitex/scholar/data/bib_files/bibliography.bib +0 -1952
  269. scitex/scholar/data/bib_files/neurovista.bib +0 -277
  270. scitex/scholar/data/bib_files/neurovista_enriched.bib +0 -441
  271. scitex/scholar/data/bib_files/neurovista_enriched_enriched.bib +0 -441
  272. scitex/scholar/data/bib_files/neurovista_processed.bib +0 -338
  273. scitex/scholar/data/bib_files/openaccess.bib +0 -89
  274. scitex/scholar/data/bib_files/pac-seizure_prediction_enriched.bib +0 -2178
  275. scitex/scholar/data/bib_files/pac.bib +0 -698
  276. scitex/scholar/data/bib_files/pac_enriched.bib +0 -1061
  277. scitex/scholar/data/bib_files/pac_processed.bib +0 -0
  278. scitex/scholar/data/bib_files/pac_titles.txt +0 -75
  279. scitex/scholar/data/bib_files/paywalled.bib +0 -98
  280. scitex/scholar/data/bib_files/related-papers-by-coauthors.bib +0 -58
  281. scitex/scholar/data/bib_files/related-papers-by-coauthors_enriched.bib +0 -87
  282. scitex/scholar/data/bib_files/seizure_prediction.bib +0 -694
  283. scitex/scholar/data/bib_files/seizure_prediction_processed.bib +0 -0
  284. scitex/scholar/data/bib_files/test_complete_enriched.bib +0 -437
  285. scitex/scholar/data/bib_files/test_final_enriched.bib +0 -437
  286. scitex/scholar/data/bib_files/test_seizure.bib +0 -46
  287. scitex/scholar/data/impact_factor/JCR_IF_2022.xlsx +0 -0
  288. scitex/scholar/data/impact_factor/JCR_IF_2024.db +0 -0
  289. scitex/scholar/data/impact_factor/JCR_IF_2024.xlsx +0 -0
  290. scitex/scholar/data/impact_factor/JCR_IF_2024_v01.db +0 -0
  291. scitex/scholar/data/impact_factor.db +0 -0
  292. scitex/scholar/examples/SUGGESTIONS.md +0 -865
  293. scitex/scholar/examples/dev.py +0 -38
  294. scitex-2.14.0.dist-info/METADATA +0 -1238
  295. /scitex/{gen → context}/_detect_environment.py +0 -0
  296. /scitex/{gen → context}/_get_notebook_path.py +0 -0
  297. /scitex/{gen/_shell.py → sh/_shell_legacy.py} +0 -0
  298. {scitex-2.14.0.dist-info → scitex-2.15.2.dist-info}/WHEEL +0 -0
  299. {scitex-2.14.0.dist-info → scitex-2.15.2.dist-info}/entry_points.txt +0 -0
  300. {scitex-2.14.0.dist-info → scitex-2.15.2.dist-info}/licenses/LICENSE +0 -0
@@ -1,1658 +0,0 @@
1
- #!/usr/bin/env python3
2
- # -*- coding: utf-8 -*-
3
- # File: ./src/scitex/vis/editor/flask_editor/templates/styles.py
4
- """CSS styles for the Flask editor UI.
5
-
6
- DEPRECATED: This inline CSS module is kept for fallback compatibility only.
7
- The CSS has been modularized into static/css/ directory:
8
- - static/css/index.css (main entry point with @imports)
9
- - static/css/base/ (variables, reset, typography)
10
- - static/css/layout/ (container, preview, controls)
11
- - static/css/components/ (buttons, forms, sections, dropdown, modal, context-menu)
12
- - static/css/features/ (canvas, panel-grid, selection, overlay, loading, statistics)
13
-
14
- To use static files (recommended):
15
- Set USE_STATIC_FILES = True in templates/__init__.py
16
-
17
- To use this inline version (fallback):
18
- Set USE_STATIC_FILES = False in templates/__init__.py
19
- """
20
-
21
- CSS_STYLES = """
22
- /* =============================================================================
23
- * SciTeX Color System - Based on scitex-cloud/static/shared/css
24
- * ============================================================================= */
25
- :root, [data-theme="light"] {
26
- /* Brand colors (light mode) */
27
- --scitex-01: #1a2a40;
28
- --scitex-02: #34495e;
29
- --scitex-03: #506b7a;
30
- --scitex-04: #6c8ba0;
31
- --scitex-05: #8fa4b0;
32
- --scitex-06: #b5c7d1;
33
- --scitex-07: #d4e1e8;
34
- --white: #fafbfc;
35
- --gray-subtle: #f6f8fa;
36
-
37
- /* Semantic tokens */
38
- --text-primary: var(--scitex-01);
39
- --text-secondary: var(--scitex-02);
40
- --text-muted: var(--scitex-04);
41
- --text-inverse: var(--white);
42
-
43
- --bg-page: #fefefe;
44
- --bg-surface: var(--white);
45
- --bg-muted: var(--gray-subtle);
46
-
47
- --border-default: var(--scitex-05);
48
- --border-muted: var(--scitex-06);
49
-
50
- /* Workspace colors */
51
- --workspace-bg-primary: #f8f9fa;
52
- --workspace-bg-secondary: #f3f4f6;
53
- --workspace-bg-tertiary: #ebedef;
54
- --workspace-bg-elevated: #ffffff;
55
- --workspace-border-subtle: #e0e4e8;
56
- --workspace-border-default: #b5c7d1;
57
-
58
- /* Status */
59
- --status-success: #4a9b7e;
60
- --status-warning: #b8956a;
61
- --status-error: #a67373;
62
-
63
- /* CTA */
64
- --color-cta: #3b82f6;
65
- --color-cta-hover: #2563eb;
66
-
67
- /* Preview background (checkered for transparency) */
68
- --preview-bg: linear-gradient(45deg, #e0e0e0 25%, transparent 25%),
69
- linear-gradient(-45deg, #e0e0e0 25%, transparent 25%),
70
- linear-gradient(45deg, transparent 75%, #e0e0e0 75%),
71
- linear-gradient(-45deg, transparent 75%, #e0e0e0 75%);
72
- }
73
-
74
- [data-theme="dark"] {
75
- /* Semantic tokens (dark mode) */
76
- --text-primary: var(--scitex-07);
77
- --text-secondary: var(--scitex-05);
78
- --text-muted: var(--scitex-04);
79
- --text-inverse: var(--scitex-01);
80
-
81
- --bg-page: #0f1419;
82
- --bg-surface: var(--scitex-01);
83
- --bg-muted: var(--scitex-02);
84
-
85
- --border-default: var(--scitex-03);
86
- --border-muted: var(--scitex-02);
87
-
88
- /* Workspace colors */
89
- --workspace-bg-primary: #0d0d0d;
90
- --workspace-bg-secondary: #151515;
91
- --workspace-bg-tertiary: #1a1a1a;
92
- --workspace-bg-elevated: #1f1f1f;
93
- --workspace-border-subtle: #1a1a1a;
94
- --workspace-border-default: #3a3a3a;
95
-
96
- /* Status */
97
- --status-success: #6ba89a;
98
- --status-warning: #d4a87a;
99
- --status-error: #c08888;
100
-
101
- /* Preview background (darker checkered) */
102
- --preview-bg: linear-gradient(45deg, #2a2a2a 25%, transparent 25%),
103
- linear-gradient(-45deg, #2a2a2a 25%, transparent 25%),
104
- linear-gradient(45deg, transparent 75%, #2a2a2a 75%),
105
- linear-gradient(-45deg, transparent 75%, #2a2a2a 75%);
106
- }
107
-
108
- /* =============================================================================
109
- * Base Styles
110
- * ============================================================================= */
111
- * { box-sizing: border-box; margin: 0; padding: 0; }
112
-
113
- body {
114
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
115
- background: var(--workspace-bg-primary);
116
- color: var(--text-primary);
117
- transition: background 0.3s, color 0.3s;
118
- }
119
-
120
- .container { display: flex; height: 100vh; }
121
-
122
- /* =============================================================================
123
- * Preview Panel
124
- * ============================================================================= */
125
- .preview {
126
- flex: 2;
127
- padding: 20px;
128
- display: flex;
129
- align-items: center;
130
- justify-content: center;
131
- background: var(--workspace-bg-secondary);
132
- }
133
-
134
- .preview-wrapper {
135
- background: var(--preview-bg);
136
- background-size: 20px 20px;
137
- background-position: 0 0, 0 10px, 10px -10px, -10px 0px;
138
- border-radius: 8px;
139
- padding: 10px;
140
- box-shadow: 0 4px 20px rgba(0,0,0,0.15);
141
- }
142
-
143
- .preview img {
144
- max-width: 100%;
145
- max-height: calc(100vh - 80px);
146
- display: block;
147
- }
148
-
149
- /* Hover overlay for interactive selection */
150
- .preview-container {
151
- position: relative;
152
- display: inline-block;
153
- }
154
-
155
- .hover-overlay {
156
- position: absolute;
157
- top: 0;
158
- left: 0;
159
- pointer-events: none;
160
- }
161
-
162
- /* Color-neutral hover/selection: white outline with glow works with any element color */
163
- .hover-rect {
164
- fill: none;
165
- stroke: rgba(255, 255, 255, 0.9);
166
- stroke-width: 2;
167
- pointer-events: none;
168
- filter: drop-shadow(0 0 3px rgba(0, 0, 0, 0.5)) drop-shadow(0 0 1px rgba(255, 255, 255, 0.8));
169
- }
170
-
171
- .selected-rect {
172
- fill: none;
173
- stroke: rgba(255, 255, 255, 1);
174
- stroke-width: 2;
175
- stroke-dasharray: 4 2;
176
- pointer-events: none;
177
- filter: drop-shadow(0 0 4px rgba(0, 0, 0, 0.7)) drop-shadow(0 0 2px rgba(255, 255, 255, 1));
178
- }
179
-
180
- .hover-label {
181
- font-size: 10px;
182
- fill: rgba(255, 255, 255, 0.9);
183
- pointer-events: none;
184
- filter: drop-shadow(0 0 2px rgba(0, 0, 0, 0.8));
185
- }
186
-
187
- .selected-label {
188
- font-size: 10px;
189
- fill: rgba(255, 255, 255, 1);
190
- pointer-events: none;
191
- filter: drop-shadow(0 0 3px rgba(0, 0, 0, 0.9));
192
- }
193
-
194
- .hover-path {
195
- fill: none;
196
- stroke: rgba(255, 255, 255, 0.9);
197
- stroke-width: 6;
198
- stroke-linecap: round;
199
- stroke-linejoin: round;
200
- pointer-events: none;
201
- filter: drop-shadow(0 0 3px rgba(0, 0, 0, 0.6));
202
- }
203
-
204
- .selected-path {
205
- fill: none;
206
- stroke: rgba(255, 255, 255, 1);
207
- stroke-width: 6;
208
- stroke-linecap: round;
209
- stroke-linejoin: round;
210
- stroke-dasharray: 8 4;
211
- pointer-events: none;
212
- filter: drop-shadow(0 0 4px rgba(0, 0, 0, 0.7));
213
- }
214
-
215
- /* Debug mode - show all hit areas */
216
- .debug-rect {
217
- fill: rgba(255, 0, 0, 0.15);
218
- stroke: rgba(255, 0, 0, 0.6);
219
- stroke-width: 1;
220
- stroke-dasharray: 4 2;
221
- pointer-events: none;
222
- }
223
-
224
- .debug-rect-trace {
225
- fill: rgba(0, 255, 0, 0.15);
226
- stroke: rgba(0, 200, 0, 0.8);
227
- stroke-width: 1;
228
- stroke-dasharray: 3 2;
229
- pointer-events: none;
230
- }
231
-
232
- .debug-rect-legend {
233
- fill: rgba(255, 165, 0, 0.2);
234
- stroke: rgba(255, 140, 0, 0.8);
235
- stroke-width: 1;
236
- stroke-dasharray: 3 2;
237
- pointer-events: none;
238
- }
239
-
240
- .debug-label {
241
- font-size: 8px;
242
- fill: rgba(255, 0, 0, 0.9);
243
- pointer-events: none;
244
- font-family: monospace;
245
- }
246
-
247
- .debug-path {
248
- fill: none;
249
- stroke: rgba(0, 200, 0, 0.7);
250
- stroke-width: 2;
251
- stroke-linecap: round;
252
- stroke-linejoin: round;
253
- stroke-dasharray: 5 3;
254
- pointer-events: none;
255
- }
256
-
257
- .debug-toggle {
258
- position: fixed;
259
- bottom: 10px;
260
- right: 10px;
261
- z-index: 1000;
262
- padding: 8px 12px;
263
- background: #333;
264
- color: #fff;
265
- border: none;
266
- border-radius: 4px;
267
- cursor: pointer;
268
- font-size: 12px;
269
- }
270
-
271
- .debug-toggle:hover {
272
- background: #555;
273
- }
274
-
275
- .debug-toggle.active {
276
- background: #c00;
277
- }
278
-
279
- /* Hover scatter: White ring around points */
280
- .hover-scatter {
281
- fill: none;
282
- stroke: rgba(255, 255, 255, 0.9);
283
- stroke-width: 3;
284
- pointer-events: none;
285
- filter: drop-shadow(0 0 2px rgba(0, 0, 0, 0.6));
286
- }
287
-
288
- /* Selected scatter: Dashed white ring */
289
- .selected-scatter {
290
- fill: none;
291
- stroke: rgba(255, 255, 255, 1);
292
- stroke-width: 3;
293
- stroke-dasharray: 3 2;
294
- pointer-events: none;
295
- filter: drop-shadow(0 0 3px rgba(0, 0, 0, 0.7));
296
- }
297
-
298
- /* =============================================================================
299
- * Selected Element Panel
300
- * ============================================================================= */
301
- #section-selected {
302
- border: 2px solid var(--accent-muted);
303
- background: var(--bg-secondary);
304
- }
305
-
306
- #section-selected .section-header {
307
- background: var(--accent-muted);
308
- color: var(--text-primary);
309
- font-weight: 600;
310
- }
311
-
312
- .selected-info {
313
- display: flex;
314
- align-items: center;
315
- gap: 10px;
316
- margin-bottom: 12px;
317
- padding: 8px;
318
- background: var(--bg-primary);
319
- border-radius: 4px;
320
- }
321
-
322
- .element-type-badge {
323
- padding: 4px 10px;
324
- border-radius: 12px;
325
- font-size: 11px;
326
- font-weight: 600;
327
- text-transform: uppercase;
328
- }
329
-
330
- .element-type-badge.trace { background: #3498db; color: white; }
331
- .element-type-badge.scatter { background: #e74c3c; color: white; }
332
- .element-type-badge.fill { background: #9b59b6; color: white; }
333
- .element-type-badge.bar { background: #f39c12; color: white; }
334
- .element-type-badge.label { background: #2ecc71; color: white; }
335
- .element-type-badge.panel { background: #34495e; color: white; }
336
- .element-type-badge.legend { background: #1abc9c; color: white; }
337
-
338
- .element-axis-info {
339
- font-size: 12px;
340
- color: var(--text-secondary);
341
- }
342
-
343
- .element-props {
344
- border-top: 1px solid var(--border-color);
345
- padding-top: 12px;
346
- margin-top: 8px;
347
- }
348
-
349
- /* Range slider styling */
350
- input[type="range"] {
351
- width: 100%;
352
- height: 6px;
353
- border-radius: 3px;
354
- background: var(--bg-tertiary);
355
- outline: none;
356
- -webkit-appearance: none;
357
- }
358
-
359
- input[type="range"]::-webkit-slider-thumb {
360
- -webkit-appearance: none;
361
- width: 16px;
362
- height: 16px;
363
- border-radius: 50%;
364
- background: var(--accent);
365
- cursor: pointer;
366
- }
367
-
368
- input[type="range"]::-moz-range-thumb {
369
- width: 16px;
370
- height: 16px;
371
- border-radius: 50%;
372
- background: var(--accent);
373
- cursor: pointer;
374
- border: none;
375
- }
376
-
377
- /* =============================================================================
378
- * Controls Panel
379
- * ============================================================================= */
380
- .controls {
381
- flex: 1;
382
- min-width: 320px;
383
- max-width: 420px;
384
- background: var(--workspace-bg-elevated);
385
- border-left: 1px solid var(--workspace-border-default);
386
- overflow-y: auto;
387
- display: flex;
388
- flex-direction: column;
389
- }
390
-
391
- .controls-header {
392
- padding: 12px 16px;
393
- border-bottom: 1px solid var(--workspace-border-subtle);
394
- display: flex;
395
- justify-content: space-between;
396
- align-items: center;
397
- background: var(--bg-surface);
398
- position: sticky;
399
- top: 0;
400
- z-index: 10;
401
- }
402
-
403
- .controls-header h1 {
404
- font-size: 1.0em;
405
- font-weight: 600;
406
- color: var(--status-success);
407
- }
408
-
409
- .controls-body {
410
- padding: 0 14px 14px;
411
- flex: 1;
412
- }
413
-
414
- .filename {
415
- font-size: 0.8em;
416
- color: var(--text-muted);
417
- margin-top: 4px;
418
- word-break: break-all;
419
- }
420
-
421
- .panel-path {
422
- font-size: 0.75em;
423
- color: var(--text-muted);
424
- margin-top: 2px;
425
- opacity: 0.8;
426
- }
427
-
428
- /* Theme toggle */
429
- .theme-toggle {
430
- background: transparent;
431
- border: 1px solid var(--border-muted);
432
- color: var(--text-secondary);
433
- cursor: pointer;
434
- font-size: 16px;
435
- padding: 6px 10px;
436
- border-radius: 6px;
437
- transition: all 0.2s;
438
- display: flex;
439
- align-items: center;
440
- gap: 6px;
441
- }
442
-
443
- .theme-toggle:hover {
444
- background: var(--bg-muted);
445
- border-color: var(--border-default);
446
- }
447
-
448
- /* =============================================================================
449
- * Section Headers
450
- * ============================================================================= */
451
- .section {
452
- margin-top: 10px;
453
- }
454
-
455
- .section-header {
456
- font-size: 0.72em;
457
- font-weight: 600;
458
- text-transform: uppercase;
459
- letter-spacing: 0.5px;
460
- color: var(--text-inverse);
461
- background: var(--status-success);
462
- padding: 6px 10px;
463
- border-radius: 4px;
464
- margin-bottom: 8px;
465
- }
466
-
467
- /* =============================================================================
468
- * Form Fields
469
- * ============================================================================= */
470
- .field { margin-bottom: 8px; }
471
-
472
- .field label {
473
- display: block;
474
- font-size: 0.78em;
475
- font-weight: 500;
476
- margin-bottom: 3px;
477
- color: var(--text-secondary);
478
- }
479
-
480
- .field input[type="text"],
481
- .field input[type="number"],
482
- .field select {
483
- width: 100%;
484
- padding: 5px 8px;
485
- border: 1px solid var(--border-muted);
486
- border-radius: 4px;
487
- background: var(--bg-surface);
488
- color: var(--text-primary);
489
- font-size: 0.82em;
490
- transition: border-color 0.2s;
491
- }
492
-
493
- .field input:focus,
494
- .field select:focus {
495
- outline: none;
496
- border-color: var(--status-success);
497
- }
498
-
499
- .field input[type="color"] {
500
- width: 40px;
501
- height: 32px;
502
- padding: 2px;
503
- border: 1px solid var(--border-muted);
504
- border-radius: 4px;
505
- cursor: pointer;
506
- background: var(--bg-surface);
507
- }
508
-
509
- .field-row {
510
- display: flex;
511
- gap: 8px;
512
- }
513
-
514
- .field-row .field { flex: 1; margin-bottom: 0; }
515
-
516
- /* Checkbox styling */
517
- .checkbox-field {
518
- display: flex;
519
- align-items: center;
520
- gap: 6px;
521
- cursor: pointer;
522
- padding: 4px 0;
523
- }
524
-
525
- .checkbox-field input[type="checkbox"] {
526
- width: 16px;
527
- height: 16px;
528
- accent-color: var(--status-success);
529
- }
530
-
531
- .checkbox-field span {
532
- font-size: 0.85em;
533
- color: var(--text-primary);
534
- }
535
-
536
- /* Color field with input */
537
- .color-field {
538
- display: flex;
539
- align-items: center;
540
- gap: 8px;
541
- }
542
-
543
- .color-field input[type="text"] {
544
- flex: 1;
545
- }
546
-
547
- /* =============================================================================
548
- * Traces Section
549
- * ============================================================================= */
550
- .traces-list {
551
- max-height: 200px;
552
- overflow-y: auto;
553
- border: 1px solid var(--border-muted);
554
- border-radius: 4px;
555
- background: var(--bg-muted);
556
- }
557
-
558
- .trace-item {
559
- display: flex;
560
- align-items: center;
561
- gap: 8px;
562
- padding: 8px 10px;
563
- border-bottom: 1px solid var(--border-muted);
564
- font-size: 0.85em;
565
- }
566
-
567
- .trace-item:last-child { border-bottom: none; }
568
-
569
- .trace-item-highlight {
570
- background: var(--status-success);
571
- color: var(--text-inverse);
572
- animation: traceHighlightFade 1.5s ease-out forwards;
573
- }
574
-
575
- @keyframes traceHighlightFade {
576
- 0% { background: var(--status-success); }
577
- 100% { background: var(--bg-muted); }
578
- }
579
-
580
- .trace-color {
581
- width: 24px;
582
- height: 24px;
583
- border-radius: 4px;
584
- border: 1px solid var(--border-default);
585
- cursor: pointer;
586
- }
587
-
588
- .trace-label {
589
- flex: 1;
590
- color: var(--text-primary);
591
- }
592
-
593
- .trace-style select {
594
- padding: 4px 6px;
595
- font-size: 0.8em;
596
- border: 1px solid var(--border-muted);
597
- border-radius: 3px;
598
- background: var(--bg-surface);
599
- color: var(--text-primary);
600
- }
601
-
602
- /* =============================================================================
603
- * Annotations
604
- * ============================================================================= */
605
- .annotations-list {
606
- margin-top: 10px;
607
- max-height: 120px;
608
- overflow-y: auto;
609
- }
610
-
611
- .annotation-item {
612
- display: flex;
613
- justify-content: space-between;
614
- align-items: center;
615
- padding: 6px 10px;
616
- background: var(--bg-muted);
617
- border-radius: 4px;
618
- margin-bottom: 5px;
619
- font-size: 0.85em;
620
- }
621
-
622
- .annotation-item span { color: var(--text-primary); }
623
-
624
- .annotation-item button {
625
- padding: 3px 8px;
626
- font-size: 0.75em;
627
- background: var(--status-error);
628
- border: none;
629
- border-radius: 3px;
630
- color: white;
631
- cursor: pointer;
632
- }
633
-
634
- /* =============================================================================
635
- * Buttons
636
- * ============================================================================= */
637
- .btn {
638
- width: 100%;
639
- padding: 7px 12px;
640
- margin-top: 6px;
641
- border: none;
642
- border-radius: 4px;
643
- cursor: pointer;
644
- font-size: 0.9em;
645
- font-weight: 500;
646
- transition: all 0.2s;
647
- }
648
-
649
- .btn-primary {
650
- background: var(--status-success);
651
- color: white;
652
- }
653
-
654
- .btn-primary:hover {
655
- filter: brightness(1.1);
656
- }
657
-
658
- .btn-secondary {
659
- background: var(--bg-muted);
660
- color: var(--text-primary);
661
- border: 1px solid var(--border-muted);
662
- }
663
-
664
- .btn-secondary:hover {
665
- background: var(--workspace-bg-tertiary);
666
- }
667
-
668
- .btn-cta {
669
- background: var(--color-cta);
670
- color: white;
671
- }
672
-
673
- .btn-cta:hover {
674
- background: var(--color-cta-hover);
675
- }
676
-
677
- /* =============================================================================
678
- * Unit Toggle
679
- * ============================================================================= */
680
- .unit-toggle {
681
- display: flex;
682
- gap: 0;
683
- border-radius: 4px;
684
- overflow: hidden;
685
- border: 1px solid var(--border-default);
686
- }
687
-
688
- .unit-btn {
689
- padding: 4px 12px;
690
- font-size: 0.8em;
691
- font-weight: 500;
692
- border: none;
693
- background: var(--bg-muted);
694
- color: var(--text-muted);
695
- cursor: pointer;
696
- transition: all 0.15s;
697
- }
698
-
699
- .unit-btn:first-child {
700
- border-right: 1px solid var(--border-default);
701
- }
702
-
703
- .unit-btn:hover {
704
- background: var(--bg-surface);
705
- color: var(--text-secondary);
706
- }
707
-
708
- .unit-btn.active {
709
- background: var(--color-cta);
710
- color: white;
711
- }
712
-
713
- /* =============================================================================
714
- * Background Type Toggle
715
- * ============================================================================= */
716
- .bg-toggle {
717
- display: flex;
718
- gap: 6px;
719
- }
720
-
721
- .bg-btn {
722
- display: flex;
723
- flex-direction: column;
724
- align-items: center;
725
- gap: 4px;
726
- padding: 6px 10px;
727
- font-size: 0.75em;
728
- border: 1px solid var(--border-default);
729
- border-radius: 4px;
730
- background: var(--bg-muted);
731
- color: var(--text-muted);
732
- cursor: pointer;
733
- transition: all 0.15s;
734
- flex: 1;
735
- }
736
-
737
- .bg-btn:hover {
738
- background: var(--bg-surface);
739
- color: var(--text-secondary);
740
- }
741
-
742
- .bg-btn.active {
743
- border-color: var(--color-cta);
744
- background: var(--bg-surface);
745
- color: var(--text-primary);
746
- box-shadow: 0 0 0 1px var(--color-cta);
747
- }
748
-
749
- .bg-preview {
750
- width: 20px;
751
- height: 14px;
752
- border-radius: 2px;
753
- border: 1px solid var(--border-default);
754
- }
755
-
756
- .bg-preview.white {
757
- background: #ffffff;
758
- }
759
-
760
- .bg-preview.transparent {
761
- background: linear-gradient(45deg, #ccc 25%, transparent 25%),
762
- linear-gradient(-45deg, #ccc 25%, transparent 25%),
763
- linear-gradient(45deg, transparent 75%, #ccc 75%),
764
- linear-gradient(-45deg, transparent 75%, #ccc 75%);
765
- background-size: 8px 8px;
766
- background-position: 0 0, 0 4px, 4px -4px, -4px 0px;
767
- background-color: #fff;
768
- }
769
-
770
- .bg-preview.black {
771
- background: #000000;
772
- }
773
-
774
- /* =============================================================================
775
- * Section Hints
776
- * ============================================================================= */
777
- .section-hint {
778
- font-size: 0.75em;
779
- color: var(--text-muted);
780
- font-style: italic;
781
- margin-bottom: 10px;
782
- padding: 6px 8px;
783
- background: var(--bg-muted);
784
- border-radius: 4px;
785
- border-left: 2px solid var(--border-default);
786
- }
787
-
788
- /* =============================================================================
789
- * Element Statistics
790
- * ============================================================================= */
791
- .element-stats {
792
- margin-top: 12px;
793
- padding: 10px;
794
- background: var(--bg-muted);
795
- border-radius: 4px;
796
- border: 1px solid var(--border-muted);
797
- }
798
-
799
- .stats-header {
800
- font-size: 0.8em;
801
- font-weight: 600;
802
- color: var(--text-secondary);
803
- margin-bottom: 8px;
804
- text-transform: uppercase;
805
- letter-spacing: 0.5px;
806
- }
807
-
808
- .stats-grid {
809
- display: grid;
810
- grid-template-columns: repeat(3, 1fr);
811
- gap: 8px;
812
- }
813
-
814
- .stat-item {
815
- display: flex;
816
- flex-direction: column;
817
- gap: 2px;
818
- }
819
-
820
- .stat-label {
821
- font-size: 0.7em;
822
- color: var(--text-muted);
823
- text-transform: uppercase;
824
- }
825
-
826
- .stat-value {
827
- font-size: 0.85em;
828
- font-weight: 500;
829
- color: var(--text-primary);
830
- font-family: 'SF Mono', Monaco, 'Cascadia Code', monospace;
831
- }
832
-
833
- /* =============================================================================
834
- * Status Bar
835
- * ============================================================================= */
836
- .status-bar {
837
- margin-top: 16px;
838
- padding: 10px 12px;
839
- border-radius: 4px;
840
- background: var(--bg-muted);
841
- font-size: 0.8em;
842
- color: var(--text-secondary);
843
- border-left: 3px solid var(--status-success);
844
- }
845
-
846
- .status-bar.error {
847
- border-left-color: var(--status-error);
848
- }
849
-
850
- /* =============================================================================
851
- * Collapsible Sections
852
- * ============================================================================= */
853
- .section-toggle {
854
- cursor: pointer;
855
- display: flex;
856
- align-items: center;
857
- gap: 8px;
858
- }
859
-
860
- .section-toggle::before {
861
- content: "\\25BC";
862
- font-size: 0.7em;
863
- transition: transform 0.2s;
864
- }
865
-
866
- .section-toggle.collapsed::before {
867
- transform: rotate(-90deg);
868
- }
869
-
870
- .section-content {
871
- overflow: hidden;
872
- transition: max-height 0.3s ease;
873
- }
874
-
875
- .section-content.collapsed {
876
- max-height: 0 !important;
877
- }
878
-
879
- /* =============================================================================
880
- * Scrollbar Styling
881
- * ============================================================================= */
882
- .controls::-webkit-scrollbar,
883
- .traces-list::-webkit-scrollbar,
884
- .annotations-list::-webkit-scrollbar {
885
- width: 6px;
886
- }
887
-
888
- .controls::-webkit-scrollbar-track,
889
- .traces-list::-webkit-scrollbar-track,
890
- .annotations-list::-webkit-scrollbar-track {
891
- background: var(--bg-muted);
892
- }
893
-
894
- .controls::-webkit-scrollbar-thumb,
895
- .traces-list::-webkit-scrollbar-thumb,
896
- .annotations-list::-webkit-scrollbar-thumb {
897
- background: var(--border-default);
898
- border-radius: 3px;
899
- }
900
-
901
- .controls::-webkit-scrollbar-thumb:hover,
902
- .traces-list::-webkit-scrollbar-thumb:hover,
903
- .annotations-list::-webkit-scrollbar-thumb:hover {
904
- background: var(--text-muted);
905
- }
906
-
907
- /* =============================================================================
908
- * Statistics Section
909
- * ============================================================================= */
910
- #stats-container {
911
- font-family: 'JetBrains Mono', 'Fira Code', 'Monaco', monospace;
912
- font-size: 11px;
913
- line-height: 1.5;
914
- }
915
-
916
- .stats-loading {
917
- color: var(--text-muted);
918
- font-style: italic;
919
- padding: 10px;
920
- text-align: center;
921
- }
922
-
923
- .stats-empty {
924
- color: var(--text-muted);
925
- padding: 10px;
926
- text-align: center;
927
- background: var(--bg-muted);
928
- border-radius: 4px;
929
- }
930
-
931
- .stats-card {
932
- background: var(--bg-surface);
933
- border: 1px solid var(--workspace-border-subtle);
934
- border-radius: 6px;
935
- padding: 12px;
936
- margin-bottom: 10px;
937
- }
938
-
939
- .stats-card-header {
940
- display: flex;
941
- justify-content: space-between;
942
- align-items: center;
943
- margin-bottom: 8px;
944
- padding-bottom: 8px;
945
- border-bottom: 1px solid var(--workspace-border-subtle);
946
- }
947
-
948
- .stats-card-title {
949
- font-weight: 600;
950
- font-size: 12px;
951
- color: var(--text-primary);
952
- }
953
-
954
- .stats-significance {
955
- display: inline-block;
956
- padding: 2px 8px;
957
- border-radius: 4px;
958
- font-weight: bold;
959
- font-size: 11px;
960
- }
961
-
962
- .stats-significance.sig-high {
963
- background: #dcfce7;
964
- color: #166534;
965
- }
966
-
967
- .stats-significance.sig-medium {
968
- background: #fef9c3;
969
- color: #854d0e;
970
- }
971
-
972
- .stats-significance.sig-low {
973
- background: #fee2e2;
974
- color: #991b1b;
975
- }
976
-
977
- .stats-significance.sig-ns {
978
- background: var(--bg-muted);
979
- color: var(--text-muted);
980
- }
981
-
982
- .stats-row {
983
- display: flex;
984
- justify-content: space-between;
985
- padding: 3px 0;
986
- }
987
-
988
- .stats-label {
989
- color: var(--text-secondary);
990
- }
991
-
992
- .stats-value {
993
- font-weight: 500;
994
- color: var(--text-primary);
995
- }
996
-
997
- .stats-groups {
998
- display: grid;
999
- grid-template-columns: 1fr 1fr;
1000
- gap: 8px;
1001
- margin-top: 8px;
1002
- padding-top: 8px;
1003
- border-top: 1px dashed var(--workspace-border-subtle);
1004
- }
1005
-
1006
- .stats-group {
1007
- background: var(--bg-muted);
1008
- padding: 8px;
1009
- border-radius: 4px;
1010
- font-size: 10px;
1011
- }
1012
-
1013
- .stats-group-name {
1014
- font-weight: 600;
1015
- margin-bottom: 4px;
1016
- color: var(--text-primary);
1017
- }
1018
-
1019
- .stats-correction-badge {
1020
- display: inline-block;
1021
- background: var(--color-cta);
1022
- color: white;
1023
- padding: 2px 6px;
1024
- border-radius: 3px;
1025
- font-size: 9px;
1026
- margin-left: 6px;
1027
- }
1028
-
1029
- .stats-summary-header {
1030
- background: var(--scitex-01);
1031
- color: var(--text-inverse);
1032
- padding: 10px 12px;
1033
- border-radius: 6px 6px 0 0;
1034
- font-weight: 600;
1035
- margin-bottom: 0;
1036
- }
1037
-
1038
- .stats-summary-body {
1039
- background: var(--bg-surface);
1040
- border: 1px solid var(--scitex-01);
1041
- border-top: none;
1042
- border-radius: 0 0 6px 6px;
1043
- padding: 12px;
1044
- }
1045
-
1046
- /* =============================================================================
1047
- * Subsection Headers (for grouped controls like X/Y axis settings)
1048
- * ============================================================================= */
1049
- .subsection-header {
1050
- font-size: 0.68em;
1051
- font-weight: 600;
1052
- text-transform: uppercase;
1053
- letter-spacing: 0.3px;
1054
- color: var(--text-secondary);
1055
- padding: 4px 6px;
1056
- margin-bottom: 6px;
1057
- margin-top: 8px;
1058
- background: var(--bg-muted);
1059
- border-left: 2px solid var(--status-success);
1060
- border-radius: 0 4px 4px 0;
1061
- }
1062
-
1063
- .subsection-header:first-child {
1064
- margin-top: 0;
1065
- }
1066
-
1067
- /* =============================================================================
1068
- * Axis Tabs (for X/Y/Z axis switching)
1069
- * ============================================================================= */
1070
- .axis-tabs {
1071
- display: flex;
1072
- gap: 3px;
1073
- margin-bottom: 8px;
1074
- background: var(--bg-muted);
1075
- padding: 3px;
1076
- border-radius: 6px;
1077
- }
1078
-
1079
- .axis-tab {
1080
- flex: 1;
1081
- padding: 4px 8px;
1082
- border: none;
1083
- background: transparent;
1084
- color: var(--text-secondary);
1085
- font-size: 0.8em;
1086
- font-weight: 600;
1087
- cursor: pointer;
1088
- border-radius: 4px;
1089
- transition: all 0.15s ease;
1090
- }
1091
-
1092
- .axis-tab:hover {
1093
- background: var(--bg-surface);
1094
- color: var(--text-primary);
1095
- }
1096
-
1097
- .axis-tab.active {
1098
- background: var(--scitex-01);
1099
- color: var(--bg-primary);
1100
- }
1101
-
1102
- .axis-panel {
1103
- animation: fadeIn 0.15s ease;
1104
- }
1105
-
1106
- @keyframes fadeIn {
1107
- from { opacity: 0; }
1108
- to { opacity: 1; }
1109
- }
1110
-
1111
- /* =============================================================================
1112
- * Loading Spinner Overlay
1113
- * ============================================================================= */
1114
- .loading-overlay {
1115
- position: absolute;
1116
- top: 0;
1117
- left: 0;
1118
- right: 0;
1119
- bottom: 0;
1120
- background: rgba(0, 0, 0, 0.3);
1121
- display: flex;
1122
- align-items: center;
1123
- justify-content: center;
1124
- z-index: 100;
1125
- border-radius: 8px;
1126
- }
1127
-
1128
- /* Global loading overlay - non-intrusive top bar style */
1129
- .global-loading-overlay {
1130
- position: fixed;
1131
- top: 0;
1132
- left: 0;
1133
- width: 100%;
1134
- height: 36px;
1135
- background: var(--workspace-bg-elevated);
1136
- border-bottom: 1px solid var(--workspace-border-default);
1137
- display: flex;
1138
- align-items: center;
1139
- justify-content: center;
1140
- z-index: 9999;
1141
- gap: 8px;
1142
- box-shadow: 0 2px 8px rgba(0,0,0,0.1);
1143
- }
1144
-
1145
- .global-loading-overlay .loading-text {
1146
- color: var(--text-secondary);
1147
- font-size: 12px;
1148
- font-weight: 500;
1149
- }
1150
-
1151
- .spinner {
1152
- width: 16px;
1153
- height: 16px;
1154
- border: 2px solid var(--scitex-06);
1155
- border-top: 2px solid var(--status-success);
1156
- border-radius: 50%;
1157
- animation: spin 0.6s linear infinite;
1158
- }
1159
-
1160
- .spinner-small {
1161
- width: 14px;
1162
- height: 14px;
1163
- border-width: 2px;
1164
- }
1165
-
1166
- @keyframes spin {
1167
- 0% { transform: rotate(0deg); }
1168
- 100% { transform: rotate(360deg); }
1169
- }
1170
-
1171
- /* =============================================================================
1172
- * Panel Grid View (for multi-panel figure bundles)
1173
- * ============================================================================= */
1174
- .panel-grid-section {
1175
- width: 100%;
1176
- margin-bottom: 20px;
1177
- background: var(--workspace-bg-elevated);
1178
- border-radius: 8px;
1179
- padding: 16px;
1180
- box-shadow: 0 2px 8px rgba(0,0,0,0.1);
1181
- }
1182
-
1183
- .panel-grid-header {
1184
- display: flex;
1185
- justify-content: space-between;
1186
- align-items: center;
1187
- margin-bottom: 12px;
1188
- }
1189
-
1190
- .panel-grid-header h3 {
1191
- font-size: 1em;
1192
- font-weight: 600;
1193
- color: var(--text-primary);
1194
- margin: 0;
1195
- }
1196
-
1197
- .panel-grid {
1198
- display: grid;
1199
- grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
1200
- gap: 12px;
1201
- }
1202
-
1203
- .panel-card {
1204
- background: var(--preview-bg);
1205
- background-size: 16px 16px;
1206
- background-position: 0 0, 0 8px, 8px -8px, -8px 0px;
1207
- border-radius: 6px;
1208
- overflow: hidden;
1209
- cursor: pointer;
1210
- transition: all 0.2s ease;
1211
- border: 2px solid transparent;
1212
- position: relative;
1213
- }
1214
-
1215
- .panel-card:hover {
1216
- border-color: var(--color-cta);
1217
- transform: translateY(-2px);
1218
- box-shadow: 0 4px 12px rgba(0,0,0,0.15);
1219
- }
1220
-
1221
- .panel-card.active {
1222
- border-color: var(--status-success);
1223
- box-shadow: 0 0 0 2px var(--status-success);
1224
- }
1225
-
1226
- .panel-card img {
1227
- width: 100%;
1228
- height: auto;
1229
- display: block;
1230
- }
1231
-
1232
- /* Dark mode: invert plot colors for visibility */
1233
- [data-theme="dark"] .panel-card img,
1234
- [data-theme="dark"] .panel-canvas-item img,
1235
- [data-theme="dark"] .preview-wrapper img {
1236
- filter: invert(0.88) hue-rotate(180deg);
1237
- }
1238
-
1239
- .panel-card-container {
1240
- position: relative;
1241
- display: inline-block;
1242
- width: 100%;
1243
- }
1244
-
1245
- .panel-card-overlay {
1246
- position: absolute;
1247
- top: 0;
1248
- left: 0;
1249
- pointer-events: none;
1250
- z-index: 5;
1251
- }
1252
-
1253
- .panel-card-label {
1254
- position: absolute;
1255
- top: 6px;
1256
- left: 6px;
1257
- background: rgba(0,0,0,0.7);
1258
- color: white;
1259
- padding: 3px 8px;
1260
- border-radius: 4px;
1261
- font-size: 0.75em;
1262
- font-weight: 600;
1263
- }
1264
-
1265
- .panel-card-loading {
1266
- display: flex;
1267
- align-items: center;
1268
- justify-content: center;
1269
- min-height: 120px;
1270
- color: var(--text-muted);
1271
- font-size: 0.85em;
1272
- }
1273
-
1274
- /* Panel Navigation Header */
1275
- .preview-header {
1276
- display: flex;
1277
- justify-content: space-between;
1278
- align-items: center;
1279
- padding: 8px 12px;
1280
- background: var(--workspace-bg-elevated);
1281
- border-radius: 8px 8px 0 0;
1282
- border-bottom: 1px solid var(--workspace-border-subtle);
1283
- }
1284
-
1285
- #current-panel-name {
1286
- font-weight: 600;
1287
- color: var(--text-primary);
1288
- font-size: 0.9em;
1289
- }
1290
-
1291
- .panel-nav {
1292
- display: flex;
1293
- align-items: center;
1294
- gap: 8px;
1295
- }
1296
-
1297
- #panel-indicator {
1298
- font-size: 0.8em;
1299
- color: var(--text-muted);
1300
- min-width: 50px;
1301
- text-align: center;
1302
- }
1303
-
1304
- .btn-sm {
1305
- padding: 4px 10px;
1306
- font-size: 0.8em;
1307
- width: auto;
1308
- margin: 0;
1309
- }
1310
-
1311
- /* Preview area adjustments when panel header is visible */
1312
- .preview-wrapper:has(.preview-header:not([style*="display: none"])) {
1313
- border-radius: 0 0 8px 8px;
1314
- }
1315
-
1316
- .preview {
1317
- flex-direction: column;
1318
- align-items: stretch;
1319
- padding: 20px;
1320
- overflow-y: auto;
1321
- }
1322
-
1323
- .preview > .preview-wrapper {
1324
- flex-shrink: 0;
1325
- }
1326
-
1327
- /* =============================================================================
1328
- * Unified Panel Canvas (matches figure export layout)
1329
- * Exactly matches SciTeX Cloud's .plot-preview-area styling
1330
- * ============================================================================= */
1331
- .panel-canvas {
1332
- position: relative;
1333
- min-height: 400px;
1334
- /* White background with grid pattern - exact match to SciTeX Cloud */
1335
- background: #ffffff;
1336
- background-image:
1337
- linear-gradient(0deg, transparent 23px, #e5e5e5 23px),
1338
- linear-gradient(90deg, transparent 23px, #e5e5e5 23px);
1339
- background-size: 24px 24px;
1340
- border-radius: 8px;
1341
- overflow: visible; /* Allow panels to extend slightly if needed */
1342
- }
1343
-
1344
- /* Dark mode: dark canvas background for eye comfort */
1345
- [data-theme="dark"] .panel-canvas,
1346
- .dark-mode .panel-canvas {
1347
- background: #1a1a1a;
1348
- background-image:
1349
- linear-gradient(0deg, transparent 23px, #2a2a2a 23px),
1350
- linear-gradient(90deg, transparent 23px, #2a2a2a 23px);
1351
- background-size: 24px 24px;
1352
- }
1353
-
1354
- /* Hide grid when toggled off (G key) */
1355
- .panel-canvas.hide-grid {
1356
- background-image: none !important;
1357
- }
1358
-
1359
- /* Unified canvas - panels appear as single figure matching figure export */
1360
- .panel-canvas-item {
1361
- position: absolute;
1362
- user-select: none;
1363
- background: transparent;
1364
- overflow: visible;
1365
- border: none;
1366
- cursor: grab; /* Indicate draggability */
1367
- }
1368
-
1369
- .panel-canvas-item:hover {
1370
- z-index: 10;
1371
- }
1372
-
1373
- .panel-canvas-item:active {
1374
- cursor: grabbing;
1375
- }
1376
-
1377
- .panel-canvas-item.active {
1378
- outline: 2px solid var(--status-success);
1379
- outline-offset: 2px;
1380
- }
1381
-
1382
- .panel-canvas-item .panel-card-container {
1383
- width: 100%;
1384
- height: 100%;
1385
- position: relative;
1386
- }
1387
-
1388
- .panel-canvas-item img {
1389
- width: 100%;
1390
- height: 100%;
1391
- object-fit: contain; /* Preserve aspect ratio - never distort figures */
1392
- pointer-events: none;
1393
- display: block;
1394
- }
1395
-
1396
- .panel-canvas-label {
1397
- position: absolute;
1398
- top: 4px;
1399
- left: 4px;
1400
- background: rgba(0,0,0,0.6);
1401
- color: white;
1402
- padding: 2px 6px;
1403
- border-radius: 3px;
1404
- font-size: 0.65em;
1405
- font-weight: 600;
1406
- cursor: move;
1407
- opacity: 1; /* Show by default */
1408
- transition: opacity 0.2s, background 0.2s;
1409
- z-index: 5;
1410
- }
1411
-
1412
- .panel-canvas-item:hover .panel-canvas-label {
1413
- opacity: 1;
1414
- background: rgba(0,0,0,0.8); /* Slightly darker on hover */
1415
- }
1416
-
1417
- /* Drag handle for panel repositioning */
1418
- .panel-drag-handle {
1419
- position: absolute;
1420
- top: 4px;
1421
- right: 4px;
1422
- background: rgba(0,0,0,0.5);
1423
- color: white;
1424
- padding: 2px 4px;
1425
- border-radius: 3px;
1426
- font-size: 0.7em;
1427
- cursor: move;
1428
- opacity: 0;
1429
- transition: opacity 0.2s, background 0.2s;
1430
- z-index: 5;
1431
- user-select: none;
1432
- }
1433
-
1434
- .panel-canvas-item:hover .panel-drag-handle {
1435
- opacity: 1;
1436
- }
1437
-
1438
- .panel-drag-handle:hover {
1439
- background: rgba(0,0,0,0.8);
1440
- }
1441
-
1442
- .panel-drag-handle:active {
1443
- background: var(--accent-primary);
1444
- }
1445
-
1446
- /* Position indicator while dragging */
1447
- .panel-position-indicator {
1448
- position: absolute;
1449
- bottom: 4px;
1450
- left: 4px;
1451
- background: rgba(0,0,0,0.7);
1452
- color: #4fc3f7;
1453
- padding: 2px 6px;
1454
- border-radius: 3px;
1455
- font-size: 0.6em;
1456
- font-family: monospace;
1457
- pointer-events: none;
1458
- opacity: 0;
1459
- transition: opacity 0.3s;
1460
- z-index: 5;
1461
- }
1462
-
1463
- /* Dragging state */
1464
- .panel-canvas-item.dragging {
1465
- opacity: 0.85;
1466
- z-index: 100;
1467
- box-shadow: 0 8px 24px rgba(0,0,0,0.3);
1468
- outline: 2px dashed var(--accent-primary);
1469
- outline-offset: 2px;
1470
- cursor: grabbing;
1471
- }
1472
-
1473
- .panel-canvas-item.dragging .panel-position-indicator {
1474
- opacity: 1;
1475
- }
1476
-
1477
- .canvas-controls {
1478
- display: flex;
1479
- gap: 8px;
1480
- margin-bottom: 8px;
1481
- align-items: center;
1482
- }
1483
-
1484
- .canvas-controls button {
1485
- padding: 4px 12px;
1486
- font-size: 0.8em;
1487
- }
1488
-
1489
- /* Toolbar separator */
1490
- .toolbar-separator {
1491
- width: 1px;
1492
- height: 24px;
1493
- background: #555;
1494
- margin: 0 4px;
1495
- }
1496
-
1497
- /* Download dropdown in toolbar */
1498
- .download-dropdown {
1499
- position: relative;
1500
- display: inline-block;
1501
- }
1502
-
1503
- .download-dropdown #download-btn {
1504
- background: #4a90d9;
1505
- border: none;
1506
- color: white;
1507
- padding: 4px 12px;
1508
- font-size: 0.8em;
1509
- border-radius: 3px;
1510
- cursor: pointer;
1511
- }
1512
-
1513
- .download-dropdown #download-btn:hover {
1514
- background: #5a9fe9;
1515
- }
1516
-
1517
- #download-menu {
1518
- display: none;
1519
- position: absolute;
1520
- top: 100%;
1521
- left: 0;
1522
- background: #2a2a2a;
1523
- border: 1px solid #444;
1524
- border-radius: 4px;
1525
- min-width: 160px;
1526
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
1527
- z-index: 1000;
1528
- margin-top: 4px;
1529
- padding: 4px 0;
1530
- }
1531
-
1532
- .download-item {
1533
- display: block;
1534
- padding: 8px 12px;
1535
- color: #ddd;
1536
- text-decoration: none;
1537
- font-size: 0.85em;
1538
- transition: background 0.15s;
1539
- white-space: nowrap;
1540
- }
1541
-
1542
- .download-item:hover {
1543
- background: #3a3a3a;
1544
- color: #fff;
1545
- }
1546
-
1547
- .download-divider {
1548
- height: 1px;
1549
- background: #444;
1550
- margin: 4px 0;
1551
- }
1552
-
1553
- /* =============================================================================
1554
- Context Menu (Right-Click)
1555
- ============================================================================= */
1556
- .context-menu {
1557
- position: fixed;
1558
- background: var(--bg-secondary, #2a2a2a);
1559
- border: 1px solid var(--border-color, #444);
1560
- border-radius: 6px;
1561
- box-shadow: 0 4px 16px rgba(0, 0, 0, 0.4);
1562
- min-width: 200px;
1563
- z-index: 10000;
1564
- padding: 4px 0;
1565
- font-size: 13px;
1566
- }
1567
-
1568
- .context-menu-item {
1569
- display: flex;
1570
- align-items: center;
1571
- padding: 8px 12px;
1572
- cursor: pointer;
1573
- color: var(--text-primary, #ddd);
1574
- transition: background 0.1s;
1575
- position: relative;
1576
- }
1577
-
1578
- .context-menu-item:hover:not(.disabled) {
1579
- background: var(--accent-primary, #4a90d9);
1580
- color: #fff;
1581
- }
1582
-
1583
- .context-menu-item.disabled {
1584
- color: var(--text-muted, #666);
1585
- cursor: not-allowed;
1586
- }
1587
-
1588
- .context-menu-icon {
1589
- width: 20px;
1590
- margin-right: 8px;
1591
- text-align: center;
1592
- font-size: 14px;
1593
- }
1594
-
1595
- .context-menu-shortcut {
1596
- margin-left: auto;
1597
- font-size: 11px;
1598
- color: var(--text-muted, #888);
1599
- padding-left: 16px;
1600
- }
1601
-
1602
- .context-menu-item:hover:not(.disabled) .context-menu-shortcut {
1603
- color: rgba(255, 255, 255, 0.7);
1604
- }
1605
-
1606
- .context-menu-arrow {
1607
- margin-left: auto;
1608
- font-size: 10px;
1609
- color: var(--text-muted, #888);
1610
- }
1611
-
1612
- .context-menu-divider {
1613
- height: 1px;
1614
- background: var(--border-color, #444);
1615
- margin: 4px 0;
1616
- }
1617
-
1618
- /* Submenu */
1619
- .context-menu-submenu {
1620
- position: relative;
1621
- }
1622
-
1623
- .context-submenu {
1624
- display: none;
1625
- position: absolute;
1626
- left: 100%;
1627
- top: 0;
1628
- background: var(--bg-secondary, #2a2a2a);
1629
- border: 1px solid var(--border-color, #444);
1630
- border-radius: 6px;
1631
- box-shadow: 0 4px 16px rgba(0, 0, 0, 0.4);
1632
- min-width: 150px;
1633
- padding: 4px 0;
1634
- }
1635
-
1636
- .context-menu-submenu:hover > .context-submenu {
1637
- display: block;
1638
- }
1639
-
1640
- .context-submenu .context-menu-item {
1641
- padding: 6px 12px;
1642
- }
1643
-
1644
- /* Panel selection styling */
1645
- .panel-canvas-item.active {
1646
- outline: 3px solid var(--accent-primary, #4a90d9);
1647
- outline-offset: 2px;
1648
- z-index: 100;
1649
- }
1650
-
1651
- .panel-canvas-item:hover:not(.active) {
1652
- outline: 2px dashed var(--accent-secondary, #6ab04c);
1653
- outline-offset: 2px;
1654
- }
1655
- """
1656
-
1657
-
1658
- # EOF