nirs4all-ui 0.1.15 → 0.1.17

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 (330) hide show
  1. package/README.md +28 -1
  2. package/assets/pipeline-presets.css +38 -0
  3. package/assets/qualification.css +176 -0
  4. package/assets/workbench.css +1482 -0
  5. package/dist/components/PipelinePresetCard.d.ts +16 -0
  6. package/dist/components/PipelinePresetCard.d.ts.map +1 -0
  7. package/dist/components/PipelinePresetCard.js +21 -0
  8. package/dist/components/PipelinePresetCard.js.map +1 -0
  9. package/dist/components/index.d.ts +1 -0
  10. package/dist/components/index.d.ts.map +1 -1
  11. package/dist/components/index.js +1 -0
  12. package/dist/components/index.js.map +1 -1
  13. package/dist/index.d.ts +5 -0
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +5 -0
  16. package/dist/index.js.map +1 -1
  17. package/dist/inspector/ChainList.d.ts +36 -0
  18. package/dist/inspector/ChainList.d.ts.map +1 -0
  19. package/dist/inspector/ChainList.js +89 -0
  20. package/dist/inspector/ChainList.js.map +1 -0
  21. package/dist/inspector/Inspector.d.ts +62 -0
  22. package/dist/inspector/Inspector.d.ts.map +1 -0
  23. package/dist/inspector/Inspector.js +640 -0
  24. package/dist/inspector/Inspector.js.map +1 -0
  25. package/dist/inspector/analysis.d.ts +100 -0
  26. package/dist/inspector/analysis.d.ts.map +1 -0
  27. package/dist/inspector/analysis.js +297 -0
  28. package/dist/inspector/analysis.js.map +1 -0
  29. package/dist/inspector/index.d.ts +30 -0
  30. package/dist/inspector/index.d.ts.map +1 -0
  31. package/dist/inspector/index.js +30 -0
  32. package/dist/inspector/index.js.map +1 -0
  33. package/dist/inspector/insights.d.ts +206 -0
  34. package/dist/inspector/insights.d.ts.map +1 -0
  35. package/dist/inspector/insights.js +404 -0
  36. package/dist/inspector/insights.js.map +1 -0
  37. package/dist/inspector/locale.d.ts +185 -0
  38. package/dist/inspector/locale.d.ts.map +1 -0
  39. package/dist/inspector/locale.js +403 -0
  40. package/dist/inspector/locale.js.map +1 -0
  41. package/dist/inspector/rankingViews.d.ts +25 -0
  42. package/dist/inspector/rankingViews.d.ts.map +1 -0
  43. package/dist/inspector/rankingViews.js +157 -0
  44. package/dist/inspector/rankingViews.js.map +1 -0
  45. package/dist/inspector/stepViews.d.ts +26 -0
  46. package/dist/inspector/stepViews.d.ts.map +1 -0
  47. package/dist/inspector/stepViews.js +93 -0
  48. package/dist/inspector/stepViews.js.map +1 -0
  49. package/dist/inspector/types.d.ts +66 -0
  50. package/dist/inspector/types.d.ts.map +1 -0
  51. package/dist/inspector/types.js +10 -0
  52. package/dist/inspector/types.js.map +1 -0
  53. package/dist/inspector/views.d.ts +133 -0
  54. package/dist/inspector/views.d.ts.map +1 -0
  55. package/dist/inspector/views.js +406 -0
  56. package/dist/inspector/views.js.map +1 -0
  57. package/dist/pipelines/canonicalPipelinePreview.d.ts +21 -0
  58. package/dist/pipelines/canonicalPipelinePreview.d.ts.map +1 -0
  59. package/dist/pipelines/canonicalPipelinePreview.js +384 -0
  60. package/dist/pipelines/canonicalPipelinePreview.js.map +1 -0
  61. package/dist/pipelines/index.d.ts +5 -0
  62. package/dist/pipelines/index.d.ts.map +1 -0
  63. package/dist/pipelines/index.js +5 -0
  64. package/dist/pipelines/index.js.map +1 -0
  65. package/dist/pipelines/pipelineStats.d.ts +27 -0
  66. package/dist/pipelines/pipelineStats.d.ts.map +1 -0
  67. package/dist/pipelines/pipelineStats.js +128 -0
  68. package/dist/pipelines/pipelineStats.js.map +1 -0
  69. package/dist/pipelines/presets.d.ts +50 -0
  70. package/dist/pipelines/presets.d.ts.map +1 -0
  71. package/dist/pipelines/presets.js +92 -0
  72. package/dist/pipelines/presets.js.map +1 -0
  73. package/dist/pipelines/studio-presets.json +3996 -0
  74. package/dist/pipelines/studioPresets.d.ts +21 -0
  75. package/dist/pipelines/studioPresets.d.ts.map +1 -0
  76. package/dist/pipelines/studioPresets.js +12 -0
  77. package/dist/pipelines/studioPresets.js.map +1 -0
  78. package/dist/playground/OperatorPicker.d.ts +31 -0
  79. package/dist/playground/OperatorPicker.d.ts.map +1 -0
  80. package/dist/playground/OperatorPicker.js +145 -0
  81. package/dist/playground/OperatorPicker.js.map +1 -0
  82. package/dist/playground/ParamEditor.d.ts +10 -0
  83. package/dist/playground/ParamEditor.d.ts.map +1 -0
  84. package/dist/playground/ParamEditor.js +31 -0
  85. package/dist/playground/ParamEditor.js.map +1 -0
  86. package/dist/playground/PipelinePanel.d.ts +56 -0
  87. package/dist/playground/PipelinePanel.d.ts.map +1 -0
  88. package/dist/playground/PipelinePanel.js +72 -0
  89. package/dist/playground/PipelinePanel.js.map +1 -0
  90. package/dist/playground/Playground.d.ts +65 -0
  91. package/dist/playground/Playground.d.ts.map +1 -0
  92. package/dist/playground/Playground.js +578 -0
  93. package/dist/playground/Playground.js.map +1 -0
  94. package/dist/playground/index.d.ts +24 -0
  95. package/dist/playground/index.d.ts.map +1 -0
  96. package/dist/playground/index.js +24 -0
  97. package/dist/playground/index.js.map +1 -0
  98. package/dist/playground/locale.d.ts +183 -0
  99. package/dist/playground/locale.d.ts.map +1 -0
  100. package/dist/playground/locale.js +355 -0
  101. package/dist/playground/locale.js.map +1 -0
  102. package/dist/playground/model.d.ts +50 -0
  103. package/dist/playground/model.d.ts.map +1 -0
  104. package/dist/playground/model.js +203 -0
  105. package/dist/playground/model.js.map +1 -0
  106. package/dist/playground/pipeline.d.ts +41 -0
  107. package/dist/playground/pipeline.d.ts.map +1 -0
  108. package/dist/playground/pipeline.js +142 -0
  109. package/dist/playground/pipeline.js.map +1 -0
  110. package/dist/playground/types.d.ts +214 -0
  111. package/dist/playground/types.d.ts.map +1 -0
  112. package/dist/playground/types.js +12 -0
  113. package/dist/playground/types.js.map +1 -0
  114. package/dist/playground/views.d.ts +233 -0
  115. package/dist/playground/views.d.ts.map +1 -0
  116. package/dist/playground/views.js +866 -0
  117. package/dist/playground/views.js.map +1 -0
  118. package/dist/qualification/AvailabilitySummary.d.ts +12 -0
  119. package/dist/qualification/AvailabilitySummary.d.ts.map +1 -0
  120. package/dist/qualification/AvailabilitySummary.js +23 -0
  121. package/dist/qualification/AvailabilitySummary.js.map +1 -0
  122. package/dist/qualification/Badges.d.ts +22 -0
  123. package/dist/qualification/Badges.d.ts.map +1 -0
  124. package/dist/qualification/Badges.js +19 -0
  125. package/dist/qualification/Badges.js.map +1 -0
  126. package/dist/qualification/CapabilityGrid.d.ts +10 -0
  127. package/dist/qualification/CapabilityGrid.d.ts.map +1 -0
  128. package/dist/qualification/CapabilityGrid.js +16 -0
  129. package/dist/qualification/CapabilityGrid.js.map +1 -0
  130. package/dist/qualification/CapabilityTable.d.ts +9 -0
  131. package/dist/qualification/CapabilityTable.d.ts.map +1 -0
  132. package/dist/qualification/CapabilityTable.js +9 -0
  133. package/dist/qualification/CapabilityTable.js.map +1 -0
  134. package/dist/qualification/ChartDataTable.d.ts +13 -0
  135. package/dist/qualification/ChartDataTable.d.ts.map +1 -0
  136. package/dist/qualification/ChartDataTable.js +9 -0
  137. package/dist/qualification/ChartDataTable.js.map +1 -0
  138. package/dist/qualification/CheckList.d.ts +19 -0
  139. package/dist/qualification/CheckList.d.ts.map +1 -0
  140. package/dist/qualification/CheckList.js +14 -0
  141. package/dist/qualification/CheckList.js.map +1 -0
  142. package/dist/qualification/ComparisonMatrix.d.ts +37 -0
  143. package/dist/qualification/ComparisonMatrix.d.ts.map +1 -0
  144. package/dist/qualification/ComparisonMatrix.js +30 -0
  145. package/dist/qualification/ComparisonMatrix.js.map +1 -0
  146. package/dist/qualification/EigenvalueScree.d.ts +17 -0
  147. package/dist/qualification/EigenvalueScree.d.ts.map +1 -0
  148. package/dist/qualification/EigenvalueScree.js +39 -0
  149. package/dist/qualification/EigenvalueScree.js.map +1 -0
  150. package/dist/qualification/EvidenceTable.d.ts +12 -0
  151. package/dist/qualification/EvidenceTable.d.ts.map +1 -0
  152. package/dist/qualification/EvidenceTable.js +13 -0
  153. package/dist/qualification/EvidenceTable.js.map +1 -0
  154. package/dist/qualification/FindingList.d.ts +12 -0
  155. package/dist/qualification/FindingList.d.ts.map +1 -0
  156. package/dist/qualification/FindingList.js +14 -0
  157. package/dist/qualification/FindingList.js.map +1 -0
  158. package/dist/qualification/HypothesisTestTable.d.ts +48 -0
  159. package/dist/qualification/HypothesisTestTable.d.ts.map +1 -0
  160. package/dist/qualification/HypothesisTestTable.js +26 -0
  161. package/dist/qualification/HypothesisTestTable.js.map +1 -0
  162. package/dist/qualification/MeasureBars.d.ts +45 -0
  163. package/dist/qualification/MeasureBars.d.ts.map +1 -0
  164. package/dist/qualification/MeasureBars.js +52 -0
  165. package/dist/qualification/MeasureBars.js.map +1 -0
  166. package/dist/qualification/PopulationFlow.d.ts +42 -0
  167. package/dist/qualification/PopulationFlow.d.ts.map +1 -0
  168. package/dist/qualification/PopulationFlow.js +123 -0
  169. package/dist/qualification/PopulationFlow.js.map +1 -0
  170. package/dist/qualification/QualificationOverview.d.ts +10 -0
  171. package/dist/qualification/QualificationOverview.d.ts.map +1 -0
  172. package/dist/qualification/QualificationOverview.js +12 -0
  173. package/dist/qualification/QualificationOverview.js.map +1 -0
  174. package/dist/qualification/RepeatabilityProfile.d.ts +19 -0
  175. package/dist/qualification/RepeatabilityProfile.d.ts.map +1 -0
  176. package/dist/qualification/RepeatabilityProfile.js +119 -0
  177. package/dist/qualification/RepeatabilityProfile.js.map +1 -0
  178. package/dist/qualification/ReplicateHistogram.d.ts +23 -0
  179. package/dist/qualification/ReplicateHistogram.d.ts.map +1 -0
  180. package/dist/qualification/ReplicateHistogram.js +41 -0
  181. package/dist/qualification/ReplicateHistogram.js.map +1 -0
  182. package/dist/qualification/ScoreMap.d.ts +38 -0
  183. package/dist/qualification/ScoreMap.d.ts.map +1 -0
  184. package/dist/qualification/ScoreMap.js +77 -0
  185. package/dist/qualification/ScoreMap.js.map +1 -0
  186. package/dist/qualification/SpectraExplorer.d.ts +31 -0
  187. package/dist/qualification/SpectraExplorer.d.ts.map +1 -0
  188. package/dist/qualification/SpectraExplorer.js +111 -0
  189. package/dist/qualification/SpectraExplorer.js.map +1 -0
  190. package/dist/qualification/StatTile.d.ts +16 -0
  191. package/dist/qualification/StatTile.d.ts.map +1 -0
  192. package/dist/qualification/StatTile.js +10 -0
  193. package/dist/qualification/StatTile.js.map +1 -0
  194. package/dist/qualification/TargetDistribution.d.ts +34 -0
  195. package/dist/qualification/TargetDistribution.d.ts.map +1 -0
  196. package/dist/qualification/TargetDistribution.js +72 -0
  197. package/dist/qualification/TargetDistribution.js.map +1 -0
  198. package/dist/qualification/_chart.d.ts +19 -0
  199. package/dist/qualification/_chart.d.ts.map +1 -0
  200. package/dist/qualification/_chart.js +30 -0
  201. package/dist/qualification/_chart.js.map +1 -0
  202. package/dist/qualification/_cx.d.ts +2 -0
  203. package/dist/qualification/_cx.d.ts.map +1 -0
  204. package/dist/qualification/_cx.js +6 -0
  205. package/dist/qualification/_cx.js.map +1 -0
  206. package/dist/qualification/engineNumber.d.ts +26 -0
  207. package/dist/qualification/engineNumber.d.ts.map +1 -0
  208. package/dist/qualification/engineNumber.js +88 -0
  209. package/dist/qualification/engineNumber.js.map +1 -0
  210. package/dist/qualification/extract.d.ts +107 -0
  211. package/dist/qualification/extract.d.ts.map +1 -0
  212. package/dist/qualification/extract.js +139 -0
  213. package/dist/qualification/extract.js.map +1 -0
  214. package/dist/qualification/extractBlocks.d.ts +421 -0
  215. package/dist/qualification/extractBlocks.d.ts.map +1 -0
  216. package/dist/qualification/extractBlocks.js +542 -0
  217. package/dist/qualification/extractBlocks.js.map +1 -0
  218. package/dist/qualification/index.d.ts +39 -0
  219. package/dist/qualification/index.d.ts.map +1 -0
  220. package/dist/qualification/index.js +39 -0
  221. package/dist/qualification/index.js.map +1 -0
  222. package/dist/qualification/locale.d.ts +405 -0
  223. package/dist/qualification/locale.d.ts.map +1 -0
  224. package/dist/qualification/locale.js +395 -0
  225. package/dist/qualification/locale.js.map +1 -0
  226. package/dist/qualification/report.d.ts +22 -0
  227. package/dist/qualification/report.d.ts.map +1 -0
  228. package/dist/qualification/report.js +112 -0
  229. package/dist/qualification/report.js.map +1 -0
  230. package/dist/qualification/types.d.ts +118 -0
  231. package/dist/qualification/types.d.ts.map +1 -0
  232. package/dist/qualification/types.js +14 -0
  233. package/dist/qualification/types.js.map +1 -0
  234. package/dist/styles/index.d.ts +19 -1
  235. package/dist/styles/index.d.ts.map +1 -1
  236. package/dist/styles/index.js +17 -0
  237. package/dist/styles/index.js.map +1 -1
  238. package/dist/workbench/CanvasPlot.d.ts +84 -0
  239. package/dist/workbench/CanvasPlot.d.ts.map +1 -0
  240. package/dist/workbench/CanvasPlot.js +209 -0
  241. package/dist/workbench/CanvasPlot.js.map +1 -0
  242. package/dist/workbench/ColorLegend.d.ts +20 -0
  243. package/dist/workbench/ColorLegend.d.ts.map +1 -0
  244. package/dist/workbench/ColorLegend.js +20 -0
  245. package/dist/workbench/ColorLegend.js.map +1 -0
  246. package/dist/workbench/ColorSchemePicker.d.ts +27 -0
  247. package/dist/workbench/ColorSchemePicker.d.ts.map +1 -0
  248. package/dist/workbench/ColorSchemePicker.js +44 -0
  249. package/dist/workbench/ColorSchemePicker.js.map +1 -0
  250. package/dist/workbench/DistributionView.d.ts +40 -0
  251. package/dist/workbench/DistributionView.d.ts.map +1 -0
  252. package/dist/workbench/DistributionView.js +189 -0
  253. package/dist/workbench/DistributionView.js.map +1 -0
  254. package/dist/workbench/ProfileView.d.ts +50 -0
  255. package/dist/workbench/ProfileView.d.ts.map +1 -0
  256. package/dist/workbench/ProfileView.js +136 -0
  257. package/dist/workbench/ProfileView.js.map +1 -0
  258. package/dist/workbench/Scatter3DView.d.ts +39 -0
  259. package/dist/workbench/Scatter3DView.d.ts.map +1 -0
  260. package/dist/workbench/Scatter3DView.js +350 -0
  261. package/dist/workbench/Scatter3DView.js.map +1 -0
  262. package/dist/workbench/ScatterView.d.ts +112 -0
  263. package/dist/workbench/ScatterView.d.ts.map +1 -0
  264. package/dist/workbench/ScatterView.js +195 -0
  265. package/dist/workbench/ScatterView.js.map +1 -0
  266. package/dist/workbench/SpectraView.d.ts +84 -0
  267. package/dist/workbench/SpectraView.d.ts.map +1 -0
  268. package/dist/workbench/SpectraView.js +461 -0
  269. package/dist/workbench/SpectraView.js.map +1 -0
  270. package/dist/workbench/VirtualTable.d.ts +36 -0
  271. package/dist/workbench/VirtualTable.d.ts.map +1 -0
  272. package/dist/workbench/VirtualTable.js +48 -0
  273. package/dist/workbench/VirtualTable.js.map +1 -0
  274. package/dist/workbench/_cx.d.ts +2 -0
  275. package/dist/workbench/_cx.d.ts.map +1 -0
  276. package/dist/workbench/_cx.js +6 -0
  277. package/dist/workbench/_cx.js.map +1 -0
  278. package/dist/workbench/colorBy.d.ts +123 -0
  279. package/dist/workbench/colorBy.d.ts.map +1 -0
  280. package/dist/workbench/colorBy.js +215 -0
  281. package/dist/workbench/colorBy.js.map +1 -0
  282. package/dist/workbench/controls.d.ts +120 -0
  283. package/dist/workbench/controls.d.ts.map +1 -0
  284. package/dist/workbench/controls.js +129 -0
  285. package/dist/workbench/controls.js.map +1 -0
  286. package/dist/workbench/format.d.ts +7 -0
  287. package/dist/workbench/format.d.ts.map +1 -0
  288. package/dist/workbench/format.js +45 -0
  289. package/dist/workbench/format.js.map +1 -0
  290. package/dist/workbench/hooks.d.ts +21 -0
  291. package/dist/workbench/hooks.d.ts.map +1 -0
  292. package/dist/workbench/hooks.js +89 -0
  293. package/dist/workbench/hooks.js.map +1 -0
  294. package/dist/workbench/icons.d.ts +11 -0
  295. package/dist/workbench/icons.d.ts.map +1 -0
  296. package/dist/workbench/icons.js +61 -0
  297. package/dist/workbench/icons.js.map +1 -0
  298. package/dist/workbench/index.d.ts +39 -0
  299. package/dist/workbench/index.d.ts.map +1 -0
  300. package/dist/workbench/index.js +42 -0
  301. package/dist/workbench/index.js.map +1 -0
  302. package/dist/workbench/layout.d.ts +108 -0
  303. package/dist/workbench/layout.d.ts.map +1 -0
  304. package/dist/workbench/layout.js +132 -0
  305. package/dist/workbench/layout.js.map +1 -0
  306. package/dist/workbench/matrix.d.ts +47 -0
  307. package/dist/workbench/matrix.d.ts.map +1 -0
  308. package/dist/workbench/matrix.js +168 -0
  309. package/dist/workbench/matrix.js.map +1 -0
  310. package/dist/workbench/projection3d.d.ts +82 -0
  311. package/dist/workbench/projection3d.d.ts.map +1 -0
  312. package/dist/workbench/projection3d.js +127 -0
  313. package/dist/workbench/projection3d.js.map +1 -0
  314. package/dist/workbench/sampling.d.ts +20 -0
  315. package/dist/workbench/sampling.d.ts.map +1 -0
  316. package/dist/workbench/sampling.js +118 -0
  317. package/dist/workbench/sampling.js.map +1 -0
  318. package/dist/workbench/selection.d.ts +49 -0
  319. package/dist/workbench/selection.d.ts.map +1 -0
  320. package/dist/workbench/selection.js +99 -0
  321. package/dist/workbench/selection.js.map +1 -0
  322. package/dist/workbench/shortcuts.d.ts +27 -0
  323. package/dist/workbench/shortcuts.d.ts.map +1 -0
  324. package/dist/workbench/shortcuts.js +60 -0
  325. package/dist/workbench/shortcuts.js.map +1 -0
  326. package/dist/workbench/spatial.d.ts +44 -0
  327. package/dist/workbench/spatial.d.ts.map +1 -0
  328. package/dist/workbench/spatial.js +155 -0
  329. package/dist/workbench/spatial.js.map +1 -0
  330. package/package.json +24 -3
package/README.md CHANGED
@@ -28,6 +28,9 @@ spectra motion asset.
28
28
  | `viz` | `nirs4all-ui/viz` | Dependency-free scientific SVG charts. Each chart provides a data-derived accessible description and accepts a `description` override for localized or domain-specific wording. Hosts supply computed values and retain analysis/execution. |
29
29
  | `dag` | `nirs4all-ui/dag` | Interactive compiled-DAG explorer (layered layout, pan/zoom, culling/LOD, collapsible clusters) plus the pure engine and a `fromCompiledGraph` adapter for a serialized DAG-ML graph/plan. |
30
30
  | `chains` | `nirs4all-ui/chains` | Chain-effect explorer over a corpus of scored pipelines: per-node influence ranking, position (early/mid/late) and predecessor×successor order effects, and with/without distribution shift, with per-dataset rank/z normalization. Pure engine + charts + interactive explorer, plus a `parseChainEffectAnalysis` adapter for the serialized `dag-ml` artifact. |
31
+ | `workbench` | `nirs4all-ui/workbench` | Shared interactive-analysis kit behind the capsules: selection algebra (click / box / lasso, Shift add · Alt subtract · Ctrl toggle), color-by resolution, canvas views (`SpectraView` lines / bands / density, `ScatterView`, `DistributionView`, `ProfileView`) on a layered `CanvasPlot`, view grid with layout presets, panel chrome, virtual table, capsule-scoped shortcuts. |
32
+ | `playground` | `nirs4all-ui/playground` | The **Playground capsule**: dataset exploration and live operator chains (pipeline timeline with preview cursor, operator picker, linked spectra / scores / target / T²–Q / loadings / r(λ) / folds / replicates / samples views, selection drawer). The host executes `PlaygroundRunRequest`s and returns `PlaygroundResult`s. |
33
+ | `inspector` | `nirs4all-ui/inspector` | The **Inspector capsule**: rank and dissect trained chains (leaderboard with ☆ compare, score landscape, pivot heatmap, generalization, hyper-parameters, step effects, parity, residuals, fold stability, confusion, hard samples, chain details with step diff). The host supplies chains, score references and on-demand predictions. |
31
34
  | `lab` | `nirs4all-ui/lab` | Quality/lab decision, sample lifecycle, health, model report, worklist, and budget display contracts plus presentational components. |
32
35
  | `datasetBuilder` | `nirs4all-ui/datasetBuilder` | Multisource dataset-builder wizard components and pure dataset-config helpers. |
33
36
  | `brand` | `nirs4all-ui/brand` | Ecosystem brand definitions, stable asset paths, palettes, and deterministic SVG generators. |
@@ -37,7 +40,7 @@ spectra motion asset.
37
40
  The root export also exposes namespace barrels:
38
41
 
39
42
  ```ts
40
- import { brand, chains, conformal, dag, dataset, datasetBuilder, keywordRegistry, lab, nodeRegistry, robustness, runtime, score, styles, tuning } from "nirs4all-ui";
43
+ import { brand, chains, conformal, dag, inspector, playground, workbench, dataset, datasetBuilder, keywordRegistry, lab, nodeRegistry, robustness, runtime, score, styles, tuning } from "nirs4all-ui";
41
44
  ```
42
45
 
43
46
  Prefer domain imports when a consumer only needs one area:
@@ -52,6 +55,9 @@ import { createKeywordRegistryFieldViews, createKeywordRegistryWorkspacePredicti
52
55
  import { projectN4mManifest } from "nirs4all-ui/nodeRegistry";
53
56
  import { createTuningSearchSpacePreview, createTuningStudySummary, createTuningSummaryCard, createTuningTrialRows, parseOrderedTuningSearchSpaceArtifact, parseTuningResultArtifact, parseTuningSummaryArtifact } from "nirs4all-ui/tuning";
54
57
  import { DatasetBuilder } from "nirs4all-ui/datasetBuilder";
58
+ import { Playground } from "nirs4all-ui/playground";
59
+ import { Inspector } from "nirs4all-ui/inspector";
60
+ import { SpectraView, ScatterView, combineSelection } from "nirs4all-ui/workbench";
55
61
  import { DagGraphView, fromCompiledGraph } from "nirs4all-ui/dag";
56
62
  import { ChainExplorer, fromScoredChains, parseChainEffectAnalysis } from "nirs4all-ui/chains";
57
63
  import { DecisionBadge } from "nirs4all-ui/lab";
@@ -71,6 +77,7 @@ Static assets are published through the existing `nirs4all-ui/assets/*` export:
71
77
  ```css
72
78
  @import "nirs4all-ui/assets/styles/nirs4all-default.css";
73
79
  @import "nirs4all-ui/assets/datasetBuilder.css";
80
+ @import "nirs4all-ui/assets/workbench.css";
74
81
  @import "nirs4all-ui/assets/theme.css";
75
82
  ```
76
83
 
@@ -143,3 +150,23 @@ verifies that every public React component, lab, and dataset-builder export
143
150
  appears in the page and that the mirrored brand/logo, crawler metadata,
144
151
  manifest, default styles, package CSS assets, motion asset, reusable brand kit,
145
152
  and canonical URLs stay in sync with the packaged asset set.
153
+
154
+ ### Pipeline preset cards
155
+
156
+ `PipelinePresetCard` from `nirs4all-ui/components` presents Studio's preset metadata,
157
+ complexity, canonical recipe statistics and preview, with host-provided task actions
158
+ and icons. Import `nirs4all-ui/assets/pipeline-presets.css` for the shared appearance.
159
+ `nirs4all-ui/pipelines` exports the pure canonical preview, statistics and preset
160
+ model helpers. The component supports React server rendering for static catalogues;
161
+ it owns no routing, API access or application state.
162
+
163
+ The shared preset content is generated from Studio's `api/presets/*.yaml`:
164
+
165
+ ```bash
166
+ python scripts/sync-studio-presets.py --studio ../nirs4all-studio
167
+ # Requires PyYAML; use a Studio or Repository Python environment.
168
+ ```
169
+
170
+ `getStudioPipelinePresets()` returns independent copies of all ten defaults and
171
+ both task variants. Studio checks the snapshot against its authored YAML hashes;
172
+ Repository checks its recipes against the same shared data before rendering.
@@ -0,0 +1,38 @@
1
+ .n4-preset-card {
2
+ --preset-text: var(--n4-color-text, #0f172a);
3
+ --preset-muted: var(--n4-color-muted, #64748b);
4
+ --preset-border: var(--n4-color-border, #e2e8f0);
5
+ --preset-primary: var(--n4-color-primary, #0d9488);
6
+ display: flex; flex-direction: column; height: 100%; min-width: 0; box-sizing: border-box;
7
+ padding: 16px; border: 1px solid var(--preset-border); border-radius: 8px;
8
+ background: var(--n4-color-surface, #fff); color: var(--preset-text); line-height: 1.5;
9
+ font-family: var(--n4-font-sans, Inter, system-ui, sans-serif);
10
+ }
11
+ .n4-preset-header { display: flex; align-items: flex-start; justify-content: space-between; gap: 8px; margin-bottom: 12px; flex-wrap: wrap; }
12
+ .n4-preset-template { display: flex; align-items: center; gap: 8px; padding: 2px 8px; border-radius: 4px; background: #06b6d41a; color: #0891b2; font-size: 12px; font-weight: 500; }
13
+ .n4-preset-name { font: 600 16px/1.5 var(--n4-font-sans, Inter, system-ui, sans-serif); margin: 0; color: inherit; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
14
+ .n4-preset-description { font-size: 11px; color: var(--preset-muted); margin: 4px 0 0; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
15
+ .n4-preset-hint { display: flex; align-items: center; gap: 6px; margin-top: 8px; font-size: 11px; color: var(--preset-muted); }
16
+ .n4-preset-stats { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; padding: 8px 12px; margin: 12px 0 0; border: 1px solid var(--preset-border); border-radius: 6px; background: color-mix(in srgb, var(--preset-muted) 4%, transparent); }
17
+ .n4-preset-stats dd { margin: 0; font-size: 14px; font-weight: 600; font-variant-numeric: tabular-nums; line-height: 1; overflow-wrap: anywhere; }
18
+ .n4-preset-stats dt { font-size: 10px; margin-top: 2px; text-transform: uppercase; letter-spacing: .025em; color: var(--preset-muted); }
19
+ .n4-preset-stats .n4-preset-emphasize { font-size: clamp(12px, 1vw, 14px); white-space: nowrap; color: var(--preset-primary); }
20
+ .n4-preset-preview { padding: 0; margin: 12px 0 0; list-style: none; font-size: 12px; }
21
+ .n4-preset-preview li { display: flex; align-items: center; gap: 8px; min-width: 0; margin-top: 4px; color: var(--preset-muted); }
22
+ .n4-preset-preview li > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
23
+ .n4-preset-preview svg, .n4-preset-header svg, .n4-preset-hint svg { width: 12px; height: 12px; flex-shrink: 0; }
24
+ .n4-preset-preview .n4-preset-more { font-size: 11px; font-style: italic; }
25
+ .n4-preset-actions { display: flex; gap: 8px; margin-top: auto; padding-top: 12px; }
26
+ .n4-preset-actions > div { flex: 1; min-width: 0; }
27
+ .n4-preset-action { display: flex; justify-content: center; align-items: center; box-sizing: border-box; width: 100%; min-height: 32px; padding: 4px 12px; border: 1px solid #10b98140; border-radius: 999px; background: #10b9811a; color: #047857; font-size: 11px; font-weight: 600; text-decoration: none; }
28
+ .n4-preset-action:hover { background: #10b98129; text-decoration: none; }
29
+ .n4-preset-action-classification { border-color: #0ea5e940; background: #0ea5e91a; color: #0369a1; }
30
+ .n4-preset-action-classification:hover { background: #0ea5e929; }
31
+ .n4-preset-complexity { display: inline-flex; align-items: center; gap: 6px; border: 1px solid; padding: 4px 10px; border-radius: 999px; font-size: 11px; font-weight: 600; }
32
+ .n4-preset-complexity > span { text-transform: capitalize; }
33
+ .n4-preset-starter { color: #047857; border-color: #10b98140; background: #10b9811a; }
34
+ .n4-preset-quick { color: #0369a1; border-color: #0ea5e940; background: #0ea5e91a; }
35
+ .n4-preset-balanced { color: #b45309; border-color: #f59e0b40; background: #f59e0b1a; }
36
+ .n4-preset-heavy { color: #c2410c; border-color: #f9731640; background: #f973161a; }
37
+ .n4-preset-exhaustive { color: #be123c; border-color: #f43f5e40; background: #f43f5e1a; }
38
+ .n4-preset-action:focus-visible { outline: 2px solid var(--preset-primary, #0d9488); outline-offset: 3px; }
@@ -0,0 +1,176 @@
1
+ /* nirs4all-ui qualification domain. Variables fall back to the shared teal/red brand. */
2
+ .n4q-badge{display:inline-flex;align-items:center;gap:.4em;padding:.15em .6em;border-radius:999px;font-size:.78rem;font-weight:600;border:1px solid currentColor;background:var(--n4q-badge-bg,transparent);white-space:nowrap}
3
+ .n4q-reason{font-weight:400;font-size:.72rem;opacity:.85}
4
+ .n4q-profile-exploratory{color:#b45309}.n4q-profile-partial{color:#0f766e}.n4q-profile-complete{color:#047857}
5
+ .n4q-avail-computed{color:#047857}.n4q-avail-not_applicable,.n4q-avail-undefined{color:#475569}
6
+ .n4q-avail-insufficient_data,.n4q-avail-unsupported,.n4q-avail-not_identifiable{color:#b45309}
7
+ .n4q-avail-cancelled{color:#6d28d9}.n4q-avail-error{color:#b91c1c}
8
+ .n4q-conf-unknown{color:#475569}.n4q-conf-low{color:#b45309}.n4q-conf-medium{color:#0f766e}.n4q-conf-high{color:#047857}
9
+ .n4q-sev-info{color:#0f766e}.n4q-sev-warning{color:#b45309}.n4q-sev-high{color:#b91c1c}.n4q-sev-blocking{color:#7f1d1d}
10
+ .n4q-table-wrap{overflow-x:auto;max-width:100%}
11
+ .n4q-table-wrap:focus-visible,.n4q-datatable summary:focus-visible{outline:2px solid var(--n4q-focus,#058e96);outline-offset:2px}
12
+ .n4q-table{width:100%;border-collapse:collapse;font-size:.88rem}
13
+ .n4q-table caption{text-align:left;font-weight:600;padding:.4rem 0}
14
+ .n4q-table th,.n4q-table td{padding:.45rem .6rem;border-bottom:1px solid var(--n4q-line,rgba(100,116,139,.3));text-align:left;vertical-align:top}
15
+ .n4q-table thead th{font-size:.76rem;text-transform:uppercase;letter-spacing:.04em}
16
+ .n4q-table-compact th,.n4q-table-compact td{padding:.25rem .5rem}
17
+ .n4q-num{text-align:right;font-variant-numeric:tabular-nums}
18
+ .n4q-sub{display:block;font-size:.76rem;opacity:.75}
19
+ .n4q-null{opacity:.7;font-style:italic}
20
+ .n4q-unit{opacity:.75}
21
+ .n4q-findings{list-style:none;margin:0;padding:0;display:grid;gap:.6rem}
22
+ .n4q-finding{border:1px solid var(--n4q-line,rgba(100,116,139,.3));border-left-width:4px;border-radius:8px;padding:.6rem .8rem}
23
+ .n4q-finding[data-severity=blocking]{border-left-color:#7f1d1d}.n4q-finding[data-severity=high]{border-left-color:#b91c1c}.n4q-finding[data-severity=warning]{border-left-color:#b45309}.n4q-finding[data-severity=info]{border-left-color:#058e96}
24
+ .n4q-finding-head{display:flex;flex-wrap:wrap;gap:.4rem;align-items:center}
25
+ .n4q-finding p{margin:.35rem 0 0}
26
+ .n4q-empty{opacity:.8}
27
+ .n4q-overview{display:grid;gap:.8rem}
28
+ .n4q-overview-head{display:flex;flex-wrap:wrap;gap:.6rem;align-items:center}.n4q-overview-head p{margin:0}
29
+ .n4q-provenance{display:grid;grid-template-columns:max-content 1fr;gap:.2rem .8rem;margin:0;font-size:.85rem}.n4q-provenance dt{opacity:.75}.n4q-provenance dd{margin:0}
30
+ .n4q-summary{margin:0;display:grid;gap:.5rem}
31
+ .n4q-bar{width:100%;height:14px;border-radius:7px;overflow:hidden;background:rgba(100,116,139,.15)}
32
+ .n4q-swatch{display:inline-block;width:.8em;height:.8em;margin-right:.5em;border-radius:2px;vertical-align:baseline}
33
+ .n4q-fill-computed{fill:#059669;background:#059669}.n4q-fill-not_applicable{fill:#94a3b8;background:#94a3b8}
34
+ .n4q-fill-insufficient_data{fill:#d97706;background:#d97706}.n4q-fill-unsupported{fill:#b45309;background:#b45309}
35
+ .n4q-fill-not_identifiable{fill:#0891b2;background:#0891b2}.n4q-fill-undefined{fill:#64748b;background:#64748b}
36
+ .n4q-fill-cancelled{fill:#7c3aed;background:#7c3aed}.n4q-fill-error{fill:#dc2626;background:#dc2626}
37
+ .n4q-datatable summary{cursor:pointer;font-size:.85rem}
38
+
39
+ /* --- charts (PopulationFlow, RepeatabilityProfile, EigenvalueScree, ScoreMap, TargetDistribution) --- */
40
+ .n4q-chart{margin:0;display:grid;gap:.6rem;min-width:0}
41
+ .n4q-chart-plot{position:relative;min-width:0}
42
+ .n4q-svg{display:block;width:100%;height:auto;overflow:visible;font-family:var(--font,Inter,system-ui,sans-serif)}
43
+ .n4q-svg:focus-visible{outline:2px solid var(--teal,#0d9488);outline-offset:4px;border-radius:6px}
44
+ .n4q-grid{stroke:var(--n4q-grid,rgba(100,116,139,.16));stroke-width:1}
45
+ .n4q-zero,.n4q-baseline{stroke:var(--n4q-axis,rgba(100,116,139,.55));stroke-width:1}
46
+ .n4q-crosshair{stroke:var(--text-2,#475569);stroke-width:1;stroke-opacity:.6}
47
+ .n4q-tick{font-family:var(--mono,"JetBrains Mono",monospace);font-size:10px;fill:var(--text-3,#64748b)}
48
+ .n4q-axis-title{font-size:11px;font-weight:600;fill:var(--text-2,#475569)}
49
+ .n4q-line{fill:none;stroke-width:2;stroke-linejoin:round;stroke-linecap:round}
50
+ .n4q-marker,.n4q-dot{stroke:var(--n4q-surface,var(--surface,#fff));stroke-width:2;transition:r .12s}
51
+ .n4q-whisker{stroke:var(--teal-d,#0f766e);stroke-width:1.5}
52
+ .n4q-hit{cursor:default;outline:none}
53
+ .n4q-hit:focus-visible rect:first-child{stroke:var(--teal,#0d9488);stroke-width:1.5;stroke-dasharray:3 3}
54
+ .n4q-flow-label{font-size:12px;fill:var(--text-2,#475569)}
55
+ .n4q-flow-total{font-size:15px;font-weight:700;fill:var(--text,#0f172a)}
56
+ .n4q-flow-stage{font-weight:600;fill:var(--text,#0f172a)}
57
+ .n4q-flow-link{fill-opacity:.1}
58
+ .n4q-flow-empty{fill:var(--n4q-null-fill,#e2e8f0)}
59
+ .n4q-flow-seg{outline:none;cursor:default}
60
+ .n4q-flow-seg rect{transition:opacity .15s}
61
+ .n4q-flow-seg[data-active] rect,.n4q-flow-seg:focus-visible rect{opacity:.82}
62
+ .n4q-flow-seg:focus-visible rect{stroke:var(--text,#0f172a);stroke-width:2}
63
+ .n4q-flow-inbar{font-size:11.5px;fill:#fff;pointer-events:none}
64
+ .n4q-cat-label{font-size:12px;fill:var(--text-2,#475569)}
65
+ .n4q-cat-value{font-size:12px;font-weight:700;fill:var(--text,#0f172a)}
66
+
67
+ .n4q-tip{position:absolute;z-index:5;pointer-events:none;min-width:150px;max-width:280px;padding:.55rem .7rem;border-radius:10px;
68
+ background:var(--n4q-tip-bg,rgba(255,255,255,.97));color:var(--text,#0f172a);border:1px solid var(--border,#e2e8f0);
69
+ box-shadow:0 14px 34px -14px rgba(15,23,42,.35);font-size:.78rem;line-height:1.35;backdrop-filter:blur(8px)}
70
+ .n4q-tip-head{font-weight:700;margin-bottom:.25rem;font-family:var(--mono,monospace);font-size:.74rem}
71
+ .n4q-tip-row{display:flex;align-items:center;gap:.45rem;white-space:nowrap}
72
+ .n4q-tip-row strong{font-variant-numeric:tabular-nums}
73
+ .n4q-tip-row span:last-child{color:var(--text-2,#475569);overflow:hidden;text-overflow:ellipsis}
74
+ .n4q-tip-sub{color:var(--text-3,#64748b);font-size:.72rem}
75
+ .n4q-tip-block+.n4q-tip-block{margin-top:.3rem;padding-top:.3rem;border-top:1px solid var(--border,#e2e8f0)}
76
+
77
+ .n4q-legend{display:flex;flex-wrap:wrap;gap:.35rem 1rem;list-style:none;margin:0;padding:0;font-size:.8rem;color:var(--text-2,#475569)}
78
+ .n4q-legend li{display:inline-flex;align-items:center;gap:.4rem}
79
+ .n4q-legend li[data-zero]{opacity:.55}
80
+ .n4q-legend strong{color:var(--text,#0f172a);font-variant-numeric:tabular-nums}
81
+ .n4q-legend-title{font-weight:600;color:var(--text,#0f172a)}
82
+ .n4q-legend-sub{color:var(--text-3,#64748b)}
83
+ .n4q-key-dot{display:inline-block;width:10px;height:10px;border-radius:50%;flex:none}
84
+ .n4q-key-hollow{background:transparent;border:2px solid}
85
+ .n4q-key-null{background:transparent;border:1.5px solid #94a3b8}
86
+ .n4q-key-line{display:inline-block;width:16px;height:3px;border-radius:2px;flex:none}
87
+ .n4q-key-box{display:inline-block;width:16px;height:10px;border-radius:3px;background:rgba(13,148,136,.25);border-left:3px solid #0d9488;flex:none}
88
+ .n4q-key-diamond{display:inline-block;width:9px;height:9px;transform:rotate(45deg);flex:none}
89
+ .n4q-colorbar{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem;font-size:.8rem;color:var(--text-2,#475569);font-variant-numeric:tabular-nums}
90
+ .n4q-colorbar-ramp{display:inline-block;width:140px;height:10px;border-radius:5px}
91
+ .n4q-visually-hidden{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
92
+
93
+ .n4q-stat{display:grid;gap:.15rem;align-content:start;padding:1rem 1.1rem;border-radius:var(--radius-sm,10px);background:var(--surface,#fff);
94
+ border:1px solid var(--border,#e2e8f0);color:inherit;text-decoration:none;position:relative;overflow:hidden;transition:border-color .2s,transform .2s,box-shadow .2s}
95
+ .n4q-stat::before{content:"";position:absolute;left:0;top:0;bottom:0;width:3px;background:var(--n4q-stat-accent,var(--teal,#0d9488));opacity:.85}
96
+ .n4q-stat[data-tone=good]{--n4q-stat-accent:#059669}.n4q-stat[data-tone=warning]{--n4q-stat-accent:#d97706}.n4q-stat[data-tone=critical]{--n4q-stat-accent:#e11d48}
97
+ a.n4q-stat:hover{border-color:var(--teal,#0d9488);transform:translateY(-1px);box-shadow:var(--shadow,0 4px 16px -4px rgba(17,24,39,.08))}
98
+ .n4q-stat-label{font-size:.76rem;font-weight:600;color:var(--text-2,#475569)}
99
+ .n4q-stat-value{font-size:1.75rem;font-weight:600;letter-spacing:-.02em;color:var(--text,#0f172a);line-height:1.15}
100
+ .n4q-stat-suffix{font-size:.85rem;font-weight:500;color:var(--text-3,#64748b);margin-left:.3rem;letter-spacing:0}
101
+ .n4q-stat-hint{font-size:.76rem;color:var(--text-3,#64748b)}
102
+
103
+ .n4q-capgrid{display:grid;gap:1rem;grid-template-columns:repeat(auto-fit,minmax(min(100%,260px),1fr))}
104
+ .n4q-capgroup{border:1px solid var(--border,#e2e8f0);border-radius:var(--radius-sm,10px);padding:.8rem .9rem;background:var(--surface,#fff)}
105
+ .n4q-capgroup h4{display:flex;align-items:center;gap:.5rem;margin:0 0 .6rem;font-size:.85rem}
106
+ .n4q-capcount{margin-left:auto;font-family:var(--mono,monospace);font-size:.75rem;color:var(--text-3,#64748b)}
107
+ .n4q-capdot{width:9px;height:9px;border-radius:50%;background:#94a3b8}
108
+ .n4q-capgroup[data-group=qualified] .n4q-capdot{background:#059669}
109
+ .n4q-capgroup[data-group=available] .n4q-capdot{background:#d97706}
110
+ .n4q-capgroup ul{list-style:none;margin:0;padding:0;display:grid;gap:.45rem}
111
+ .n4q-capgroup li{display:grid;font-size:.84rem;line-height:1.3}
112
+ .n4q-capgroup li code{font-size:.7rem;color:var(--text-3,#64748b)}
113
+ .n4q-capgroup[data-group=unavailable] li strong{font-weight:500;color:var(--text-2,#475569)}
114
+ .n4q-metric-name{display:block;font-weight:600;font-size:.84rem}
115
+ .n4q-evidence-link{display:inline-block;margin-right:.5rem;font-weight:600}
116
+ :root[data-theme=dark] .n4q-tip,.theme-dark .n4q-tip{--n4q-tip-bg:rgba(16,35,58,.97)}
117
+ :root[data-theme=dark],.theme-dark{--n4q-null-fill:#334155;--n4q-grid:rgba(255,255,255,.08);--n4q-axis:rgba(255,255,255,.3)}
118
+ .n4q-capgroup ul{grid-template-columns:repeat(auto-fill,minmax(min(100%,210px),1fr));gap:.7rem 1.2rem}
119
+ :root[data-theme=dark] .n4q-avail-not_applicable,:root[data-theme=dark] .n4q-avail-undefined,:root[data-theme=dark] .n4q-conf-unknown{color:#94a3b8}
120
+ :root[data-theme=dark] .n4q-profile-exploratory,:root[data-theme=dark] .n4q-avail-insufficient_data,:root[data-theme=dark] .n4q-avail-unsupported,:root[data-theme=dark] .n4q-avail-not_identifiable,:root[data-theme=dark] .n4q-conf-low,:root[data-theme=dark] .n4q-sev-warning{color:#fbbf24}
121
+ :root[data-theme=dark] .n4q-avail-computed,:root[data-theme=dark] .n4q-profile-complete,:root[data-theme=dark] .n4q-conf-high{color:#34d399}
122
+ :root[data-theme=dark] .n4q-profile-partial,:root[data-theme=dark] .n4q-conf-medium,:root[data-theme=dark] .n4q-sev-info{color:#2dd4bf}
123
+ :root[data-theme=dark] .n4q-avail-error,:root[data-theme=dark] .n4q-sev-high{color:#fb7185}
124
+ :root[data-theme=dark] .n4q-sev-blocking{color:#fda4af}:root[data-theme=dark] .n4q-avail-cancelled{color:#a78bfa}
125
+ .n4q-tip-ctx{display:flex;align-items:center;gap:.45rem;font-size:.72rem;color:var(--text-2,#475569);margin-bottom:.1rem;white-space:nowrap}
126
+
127
+ /* --- SpectraExplorer --- */
128
+ .n4q-explorer-line{fill:none;stroke-width:1.3;stroke-opacity:.72;stroke-linejoin:round;transition:stroke-opacity .15s}
129
+ .n4q-explorer-lines[data-dim] .n4q-explorer-line{stroke-opacity:.16}
130
+ .n4q-explorer-focus{fill:none;stroke-width:2.6;stroke-linejoin:round;stroke-linecap:round;pointer-events:none}
131
+ .n4q-explorer-missing{opacity:.8}.n4q-explorer-missing[data-active]{opacity:1;transform-box:fill-box}
132
+ .n4q-tip-alert{color:#e11d48;font-weight:600}
133
+
134
+ /* --- CheckList --- */
135
+ .n4q-checks{list-style:none;margin:0;padding:0;display:grid;gap:2px}
136
+ .n4q-check{display:grid;grid-template-columns:auto 1fr auto;align-items:start;gap:.8rem;padding:.75rem .5rem;border-radius:10px;transition:background .15s}
137
+ .n4q-check+.n4q-check{border-top:1px solid var(--border,#e2e8f0)}
138
+ .n4q-check:hover{background:rgba(100,116,139,.06)}
139
+ .n4q-check-icon{flex:none;margin-top:1px}
140
+ .n4q-check-icon circle{fill:var(--n4q-check-bg)}
141
+ .n4q-check-icon path{fill:none;stroke:var(--n4q-check-fg);stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round}
142
+ .n4q-check[data-status=ok]{--n4q-check-bg:rgba(16,185,129,.16);--n4q-check-fg:#059669}
143
+ .n4q-check[data-status=attention]{--n4q-check-bg:rgba(217,119,6,.16);--n4q-check-fg:#b45309}
144
+ .n4q-check[data-status=critical]{--n4q-check-bg:rgba(225,29,72,.14);--n4q-check-fg:#e11d48}
145
+ .n4q-check[data-status=unavailable]{--n4q-check-bg:rgba(100,116,139,.14);--n4q-check-fg:#64748b}
146
+ :root[data-theme=dark] .n4q-check[data-status=ok]{--n4q-check-fg:#34d399}
147
+ :root[data-theme=dark] .n4q-check[data-status=attention]{--n4q-check-fg:#fbbf24}
148
+ :root[data-theme=dark] .n4q-check[data-status=critical]{--n4q-check-fg:#fb7185}
149
+ :root[data-theme=dark] .n4q-check[data-status=unavailable]{--n4q-check-fg:#94a3b8}
150
+ .n4q-check-head{display:flex;flex-wrap:wrap;align-items:baseline;gap:.2rem .6rem}
151
+ .n4q-check-head strong{font-size:.92rem}
152
+ .n4q-check-status{font-size:.68rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--n4q-check-fg)}
153
+ .n4q-check-body p{margin:.15rem 0 0;font-size:.84rem;color:var(--text-2,#475569);line-height:1.45}
154
+ .n4q-check-link{font-size:.8rem;font-weight:600;white-space:nowrap;align-self:center}
155
+ .n4q-finding code,.n4q-finding-head code{overflow-wrap:anywhere}
156
+ .n4q-finding{min-width:0}
157
+
158
+ /* --- 0.1.0 blocks: MeasureBars, HypothesisTestTable, ComparisonMatrix, ReplicateHistogram, interval bands --- */
159
+ .n4q-band{fill-opacity:.16;stroke:none}
160
+ .n4q-identity{stroke:var(--text-3,#64748b);stroke-width:1;stroke-dasharray:4 4}
161
+ .n4q-measure .n4q-cat-label{font-size:11.5px}
162
+ .n4q-decision{font-weight:600;white-space:nowrap}
163
+ .n4q-decision[data-rejects=true]{color:#b45309}
164
+ .n4q-decision[data-rejects=false]{color:var(--text-2,#475569);font-weight:500}
165
+ :root[data-theme=dark] .n4q-decision[data-rejects=true]{color:#fbbf24}
166
+ .n4q-tests tbody th,.n4q-matrix tbody th{font-weight:600;white-space:nowrap}
167
+ .n4q-tests tr[data-rejects=true] th{box-shadow:inset 3px 0 0 #d97706}
168
+ .n4q-matrix-cell{min-width:7.5rem}
169
+ .n4q-matrix-value{display:block;font-variant-numeric:tabular-nums}
170
+ .n4q-matrix-track{position:relative;display:block;height:6px;margin-top:3px;border-radius:3px;background:rgba(100,116,139,.14);overflow:hidden}
171
+ .n4q-matrix-bar{position:absolute;top:0;bottom:0;left:0;border-radius:3px;background:var(--teal,#0d9488);opacity:.8}
172
+ .n4q-matrix-track[data-centred=true]::after{content:"";position:absolute;left:50%;top:-1px;bottom:-1px;width:1px;background:var(--n4q-axis,rgba(100,116,139,.55))}
173
+ .n4q-matrix-bar[data-below=true]{background:#6366f1}
174
+ :root[data-theme=dark] .n4q-matrix-track{background:rgba(255,255,255,.08)}
175
+ :root[data-theme=dark] .n4q-band{fill-opacity:.22}
176
+ .n4q-table thead .n4q-nocase{text-transform:none;letter-spacing:0}