@morscherlab/mint-sdk 1.4.0-beta.1 → 1.4.0-beta.11

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 (266) hide show
  1. package/dist/{ActionMenu-CScINahU.js → AlertBox-B2Bgr3ei.js} +40 -209
  2. package/dist/AlertBox-B2Bgr3ei.js.map +1 -0
  3. package/dist/{AppSidebar-BmiiPfz9.js → AppSidebar-mvm--GxN.js} +161 -110
  4. package/dist/AppSidebar-mvm--GxN.js.map +1 -0
  5. package/dist/{ConfirmDialog-CJ7hqYUP.js → ConfirmDialog-nbJj51is.js} +2 -2
  6. package/dist/{ConfirmDialog-CJ7hqYUP.js.map → ConfirmDialog-nbJj51is.js.map} +1 -1
  7. package/dist/ExperimentPopover-5T1fAq2L.js +337 -0
  8. package/dist/ExperimentPopover-5T1fAq2L.js.map +1 -0
  9. package/dist/{ExperimentSelectorModal-D-9z7cNx.js → ExperimentSelectorModal-65peG4Up.js} +198 -181
  10. package/dist/ExperimentSelectorModal-65peG4Up.js.map +1 -0
  11. package/dist/{SegmentedControl-DERBN-Xd.js → SegmentedControl-BtnnjWzs.js} +2 -2
  12. package/dist/{SegmentedControl-DERBN-Xd.js.map → SegmentedControl-BtnnjWzs.js.map} +1 -1
  13. package/dist/{SettingsModal-CSLE31yg.js → SettingsModal-DO3IZ7qz.js} +9 -9
  14. package/dist/SettingsModal-DO3IZ7qz.js.map +1 -0
  15. package/dist/__tests__/styles/v2AuditRules.test.d.ts +1 -0
  16. package/dist/components/AppSidebar.vue.d.ts +1 -1
  17. package/dist/components/ArtifactSaveDialog.vue.d.ts +9 -1
  18. package/dist/components/AuditTrail.vue.d.ts +1 -1
  19. package/dist/components/BaseSelect.vue.d.ts +2 -2
  20. package/dist/components/ChartContainer.vue.d.ts +2 -0
  21. package/dist/components/DatePicker.vue.d.ts +1 -1
  22. package/dist/components/ExperimentPopover.vue.d.ts +18 -0
  23. package/dist/components/ExperimentSelectorModal.vue.d.ts +0 -4
  24. package/dist/components/FilePicker.vue.d.ts +1 -1
  25. package/dist/components/FileUploader.vue.d.ts +2 -2
  26. package/dist/components/PluginIcon.vue.d.ts +2 -2
  27. package/dist/components/SampleSelector.vue.d.ts +6 -6
  28. package/dist/components/SequenceProgressBar.vue.d.ts +3 -0
  29. package/dist/components/StepWizard.vue.d.ts +3 -0
  30. package/dist/components/internal/AutoGroupModalInternal.vue.d.ts +1 -1
  31. package/dist/components/internal/DatePickerTimeInternal.vue.d.ts +1 -1
  32. package/dist/components/internal/ResourcePickerListInternal.vue.d.ts +2 -7
  33. package/dist/components/internal/SelectMultipleInternal.vue.d.ts +4 -0
  34. package/dist/composables/createClient.d.ts +2 -0
  35. package/dist/composables/index.d.ts +1 -0
  36. package/dist/composables/pluginIdentity.d.ts +24 -0
  37. package/dist/composables/pluginWorkspaceModel.d.ts +2 -2
  38. package/dist/composables/useAppExperiment.d.ts +8 -0
  39. package/dist/composables/useCalendarGrid.d.ts +1 -1
  40. package/dist/composables/useExperimentSelector.d.ts +6 -2
  41. package/dist/composables/usePlatform.d.ts +1 -0
  42. package/dist/{controlSchemaModel-CP5-_nAj.js → controlSchemaModel-B8CTXagP.js} +2 -2
  43. package/dist/{controlSchemaModel-CP5-_nAj.js.map → controlSchemaModel-B8CTXagP.js.map} +1 -1
  44. package/dist/{data-C2PwI_dn.js → data-CgILxDLW.js} +178 -124
  45. package/dist/data-CgILxDLW.js.map +1 -0
  46. package/dist/data.js +8 -8
  47. package/dist/{experimentStatus-BZmU4czV.js → experimentStatus-Cqp6qNrR.js} +3 -3
  48. package/dist/{experimentStatus-BZmU4czV.js.map → experimentStatus-Cqp6qNrR.js.map} +1 -1
  49. package/dist/index.js +19 -19
  50. package/dist/{install-DAID6c2-.js → install-mB8-IyvO.js} +15 -14
  51. package/dist/{install-DAID6c2-.js.map → install-mB8-IyvO.js.map} +1 -1
  52. package/dist/install.js +1 -1
  53. package/dist/{lab-DLwRl_Ql.js → lab-D5bIX426.js} +128 -147
  54. package/dist/lab-D5bIX426.js.map +1 -0
  55. package/dist/lab.js +4 -3
  56. package/dist/{records-BzTcxekG.js → records-B6gpM_3e.js} +472 -274
  57. package/dist/records-B6gpM_3e.js.map +1 -0
  58. package/dist/{runtime-D6gVat6r.js → runtime-D7vKpfbF.js} +27 -31
  59. package/dist/runtime-D7vKpfbF.js.map +1 -0
  60. package/dist/runtime.js +6 -6
  61. package/dist/{shell-5ju97nOS.js → shell-CywENwBT.js} +5 -5
  62. package/dist/{shell-5ju97nOS.js.map → shell-CywENwBT.js.map} +1 -1
  63. package/dist/shell.js +5 -5
  64. package/dist/styles.css +1644 -1688
  65. package/dist/types/componentWorkflowTypes.d.ts +2 -0
  66. package/dist/types/generated/platformContext.d.ts +1 -0
  67. package/dist/types/generated-ui.d.ts +4 -0
  68. package/dist/{BaseModal-DfRIuVoj.js → useDropdownState-8yWMu-7_.js} +60 -2
  69. package/dist/useDropdownState-8yWMu-7_.js.map +1 -0
  70. package/dist/{useExperimentSamples-CxcnxZ8h.js → useExperimentSamples-DHnxKFAF.js} +3 -3
  71. package/dist/{useExperimentSamples-CxcnxZ8h.js.map → useExperimentSamples-DHnxKFAF.js.map} +1 -1
  72. package/dist/{useListReorder-CcbEYxX-.js → useListReorder-BitdUhxn.js} +109 -277
  73. package/dist/useListReorder-BitdUhxn.js.map +1 -0
  74. package/dist/{useRackEditor-BD5NIo5s.js → useRackEditor-Q8xO-cCy.js} +72 -58
  75. package/dist/useRackEditor-Q8xO-cCy.js.map +1 -0
  76. package/dist/{useRealtime-PalKue84.js → useRealtime-C3iy9QkU.js} +7 -4
  77. package/dist/useRealtime-C3iy9QkU.js.map +1 -0
  78. package/dist/useRequest-D506eHi8.js +244 -0
  79. package/dist/useRequest-D506eHi8.js.map +1 -0
  80. package/dist/utils/time.d.ts +7 -0
  81. package/package.json +1 -1
  82. package/src/__tests__/components/AppTopBar.test.ts +51 -2
  83. package/src/__tests__/components/AppTopBarPillNav.test.ts +35 -0
  84. package/src/__tests__/components/ArtifactSaveDialog.test.ts +78 -0
  85. package/src/__tests__/components/BaseSelect.multiple.test.ts +87 -32
  86. package/src/__tests__/components/BaseSelect.test.ts +2 -1
  87. package/src/__tests__/components/BatchProgressList.test.ts +16 -0
  88. package/src/__tests__/components/CalendarGridPanel.test.ts +2 -2
  89. package/src/__tests__/components/ChartContainer.test.ts +11 -0
  90. package/src/__tests__/components/ChemicalFormula.test.ts +6 -3
  91. package/src/__tests__/components/DatePicker.datetime.test.ts +6 -0
  92. package/src/__tests__/components/DatePicker.test.ts +21 -0
  93. package/src/__tests__/components/DatePicker.time.test.ts +2 -2
  94. package/src/__tests__/components/EmptyState.test.ts +1 -1
  95. package/src/__tests__/components/ExperimentPopover.test.ts +125 -16
  96. package/src/__tests__/components/ExperimentSelectorModal.test.ts +119 -13
  97. package/src/__tests__/components/GeneratedPluginView.test.ts +22 -1
  98. package/src/__tests__/components/InstrumentStateBadge.test.ts +4 -4
  99. package/src/__tests__/components/PluginWorkspaceView.test.ts +7 -0
  100. package/src/__tests__/components/ResourcePickerListInternal.test.ts +0 -20
  101. package/src/__tests__/components/SampleSelector.test.ts +13 -8
  102. package/src/__tests__/components/SequenceProgressBar.test.ts +12 -0
  103. package/src/__tests__/components/StepWizard.test.ts +11 -0
  104. package/src/__tests__/components/WellPlate.decoration.test.ts +11 -4
  105. package/src/__tests__/components/deprecationTags.test.ts +1 -1
  106. package/src/__tests__/composables/useAppExperiment.test.ts +27 -1
  107. package/src/__tests__/composables/useCalendarGrid.test.ts +4 -2
  108. package/src/__tests__/composables/useExperimentSelector.test.ts +111 -0
  109. package/src/__tests__/styles/baseControlsRules.test.ts +6 -2
  110. package/src/__tests__/styles/controlRefreshRules.test.ts +0 -6
  111. package/src/__tests__/styles/cssTokens.test.ts +2 -2
  112. package/src/__tests__/styles/menusShellRefresh.test.ts +14 -10
  113. package/src/__tests__/styles/v2AuditRules.test.ts +96 -0
  114. package/src/__tests__/utils/plotlyTemplate.test.ts +4 -4
  115. package/src/__tests__/utils/time.test.ts +18 -1
  116. package/src/components/AdductText.story.vue +7 -0
  117. package/src/components/AdductText.vue +1 -1
  118. package/src/components/AlertBox.story.vue +2 -2
  119. package/src/components/AlertBox.vue +18 -16
  120. package/src/components/AppSidebar.story.vue +0 -28
  121. package/src/components/AppTopBar.story.vue +47 -12
  122. package/src/components/AppTopBar.vue +118 -114
  123. package/src/components/ArtifactSaveDialog.story.vue +23 -0
  124. package/src/components/ArtifactSaveDialog.vue +102 -12
  125. package/src/components/AuditTrail.story.vue +2 -1
  126. package/src/components/AuditTrail.vue +2 -21
  127. package/src/components/Avatar.vue +10 -14
  128. package/src/components/BaseSelect.multiple.story.vue +13 -2
  129. package/src/components/BaseSelect.vue +4 -3
  130. package/src/components/BatchProgressList.vue +35 -25
  131. package/src/components/ChartContainer.story.vue +2 -1
  132. package/src/components/ChartContainer.vue +8 -6
  133. package/src/components/ConfirmDialog.story.vue +1 -1
  134. package/src/components/EmptyState.vue +1 -1
  135. package/src/components/ExperimentPopover.story.vue +165 -53
  136. package/src/components/ExperimentPopover.vue +169 -187
  137. package/src/components/ExperimentSelectorModal.story.vue +40 -36
  138. package/src/components/ExperimentSelectorModal.vue +124 -110
  139. package/src/components/FormField.story.vue +8 -48
  140. package/src/components/GeneratedPluginView.vue +7 -1
  141. package/src/components/GeneratedResultRenderer.vue +3 -4
  142. package/src/components/InstrumentStateBadge.vue +1 -1
  143. package/src/components/JobsStatusTray.vue +1 -1
  144. package/src/components/LoadingSpinner.vue +1 -1
  145. package/src/components/NumberInput.vue +3 -6
  146. package/src/components/PluginIcon.story.vue +2 -10
  147. package/src/components/PluginIcon.vue +2 -2
  148. package/src/components/PluginWorkspaceView.story.vue +1 -1
  149. package/src/components/RuntimeUpdateNotice.vue +1 -1
  150. package/src/components/SampleSelector.story.vue +1 -1
  151. package/src/components/SampleSelector.vue +27 -37
  152. package/src/components/SampleSelectorGroupNode.vue +1 -1
  153. package/src/components/SectionCard.story.vue +2 -2
  154. package/src/components/SequenceProgressBar.story.vue +9 -0
  155. package/src/components/SequenceProgressBar.vue +6 -1
  156. package/src/components/SettingsModal.schema.ts +1 -1
  157. package/src/components/SettingsModal.vue +2 -2
  158. package/src/components/SmartGroupFieldRecipe.story.vue +1 -1
  159. package/src/components/SmartGroupManual.story.vue +1 -1
  160. package/src/components/StepWizard.story.vue +33 -0
  161. package/src/components/StepWizard.vue +8 -1
  162. package/src/components/WellPlate.story.vue +3 -1
  163. package/src/components/WellPlate.vue +7 -0
  164. package/src/components/internal/AppTopBarPillNavInternal.vue +33 -2
  165. package/src/components/internal/DatePickerDateInternal.vue +16 -40
  166. package/src/components/internal/DatePickerDateTimeInternal.vue +3 -13
  167. package/src/components/internal/DatePickerTimeInternal.vue +5 -8
  168. package/src/components/internal/ResourcePickerListInternal.vue +45 -85
  169. package/src/components/internal/SelectMultipleInternal.vue +182 -65
  170. package/src/components/internal/SelectSearchableInternal.vue +2 -3
  171. package/src/composables/createClient.ts +2 -0
  172. package/src/composables/index.ts +1 -0
  173. package/src/composables/pluginIdentity.ts +31 -0
  174. package/src/composables/pluginWorkspaceModel.ts +2 -2
  175. package/src/composables/useAppExperiment.ts +20 -0
  176. package/src/composables/useCalendarGrid.ts +4 -3
  177. package/src/composables/useExperimentSelector.ts +77 -31
  178. package/src/composables/usePluginWorkspace.ts +1 -1
  179. package/src/styles/components/adduct-text.css +13 -5
  180. package/src/styles/components/alert-box.css +39 -58
  181. package/src/styles/components/app-layout.css +7 -5
  182. package/src/styles/components/app-page-selector.css +3 -1
  183. package/src/styles/components/app-pill-nav.css +11 -12
  184. package/src/styles/components/app-sidebar.css +9 -18
  185. package/src/styles/components/app-top-bar.css +57 -55
  186. package/src/styles/components/artifact-save-dialog.css +153 -2
  187. package/src/styles/components/audit-trail.css +16 -19
  188. package/src/styles/components/avatar.css +6 -4
  189. package/src/styles/components/batch-progress-list.css +38 -36
  190. package/src/styles/components/button.css +28 -59
  191. package/src/styles/components/calendar.css +12 -12
  192. package/src/styles/components/chart-container.css +34 -23
  193. package/src/styles/components/checkbox.css +2 -12
  194. package/src/styles/components/collapsible-card.css +27 -29
  195. package/src/styles/components/confirm-dialog.css +13 -14
  196. package/src/styles/components/dataframe.css +13 -5
  197. package/src/styles/components/date-picker.css +80 -92
  198. package/src/styles/components/datetime-picker.css +31 -43
  199. package/src/styles/components/divider.css +20 -20
  200. package/src/styles/components/dose-calculator.css +3 -3
  201. package/src/styles/components/empty-state.css +20 -17
  202. package/src/styles/components/experiment-code-badge.css +2 -0
  203. package/src/styles/components/experiment-popover.css +174 -329
  204. package/src/styles/components/experiment-selector-modal.css +75 -56
  205. package/src/styles/components/file-picker.css +3 -3
  206. package/src/styles/components/file-uploader.css +38 -49
  207. package/src/styles/components/form-builder.css +3 -3
  208. package/src/styles/components/formula-input.css +1 -1
  209. package/src/styles/components/icon-button.css +18 -24
  210. package/src/styles/components/input.css +5 -4
  211. package/src/styles/components/instrument-monitor.css +13 -15
  212. package/src/styles/components/jobs-status-tray.css +31 -25
  213. package/src/styles/components/modal.css +4 -6
  214. package/src/styles/components/molecule-input.css +2 -2
  215. package/src/styles/components/multi-select.css +65 -117
  216. package/src/styles/components/number-input.css +26 -19
  217. package/src/styles/components/pill.css +3 -2
  218. package/src/styles/components/plate-editor.css +0 -1
  219. package/src/styles/components/plugin-icon.css +26 -23
  220. package/src/styles/components/popover.css +2 -2
  221. package/src/styles/components/presence-avatars.css +1 -1
  222. package/src/styles/components/progress-bar.css +3 -3
  223. package/src/styles/components/protocol-step-editor.css +1 -3
  224. package/src/styles/components/resource-card.css +2 -2
  225. package/src/styles/components/resource-picker-list.css +6 -57
  226. package/src/styles/components/sample-hierarchy-tree.css +4 -4
  227. package/src/styles/components/sample-selector.css +95 -79
  228. package/src/styles/components/schedule-calendar.css +8 -8
  229. package/src/styles/components/searchable-select.css +12 -12
  230. package/src/styles/components/section-card.css +30 -47
  231. package/src/styles/components/segmented-control.css +18 -15
  232. package/src/styles/components/select.css +3 -3
  233. package/src/styles/components/sequence-input.css +2 -2
  234. package/src/styles/components/sequence-progress-bar.css +17 -8
  235. package/src/styles/components/settings-modal.css +7 -2
  236. package/src/styles/components/smart-group.css +18 -18
  237. package/src/styles/components/step-wizard.css +52 -16
  238. package/src/styles/components/tabs.css +2 -2
  239. package/src/styles/components/textarea.css +3 -3
  240. package/src/styles/components/time-picker.css +36 -21
  241. package/src/styles/components/toast.css +12 -10
  242. package/src/styles/components/toggle.css +1 -11
  243. package/src/styles/components/tooltip.css +10 -9
  244. package/src/styles/components/unit-input.css +8 -7
  245. package/src/styles/components/well-plate.css +9 -2
  246. package/src/styles/variables.css +118 -77
  247. package/src/types/componentWorkflowTypes.ts +2 -0
  248. package/src/types/generated/platformContext.ts +1 -0
  249. package/src/types/generated-ui.ts +4 -0
  250. package/src/utils/time.ts +21 -0
  251. package/dist/ActionMenu-CScINahU.js.map +0 -1
  252. package/dist/AppSidebar-BmiiPfz9.js.map +0 -1
  253. package/dist/BaseModal-DfRIuVoj.js.map +0 -1
  254. package/dist/ExperimentPopover-C4sGw-is.js +0 -359
  255. package/dist/ExperimentPopover-C4sGw-is.js.map +0 -1
  256. package/dist/ExperimentSelectorModal-D-9z7cNx.js.map +0 -1
  257. package/dist/SettingsModal-CSLE31yg.js.map +0 -1
  258. package/dist/data-C2PwI_dn.js.map +0 -1
  259. package/dist/lab-DLwRl_Ql.js.map +0 -1
  260. package/dist/records-BzTcxekG.js.map +0 -1
  261. package/dist/runtime-D6gVat6r.js.map +0 -1
  262. package/dist/useListReorder-CcbEYxX-.js.map +0 -1
  263. package/dist/useRackEditor-BD5NIo5s.js.map +0 -1
  264. package/dist/useRealtime-PalKue84.js.map +0 -1
  265. package/dist/useRequest-D5JDfsgZ.js +0 -76
  266. package/dist/useRequest-D5JDfsgZ.js.map +0 -1
@@ -3,7 +3,11 @@
3
3
  * @import '@morscherlab/mint-sdk/styles';
4
4
  */
5
5
 
6
- @import url('https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500;600;700&family=Fira+Sans:wght@300;400;500;600;700&display=swap');
6
+ @import url('https://fonts.googleapis.com/css2?family=Geist:wght@400;500;600;700&family=Geist+Mono:wght@400;500;600&display=swap');
7
+
8
+ /* Tailwind v4's layer order, declared first so the SDK's base and utilities
9
+ layers sort the same way with or without Tailwind in the host. */
10
+ @layer theme, base, components, utilities;
7
11
 
8
12
  /* ==========================================================================
9
13
  CSS Variables - Light Mode
@@ -21,9 +25,9 @@
21
25
  /* Strong control border — unchecked checkbox/radio, toggle off track, dashed outlines (~3.2:1 light, ~4.2:1 dark). */
22
26
  --_control-border-strong: color-mix(in srgb, var(--text-secondary) 75%, var(--border-color));
23
27
  /* Field border on hover. */
24
- --_field-border-hover: color-mix(in srgb, var(--text-secondary) 60%, var(--border-color));
25
- /* Ink: primary / error text on card and tinted surfaces. The -hover tokens
26
- have no dark value, so html.dark lifts these toward --text-primary. */
28
+ --_field-border-hover: var(--border-strong);
29
+ /* Ink: primary / error text on card and tinted surfaces. html.dark lifts
30
+ these toward --text-primary. */
27
31
  --_ink-primary: var(--color-primary-hover);
28
32
  --_ink-error: var(--mint-error-hover);
29
33
 
@@ -33,11 +37,12 @@
33
37
  --bg-tertiary: #F1F5F9;
34
38
  --bg-card: #FFFFFF;
35
39
  --bg-hover: #F1F5F9;
36
- --border-color: #E5E7EB;
37
- --border-light: #F3F4F6;
40
+ --border-color: #E2E8F0;
41
+ --border-light: #F1F5F9;
42
+ --border-strong: #CBD5E1;
38
43
 
39
44
  /* Text colors */
40
- --text-primary: #1E293B;
45
+ --text-primary: #0F172A;
41
46
  --text-secondary: #64748B;
42
47
  --text-muted: #94A3B8;
43
48
  /* De-emphasized label for low-emphasis interactive controls (secondary/ghost
@@ -46,25 +51,36 @@
46
51
  where --text-secondary would drop to ~4.35:1. */
47
52
  --text-secondary-strong: #475569;
48
53
 
49
- /* Brand colors */
50
- --color-primary: #14B8A6;
54
+ /* Brand colors — one teal accent: teal-600 fills, teal-700 hover + ink,
55
+ teal-800 pressed. White on #0D9488 is 3.74:1, a known AA exception. */
56
+ --color-primary: #0D9488;
51
57
  --color-primary-hover: #0F766E;
52
- --color-primary-soft: rgba(20, 184, 166, 0.12);
53
- --color-cta: #06B6D4;
54
- --color-cta-hover: #0891B2;
55
- --color-purple: #8B5CF6;
56
-
57
- /* Entity accent colors — experiments (cyan) and projects (sky), from the
58
- MINT 1.1 card system. -soft backs icon chips and pills, -border outlines
59
- pills that sit on a card surface. */
60
- --color-experiment: #06B6D4;
61
- --color-experiment-hover: #0891B2;
62
- --color-experiment-soft: rgba(6, 182, 212, 0.12);
63
- --color-experiment-border: rgba(6, 182, 212, 0.3);
64
- --color-project: #0EA5E9;
65
- --color-project-hover: #0284C7;
66
- --color-project-soft: rgba(14, 165, 233, 0.12);
67
- --color-project-border: rgba(14, 165, 233, 0.32);
58
+ --color-primary-pressed: #115E59;
59
+ --color-primary-soft: rgba(13, 148, 136, 0.10);
60
+ --color-primary-border: #99F6E4;
61
+ /* Fixed teal scale, the same in both themes. */
62
+ --color-primary-50: #F0FDFA;
63
+ --color-primary-100: #CCFBF1;
64
+ --color-primary-500: #14B8A6;
65
+ --color-primary-600: #0D9488;
66
+ --mint-primary: var(--color-primary);
67
+ /* Text and icons on an accent fill (filled buttons, Save). */
68
+ --text-on-accent: #FFFFFF;
69
+ /* Retired hues, aliased to the accent until 1.5 (mint doctor warns on use). */
70
+ --color-cta: var(--color-primary);
71
+ --color-cta-hover: var(--color-primary-hover);
72
+ --color-purple: var(--color-primary);
73
+
74
+ /* Entity colors — retired hues, aliased to slate until 1.5. Entities are told
75
+ apart by icon and label, not by hue. Only -hover has no neutral token. */
76
+ --color-experiment: var(--text-secondary-strong);
77
+ --color-experiment-hover: #334155;
78
+ --color-experiment-soft: var(--bg-tertiary);
79
+ --color-experiment-border: var(--border-strong);
80
+ --color-project: var(--color-experiment);
81
+ --color-project-hover: var(--color-experiment-hover);
82
+ --color-project-soft: var(--color-experiment-soft);
83
+ --color-project-border: var(--color-experiment-border);
68
84
 
69
85
  /* MINT brand mark — used for browser theme-color, marketing chrome, app icon background */
70
86
  --mint-brand: #7BD0B5;
@@ -76,13 +92,14 @@
76
92
  --scrollbar-thumb: #D1D5DB;
77
93
  --scrollbar-hover: #9CA3AF;
78
94
 
79
- /* Shadows */
80
- --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
81
- --shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
82
- --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
83
- --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
84
- /* The MINT 1.1 card system uses exactly one shadow for every card. */
85
- --card-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.04), 0 1px 3px 0 rgb(0 0 0 / 0.06);
95
+ /* Shadows — flat by default (borders, not shadows); only floating layers
96
+ (popovers, menus, dialogs) get one. */
97
+ --shadow-sm: none;
98
+ --shadow: none;
99
+ --card-shadow: none;
100
+ --shadow-md: 0 4px 12px -2px rgba(15, 23, 42, 0.10), 0 1px 3px rgba(15, 23, 42, 0.06);
101
+ --shadow-lg: 0 16px 40px -8px rgba(15, 23, 42, 0.18), 0 2px 6px rgba(15, 23, 42, 0.06);
102
+ --mint-shadow-pop: 0 4px 12px -2px rgba(15, 23, 42, 0.10), 0 1px 3px rgba(15, 23, 42, 0.06);
86
103
 
87
104
  /* Categorical sample scale — mirrored by SAMPLE_COLOR_SCALE in
88
105
  src/utils/color.ts. The JS constant carries the same hexes as a
@@ -106,20 +123,24 @@
106
123
  /* Motion — the SDK's standard easing curve. */
107
124
  --mint-ease-out-quart: cubic-bezier(0.25, 1, 0.5, 1);
108
125
 
109
- /* Typography — Fira Sans for UI text, Fira Code for data, code and routes. */
110
- --font-sans: 'Fira Sans', system-ui, -apple-system, sans-serif;
111
- --font-mono: 'Fira Code', ui-monospace, SFMono-Regular, Menlo, monospace;
112
-
113
- /* Border radius */
114
- --radius-sm: 0.25rem;
115
- --radius: 0.375rem;
116
- --radius-md: 0.5rem;
117
- --radius-lg: 0.75rem;
118
-
119
- /* Form element heights */
120
- --form-height-sm: 2rem;
121
- --form-height-md: 2.25rem;
122
- --form-height-lg: 3rem;
126
+ /* Typography — Geist for UI text, Geist Mono for codes, m/z, RT, counts and timestamps. */
127
+ --font-sans: 'Geist', system-ui, -apple-system, sans-serif;
128
+ --font-mono: 'Geist Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
129
+
130
+ /* Border radius — code badges, tags, buttons/inputs, cards/dialogs. */
131
+ --radius-sm: 3px;
132
+ --radius: 4px;
133
+ --radius-md: 6px;
134
+ --radius-lg: 8px;
135
+
136
+ /* Form element heights and page gutter — compact (normal and compact
137
+ density); [data-density="comfortable"] below restores the larger set. */
138
+ --form-height-sm: 1.75rem;
139
+ --form-height-md: 2rem;
140
+ --form-height-lg: 2.5rem;
141
+ --mint-gutter: 0.5rem;
142
+ /* Distance from the outermost cards to the window edge, in every density. */
143
+ --mint-page-inset: 1rem;
123
144
 
124
145
  /* Semantic colors */
125
146
  --mint-success: #10B981;
@@ -141,20 +162,20 @@
141
162
  --mint-info-border: rgba(59, 130, 246, 0.3);
142
163
 
143
164
  /* Extended brand tokens */
144
- --color-primary-light: #93C5FD;
165
+ --color-primary-light: #5EEAD4;
145
166
 
146
167
  /* Shared component tokens */
147
168
  --mint-disabled-opacity: 0.6;
148
169
 
149
170
  /* Focus ring tokens */
150
171
  --focus-ring: 0 0 0 2px var(--color-primary);
151
- --focus-ring-offset: 0 0 0 2px white, 0 0 0 4px var(--color-primary);
172
+ --focus-ring-offset: 0 0 0 2px #FFFFFF, 0 0 0 4px var(--color-primary);
152
173
  --focus-ring-error: 0 0 0 2px var(--mint-error);
153
174
 
154
175
  /* Soft focus rings — 3px translucent. Used by all form primitives
155
176
  post-0.16 visual refresh. Solid variants above kept for legacy
156
177
  components that haven't migrated yet. */
157
- --focus-ring-soft: 0 0 0 3px rgba(20, 184, 166, 0.20);
178
+ --focus-ring-soft: 0 0 0 3px rgba(13, 148, 136, 0.18);
158
179
  /* Red is perceptually brighter than teal at equal alpha; drop 2pp to keep visual weight matched. */
159
180
  --focus-ring-soft-error: 0 0 0 3px rgba(239, 68, 68, 0.18);
160
181
 
@@ -174,7 +195,8 @@
174
195
  --mint-text-inverse: #FFFFFF;
175
196
  --mint-border: var(--border-color);
176
197
  --mint-border-focus: var(--color-primary);
177
- --mint-transition: 150ms ease;
198
+ /* Colour-only transitions; no lift, bounce or glow. */
199
+ --mint-transition: 120ms ease;
178
200
  }
179
201
 
180
202
  /* ==========================================================================
@@ -182,24 +204,35 @@
182
204
  ========================================================================== */
183
205
  html.dark {
184
206
  /* Background colors */
185
- --bg-primary: #0F172A;
186
- --bg-secondary: #1E293B;
187
- --bg-tertiary: #334155;
188
- --bg-card: #1E293B;
189
- --bg-hover: #334155;
190
- --border-color: #334155;
191
- --border-light: #1E293B;
207
+ --bg-primary: #0B1120;
208
+ --bg-secondary: #111827;
209
+ --bg-tertiary: #1E293B;
210
+ --bg-card: #111827;
211
+ --bg-hover: #1E293B;
212
+ --border-color: #1F2937;
213
+ --border-light: #172033;
214
+ --border-strong: #334155;
215
+
216
+ /* Brand colors - Dark mode (CTA, purple and entity aliases follow) */
217
+ --color-primary: #2DD4BF;
218
+ --color-primary-hover: #5EEAD4;
219
+ --color-primary-pressed: #99F6E4;
220
+ --color-primary-soft: rgba(45, 212, 191, 0.12);
221
+ --color-primary-border: rgba(45, 212, 191, 0.35);
222
+ /* Dark ink on the light accent fill (10.1:1 on #2DD4BF). */
223
+ --text-on-accent: #0B1120;
224
+ --color-experiment-hover: #E2E8F0;
192
225
 
193
226
  /* Ink aliases (see :root): ~7:1 on --bg-card, tints included. */
194
227
  --_ink-primary: color-mix(in srgb, var(--color-primary) 50%, var(--text-primary));
195
228
  --_ink-error: color-mix(in srgb, var(--mint-error) 50%, var(--text-primary));
196
229
 
197
230
  /* Text colors */
198
- --text-primary: #F8FAFC;
231
+ --text-primary: #F1F5F9;
199
232
  --text-secondary: #94A3B8;
200
233
  --text-muted: #64748B;
201
- /* Dark-mode analog: soft light-gray instead of near-white, AA-safe (7.2:1)
202
- on the dark secondary hover surface (--bg-tertiary #334155). */
234
+ /* Dark-mode analog: soft light-gray instead of near-white, AA-safe (9.9:1)
235
+ on the dark secondary hover surface (--bg-tertiary #1E293B). */
203
236
  --text-secondary-strong: #CBD5E1;
204
237
 
205
238
  /* Scrollbar */
@@ -207,22 +240,10 @@ html.dark {
207
240
  --scrollbar-thumb: #475569;
208
241
  --scrollbar-hover: #64748B;
209
242
 
210
- /* Shadows - Dark mode */
211
- --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.2);
212
- --shadow: 0 1px 3px 0 rgb(0 0 0 / 0.3), 0 1px 2px -1px rgb(0 0 0 / 0.2);
213
- --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.3), 0 2px 4px -2px rgb(0 0 0 / 0.2);
214
- --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.3), 0 4px 6px -4px rgb(0 0 0 / 0.2);
215
- --card-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.24), 0 1px 3px 0 rgb(0 0 0 / 0.32);
216
-
217
- /* Entity accent colors - Dark mode */
218
- --color-experiment: #22D3EE;
219
- --color-experiment-hover: #67E8F9;
220
- --color-experiment-soft: rgba(34, 211, 238, 0.16);
221
- --color-experiment-border: rgba(34, 211, 238, 0.36);
222
- --color-project: #38BDF8;
223
- --color-project-hover: #7DD3FC;
224
- --color-project-soft: rgba(56, 189, 248, 0.16);
225
- --color-project-border: rgba(56, 189, 248, 0.38);
243
+ /* Shadows - Dark mode (floating layers only; --shadow-sm/--shadow/--card-shadow stay none) */
244
+ --shadow-md: 0 6px 16px -4px rgba(0, 0, 0, 0.6);
245
+ --shadow-lg: 0 16px 40px -8px rgba(0, 0, 0, 0.7);
246
+ --mint-shadow-pop: 0 6px 16px -4px rgba(0, 0, 0, 0.6);
226
247
 
227
248
  /* Semantic colors - Dark mode */
228
249
  --mint-success-bg: rgba(16, 185, 129, 0.15);
@@ -233,7 +254,7 @@ html.dark {
233
254
 
234
255
  /* Focus ring - dark mode offset uses bg-primary instead of white */
235
256
  --focus-ring-offset: 0 0 0 2px var(--bg-primary), 0 0 0 4px var(--color-primary);
236
- --focus-ring-soft: 0 0 0 3px rgba(129, 140, 248, 0.28);
257
+ --focus-ring-soft: 0 0 0 3px rgba(45, 212, 191, 0.22);
237
258
  --focus-ring-soft-error: 0 0 0 3px rgba(248, 113, 113, 0.26);
238
259
 
239
260
  /* Legacy aliases */
@@ -243,6 +264,15 @@ html.dark {
243
264
  color-scheme: dark;
244
265
  }
245
266
 
267
+ /* Comfortable density (html[data-density], written by the settings store):
268
+ the pre-v2 control heights and a wider gutter. */
269
+ [data-density="comfortable"] {
270
+ --form-height-sm: 2rem;
271
+ --form-height-md: 2.25rem;
272
+ --form-height-lg: 3rem;
273
+ --mint-gutter: 0.75rem;
274
+ }
275
+
246
276
  /* ==========================================================================
247
277
  Base Styles
248
278
  ========================================================================== */
@@ -261,6 +291,13 @@ code, pre {
261
291
  font-family: var(--font-mono);
262
292
  }
263
293
 
294
+ /* Links: accent ink. In the base layer, so Tailwind utilities and component
295
+ rules (both win over a layered element rule) keep their own link colours. */
296
+ @layer base {
297
+ a { color: var(--color-primary-hover); }
298
+ a:hover { color: var(--color-primary-pressed); }
299
+ }
300
+
264
301
  /* Native controls do not inherit the page font; Tailwind preflight covers this
265
302
  in the platform, but SDK consumers without it render buttons and selects in
266
303
  the UA font. */
@@ -313,6 +350,9 @@ button, input, select, textarea {
313
350
  /* ==========================================================================
314
351
  MINT Utility Classes (for Tailwind v4 compatibility)
315
352
  ========================================================================== */
353
+ /* In Tailwind's utilities layer: unlayered, these beat every layered rule, so a
354
+ host's responsive variant (`lg:flex-row`) lost to the SDK's `.flex-col`. */
355
+ @layer utilities {
316
356
  .bg-bg-hover {
317
357
  background-color: var(--bg-tertiary);
318
358
  }
@@ -688,6 +728,7 @@ button, input, select, textarea {
688
728
  .max-w-sm {
689
729
  max-width: 24rem;
690
730
  }
731
+ } /* @layer utilities */
691
732
 
692
733
  /* ==========================================================================
693
734
  Reduced Motion
@@ -184,5 +184,7 @@ export interface ExperimentFilters {
184
184
  project?: string | null
185
185
  experimentType?: string | null
186
186
  datePreset?: DatePreset | null
187
+ /** Only experiments the caller authored (`?mine=true`). */
188
+ mine?: boolean
187
189
  }
188
190
 
@@ -21,6 +21,7 @@ export interface PlatformContextPlugin {
21
21
  route_prefix: string
22
22
  api_prefix: string
23
23
  settings_api: "plugin" | "platform"
24
+ subtitle?: string
24
25
  description?: string
25
26
  icon?: string
26
27
  color?: string
@@ -151,7 +151,11 @@ export interface GeneratedAnalysisManifest {
151
151
  }
152
152
  ui: {
153
153
  title: string
154
+ /** Second top-bar line; the top bar falls back to `description`. */
155
+ subtitle?: string
154
156
  description: string
157
+ /** Plugin icon for the standalone top bar. */
158
+ icon?: string
155
159
  }
156
160
  jobs: GeneratedJobDefinition[]
157
161
  }
package/src/utils/time.ts CHANGED
@@ -122,6 +122,27 @@ export function findNearestTimeSlotIndex(time: string, slots: readonly string[])
122
122
  return bestIndex
123
123
  }
124
124
 
125
+ const relativeTimeFormat = new Intl.RelativeTimeFormat('en', { numeric: 'auto' })
126
+
127
+ /**
128
+ * "in 5 minutes" / "2 hours ago" up to a week, then a locale date.
129
+ * With `weeks`, times up to five weeks away read as a week count first.
130
+ */
131
+ export function formatRelativeTime(value: Date | string, { weeks = false }: { weeks?: boolean } = {}): string {
132
+ const date = value instanceof Date ? value : new Date(value)
133
+ const diffSec = Math.round((date.getTime() - Date.now()) / 1000)
134
+ const diffMin = Math.round(diffSec / 60)
135
+ const diffHr = Math.round(diffMin / 60)
136
+ const diffDay = Math.round(diffHr / 24)
137
+ const diffWeek = Math.round(diffDay / 7)
138
+ if (Math.abs(diffSec) < 60) return relativeTimeFormat.format(diffSec, 'second')
139
+ if (Math.abs(diffMin) < 60) return relativeTimeFormat.format(diffMin, 'minute')
140
+ if (Math.abs(diffHr) < 24) return relativeTimeFormat.format(diffHr, 'hour')
141
+ if (Math.abs(diffDay) < 7) return relativeTimeFormat.format(diffDay, 'day')
142
+ if (weeks && Math.abs(diffWeek) < 5) return relativeTimeFormat.format(diffWeek, 'week')
143
+ return date.toLocaleDateString()
144
+ }
145
+
125
146
  export function toMinutes(time: string): number {
126
147
  const { hour, minute } = parseTime(time)
127
148
  return hour * 60 + minute
@@ -1 +0,0 @@
1
- {"version":3,"file":"ActionMenu-CScINahU.js","names":[],"sources":["../src/composables/useTextSearch.ts","../src/components/LoadingSpinner.vue","../src/components/LoadingSpinner.vue","../src/components/internal/DataStateInternal.vue","../src/components/internal/DataStateInternal.vue","../src/components/AlertBox.vue","../src/components/AlertBox.vue","../src/components/ActionMenu.vue","../src/components/ActionMenu.vue"],"sourcesContent":["import { computed, toValue, type ComputedRef, type Ref } from 'vue'\n\nexport type TextSearchSource<T> =\n | T\n | Ref<T>\n | ComputedRef<T>\n | (() => T)\n\nexport type TextSearchCandidate = unknown | readonly unknown[]\n\nexport interface UseTextSearchOptions<TItem> {\n items: TextSearchSource<readonly TItem[]>\n query: TextSearchSource<string | null | undefined>\n enabled?: TextSearchSource<boolean | null | undefined>\n getText: (item: TItem) => TextSearchCandidate\n}\n\nexport interface UseTextSearchReturn<TItem> {\n query: ComputedRef<string>\n filteredItems: ComputedRef<TItem[]>\n matches: (item: TItem, query?: string | null | undefined) => boolean\n}\n\n/** Shared text-search filtering for tables, lists, selectors, and chip inputs. */\nexport function useTextSearch<TItem>(options: UseTextSearchOptions<TItem>): UseTextSearchReturn<TItem> {\n const query = computed(() => normalizeSearchQuery(toValue(options.query)))\n const enabled = computed(() => toValue(options.enabled) ?? true)\n\n function matches(item: TItem, overrideQuery?: string | null | undefined): boolean {\n const activeQuery = overrideQuery === undefined ? query.value : normalizeSearchQuery(overrideQuery)\n if (!activeQuery) return true\n return candidateMatchesSearch(options.getText(item), activeQuery)\n }\n\n const filteredItems = computed(() => {\n const items = [...toValue(options.items)]\n if (!enabled.value || !query.value) return items\n return items.filter(item => matches(item))\n })\n\n return {\n query,\n filteredItems,\n matches,\n }\n}\n\nexport function normalizeSearchQuery(value: string | null | undefined): string {\n return (value ?? '').trim().toLowerCase()\n}\n\nexport function candidateMatchesSearch(candidate: TextSearchCandidate, query: string): boolean {\n const normalizedQuery = normalizeSearchQuery(query)\n if (!normalizedQuery) return true\n const values = Array.isArray(candidate) ? candidate : [candidate]\n return values.some((value) => {\n if (value === null || value === undefined) return false\n return String(value).toLowerCase().includes(normalizedQuery)\n })\n}\n","<script setup lang=\"ts\">\n/** Animated SVG spinner with size and tone, and a visually hidden status label for screen readers. `tone=\"inherit\"` takes the parent's text color. */\nimport type { Tone } from '../types'\n\ninterface Props {\n size?: 'xs' | 'sm' | 'md' | 'lg'\n tone?: Tone | 'inherit'\n label?: string\n}\n\nwithDefaults(defineProps<Props>(), {\n size: 'md',\n tone: 'primary',\n label: 'Loading',\n})\n</script>\n\n<template>\n <div\n :class=\"[\n 'mint-spinner',\n `mint-spinner--${size}`,\n `mint-spinner--${tone}`,\n ]\"\n role=\"status\"\n >\n <svg\n class=\"mint-spinner__svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n >\n <circle\n style=\"opacity: 0.25\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n stroke-width=\"4\"\n />\n <path\n style=\"opacity: 0.75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n />\n </svg>\n <span class=\"mint-spinner__label\">{{ label }}</span>\n </div>\n</template>\n","<script setup lang=\"ts\">\n/** Animated SVG spinner with size and tone, and a visually hidden status label for screen readers. `tone=\"inherit\"` takes the parent's text color. */\nimport type { Tone } from '../types'\n\ninterface Props {\n size?: 'xs' | 'sm' | 'md' | 'lg'\n tone?: Tone | 'inherit'\n label?: string\n}\n\nwithDefaults(defineProps<Props>(), {\n size: 'md',\n tone: 'primary',\n label: 'Loading',\n})\n</script>\n\n<template>\n <div\n :class=\"[\n 'mint-spinner',\n `mint-spinner--${size}`,\n `mint-spinner--${tone}`,\n ]\"\n role=\"status\"\n >\n <svg\n class=\"mint-spinner__svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n >\n <circle\n style=\"opacity: 0.25\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n stroke-width=\"4\"\n />\n <path\n style=\"opacity: 0.75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n />\n </svg>\n <span class=\"mint-spinner__label\">{{ label }}</span>\n </div>\n</template>\n","<script setup lang=\"ts\">\n/**\n * Shared loading / error / empty presentation for the SDK data components.\n *\n * Internal: not exported from the package entrypoints. Data components render\n * this instead of hand-rolling their own placeholder markup so that the\n * loading, error and empty states look the same everywhere.\n */\nimport { computed } from 'vue'\nimport EmptyState from '../EmptyState.vue'\nimport LoadingSpinner from '../LoadingSpinner.vue'\n\n/** Single-path warning triangle used for the error state. */\nconst ERROR_ICON_PATH\n = 'M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z'\n + 'M12 9v4M12 17h.01'\n\ninterface Props {\n /** Which of the three placeholder states to render. */\n state: 'loading' | 'error' | 'empty'\n /** Headline for the empty/error state. */\n title?: string\n /** Supporting copy for the empty/error state. */\n description?: string\n /** Custom `<path d>` for the empty state icon (the error state has its own). */\n iconPath?: string\n /** Placeholder scale; also drives the loading spinner size. */\n size?: 'sm' | 'md' | 'lg'\n /** `EmptyState` layout variant. */\n variant?: 'illustrated' | 'inline'\n /** Accessible label (and visible caption) for the loading state. */\n loadingLabel?: string\n /** Optional call-to-action rendered under the empty/error copy. */\n actionLabel?: string\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n size: 'md',\n variant: 'illustrated',\n loadingLabel: 'Loading',\n})\n\nconst emit = defineEmits<{\n action: []\n}>()\n\nconst spinnerSize = computed(() => (props.size === 'sm' ? 'sm' : props.size === 'lg' ? 'lg' : 'md'))\n</script>\n\n<template>\n <div\n :class=\"['mint-data-state', `mint-data-state--${state}`, `mint-data-state--${size}`]\"\n :data-state=\"state\"\n >\n <template v-if=\"state === 'loading'\">\n <LoadingSpinner :size=\"spinnerSize\" :label=\"loadingLabel\" />\n <p class=\"mint-data-state__loading-text\" aria-hidden=\"true\">{{ loadingLabel }}</p>\n </template>\n <EmptyState\n v-else\n :title=\"title\"\n :description=\"description\"\n :icon-path=\"state === 'error' ? ERROR_ICON_PATH : iconPath\"\n :tone=\"state === 'error' ? 'error' : 'neutral'\"\n :size=\"size\"\n :variant=\"variant\"\n :action-label=\"actionLabel\"\n @action=\"emit('action')\"\n >\n <slot />\n </EmptyState>\n </div>\n</template>\n\n","<script setup lang=\"ts\">\n/**\n * Shared loading / error / empty presentation for the SDK data components.\n *\n * Internal: not exported from the package entrypoints. Data components render\n * this instead of hand-rolling their own placeholder markup so that the\n * loading, error and empty states look the same everywhere.\n */\nimport { computed } from 'vue'\nimport EmptyState from '../EmptyState.vue'\nimport LoadingSpinner from '../LoadingSpinner.vue'\n\n/** Single-path warning triangle used for the error state. */\nconst ERROR_ICON_PATH\n = 'M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z'\n + 'M12 9v4M12 17h.01'\n\ninterface Props {\n /** Which of the three placeholder states to render. */\n state: 'loading' | 'error' | 'empty'\n /** Headline for the empty/error state. */\n title?: string\n /** Supporting copy for the empty/error state. */\n description?: string\n /** Custom `<path d>` for the empty state icon (the error state has its own). */\n iconPath?: string\n /** Placeholder scale; also drives the loading spinner size. */\n size?: 'sm' | 'md' | 'lg'\n /** `EmptyState` layout variant. */\n variant?: 'illustrated' | 'inline'\n /** Accessible label (and visible caption) for the loading state. */\n loadingLabel?: string\n /** Optional call-to-action rendered under the empty/error copy. */\n actionLabel?: string\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n size: 'md',\n variant: 'illustrated',\n loadingLabel: 'Loading',\n})\n\nconst emit = defineEmits<{\n action: []\n}>()\n\nconst spinnerSize = computed(() => (props.size === 'sm' ? 'sm' : props.size === 'lg' ? 'lg' : 'md'))\n</script>\n\n<template>\n <div\n :class=\"['mint-data-state', `mint-data-state--${state}`, `mint-data-state--${size}`]\"\n :data-state=\"state\"\n >\n <template v-if=\"state === 'loading'\">\n <LoadingSpinner :size=\"spinnerSize\" :label=\"loadingLabel\" />\n <p class=\"mint-data-state__loading-text\" aria-hidden=\"true\">{{ loadingLabel }}</p>\n </template>\n <EmptyState\n v-else\n :title=\"title\"\n :description=\"description\"\n :icon-path=\"state === 'error' ? ERROR_ICON_PATH : iconPath\"\n :tone=\"state === 'error' ? 'error' : 'neutral'\"\n :size=\"size\"\n :variant=\"variant\"\n :action-label=\"actionLabel\"\n @action=\"emit('action')\"\n >\n <slot />\n </EmptyState>\n </div>\n</template>\n\n","<script setup lang=\"ts\">\n/** Inline alert banner with semantic icon, title, message slot, optional action button, and optional dismiss button. */\nimport { useSlots } from 'vue'\nimport type { Tone } from '../types'\nimport BaseButton from './BaseButton.vue'\n\ninterface Props {\n tone?: Tone\n title?: string\n dismissible?: boolean\n actionLabel?: string\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n tone: 'info',\n dismissible: false,\n})\n\nconst emit = defineEmits<{\n dismiss: []\n action: []\n}>()\n\nconst slots = useSlots()\nconst hasActions = () => !!props.actionLabel || !!slots.actions\n</script>\n\n<template>\n <div\n class=\"mint-alert\"\n :class=\"`mint-alert--${props.tone}`\"\n role=\"alert\"\n >\n <!-- Lucide circle-check -->\n <svg v-if=\"props.tone === 'success'\" class=\"mint-alert__icon mint-alert__icon--success\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" /><path d=\"m9 12 2 2 4-4\" />\n </svg>\n <!-- Lucide circle-x -->\n <svg v-else-if=\"props.tone === 'error'\" class=\"mint-alert__icon mint-alert__icon--error\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" /><path d=\"m15 9-6 6\" /><path d=\"m9 9 6 6\" />\n </svg>\n <!-- Lucide triangle-alert -->\n <svg v-else-if=\"props.tone === 'warning'\" class=\"mint-alert__icon mint-alert__icon--warning\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3\" /><path d=\"M12 9v4\" /><path d=\"M12 17h.01\" />\n </svg>\n <!-- Lucide info -->\n <svg v-else :class=\"['mint-alert__icon', `mint-alert__icon--${props.tone}`]\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" /><path d=\"M12 16v-4\" /><path d=\"M12 8h.01\" />\n </svg>\n\n <div class=\"mint-alert__content\">\n <h4 v-if=\"props.title\" class=\"mint-alert__title\">\n {{ props.title }}\n </h4>\n <div class=\"mint-alert__message\">\n <slot />\n </div>\n </div>\n\n <div v-if=\"hasActions()\" class=\"mint-alert__actions\">\n <slot name=\"actions\">\n <BaseButton variant=\"secondary\" size=\"sm\" @click=\"emit('action')\">\n {{ props.actionLabel }}\n </BaseButton>\n </slot>\n </div>\n\n <button\n v-if=\"props.dismissible\"\n type=\"button\"\n class=\"mint-alert__dismiss\"\n aria-label=\"Dismiss\"\n @click=\"emit('dismiss')\"\n >\n <svg class=\"mint-alert__dismiss-icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M18 6 6 18\" /><path d=\"m6 6 12 12\" />\n </svg>\n </button>\n </div>\n</template>\n","<script setup lang=\"ts\">\n/** Inline alert banner with semantic icon, title, message slot, optional action button, and optional dismiss button. */\nimport { useSlots } from 'vue'\nimport type { Tone } from '../types'\nimport BaseButton from './BaseButton.vue'\n\ninterface Props {\n tone?: Tone\n title?: string\n dismissible?: boolean\n actionLabel?: string\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n tone: 'info',\n dismissible: false,\n})\n\nconst emit = defineEmits<{\n dismiss: []\n action: []\n}>()\n\nconst slots = useSlots()\nconst hasActions = () => !!props.actionLabel || !!slots.actions\n</script>\n\n<template>\n <div\n class=\"mint-alert\"\n :class=\"`mint-alert--${props.tone}`\"\n role=\"alert\"\n >\n <!-- Lucide circle-check -->\n <svg v-if=\"props.tone === 'success'\" class=\"mint-alert__icon mint-alert__icon--success\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" /><path d=\"m9 12 2 2 4-4\" />\n </svg>\n <!-- Lucide circle-x -->\n <svg v-else-if=\"props.tone === 'error'\" class=\"mint-alert__icon mint-alert__icon--error\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" /><path d=\"m15 9-6 6\" /><path d=\"m9 9 6 6\" />\n </svg>\n <!-- Lucide triangle-alert -->\n <svg v-else-if=\"props.tone === 'warning'\" class=\"mint-alert__icon mint-alert__icon--warning\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3\" /><path d=\"M12 9v4\" /><path d=\"M12 17h.01\" />\n </svg>\n <!-- Lucide info -->\n <svg v-else :class=\"['mint-alert__icon', `mint-alert__icon--${props.tone}`]\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" /><path d=\"M12 16v-4\" /><path d=\"M12 8h.01\" />\n </svg>\n\n <div class=\"mint-alert__content\">\n <h4 v-if=\"props.title\" class=\"mint-alert__title\">\n {{ props.title }}\n </h4>\n <div class=\"mint-alert__message\">\n <slot />\n </div>\n </div>\n\n <div v-if=\"hasActions()\" class=\"mint-alert__actions\">\n <slot name=\"actions\">\n <BaseButton variant=\"secondary\" size=\"sm\" @click=\"emit('action')\">\n {{ props.actionLabel }}\n </BaseButton>\n </slot>\n </div>\n\n <button\n v-if=\"props.dismissible\"\n type=\"button\"\n class=\"mint-alert__dismiss\"\n aria-label=\"Dismiss\"\n @click=\"emit('dismiss')\"\n >\n <svg class=\"mint-alert__dismiss-icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M18 6 6 18\" /><path d=\"m6 6 12 12\" />\n </svg>\n </button>\n </div>\n</template>\n","<script setup lang=\"ts\">\n/** Compact overflow actions with an icon-only BaseButton trigger and a viewport-safe teleported menu. */\nimport { computePosition, flip, offset, shift } from '@floating-ui/dom'\nimport { Check, Ellipsis } from 'lucide-vue-next'\nimport { nextTick, onMounted, ref, watch } from 'vue'\nimport { useDropdownState } from '../composables/useDropdownState'\nimport { useMenuKeyboard } from '../composables/useMenuKeyboard'\nimport type { ActionMenuItem } from '../types/components'\nimport BaseButton from './BaseButton.vue'\n\ninterface Props {\n label: string\n items: ActionMenuItem[]\n disabled?: boolean\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n disabled: false,\n})\n\nconst emit = defineEmits<{\n select: [item: ActionMenuItem]\n open: []\n close: []\n}>()\n\ndefineSlots<{\n /** Replaces the ellipsis button; `toggle` and `keydown` go on the slotted button. */\n trigger?: (props: { open: boolean; toggle: () => void; keydown: (event: KeyboardEvent) => void }) => unknown\n}>()\n\nconst panelRef = ref<HTMLElement | null>(null)\nconst panelStyle = ref<Record<string, string>>({ visibility: 'hidden' })\n\n// Disclosure state (outside-click, Escape, scroll/resize closing, focus return)\n// comes from the shared composable; only floating-ui placement stays local.\nconst { isOpen, rootRef, triggerRef, open, close } = useDropdownState({\n closeOnScroll: true,\n insideRefs: [panelRef],\n onOpen: () => {\n panelStyle.value = { visibility: 'hidden' }\n emit('open')\n },\n onClose: () => emit('close'),\n})\n\n// BaseButton owns the actual <button>, so the trigger element is resolved from\n// the wrapper once mounted rather than bound with a template ref.\nonMounted(() => {\n triggerRef.value = rootRef.value?.querySelector('button') ?? null\n})\n\nfunction menuItems(): HTMLElement[] {\n if (!panelRef.value) return []\n return Array.from(\n panelRef.value.querySelectorAll<HTMLElement>('.mint-action-menu__item:not(:disabled)'),\n )\n}\n\nasync function positionPanel() {\n const trigger = triggerRef.value\n const panel = panelRef.value\n if (!trigger || !panel) return\n\n const position = await computePosition(trigger, panel, {\n placement: 'bottom-end',\n strategy: 'fixed',\n middleware: [\n offset(4),\n flip(),\n shift({ padding: 8 }),\n ],\n })\n panelStyle.value = {\n left: `${position.x}px`,\n top: `${position.y}px`,\n visibility: 'visible',\n }\n}\n\n/** `focusFirst` is false when the keyboard composable owns the initial focus. */\nfunction openMenu(focusFirst = true) {\n if (props.disabled || isOpen.value) return\n open()\n if (focusFirst) {\n void nextTick(() => menuItems()[0]?.focus())\n }\n}\n\nfunction toggleMenu() {\n if (props.disabled) return\n if (isOpen.value) close()\n else openMenu()\n}\n\nconst { handleTriggerKeydown, handlePanelKeydown } = useMenuKeyboard({\n items: menuItems,\n isOpen: () => isOpen.value,\n open: () => openMenu(false),\n close,\n})\n\nfunction handleSelect(item: ActionMenuItem) {\n if (item.disabled) return\n emit('select', item)\n close()\n}\n\nwatch(isOpen, async (opened) => {\n if (!opened) return\n await nextTick()\n await positionPanel()\n})\n</script>\n\n<template>\n <span ref=\"rootRef\" class=\"mint-action-menu\">\n <!-- A custom trigger must render one <button> and wire toggle + keydown to it. -->\n <slot name=\"trigger\" :open=\"isOpen\" :toggle=\"toggleMenu\" :keydown=\"handleTriggerKeydown\">\n <BaseButton\n variant=\"secondary\"\n size=\"sm\"\n :icon=\"Ellipsis\"\n :label=\"label\"\n :disabled=\"disabled\"\n aria-haspopup=\"menu\"\n :aria-expanded=\"isOpen\"\n @click=\"toggleMenu\"\n @keydown=\"handleTriggerKeydown\"\n />\n </slot>\n </span>\n\n <Teleport to=\"body\">\n <div\n v-if=\"isOpen\"\n ref=\"panelRef\"\n class=\"mint-popover mint-action-menu__panel\"\n :style=\"panelStyle\"\n role=\"menu\"\n @keydown=\"handlePanelKeydown\"\n >\n <template v-for=\"(item, index) in items\" :key=\"item.id\">\n <div\n v-if=\"item.danger && index > 0 && !items[index - 1].danger\"\n class=\"mint-menu-separator\"\n role=\"separator\"\n />\n <a\n v-if=\"item.href !== undefined && !item.disabled\"\n :href=\"item.href\"\n :target=\"item.target\"\n :rel=\"item.target === '_blank' ? 'noopener noreferrer' : undefined\"\n :class=\"['mint-menu-item mint-action-menu__item', { 'mint-menu-item--danger mint-action-menu__item--danger': item.danger }]\"\n role=\"menuitem\"\n @click=\"handleSelect(item)\"\n >\n {{ item.label }}\n </a>\n <button\n v-else\n type=\"button\"\n :class=\"['mint-menu-item mint-action-menu__item', { 'mint-menu-item--danger mint-action-menu__item--danger': item.danger }]\"\n :role=\"item.checked === undefined ? 'menuitem' : 'menuitemradio'\"\n :aria-checked=\"item.checked\"\n :disabled=\"item.disabled\"\n @click=\"handleSelect(item)\"\n >\n <Check\n v-if=\"item.checked !== undefined\"\n class=\"mint-action-menu__check\"\n :class=\"{ 'mint-action-menu__check--off': !item.checked }\"\n :size=\"14\"\n aria-hidden=\"true\"\n />\n {{ item.label }}\n </button>\n </template>\n </div>\n </Teleport>\n</template>\n","<script setup lang=\"ts\">\n/** Compact overflow actions with an icon-only BaseButton trigger and a viewport-safe teleported menu. */\nimport { computePosition, flip, offset, shift } from '@floating-ui/dom'\nimport { Check, Ellipsis } from 'lucide-vue-next'\nimport { nextTick, onMounted, ref, watch } from 'vue'\nimport { useDropdownState } from '../composables/useDropdownState'\nimport { useMenuKeyboard } from '../composables/useMenuKeyboard'\nimport type { ActionMenuItem } from '../types/components'\nimport BaseButton from './BaseButton.vue'\n\ninterface Props {\n label: string\n items: ActionMenuItem[]\n disabled?: boolean\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n disabled: false,\n})\n\nconst emit = defineEmits<{\n select: [item: ActionMenuItem]\n open: []\n close: []\n}>()\n\ndefineSlots<{\n /** Replaces the ellipsis button; `toggle` and `keydown` go on the slotted button. */\n trigger?: (props: { open: boolean; toggle: () => void; keydown: (event: KeyboardEvent) => void }) => unknown\n}>()\n\nconst panelRef = ref<HTMLElement | null>(null)\nconst panelStyle = ref<Record<string, string>>({ visibility: 'hidden' })\n\n// Disclosure state (outside-click, Escape, scroll/resize closing, focus return)\n// comes from the shared composable; only floating-ui placement stays local.\nconst { isOpen, rootRef, triggerRef, open, close } = useDropdownState({\n closeOnScroll: true,\n insideRefs: [panelRef],\n onOpen: () => {\n panelStyle.value = { visibility: 'hidden' }\n emit('open')\n },\n onClose: () => emit('close'),\n})\n\n// BaseButton owns the actual <button>, so the trigger element is resolved from\n// the wrapper once mounted rather than bound with a template ref.\nonMounted(() => {\n triggerRef.value = rootRef.value?.querySelector('button') ?? null\n})\n\nfunction menuItems(): HTMLElement[] {\n if (!panelRef.value) return []\n return Array.from(\n panelRef.value.querySelectorAll<HTMLElement>('.mint-action-menu__item:not(:disabled)'),\n )\n}\n\nasync function positionPanel() {\n const trigger = triggerRef.value\n const panel = panelRef.value\n if (!trigger || !panel) return\n\n const position = await computePosition(trigger, panel, {\n placement: 'bottom-end',\n strategy: 'fixed',\n middleware: [\n offset(4),\n flip(),\n shift({ padding: 8 }),\n ],\n })\n panelStyle.value = {\n left: `${position.x}px`,\n top: `${position.y}px`,\n visibility: 'visible',\n }\n}\n\n/** `focusFirst` is false when the keyboard composable owns the initial focus. */\nfunction openMenu(focusFirst = true) {\n if (props.disabled || isOpen.value) return\n open()\n if (focusFirst) {\n void nextTick(() => menuItems()[0]?.focus())\n }\n}\n\nfunction toggleMenu() {\n if (props.disabled) return\n if (isOpen.value) close()\n else openMenu()\n}\n\nconst { handleTriggerKeydown, handlePanelKeydown } = useMenuKeyboard({\n items: menuItems,\n isOpen: () => isOpen.value,\n open: () => openMenu(false),\n close,\n})\n\nfunction handleSelect(item: ActionMenuItem) {\n if (item.disabled) return\n emit('select', item)\n close()\n}\n\nwatch(isOpen, async (opened) => {\n if (!opened) return\n await nextTick()\n await positionPanel()\n})\n</script>\n\n<template>\n <span ref=\"rootRef\" class=\"mint-action-menu\">\n <!-- A custom trigger must render one <button> and wire toggle + keydown to it. -->\n <slot name=\"trigger\" :open=\"isOpen\" :toggle=\"toggleMenu\" :keydown=\"handleTriggerKeydown\">\n <BaseButton\n variant=\"secondary\"\n size=\"sm\"\n :icon=\"Ellipsis\"\n :label=\"label\"\n :disabled=\"disabled\"\n aria-haspopup=\"menu\"\n :aria-expanded=\"isOpen\"\n @click=\"toggleMenu\"\n @keydown=\"handleTriggerKeydown\"\n />\n </slot>\n </span>\n\n <Teleport to=\"body\">\n <div\n v-if=\"isOpen\"\n ref=\"panelRef\"\n class=\"mint-popover mint-action-menu__panel\"\n :style=\"panelStyle\"\n role=\"menu\"\n @keydown=\"handlePanelKeydown\"\n >\n <template v-for=\"(item, index) in items\" :key=\"item.id\">\n <div\n v-if=\"item.danger && index > 0 && !items[index - 1].danger\"\n class=\"mint-menu-separator\"\n role=\"separator\"\n />\n <a\n v-if=\"item.href !== undefined && !item.disabled\"\n :href=\"item.href\"\n :target=\"item.target\"\n :rel=\"item.target === '_blank' ? 'noopener noreferrer' : undefined\"\n :class=\"['mint-menu-item mint-action-menu__item', { 'mint-menu-item--danger mint-action-menu__item--danger': item.danger }]\"\n role=\"menuitem\"\n @click=\"handleSelect(item)\"\n >\n {{ item.label }}\n </a>\n <button\n v-else\n type=\"button\"\n :class=\"['mint-menu-item mint-action-menu__item', { 'mint-menu-item--danger mint-action-menu__item--danger': item.danger }]\"\n :role=\"item.checked === undefined ? 'menuitem' : 'menuitemradio'\"\n :aria-checked=\"item.checked\"\n :disabled=\"item.disabled\"\n @click=\"handleSelect(item)\"\n >\n <Check\n v-if=\"item.checked !== undefined\"\n class=\"mint-action-menu__check\"\n :class=\"{ 'mint-action-menu__check--off': !item.checked }\"\n :size=\"14\"\n aria-hidden=\"true\"\n />\n {{ item.label }}\n </button>\n </template>\n </div>\n </Teleport>\n</template>\n"],"mappings":"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"}