scitex 2.7.0__py3-none-any.whl → 2.8.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.
Files changed (355) hide show
  1. scitex/__init__.py +6 -2
  2. scitex/__version__.py +1 -1
  3. scitex/audio/README.md +52 -0
  4. scitex/audio/__init__.py +384 -0
  5. scitex/audio/__main__.py +129 -0
  6. scitex/audio/_tts.py +334 -0
  7. scitex/audio/engines/__init__.py +44 -0
  8. scitex/audio/engines/base.py +275 -0
  9. scitex/audio/engines/elevenlabs_engine.py +143 -0
  10. scitex/audio/engines/gtts_engine.py +162 -0
  11. scitex/audio/engines/pyttsx3_engine.py +131 -0
  12. scitex/audio/mcp_server.py +757 -0
  13. scitex/bridge/_helpers.py +1 -1
  14. scitex/bridge/_plt_vis.py +1 -1
  15. scitex/bridge/_stats_vis.py +1 -1
  16. scitex/dev/plt/__init__.py +272 -0
  17. scitex/dev/plt/plot_mpl_axhline.py +28 -0
  18. scitex/dev/plt/plot_mpl_axhspan.py +28 -0
  19. scitex/dev/plt/plot_mpl_axvline.py +28 -0
  20. scitex/dev/plt/plot_mpl_axvspan.py +28 -0
  21. scitex/dev/plt/plot_mpl_bar.py +29 -0
  22. scitex/dev/plt/plot_mpl_barh.py +29 -0
  23. scitex/dev/plt/plot_mpl_boxplot.py +28 -0
  24. scitex/dev/plt/plot_mpl_contour.py +31 -0
  25. scitex/dev/plt/plot_mpl_contourf.py +31 -0
  26. scitex/dev/plt/plot_mpl_errorbar.py +30 -0
  27. scitex/dev/plt/plot_mpl_eventplot.py +28 -0
  28. scitex/dev/plt/plot_mpl_fill.py +30 -0
  29. scitex/dev/plt/plot_mpl_fill_between.py +31 -0
  30. scitex/dev/plt/plot_mpl_hexbin.py +28 -0
  31. scitex/dev/plt/plot_mpl_hist.py +28 -0
  32. scitex/dev/plt/plot_mpl_hist2d.py +28 -0
  33. scitex/dev/plt/plot_mpl_imshow.py +29 -0
  34. scitex/dev/plt/plot_mpl_pcolormesh.py +31 -0
  35. scitex/dev/plt/plot_mpl_pie.py +29 -0
  36. scitex/dev/plt/plot_mpl_plot.py +29 -0
  37. scitex/dev/plt/plot_mpl_quiver.py +31 -0
  38. scitex/dev/plt/plot_mpl_scatter.py +28 -0
  39. scitex/dev/plt/plot_mpl_stackplot.py +31 -0
  40. scitex/dev/plt/plot_mpl_stem.py +29 -0
  41. scitex/dev/plt/plot_mpl_step.py +29 -0
  42. scitex/dev/plt/plot_mpl_violinplot.py +28 -0
  43. scitex/dev/plt/plot_sns_barplot.py +29 -0
  44. scitex/dev/plt/plot_sns_boxplot.py +29 -0
  45. scitex/dev/plt/plot_sns_heatmap.py +28 -0
  46. scitex/dev/plt/plot_sns_histplot.py +29 -0
  47. scitex/dev/plt/plot_sns_kdeplot.py +29 -0
  48. scitex/dev/plt/plot_sns_lineplot.py +31 -0
  49. scitex/dev/plt/plot_sns_scatterplot.py +29 -0
  50. scitex/dev/plt/plot_sns_stripplot.py +29 -0
  51. scitex/dev/plt/plot_sns_swarmplot.py +29 -0
  52. scitex/dev/plt/plot_sns_violinplot.py +29 -0
  53. scitex/dev/plt/plot_stx_bar.py +29 -0
  54. scitex/dev/plt/plot_stx_barh.py +29 -0
  55. scitex/dev/plt/plot_stx_box.py +28 -0
  56. scitex/dev/plt/plot_stx_boxplot.py +28 -0
  57. scitex/dev/plt/plot_stx_conf_mat.py +28 -0
  58. scitex/dev/plt/plot_stx_contour.py +31 -0
  59. scitex/dev/plt/plot_stx_ecdf.py +28 -0
  60. scitex/dev/plt/plot_stx_errorbar.py +30 -0
  61. scitex/dev/plt/plot_stx_fill_between.py +31 -0
  62. scitex/dev/plt/plot_stx_fillv.py +28 -0
  63. scitex/dev/plt/plot_stx_heatmap.py +28 -0
  64. scitex/dev/plt/plot_stx_image.py +28 -0
  65. scitex/dev/plt/plot_stx_imshow.py +28 -0
  66. scitex/dev/plt/plot_stx_joyplot.py +28 -0
  67. scitex/dev/plt/plot_stx_kde.py +28 -0
  68. scitex/dev/plt/plot_stx_line.py +28 -0
  69. scitex/dev/plt/plot_stx_mean_ci.py +28 -0
  70. scitex/dev/plt/plot_stx_mean_std.py +28 -0
  71. scitex/dev/plt/plot_stx_median_iqr.py +28 -0
  72. scitex/dev/plt/plot_stx_raster.py +28 -0
  73. scitex/dev/plt/plot_stx_rectangle.py +28 -0
  74. scitex/dev/plt/plot_stx_scatter.py +29 -0
  75. scitex/dev/plt/plot_stx_shaded_line.py +29 -0
  76. scitex/dev/plt/plot_stx_violin.py +28 -0
  77. scitex/dev/plt/plot_stx_violinplot.py +28 -0
  78. scitex/diagram/README.md +197 -0
  79. scitex/diagram/__init__.py +48 -0
  80. scitex/diagram/_compile.py +312 -0
  81. scitex/diagram/_diagram.py +355 -0
  82. scitex/diagram/_presets.py +173 -0
  83. scitex/diagram/_schema.py +182 -0
  84. scitex/diagram/_split.py +278 -0
  85. scitex/fig/__init__.py +352 -0
  86. scitex/{vis → fig}/backend/_parser.py +1 -1
  87. scitex/{vis → fig}/canvas.py +1 -1
  88. scitex/{vis → fig}/editor/__init__.py +5 -2
  89. scitex/{vis → fig}/editor/_dearpygui_editor.py +1 -1
  90. scitex/{vis → fig}/editor/_defaults.py +70 -5
  91. scitex/{vis → fig}/editor/_mpl_editor.py +1 -1
  92. scitex/{vis → fig}/editor/_qt_editor.py +182 -2
  93. scitex/{vis → fig}/editor/_tkinter_editor.py +1 -1
  94. scitex/fig/editor/edit/__init__.py +50 -0
  95. scitex/fig/editor/edit/backend_detector.py +109 -0
  96. scitex/fig/editor/edit/bundle_resolver.py +240 -0
  97. scitex/fig/editor/edit/editor_launcher.py +239 -0
  98. scitex/fig/editor/edit/manual_handler.py +53 -0
  99. scitex/fig/editor/edit/panel_loader.py +232 -0
  100. scitex/fig/editor/edit/path_resolver.py +67 -0
  101. scitex/fig/editor/flask_editor/_bbox.py +1299 -0
  102. scitex/fig/editor/flask_editor/_core.py +1429 -0
  103. scitex/{vis → fig}/editor/flask_editor/_plotter.py +38 -4
  104. scitex/fig/editor/flask_editor/_renderer.py +813 -0
  105. scitex/fig/editor/flask_editor/static/css/base/reset.css +41 -0
  106. scitex/fig/editor/flask_editor/static/css/base/typography.css +16 -0
  107. scitex/fig/editor/flask_editor/static/css/base/variables.css +85 -0
  108. scitex/fig/editor/flask_editor/static/css/components/buttons.css +217 -0
  109. scitex/fig/editor/flask_editor/static/css/components/context-menu.css +93 -0
  110. scitex/fig/editor/flask_editor/static/css/components/dropdown.css +57 -0
  111. scitex/fig/editor/flask_editor/static/css/components/forms.css +112 -0
  112. scitex/fig/editor/flask_editor/static/css/components/modal.css +59 -0
  113. scitex/fig/editor/flask_editor/static/css/components/sections.css +212 -0
  114. scitex/fig/editor/flask_editor/static/css/features/canvas.css +176 -0
  115. scitex/fig/editor/flask_editor/static/css/features/element-inspector.css +190 -0
  116. scitex/fig/editor/flask_editor/static/css/features/loading.css +59 -0
  117. scitex/fig/editor/flask_editor/static/css/features/overlay.css +45 -0
  118. scitex/fig/editor/flask_editor/static/css/features/panel-grid.css +95 -0
  119. scitex/fig/editor/flask_editor/static/css/features/selection.css +101 -0
  120. scitex/fig/editor/flask_editor/static/css/features/statistics.css +138 -0
  121. scitex/fig/editor/flask_editor/static/css/index.css +31 -0
  122. scitex/fig/editor/flask_editor/static/css/layout/container.css +7 -0
  123. scitex/fig/editor/flask_editor/static/css/layout/controls.css +56 -0
  124. scitex/fig/editor/flask_editor/static/css/layout/preview.css +78 -0
  125. scitex/fig/editor/flask_editor/static/js/alignment/axis.js +314 -0
  126. scitex/fig/editor/flask_editor/static/js/alignment/basic.js +107 -0
  127. scitex/fig/editor/flask_editor/static/js/alignment/distribute.js +54 -0
  128. scitex/fig/editor/flask_editor/static/js/canvas/canvas.js +172 -0
  129. scitex/fig/editor/flask_editor/static/js/canvas/dragging.js +258 -0
  130. scitex/fig/editor/flask_editor/static/js/canvas/resize.js +48 -0
  131. scitex/fig/editor/flask_editor/static/js/canvas/selection.js +71 -0
  132. scitex/fig/editor/flask_editor/static/js/core/api.js +288 -0
  133. scitex/fig/editor/flask_editor/static/js/core/state.js +143 -0
  134. scitex/fig/editor/flask_editor/static/js/core/utils.js +245 -0
  135. scitex/fig/editor/flask_editor/static/js/dev/element-inspector.js +992 -0
  136. scitex/fig/editor/flask_editor/static/js/editor/bbox.js +339 -0
  137. scitex/fig/editor/flask_editor/static/js/editor/element-drag.js +286 -0
  138. scitex/fig/editor/flask_editor/static/js/editor/overlay.js +371 -0
  139. scitex/fig/editor/flask_editor/static/js/editor/preview.js +293 -0
  140. scitex/fig/editor/flask_editor/static/js/main.js +426 -0
  141. scitex/fig/editor/flask_editor/static/js/shortcuts/context-menu.js +152 -0
  142. scitex/fig/editor/flask_editor/static/js/shortcuts/keyboard.js +265 -0
  143. scitex/fig/editor/flask_editor/static/js/ui/controls.js +184 -0
  144. scitex/fig/editor/flask_editor/static/js/ui/download.js +57 -0
  145. scitex/fig/editor/flask_editor/static/js/ui/help.js +100 -0
  146. scitex/fig/editor/flask_editor/static/js/ui/theme.js +34 -0
  147. scitex/fig/editor/flask_editor/templates/__init__.py +123 -0
  148. scitex/fig/editor/flask_editor/templates/_html.py +852 -0
  149. scitex/fig/editor/flask_editor/templates/_scripts.py +4933 -0
  150. scitex/fig/editor/flask_editor/templates/_styles.py +1658 -0
  151. scitex/{vis → fig}/io/__init__.py +13 -1
  152. scitex/fig/io/_bundle.py +1058 -0
  153. scitex/{vis → fig}/io/_canvas.py +1 -1
  154. scitex/{vis → fig}/io/_data.py +1 -1
  155. scitex/{vis → fig}/io/_export.py +1 -1
  156. scitex/{vis → fig}/io/_load.py +1 -1
  157. scitex/{vis → fig}/io/_panel.py +1 -1
  158. scitex/{vis → fig}/io/_save.py +1 -1
  159. scitex/{vis → fig}/model/__init__.py +1 -1
  160. scitex/{vis → fig}/model/_annotations.py +1 -1
  161. scitex/{vis → fig}/model/_axes.py +1 -1
  162. scitex/{vis → fig}/model/_figure.py +1 -1
  163. scitex/{vis → fig}/model/_guides.py +1 -1
  164. scitex/{vis → fig}/model/_plot.py +1 -1
  165. scitex/{vis → fig}/model/_styles.py +1 -1
  166. scitex/{vis → fig}/utils/__init__.py +1 -1
  167. scitex/io/__init__.py +22 -26
  168. scitex/io/_bundle.py +493 -0
  169. scitex/io/_flush.py +5 -2
  170. scitex/io/_load.py +98 -0
  171. scitex/io/_load_modules/_H5Explorer.py +5 -2
  172. scitex/io/_load_modules/_canvas.py +2 -2
  173. scitex/io/_load_modules/_image.py +3 -4
  174. scitex/io/_load_modules/_txt.py +4 -2
  175. scitex/io/_metadata.py +34 -324
  176. scitex/io/_metadata_modules/__init__.py +46 -0
  177. scitex/io/_metadata_modules/_embed.py +70 -0
  178. scitex/io/_metadata_modules/_read.py +64 -0
  179. scitex/io/_metadata_modules/_utils.py +79 -0
  180. scitex/io/_metadata_modules/embed_metadata_jpeg.py +74 -0
  181. scitex/io/_metadata_modules/embed_metadata_pdf.py +53 -0
  182. scitex/io/_metadata_modules/embed_metadata_png.py +26 -0
  183. scitex/io/_metadata_modules/embed_metadata_svg.py +62 -0
  184. scitex/io/_metadata_modules/read_metadata_jpeg.py +57 -0
  185. scitex/io/_metadata_modules/read_metadata_pdf.py +51 -0
  186. scitex/io/_metadata_modules/read_metadata_png.py +39 -0
  187. scitex/io/_metadata_modules/read_metadata_svg.py +44 -0
  188. scitex/io/_qr_utils.py +5 -3
  189. scitex/io/_save.py +548 -30
  190. scitex/io/_save_modules/_canvas.py +3 -3
  191. scitex/io/_save_modules/_image.py +5 -9
  192. scitex/io/_save_modules/_tex.py +7 -4
  193. scitex/io/_zip_bundle.py +439 -0
  194. scitex/io/utils/h5_to_zarr.py +11 -9
  195. scitex/msword/__init__.py +255 -0
  196. scitex/msword/profiles.py +357 -0
  197. scitex/msword/reader.py +753 -0
  198. scitex/msword/utils.py +289 -0
  199. scitex/msword/writer.py +362 -0
  200. scitex/plt/__init__.py +5 -2
  201. scitex/plt/_subplots/_AxesWrapper.py +6 -6
  202. scitex/plt/_subplots/_AxisWrapper.py +15 -9
  203. scitex/plt/_subplots/_AxisWrapperMixins/_AdjustmentMixin/__init__.py +36 -0
  204. scitex/plt/_subplots/_AxisWrapperMixins/_AdjustmentMixin/_labels.py +264 -0
  205. scitex/plt/_subplots/_AxisWrapperMixins/_AdjustmentMixin/_metadata.py +213 -0
  206. scitex/plt/_subplots/_AxisWrapperMixins/_AdjustmentMixin/_visual.py +128 -0
  207. scitex/plt/_subplots/_AxisWrapperMixins/_MatplotlibPlotMixin/__init__.py +59 -0
  208. scitex/plt/_subplots/_AxisWrapperMixins/_MatplotlibPlotMixin/_base.py +34 -0
  209. scitex/plt/_subplots/_AxisWrapperMixins/_MatplotlibPlotMixin/_scientific.py +593 -0
  210. scitex/plt/_subplots/_AxisWrapperMixins/_MatplotlibPlotMixin/_statistical.py +654 -0
  211. scitex/plt/_subplots/_AxisWrapperMixins/_MatplotlibPlotMixin/_stx_aliases.py +527 -0
  212. scitex/plt/_subplots/_AxisWrapperMixins/_RawMatplotlibMixin.py +321 -0
  213. scitex/plt/_subplots/_AxisWrapperMixins/_SeabornMixin/__init__.py +33 -0
  214. scitex/plt/_subplots/_AxisWrapperMixins/_SeabornMixin/_base.py +152 -0
  215. scitex/plt/_subplots/_AxisWrapperMixins/_SeabornMixin/_wrappers.py +600 -0
  216. scitex/plt/_subplots/_AxisWrapperMixins/__init__.py +79 -5
  217. scitex/plt/_subplots/_FigWrapper.py +6 -6
  218. scitex/plt/_subplots/_SubplotsWrapper.py +28 -18
  219. scitex/plt/_subplots/_export_as_csv.py +35 -5
  220. scitex/plt/_subplots/_export_as_csv_formatters/__init__.py +8 -0
  221. scitex/plt/_subplots/_export_as_csv_formatters/_format_annotate.py +10 -21
  222. scitex/plt/_subplots/_export_as_csv_formatters/_format_eventplot.py +18 -7
  223. scitex/plt/_subplots/_export_as_csv_formatters/_format_imshow2d.py +28 -12
  224. scitex/plt/_subplots/_export_as_csv_formatters/_format_matshow.py +10 -4
  225. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_imshow.py +13 -1
  226. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_kde.py +12 -2
  227. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_scatter.py +10 -3
  228. scitex/plt/_subplots/_export_as_csv_formatters/_format_quiver.py +10 -4
  229. scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_jointplot.py +18 -3
  230. scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_lineplot.py +44 -36
  231. scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_pairplot.py +14 -2
  232. scitex/plt/_subplots/_export_as_csv_formatters/_format_streamplot.py +11 -5
  233. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_bar.py +84 -0
  234. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_barh.py +85 -0
  235. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_conf_mat.py +14 -3
  236. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_contour.py +54 -0
  237. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_ecdf.py +14 -2
  238. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_errorbar.py +120 -0
  239. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_heatmap.py +16 -6
  240. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_image.py +29 -19
  241. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_imshow.py +63 -0
  242. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_joyplot.py +22 -5
  243. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_mean_ci.py +18 -14
  244. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_mean_std.py +18 -14
  245. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_median_iqr.py +18 -14
  246. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_raster.py +10 -2
  247. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_scatter.py +51 -0
  248. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_scatter_hist.py +18 -9
  249. scitex/plt/ax/_plot/_stx_ecdf.py +4 -2
  250. scitex/plt/gallery/_generate.py +421 -14
  251. scitex/plt/io/__init__.py +53 -0
  252. scitex/plt/io/_bundle.py +490 -0
  253. scitex/plt/io/_layered_bundle.py +1343 -0
  254. scitex/plt/styles/SCITEX_STYLE.yaml +26 -0
  255. scitex/plt/styles/__init__.py +14 -0
  256. scitex/plt/styles/presets.py +78 -0
  257. scitex/plt/utils/__init__.py +13 -1
  258. scitex/plt/utils/_collect_figure_metadata.py +10 -14
  259. scitex/plt/utils/_configure_mpl.py +6 -18
  260. scitex/plt/utils/_crop.py +32 -14
  261. scitex/plt/utils/_csv_column_naming.py +54 -0
  262. scitex/plt/utils/_figure_mm.py +116 -1
  263. scitex/plt/utils/_hitmap.py +1643 -0
  264. scitex/plt/utils/metadata/__init__.py +25 -0
  265. scitex/plt/utils/metadata/_core.py +9 -10
  266. scitex/plt/utils/metadata/_dimensions.py +6 -3
  267. scitex/plt/utils/metadata/_editable_export.py +405 -0
  268. scitex/plt/utils/metadata/_geometry_extraction.py +570 -0
  269. scitex/schema/__init__.py +109 -16
  270. scitex/schema/_canvas.py +1 -1
  271. scitex/schema/_plot.py +1015 -0
  272. scitex/schema/_stats.py +2 -2
  273. scitex/stats/__init__.py +117 -0
  274. scitex/stats/io/__init__.py +29 -0
  275. scitex/stats/io/_bundle.py +156 -0
  276. scitex/tex/__init__.py +4 -0
  277. scitex/tex/_export.py +890 -0
  278. {scitex-2.7.0.dist-info → scitex-2.8.1.dist-info}/METADATA +11 -1
  279. {scitex-2.7.0.dist-info → scitex-2.8.1.dist-info}/RECORD +294 -170
  280. scitex/io/memo.md +0 -2827
  281. scitex/plt/REQUESTS.md +0 -191
  282. scitex/plt/_subplots/TODO.md +0 -53
  283. scitex/plt/_subplots/_AxisWrapperMixins/_AdjustmentMixin.py +0 -559
  284. scitex/plt/_subplots/_AxisWrapperMixins/_MatplotlibPlotMixin.py +0 -1609
  285. scitex/plt/_subplots/_AxisWrapperMixins/_SeabornMixin.py +0 -447
  286. scitex/plt/templates/research-master/scitex/vis/gallery/area/fill_between.json +0 -110
  287. scitex/plt/templates/research-master/scitex/vis/gallery/area/fill_betweenx.json +0 -88
  288. scitex/plt/templates/research-master/scitex/vis/gallery/area/stx_fill_between.json +0 -103
  289. scitex/plt/templates/research-master/scitex/vis/gallery/area/stx_fillv.json +0 -106
  290. scitex/plt/templates/research-master/scitex/vis/gallery/categorical/bar.json +0 -92
  291. scitex/plt/templates/research-master/scitex/vis/gallery/categorical/barh.json +0 -92
  292. scitex/plt/templates/research-master/scitex/vis/gallery/categorical/boxplot.json +0 -92
  293. scitex/plt/templates/research-master/scitex/vis/gallery/categorical/stx_bar.json +0 -84
  294. scitex/plt/templates/research-master/scitex/vis/gallery/categorical/stx_barh.json +0 -84
  295. scitex/plt/templates/research-master/scitex/vis/gallery/categorical/stx_box.json +0 -83
  296. scitex/plt/templates/research-master/scitex/vis/gallery/categorical/stx_boxplot.json +0 -93
  297. scitex/plt/templates/research-master/scitex/vis/gallery/categorical/stx_violin.json +0 -91
  298. scitex/plt/templates/research-master/scitex/vis/gallery/categorical/stx_violinplot.json +0 -91
  299. scitex/plt/templates/research-master/scitex/vis/gallery/categorical/violinplot.json +0 -91
  300. scitex/plt/templates/research-master/scitex/vis/gallery/contour/contour.json +0 -97
  301. scitex/plt/templates/research-master/scitex/vis/gallery/contour/contourf.json +0 -98
  302. scitex/plt/templates/research-master/scitex/vis/gallery/contour/stx_contour.json +0 -84
  303. scitex/plt/templates/research-master/scitex/vis/gallery/distribution/hist.json +0 -101
  304. scitex/plt/templates/research-master/scitex/vis/gallery/distribution/hist2d.json +0 -96
  305. scitex/plt/templates/research-master/scitex/vis/gallery/distribution/stx_ecdf.json +0 -95
  306. scitex/plt/templates/research-master/scitex/vis/gallery/distribution/stx_joyplot.json +0 -95
  307. scitex/plt/templates/research-master/scitex/vis/gallery/distribution/stx_kde.json +0 -93
  308. scitex/plt/templates/research-master/scitex/vis/gallery/grid/imshow.json +0 -95
  309. scitex/plt/templates/research-master/scitex/vis/gallery/grid/matshow.json +0 -95
  310. scitex/plt/templates/research-master/scitex/vis/gallery/grid/stx_conf_mat.json +0 -83
  311. scitex/plt/templates/research-master/scitex/vis/gallery/grid/stx_heatmap.json +0 -92
  312. scitex/plt/templates/research-master/scitex/vis/gallery/grid/stx_image.json +0 -121
  313. scitex/plt/templates/research-master/scitex/vis/gallery/grid/stx_imshow.json +0 -84
  314. scitex/plt/templates/research-master/scitex/vis/gallery/line/plot.json +0 -110
  315. scitex/plt/templates/research-master/scitex/vis/gallery/line/step.json +0 -92
  316. scitex/plt/templates/research-master/scitex/vis/gallery/line/stx_line.json +0 -95
  317. scitex/plt/templates/research-master/scitex/vis/gallery/line/stx_shaded_line.json +0 -96
  318. scitex/plt/templates/research-master/scitex/vis/gallery/scatter/hexbin.json +0 -95
  319. scitex/plt/templates/research-master/scitex/vis/gallery/scatter/scatter.json +0 -95
  320. scitex/plt/templates/research-master/scitex/vis/gallery/scatter/stem.json +0 -92
  321. scitex/plt/templates/research-master/scitex/vis/gallery/scatter/stx_scatter.json +0 -84
  322. scitex/plt/templates/research-master/scitex/vis/gallery/special/pie.json +0 -94
  323. scitex/plt/templates/research-master/scitex/vis/gallery/special/stx_raster.json +0 -109
  324. scitex/plt/templates/research-master/scitex/vis/gallery/special/stx_rectangle.json +0 -108
  325. scitex/plt/templates/research-master/scitex/vis/gallery/statistical/errorbar.json +0 -93
  326. scitex/plt/templates/research-master/scitex/vis/gallery/statistical/stx_errorbar.json +0 -84
  327. scitex/plt/templates/research-master/scitex/vis/gallery/statistical/stx_mean_ci.json +0 -96
  328. scitex/plt/templates/research-master/scitex/vis/gallery/statistical/stx_mean_std.json +0 -96
  329. scitex/plt/templates/research-master/scitex/vis/gallery/statistical/stx_median_iqr.json +0 -96
  330. scitex/plt/templates/research-master/scitex/vis/gallery/vector/quiver.json +0 -99
  331. scitex/plt/templates/research-master/scitex/vis/gallery/vector/streamplot.json +0 -100
  332. scitex/vis/__init__.py +0 -177
  333. scitex/vis/editor/_edit.py +0 -390
  334. scitex/vis/editor/flask_editor/_bbox.py +0 -529
  335. scitex/vis/editor/flask_editor/_core.py +0 -168
  336. scitex/vis/editor/flask_editor/_renderer.py +0 -393
  337. scitex/vis/editor/flask_editor/templates/__init__.py +0 -33
  338. scitex/vis/editor/flask_editor/templates/_html.py +0 -513
  339. scitex/vis/editor/flask_editor/templates/_scripts.py +0 -1261
  340. scitex/vis/editor/flask_editor/templates/_styles.py +0 -739
  341. /scitex/{vis → fig}/README.md +0 -0
  342. /scitex/{vis → fig}/backend/__init__.py +0 -0
  343. /scitex/{vis → fig}/backend/_export.py +0 -0
  344. /scitex/{vis → fig}/backend/_render.py +0 -0
  345. /scitex/{vis → fig}/docs/CANVAS_ARCHITECTURE.md +0 -0
  346. /scitex/{vis → fig}/editor/_flask_editor.py +0 -0
  347. /scitex/{vis → fig}/editor/flask_editor/__init__.py +0 -0
  348. /scitex/{vis → fig}/editor/flask_editor/_utils.py +0 -0
  349. /scitex/{vis → fig}/io/_directory.py +0 -0
  350. /scitex/{vis → fig}/model/_plot_types.py +0 -0
  351. /scitex/{vis → fig}/utils/_defaults.py +0 -0
  352. /scitex/{vis → fig}/utils/_validate.py +0 -0
  353. {scitex-2.7.0.dist-info → scitex-2.8.1.dist-info}/WHEEL +0 -0
  354. {scitex-2.7.0.dist-info → scitex-2.8.1.dist-info}/entry_points.txt +0 -0
  355. {scitex-2.7.0.dist-info → scitex-2.8.1.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,1658 @@
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 figz 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 figz 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 figz 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