@morscherlab/mint-sdk 1.4.0-beta.9 → 1.4.1

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 (198) hide show
  1. package/README.md +14 -3
  2. package/dist/{AlertBox-B2Bgr3ei.js → AlertBox-DwgNTEqf.js} +3 -3
  3. package/dist/{AlertBox-B2Bgr3ei.js.map → AlertBox-DwgNTEqf.js.map} +1 -1
  4. package/dist/{AppSidebar-Dq9W1jE2.js → AppSidebar-CZZaxni0.js} +1103 -144
  5. package/dist/AppSidebar-CZZaxni0.js.map +1 -0
  6. package/dist/{ConfirmDialog-nbJj51is.js → ConfirmDialog-CjWoxAD1.js} +2 -2
  7. package/dist/{ConfirmDialog-nbJj51is.js.map → ConfirmDialog-CjWoxAD1.js.map} +1 -1
  8. package/dist/{ExperimentPopover-5T1fAq2L.js → ExperimentPopover-DujiuQIO.js} +5 -5
  9. package/dist/{ExperimentPopover-5T1fAq2L.js.map → ExperimentPopover-DujiuQIO.js.map} +1 -1
  10. package/dist/{ExperimentSelectorModal-65peG4Up.js → ExperimentSelectorModal-B4j4eUOJ.js} +114 -98
  11. package/dist/ExperimentSelectorModal-B4j4eUOJ.js.map +1 -0
  12. package/dist/{SegmentedControl-BtnnjWzs.js → SegmentedControl-DyUPH3I5.js} +2 -2
  13. package/dist/{SegmentedControl-BtnnjWzs.js.map → SegmentedControl-DyUPH3I5.js.map} +1 -1
  14. package/dist/{SettingsModal-483nyI6b.js → SettingsModal-D2MOOtuO.js} +26 -25
  15. package/dist/SettingsModal-D2MOOtuO.js.map +1 -0
  16. package/dist/__stories__/experiment-helpers.d.ts +10 -0
  17. package/dist/__tests__/components/AppTopBarOnboarding.test.d.ts +1 -0
  18. package/dist/__tests__/components/FloatingPanelsInModal.test.d.ts +1 -0
  19. package/dist/__tests__/composables/useFloatingPanel.test.d.ts +1 -0
  20. package/dist/__tests__/composables/useOnboarding.test.d.ts +1 -0
  21. package/dist/__tests__/styles/paletteTokens.test.d.ts +1 -0
  22. package/dist/__tests__/styles/v2AuditRules.test.d.ts +1 -0
  23. package/dist/components/AppTopBar.vue.d.ts +20 -5
  24. package/dist/components/BaseButton.vue.d.ts +4 -2
  25. package/dist/components/ExperimentSelectorModal.vue.d.ts +15 -1
  26. package/dist/components/JobsStatusTray.vue.d.ts +15 -4
  27. package/dist/components/PluginWorkspaceView.props.d.ts +3 -0
  28. package/dist/components/PluginWorkspaceView.vue.d.ts +3 -0
  29. package/dist/components/SmartGroupFieldRecipe.vue.d.ts +3 -3
  30. package/dist/components/internal/AppTopBarOnboardingInternal.vue.d.ts +7 -0
  31. package/dist/components/internal/AppTopBarPageSelectorInternal.vue.d.ts +2 -1
  32. package/dist/components/internal/AutoGroupModalInternal.vue.d.ts +2 -2
  33. package/dist/components/internal/OnboardingLayerInternal.vue.d.ts +7 -0
  34. package/dist/components/internal/WorkspaceShellInternal.vue.d.ts +8 -0
  35. package/dist/composables/pluginWorkspaceModel.d.ts +2 -2
  36. package/dist/composables/useFileImport.d.ts +7 -0
  37. package/dist/composables/useFloatingPanel.d.ts +29 -0
  38. package/dist/composables/useJobCenter.d.ts +41 -3
  39. package/dist/composables/useOnboarding.d.ts +119 -0
  40. package/dist/{controlSchemaModel-B8CTXagP.js → controlSchemaModel-Bsg0t5Ab.js} +2 -2
  41. package/dist/{controlSchemaModel-B8CTXagP.js.map → controlSchemaModel-Bsg0t5Ab.js.map} +1 -1
  42. package/dist/{data-CgILxDLW.js → data-Boeh4uPI.js} +13 -12
  43. package/dist/{data-CgILxDLW.js.map → data-Boeh4uPI.js.map} +1 -1
  44. package/dist/data.d.ts +1 -1
  45. package/dist/data.js +9 -9
  46. package/dist/{experiment-43OJtH7R.js → experiment-DyO54FQB.js} +25 -61
  47. package/dist/experiment-DyO54FQB.js.map +1 -0
  48. package/dist/{experimentStatus-Cqp6qNrR.js → experimentStatus-DCn2QKG7.js} +2 -2
  49. package/dist/{experimentStatus-Cqp6qNrR.js.map → experimentStatus-DCn2QKG7.js.map} +1 -1
  50. package/dist/index.js +20 -20
  51. package/dist/{install-BtLWTk6H.js → install-BEHp7Mo-.js} +15 -15
  52. package/dist/{install-BtLWTk6H.js.map → install-BEHp7Mo-.js.map} +1 -1
  53. package/dist/install.js +1 -1
  54. package/dist/{lab-MHzp-_J8.js → lab-D61eaX6f.js} +68 -61
  55. package/dist/{lab-MHzp-_J8.js.map → lab-D61eaX6f.js.map} +1 -1
  56. package/dist/lab.js +4 -4
  57. package/dist/{records-B6gpM_3e.js → records-D4aQXyZu.js} +193 -133
  58. package/dist/records-D4aQXyZu.js.map +1 -0
  59. package/dist/{runtime-7vfl_bI3.js → runtime-q-R0CNLh.js} +400 -33
  60. package/dist/runtime-q-R0CNLh.js.map +1 -0
  61. package/dist/runtime.d.ts +1 -1
  62. package/dist/runtime.js +7 -7
  63. package/dist/{shell-Cs9OJMnm.js → shell-6CGFvUUw.js} +10 -5
  64. package/dist/{shell-Cs9OJMnm.js.map → shell-6CGFvUUw.js.map} +1 -1
  65. package/dist/shell.d.ts +1 -0
  66. package/dist/shell.js +6 -6
  67. package/dist/stores/index.d.ts +1 -1
  68. package/dist/stores/index.js +2 -2
  69. package/dist/stores/settings.d.ts +4 -12
  70. package/dist/styles.css +1191 -479
  71. package/dist/types/components.d.ts +2 -0
  72. package/dist/types/index.d.ts +1 -1
  73. package/dist/types/jobs.d.ts +9 -0
  74. package/dist/types/platform.d.ts +1 -1
  75. package/dist/{useDropdownState-8yWMu-7_.js → useDropdownState-uFIz6Yv8.js} +16 -4
  76. package/dist/useDropdownState-uFIz6Yv8.js.map +1 -0
  77. package/dist/{useExperimentSamples-DHnxKFAF.js → useExperimentSamples-QEFoq4tf.js} +48 -6
  78. package/dist/useExperimentSamples-QEFoq4tf.js.map +1 -0
  79. package/dist/{useListReorder-BitdUhxn.js → useListReorder-DsuzwWGS.js} +122 -172
  80. package/dist/useListReorder-DsuzwWGS.js.map +1 -0
  81. package/dist/{useRackEditor-DiwCt77M.js → useRackEditor-KpZ4iJ6o.js} +22 -32
  82. package/dist/useRackEditor-KpZ4iJ6o.js.map +1 -0
  83. package/dist/useRealtime-B58Lo-Tm.js +508 -0
  84. package/dist/useRealtime-B58Lo-Tm.js.map +1 -0
  85. package/dist/{useRequest-D506eHi8.js → useRequest-BuDmW8Jc.js} +8 -37
  86. package/dist/useRequest-BuDmW8Jc.js.map +1 -0
  87. package/package.json +3 -2
  88. package/src/__stories__/experiment-helpers.ts +3 -3
  89. package/src/__tests__/components/ActionMenu.test.ts +2 -2
  90. package/src/__tests__/components/AppTopBar.test.ts +206 -1
  91. package/src/__tests__/components/AppTopBarOnboarding.test.ts +160 -0
  92. package/src/__tests__/components/AppTopBarPageSelector.test.ts +125 -9
  93. package/src/__tests__/components/BaseButton.test.ts +19 -0
  94. package/src/__tests__/components/BaseModal.test.ts +13 -0
  95. package/src/__tests__/components/ExperimentSelectorModal.test.ts +34 -1
  96. package/src/__tests__/components/FloatingPanelsInModal.test.ts +94 -0
  97. package/src/__tests__/components/GeneratedPluginView.test.ts +1 -1
  98. package/src/__tests__/components/JobsStatusTray.test.ts +373 -71
  99. package/src/__tests__/components/PluginWorkspaceView.test.ts +63 -1
  100. package/src/__tests__/components/SampleSelector.test.ts +20 -0
  101. package/src/__tests__/components/SettingsModal.test.ts +9 -2
  102. package/src/__tests__/composables/useFileImport.test.ts +36 -0
  103. package/src/__tests__/composables/useFloatingPanel.test.ts +68 -0
  104. package/src/__tests__/composables/useJobCenter.test.ts +262 -3
  105. package/src/__tests__/composables/useOnboarding.test.ts +317 -0
  106. package/src/__tests__/docs/frontendDocsCatalog.test.ts +4 -3
  107. package/src/__tests__/fixtures/table-import/cells.xlsx +0 -0
  108. package/src/__tests__/fixtures/table-import/samples.xlsx +0 -0
  109. package/src/__tests__/stores/settings.test.ts +21 -21
  110. package/src/__tests__/styles/cssTokens.test.ts +4 -1
  111. package/src/__tests__/styles/menusShellRefresh.test.ts +8 -2
  112. package/src/__tests__/styles/paletteTokens.test.ts +44 -0
  113. package/src/__tests__/styles/v2AuditRules.test.ts +104 -0
  114. package/src/components/ActionMenu.vue +6 -37
  115. package/src/components/AppTopBar.onboarding.story.vue +69 -0
  116. package/src/components/AppTopBar.story.vue +59 -4
  117. package/src/components/AppTopBar.vue +132 -10
  118. package/src/components/BaseButton.vue +16 -2
  119. package/src/components/BaseModal.vue +2 -1
  120. package/src/components/ExperimentSelectorModal.story.vue +38 -0
  121. package/src/components/ExperimentSelectorModal.vue +20 -1
  122. package/src/components/GeneratedPluginView.vue +4 -9
  123. package/src/components/GeneratedResultRenderer.vue +3 -4
  124. package/src/components/JobsStatusTray.story.vue +97 -43
  125. package/src/components/JobsStatusTray.vue +287 -290
  126. package/src/components/LayoutResizeHandle.story.vue +65 -4
  127. package/src/components/PluginWorkspaceView.props.ts +3 -0
  128. package/src/components/PluginWorkspaceView.vue +17 -0
  129. package/src/components/SampleSelector.story.vue +21 -6
  130. package/src/components/SampleSelector.vue +10 -3
  131. package/src/components/SectionCard.story.vue +33 -0
  132. package/src/components/SettingsModal.vue +7 -12
  133. package/src/components/Tooltip.vue +9 -32
  134. package/src/components/internal/AppTopBarOnboardingInternal.vue +172 -0
  135. package/src/components/internal/AppTopBarPageSelectorInternal.vue +140 -72
  136. package/src/components/internal/DatePickerDateInternal.vue +7 -45
  137. package/src/components/internal/DatePickerDateTimeInternal.vue +7 -1
  138. package/src/components/internal/DatePickerTimeInternal.vue +8 -1
  139. package/src/components/internal/NumberUnitInputInternal.vue +4 -18
  140. package/src/components/internal/OnboardingLayerInternal.vue +173 -0
  141. package/src/components/internal/SelectMultipleInternal.vue +6 -1
  142. package/src/components/internal/SelectSearchableInternal.vue +6 -1
  143. package/src/components/internal/WellEditPopupInternal.vue +11 -22
  144. package/src/components/internal/WorkspaceShellInternal.vue +12 -0
  145. package/src/composables/pluginWorkspaceModel.ts +2 -2
  146. package/src/composables/useFileImport.ts +51 -1
  147. package/src/composables/useFloatingPanel.ts +107 -0
  148. package/src/composables/useJobCenter.ts +188 -6
  149. package/src/composables/useOnboarding.ts +465 -0
  150. package/src/composables/usePluginWorkspace.ts +1 -1
  151. package/src/data.ts +1 -0
  152. package/src/runtime.ts +2 -1
  153. package/src/shell.ts +17 -0
  154. package/src/stores/index.ts +0 -2
  155. package/src/stores/settings.ts +20 -50
  156. package/src/styles/components/action-menu.css +1 -1
  157. package/src/styles/components/app-layout.css +6 -3
  158. package/src/styles/components/app-page-selector.css +120 -45
  159. package/src/styles/components/app-top-bar.css +165 -3
  160. package/src/styles/components/button.css +8 -0
  161. package/src/styles/components/dataframe.css +1 -1
  162. package/src/styles/components/date-picker.css +4 -2
  163. package/src/styles/components/datetime-picker.css +4 -4
  164. package/src/styles/components/experiment-selector-modal.css +13 -0
  165. package/src/styles/components/jobs-status-tray.css +134 -296
  166. package/src/styles/components/layout-resize-handle.css +59 -16
  167. package/src/styles/components/modal.css +3 -3
  168. package/src/styles/components/number-input.css +1 -1
  169. package/src/styles/components/onboarding.css +368 -0
  170. package/src/styles/components/progress-bar.css +3 -3
  171. package/src/styles/components/sample-selector.css +43 -0
  172. package/src/styles/components/searchable-select.css +3 -7
  173. package/src/styles/components/section-card.css +30 -6
  174. package/src/styles/components/settings-modal.css +7 -2
  175. package/src/styles/components/time-picker.css +3 -6
  176. package/src/styles/components/toast.css +1 -1
  177. package/src/styles/components/tooltip.css +2 -2
  178. package/src/styles/components/unit-input.css +1 -1
  179. package/src/styles/components/well-edit-popup.css +2 -2
  180. package/src/styles/index.css +1 -0
  181. package/src/styles/variables.css +153 -15
  182. package/src/types/components.ts +2 -0
  183. package/src/types/index.ts +1 -0
  184. package/src/types/jobs.ts +10 -0
  185. package/src/types/platform.ts +1 -1
  186. package/dist/AppSidebar-Dq9W1jE2.js.map +0 -1
  187. package/dist/ExperimentSelectorModal-65peG4Up.js.map +0 -1
  188. package/dist/SettingsModal-483nyI6b.js.map +0 -1
  189. package/dist/experiment-43OJtH7R.js.map +0 -1
  190. package/dist/records-B6gpM_3e.js.map +0 -1
  191. package/dist/runtime-7vfl_bI3.js.map +0 -1
  192. package/dist/useDropdownState-8yWMu-7_.js.map +0 -1
  193. package/dist/useExperimentSamples-DHnxKFAF.js.map +0 -1
  194. package/dist/useListReorder-BitdUhxn.js.map +0 -1
  195. package/dist/useRackEditor-DiwCt77M.js.map +0 -1
  196. package/dist/useRealtime-C3iy9QkU.js +0 -699
  197. package/dist/useRealtime-C3iy9QkU.js.map +0 -1
  198. package/dist/useRequest-D506eHi8.js.map +0 -1
package/dist/styles.css CHANGED
@@ -48,36 +48,35 @@
48
48
  margin: 0 auto;
49
49
  }
50
50
 
51
- .mint-generated-result[data-v-d4b8e2aa] {
51
+ .mint-generated-result[data-v-f242a75c] {
52
52
  width: 100%;
53
53
  }
54
- .mint-generated-result__text[data-v-d4b8e2aa],
55
- .mint-generated-result__json[data-v-d4b8e2aa] {
54
+ .mint-generated-result__text[data-v-f242a75c],
55
+ .mint-generated-result__json[data-v-f242a75c] {
56
56
  margin: 0;
57
57
  color: var(--text-primary);
58
58
  }
59
- .mint-generated-result__text[data-v-d4b8e2aa] {
59
+ .mint-generated-result__text[data-v-f242a75c] {
60
60
  max-width: 72ch;
61
61
  white-space: pre-wrap;
62
62
  line-height: 1.65;
63
63
  }
64
- .mint-generated-result__json[data-v-d4b8e2aa] {
64
+ .mint-generated-result__json[data-v-f242a75c] {
65
65
  overflow: auto;
66
- padding: 1rem;
67
- border: 1px solid var(--border-color);
68
- border-radius: 0.75rem;
69
- background: var(--bg-secondary);
66
+ padding: 0.75rem 1rem;
67
+ border-radius: var(--radius-md);
68
+ background: var(--bg-tertiary);
70
69
  font-size: 0.8125rem;
71
70
  line-height: 1.55;
72
71
  white-space: pre-wrap;
73
72
  }
74
- .mint-generated-result__image[data-v-d4b8e2aa] {
73
+ .mint-generated-result__image[data-v-f242a75c] {
75
74
  display: block;
76
75
  max-width: 100%;
77
76
  height: auto;
78
77
  margin: 0 auto;
79
78
  }
80
- .mint-generated-result__artifact[data-v-d4b8e2aa] {
79
+ .mint-generated-result__artifact[data-v-f242a75c] {
81
80
  display: flex;
82
81
  align-items: center;
83
82
  justify-content: space-between;
@@ -122,14 +121,14 @@
122
121
  overflow-wrap: anywhere;
123
122
  }
124
123
 
125
- .mint-generated-workspace[data-v-41f5ec2e] {
124
+ .mint-generated-workspace[data-v-c8ff991b] {
126
125
  position: relative;
127
126
  min-width: 0;
128
127
  min-height: calc(100vh - 5rem);
129
128
  padding: clamp(1rem, 2.5vw, 2.5rem);
130
129
  background: var(--bg-primary);
131
130
  }
132
- .mint-generated-workspace__loading[data-v-41f5ec2e] {
131
+ .mint-generated-workspace__loading[data-v-c8ff991b] {
133
132
  display: flex;
134
133
  min-height: 24rem;
135
134
  align-items: center;
@@ -137,7 +136,7 @@
137
136
  gap: 0.75rem;
138
137
  color: var(--text-secondary);
139
138
  }
140
- .mint-generated-workspace__header[data-v-41f5ec2e] {
139
+ .mint-generated-workspace__header[data-v-c8ff991b] {
141
140
  display: flex;
142
141
  align-items: flex-start;
143
142
  justify-content: space-between;
@@ -145,29 +144,29 @@
145
144
  max-width: 76rem;
146
145
  margin: 0 auto 1.25rem;
147
146
  }
148
- .mint-generated-workspace__header h1[data-v-41f5ec2e] {
147
+ .mint-generated-workspace__header h1[data-v-c8ff991b] {
149
148
  margin: 0;
150
149
  color: var(--text-primary);
151
150
  font-size: clamp(1.35rem, 2vw, 1.8rem);
152
151
  line-height: 1.2;
153
152
  }
154
- .mint-generated-workspace__header p[data-v-41f5ec2e]:not(.mint-generated-workspace__eyebrow) {
153
+ .mint-generated-workspace__header p[data-v-c8ff991b]:not(.mint-generated-workspace__eyebrow) {
155
154
  margin: 0.4rem 0 0;
156
155
  color: var(--text-secondary);
157
156
  }
158
- .mint-generated-workspace__eyebrow[data-v-41f5ec2e] {
157
+ .mint-generated-workspace__eyebrow[data-v-c8ff991b] {
159
158
  margin: 0 0 0.35rem;
160
159
  color: var(--text-secondary);
161
160
  font-size: 0.72rem;
162
161
  font-weight: 700;
163
162
  }
164
- .mint-generated-workspace__resources[data-v-41f5ec2e] {
163
+ .mint-generated-workspace__resources[data-v-c8ff991b] {
165
164
  display: flex;
166
165
  flex-wrap: wrap;
167
166
  justify-content: flex-end;
168
167
  gap: 0.4rem;
169
168
  }
170
- .mint-generated-workspace__resources span[data-v-41f5ec2e] {
169
+ .mint-generated-workspace__resources span[data-v-c8ff991b] {
171
170
  padding: 0.3rem 0.55rem;
172
171
  border: 1px solid var(--border-color);
173
172
  border-radius: 999px;
@@ -176,7 +175,7 @@
176
175
  font-size: 0.75rem;
177
176
  font-weight: 600;
178
177
  }
179
- .mint-generated-workspace__result[data-v-41f5ec2e] {
178
+ .mint-generated-workspace__result[data-v-c8ff991b] {
180
179
  max-width: 76rem;
181
180
  min-height: 24rem;
182
181
  margin: 0 auto;
@@ -187,10 +186,10 @@
187
186
  box-shadow: var(--shadow-sm);
188
187
  }
189
188
  @media (max-width: 640px) {
190
- .mint-generated-workspace__header[data-v-41f5ec2e] {
189
+ .mint-generated-workspace__header[data-v-c8ff991b] {
191
190
  flex-direction: column;
192
191
  }
193
- .mint-generated-workspace__resources[data-v-41f5ec2e] {
192
+ .mint-generated-workspace__resources[data-v-c8ff991b] {
194
193
  justify-content: flex-start;
195
194
  }
196
195
  }
@@ -303,7 +302,7 @@
303
302
 
304
303
 
305
304
 
306
-
305
+ @layer theme, base, components, utilities;
307
306
  /* MINT SDK Styles - Main entry point
308
307
  * This file combines all SDK styles for proper bundling
309
308
  */
@@ -315,6 +314,9 @@
315
314
  * @import '@morscherlab/mint-sdk/styles';
316
315
  */
317
316
 
317
+ /* Tailwind v4's layer order, declared first so the SDK's base and utilities
318
+ layers sort the same way with or without Tailwind in the host. */
319
+
318
320
  /* ==========================================================================
319
321
  CSS Variables - Light Mode
320
322
  ========================================================================== */
@@ -357,13 +359,8 @@
357
359
  where --text-secondary would drop to ~4.35:1. */
358
360
  --text-secondary-strong: #475569;
359
361
 
360
- /* Brand colors — one teal accent: teal-600 fills, teal-700 hover + ink,
361
- teal-800 pressed. White on #0D9488 is 3.74:1, a known AA exception. */
362
- --color-primary: #0D9488;
363
- --color-primary-hover: #0F766E;
364
- --color-primary-pressed: #115E59;
365
- --color-primary-soft: rgba(13, 148, 136, 0.10);
366
- --color-primary-border: #99F6E4;
362
+ /* Brand colors: the accent (--color-primary*) comes from the palette
363
+ blocks below the dark block (html[data-palette], default teal). */
367
364
  /* Fixed teal scale, the same in both themes. */
368
365
  --color-primary-50: #F0FDFA;
369
366
  --color-primary-100: #CCFBF1;
@@ -445,6 +442,8 @@
445
442
  --form-height-md: 2rem;
446
443
  --form-height-lg: 2.5rem;
447
444
  --mint-gutter: 0.5rem;
445
+ /* Distance from the outermost cards to the window edge, in every density. */
446
+ --mint-page-inset: 1rem;
448
447
 
449
448
  /* Semantic colors */
450
449
  --mint-success: #10B981;
@@ -479,7 +478,7 @@
479
478
  /* Soft focus rings — 3px translucent. Used by all form primitives
480
479
  post-0.16 visual refresh. Solid variants above kept for legacy
481
480
  components that haven't migrated yet. */
482
- --focus-ring-soft: 0 0 0 3px rgba(13, 148, 136, 0.18);
481
+ --focus-ring-soft: 0 0 0 3px color-mix(in srgb, var(--color-primary) 18%, transparent);
483
482
  /* Red is perceptually brighter than teal at equal alpha; drop 2pp to keep visual weight matched. */
484
483
  --focus-ring-soft-error: 0 0 0 3px rgba(239, 68, 68, 0.18);
485
484
 
@@ -501,6 +500,12 @@
501
500
  --mint-border-focus: var(--color-primary);
502
501
  /* Colour-only transitions; no lift, bounce or glow. */
503
502
  --mint-transition: 120ms ease;
503
+ /* Stacking layers: modal < jobs tray < onboarding tour < floating panels < tooltips and toasts. */
504
+ --mint-z-modal: 50;
505
+ --mint-z-tray: 1000;
506
+ --mint-z-tour: 1100;
507
+ --mint-z-popover: 1200;
508
+ --mint-z-toast: 9999;
504
509
  }
505
510
 
506
511
  /* ==========================================================================
@@ -517,12 +522,7 @@ html.dark {
517
522
  --border-light: #172033;
518
523
  --border-strong: #334155;
519
524
 
520
- /* Brand colors - Dark mode (CTA, purple and entity aliases follow) */
521
- --color-primary: #2DD4BF;
522
- --color-primary-hover: #5EEAD4;
523
- --color-primary-pressed: #99F6E4;
524
- --color-primary-soft: rgba(45, 212, 191, 0.12);
525
- --color-primary-border: rgba(45, 212, 191, 0.35);
525
+ /* Brand colors - Dark mode: the accent comes from the palette blocks below. */
526
526
  /* Dark ink on the light accent fill (10.1:1 on #2DD4BF). */
527
527
  --text-on-accent: #0B1120;
528
528
  --color-experiment-hover: #E2E8F0;
@@ -558,7 +558,7 @@ html.dark {
558
558
 
559
559
  /* Focus ring - dark mode offset uses bg-primary instead of white */
560
560
  --focus-ring-offset: 0 0 0 2px var(--bg-primary), 0 0 0 4px var(--color-primary);
561
- --focus-ring-soft: 0 0 0 3px rgba(45, 212, 191, 0.22);
561
+ --focus-ring-soft: 0 0 0 3px color-mix(in srgb, var(--color-primary) 22%, transparent);
562
562
  --focus-ring-soft-error: 0 0 0 3px rgba(248, 113, 113, 0.26);
563
563
 
564
564
  /* Legacy aliases */
@@ -568,6 +568,122 @@ html.dark {
568
568
  color-scheme: dark;
569
569
  }
570
570
 
571
+ /* Accent palettes (Settings → Color palette). The settings store writes
572
+ html[data-palette]; the palette swatches set the same attribute on their
573
+ strip to preview a palette. Each palette is one accent in both themes: white
574
+ text on the light-mode fill, dark text (--text-on-accent) on the dark-mode
575
+ fill. Hues come from the biology plot-style palettes. */
576
+
577
+ /* Teal (default): teal-600 fill, teal-700 hover + ink, teal-800 pressed.
578
+ White on #0D9488 is 3.74:1, a known AA exception. */
579
+ :root,
580
+ [data-palette="default"] {
581
+ --color-primary: #0D9488;
582
+ --color-primary-hover: #0F766E;
583
+ --color-primary-pressed: #115E59;
584
+ --color-primary-soft: rgba(13, 148, 136, 0.10);
585
+ --color-primary-border: #99F6E4;
586
+ }
587
+ html.dark,
588
+ html.dark [data-palette="default"] {
589
+ --color-primary: #2DD4BF;
590
+ --color-primary-hover: #5EEAD4;
591
+ --color-primary-pressed: #99F6E4;
592
+ --color-primary-soft: rgba(45, 212, 191, 0.12);
593
+ --color-primary-border: rgba(45, 212, 191, 0.35);
594
+ }
595
+
596
+ /* Colour-blind safe: Okabe-Ito blue accent, and Okabe-Ito bluish green,
597
+ vermilion and orange for status, so success and error differ for every
598
+ colour-vision type. White on #0072B2 is 5.19:1. */
599
+ :root[data-palette="colorblind"],
600
+ [data-palette="colorblind"] {
601
+ --color-primary: #0072B2;
602
+ --color-primary-hover: #005F94;
603
+ --color-primary-pressed: #004C77;
604
+ --color-primary-soft: rgba(0, 114, 178, 0.10);
605
+ --color-primary-border: #B3D5EA;
606
+ --mint-success: #009E73;
607
+ --mint-success-hover: #00805D;
608
+ --mint-success-bg: rgba(0, 158, 115, 0.1);
609
+ --mint-success-border: rgba(0, 158, 115, 0.3);
610
+ --mint-error: #D55E00;
611
+ --mint-error-hover: #B34E00;
612
+ --mint-error-bg: rgba(213, 94, 0, 0.1);
613
+ --mint-error-border: rgba(213, 94, 0, 0.3);
614
+ --mint-warning: #E69F00;
615
+ --mint-warning-hover: #C78800;
616
+ --mint-warning-bg: rgba(230, 159, 0, 0.1);
617
+ --mint-warning-border: rgba(230, 159, 0, 0.3);
618
+ --mint-warning-text: #8F5F00;
619
+ }
620
+ html.dark[data-palette="colorblind"],
621
+ html.dark [data-palette="colorblind"] {
622
+ --color-primary: #56B4E9;
623
+ --color-primary-hover: #7CC5EE;
624
+ --color-primary-pressed: #A3D6F3;
625
+ --color-primary-soft: rgba(86, 180, 233, 0.14);
626
+ --color-primary-border: rgba(86, 180, 233, 0.38);
627
+ --mint-success-bg: rgba(0, 158, 115, 0.15);
628
+ --mint-error-bg: rgba(213, 94, 0, 0.15);
629
+ --mint-warning-bg: rgba(230, 159, 0, 0.15);
630
+ --mint-warning-text: #FCD34D;
631
+ }
632
+
633
+ /* Purple: plot-style purple #8781bd, deepened so white text is 5.15:1. */
634
+ :root[data-palette="purple"],
635
+ [data-palette="purple"] {
636
+ --color-primary: #6B64B0;
637
+ --color-primary-hover: #5A539E;
638
+ --color-primary-pressed: #4A448A;
639
+ --color-primary-soft: rgba(107, 100, 176, 0.10);
640
+ --color-primary-border: #D3D0EC;
641
+ }
642
+ html.dark[data-palette="purple"],
643
+ html.dark [data-palette="purple"] {
644
+ --color-primary: #A9A3DB;
645
+ --color-primary-hover: #C2BDE7;
646
+ --color-primary-pressed: #D8D4F1;
647
+ --color-primary-soft: rgba(169, 163, 219, 0.14);
648
+ --color-primary-border: rgba(169, 163, 219, 0.38);
649
+ }
650
+
651
+ /* Ocean: plot-style ocean ramp, #2171B5 fill (white 5.13:1), #6BAED6 dark. */
652
+ :root[data-palette="ocean"],
653
+ [data-palette="ocean"] {
654
+ --color-primary: #2171B5;
655
+ --color-primary-hover: #1B5F99;
656
+ --color-primary-pressed: #164E7E;
657
+ --color-primary-soft: rgba(33, 113, 181, 0.10);
658
+ --color-primary-border: #BBD7EE;
659
+ }
660
+ html.dark[data-palette="ocean"],
661
+ html.dark [data-palette="ocean"] {
662
+ --color-primary: #6BAED6;
663
+ --color-primary-hover: #8EC2E2;
664
+ --color-primary-pressed: #B0D5EC;
665
+ --color-primary-soft: rgba(107, 174, 214, 0.14);
666
+ --color-primary-border: rgba(107, 174, 214, 0.38);
667
+ }
668
+
669
+ /* Forest: plot-style forest_clay, #2F6B4F fill (white 6.29:1), #7AA874 dark. */
670
+ :root[data-palette="forest"],
671
+ [data-palette="forest"] {
672
+ --color-primary: #2F6B4F;
673
+ --color-primary-hover: #275A42;
674
+ --color-primary-pressed: #1F4935;
675
+ --color-primary-soft: rgba(47, 107, 79, 0.10);
676
+ --color-primary-border: #BFD8C6;
677
+ }
678
+ html.dark[data-palette="forest"],
679
+ html.dark [data-palette="forest"] {
680
+ --color-primary: #7AA874;
681
+ --color-primary-hover: #95BC90;
682
+ --color-primary-pressed: #B1CFAD;
683
+ --color-primary-soft: rgba(122, 168, 116, 0.14);
684
+ --color-primary-border: rgba(122, 168, 116, 0.38);
685
+ }
686
+
571
687
  /* Comfortable density (html[data-density], written by the settings store):
572
688
  the pre-v2 control heights and a wider gutter. */
573
689
  [data-density="comfortable"] {
@@ -591,6 +707,22 @@ body {
591
707
  transition: background-color 0.15s, color 0.15s;
592
708
  }
593
709
 
710
+ /* No page-level rubber-band bounce or pull-to-refresh; overflow: hidden does
711
+ not stop it. Panels still scroll, and their overscroll stops at their own
712
+ edge. A browser tab keeps the horizontal swipe for back and forward; an
713
+ installed PWA has no history swipe, so it drops both axes. */
714
+ html,
715
+ body {
716
+ overscroll-behavior-y: none;
717
+ }
718
+
719
+ @media (display-mode: standalone) {
720
+ html,
721
+ body {
722
+ overscroll-behavior: none;
723
+ }
724
+ }
725
+
594
726
  code, pre {
595
727
  font-family: var(--font-mono);
596
728
  }
@@ -654,6 +786,9 @@ button, input, select, textarea {
654
786
  /* ==========================================================================
655
787
  MINT Utility Classes (for Tailwind v4 compatibility)
656
788
  ========================================================================== */
789
+ /* In Tailwind's utilities layer: unlayered, these beat every layered rule, so a
790
+ host's responsive variant (`lg:flex-row`) lost to the SDK's `.flex-col`. */
791
+ @layer utilities {
657
792
  .bg-bg-hover {
658
793
  background-color: var(--bg-tertiary);
659
794
  }
@@ -1029,6 +1164,7 @@ button, input, select, textarea {
1029
1164
  .max-w-sm {
1030
1165
  max-width: 24rem;
1031
1166
  }
1167
+ } /* @layer utilities */
1032
1168
 
1033
1169
  /* ==========================================================================
1034
1170
  Reduced Motion
@@ -1215,7 +1351,7 @@ button, input, select, textarea {
1215
1351
 
1216
1352
  .mint-action-menu__panel {
1217
1353
  position: fixed;
1218
- z-index: 1000;
1354
+ z-index: var(--mint-z-popover);
1219
1355
  min-width: 10rem;
1220
1356
  max-width: min(18rem, calc(100vw - 1rem));
1221
1357
  }
@@ -1490,10 +1626,11 @@ button, input, select, textarea {
1490
1626
  }
1491
1627
 
1492
1628
  /* Floating variant: all sections appear as separate cards on a background,
1493
- spaced by the density gutter (8px, 12px comfortable). */
1629
+ 16px from the window edge and spaced by the density gutter (8px, 12px
1630
+ comfortable). */
1494
1631
  .mint-layout--floating {
1495
1632
  background-color: var(--bg-primary);
1496
- padding: var(--mint-gutter);
1633
+ padding: var(--mint-page-inset);
1497
1634
  gap: var(--mint-gutter);
1498
1635
  }
1499
1636
 
@@ -1553,8 +1690,10 @@ button, input, select, textarea {
1553
1690
  transform: translateX(calc(100% + 1rem));
1554
1691
  }
1555
1692
 
1693
+ /* `none`, not translateX(0): any transform makes the sidebar the containing
1694
+ block of its fixed dropdown panels, and its overflow would clip them. */
1556
1695
  .mint-layout--responsive-sidebar.mint-layout--sidebar-open .mint-layout__sidebar {
1557
- transform: translateX(0);
1696
+ transform: none;
1558
1697
  }
1559
1698
 
1560
1699
  .mint-layout--responsive-sidebar .mint-layout__sidebar-toggle {
@@ -2267,10 +2406,10 @@ button, input, select, textarea {
2267
2406
  padding: 0 0.375rem 0 0;
2268
2407
  }
2269
2408
 
2270
- /* Variant: card - flat floating card, inset by the layout gutter */
2409
+ /* Variant: card - flat floating card, inset 16px from the window edge */
2271
2410
  .mint-topbar--card {
2272
- width: calc(100% - 2 * var(--mint-gutter));
2273
- margin: var(--mint-gutter) var(--mint-gutter) 0;
2411
+ width: calc(100% - 2 * var(--mint-page-inset));
2412
+ margin: var(--mint-page-inset) var(--mint-page-inset) 0;
2274
2413
  padding: 0.375rem 0.5rem 0.375rem 0.625rem;
2275
2414
  border-radius: var(--radius-lg);
2276
2415
  border: 1px solid var(--border-color);
@@ -2388,6 +2527,168 @@ button, input, select, textarea {
2388
2527
  white-space: nowrap;
2389
2528
  user-select: none;
2390
2529
  }
2530
+
2531
+ /* ─── Run slot: [ experiment | job ] ───
2532
+ While a job shows, one border wraps the experiment chip and the job
2533
+ segment, as the experiment popover does for Save. The wrapper does not
2534
+ clip: the popover panel and the focus rings reach outside it, so each
2535
+ segment rounds its own outer corners. The idle Jobs button stands apart
2536
+ with its own border. */
2537
+ .mint-topbar__run-slot {
2538
+ display: inline-flex;
2539
+ align-items: center;
2540
+ gap: 0.5rem;
2541
+ min-width: 0;
2542
+ }
2543
+
2544
+ .mint-topbar__run-slot--joined {
2545
+ gap: 0;
2546
+ border: 1px solid var(--border-color);
2547
+ border-radius: var(--radius-md);
2548
+ background: var(--bg-card);
2549
+ }
2550
+
2551
+ .mint-topbar__run-slot--joined .mint-experiment-popover,
2552
+ .mint-topbar__run-slot--joined .mint-experiment-popover__trigger {
2553
+ border: 0;
2554
+ border-radius: calc(var(--radius-md) - 1px) 0 0 calc(var(--radius-md) - 1px);
2555
+ }
2556
+
2557
+ /* The job takes the name's place: the name folds away while the job grows in,
2558
+ and the code badge stays. The name stays in the accessible name. A trigger
2559
+ with no code, the empty placeholder and the error text keep their text. */
2560
+ .mint-topbar__run-slot .mint-experiment-popover__trigger-text {
2561
+ transition:
2562
+ max-width 200ms ease,
2563
+ opacity 150ms ease,
2564
+ margin 200ms ease;
2565
+ }
2566
+
2567
+ .mint-topbar__run-slot--joined
2568
+ .mint-experiment-popover__trigger:has(.mint-exp-code)
2569
+ .mint-experiment-popover__trigger-text {
2570
+ max-width: 0 !important; /* beats the inline maxNameWidth */
2571
+ margin-inline-start: -0.5rem; /* takes back the trigger gap */
2572
+ opacity: 0;
2573
+ }
2574
+
2575
+ .mint-topbar__job {
2576
+ display: inline-flex;
2577
+ max-width: 6rem; /* close to the content (icon + bar, or "Jobs"), so the fold is even */
2578
+ overflow: hidden;
2579
+ align-items: center;
2580
+ gap: 0.375rem;
2581
+ flex-shrink: 0;
2582
+ height: 30px;
2583
+ padding: 0 0.625rem;
2584
+ border: 0;
2585
+ background: transparent;
2586
+ color: var(--text-secondary);
2587
+ font: inherit;
2588
+ font-size: 0.75rem;
2589
+ font-weight: 500;
2590
+ white-space: nowrap;
2591
+ cursor: pointer;
2592
+ transition: background-color var(--mint-transition);
2593
+ }
2594
+
2595
+ .mint-topbar__run-slot--joined .mint-topbar__job {
2596
+ border-radius: calc(var(--radius-md) - 1px);
2597
+ }
2598
+
2599
+ .mint-topbar__run-slot--joined .mint-experiment-popover + .mint-topbar__job {
2600
+ border-left: 1px solid var(--border-color);
2601
+ border-radius: 0 calc(var(--radius-md) - 1px) calc(var(--radius-md) - 1px) 0;
2602
+ }
2603
+
2604
+ .mint-topbar__job--idle {
2605
+ height: 32px;
2606
+ border: 1px solid var(--border-color);
2607
+ border-radius: var(--radius-md);
2608
+ background: var(--bg-card);
2609
+ }
2610
+
2611
+ .mint-topbar__job--idle:hover,
2612
+ .mint-topbar__job--neutral:hover {
2613
+ background: var(--bg-hover);
2614
+ }
2615
+
2616
+ .mint-topbar__job:focus-visible {
2617
+ outline: none;
2618
+ box-shadow: inset var(--focus-ring);
2619
+ }
2620
+
2621
+ .mint-topbar__job--primary { background: var(--color-primary-soft); color: var(--_ink-primary); }
2622
+ .mint-topbar__job--warning { background: var(--mint-warning-bg); color: var(--mint-warning-text); }
2623
+ .mint-topbar__job--success { background: var(--mint-success-bg); color: color-mix(in srgb, var(--mint-success) 50%, var(--text-primary)); }
2624
+ .mint-topbar__job--error { background: var(--mint-error-bg); color: var(--_ink-error); }
2625
+
2626
+ .mint-topbar__job--primary:hover,
2627
+ .mint-topbar__job--warning:hover,
2628
+ .mint-topbar__job--success:hover,
2629
+ .mint-topbar__job--error:hover {
2630
+ filter: brightness(0.97);
2631
+ }
2632
+
2633
+ .mint-topbar__job-icon {
2634
+ flex-shrink: 0;
2635
+ }
2636
+
2637
+ .mint-topbar__job-count {
2638
+ color: var(--text-muted);
2639
+ font-family: var(--font-mono);
2640
+ font-size: 0.6875rem;
2641
+ font-variant-numeric: tabular-nums;
2642
+ }
2643
+
2644
+ .mint-topbar__job-icon--spin {
2645
+ animation: mint-topbar-job-spin 1s linear infinite;
2646
+ }
2647
+
2648
+ @keyframes mint-topbar-job-spin {
2649
+ to { transform: rotate(360deg); }
2650
+ }
2651
+
2652
+ .mint-topbar__job-bar {
2653
+ width: 2rem;
2654
+ height: 4px;
2655
+ border-radius: 2px;
2656
+ background: var(--border-color);
2657
+ overflow: hidden;
2658
+ }
2659
+
2660
+ .mint-topbar__job-bar > span {
2661
+ display: block;
2662
+ height: 100%;
2663
+ background: var(--color-primary);
2664
+ transition: width var(--mint-transition);
2665
+ }
2666
+
2667
+ /* Enter and leave: the job grows in from zero width and folds back out. */
2668
+ .mint-topbar-job-enter-active,
2669
+ .mint-topbar-job-leave-active {
2670
+ transition:
2671
+ max-width 200ms ease,
2672
+ padding 200ms ease,
2673
+ opacity 150ms ease;
2674
+ }
2675
+
2676
+ .mint-topbar-job-enter-from,
2677
+ .mint-topbar-job-leave-to {
2678
+ max-width: 0;
2679
+ padding-inline: 0;
2680
+ opacity: 0;
2681
+ }
2682
+
2683
+ /* Screen-reader only: announces status changes of the shown job. */
2684
+ .mint-topbar__job-status {
2685
+ position: absolute;
2686
+ width: 1px;
2687
+ height: 1px;
2688
+ overflow: hidden;
2689
+ clip-path: inset(50%);
2690
+ white-space: nowrap;
2691
+ }
2391
2692
  /* BaseButton Component Styles */
2392
2693
 
2393
2694
  .mint-button {
@@ -2540,6 +2841,14 @@ button, input, select, textarea {
2540
2841
  height: 1.25rem;
2541
2842
  }
2542
2843
 
2844
+ /* Flex centring centres the line box, and Geist's ascender puts the caps
2845
+ about 1.6px above the middle. Trim the text box to cap height and baseline
2846
+ so the caps sit on the centre line. Browsers without text-box keep the
2847
+ untrimmed box. */
2848
+ .mint-button__label {
2849
+ text-box: trim-both cap alphabetic;
2850
+ }
2851
+
2543
2852
  /* Spinner */
2544
2853
  .mint-button__spinner {
2545
2854
  animation: mint-button-spin 1s linear infinite;
@@ -3249,11 +3558,13 @@ button, input, select, textarea {
3249
3558
  height: 0.875rem;
3250
3559
  }
3251
3560
 
3252
- /* Calendar dropdown (teleported to body, positioned via JS). */
3561
+ /* Calendar dropdown (teleported to body, positioned by useFloatingPanel). */
3253
3562
  .mint-date-picker__dropdown {
3254
3563
  position: fixed;
3255
- z-index: 9999;
3564
+ z-index: var(--mint-z-popover);
3256
3565
  width: 252px;
3566
+ max-height: var(--mint-floating-available-height, none);
3567
+ overflow-y: auto;
3257
3568
  padding: 0.5rem;
3258
3569
  }
3259
3570
 
@@ -4033,11 +4344,9 @@ button, input, select, textarea {
4033
4344
  }
4034
4345
  }
4035
4346
 
4347
+ /* The compact jobs panel of design v2: opened from the top-bar run slot, one list
4348
+ (Active, then Finished), one row per job. Non-modal: the page is not dimmed. */
4036
4349
  .mint-jobs-tray {
4037
- position: fixed;
4038
- right: max(1.25rem, env(safe-area-inset-right));
4039
- bottom: max(1.25rem, env(safe-area-inset-bottom));
4040
- z-index: 1000;
4041
4350
  color: var(--text-primary);
4042
4351
  font-family: var(--font-sans);
4043
4352
  }
@@ -4047,146 +4356,79 @@ button, input, select, textarea {
4047
4356
  --border-light: var(--border-color);
4048
4357
  }
4049
4358
 
4050
- .mint-jobs-tray__trigger {
4051
- display: inline-flex;
4052
- min-height: 2.75rem;
4053
- align-items: center;
4054
- gap: 0.625rem;
4055
- padding: 0.5rem 1rem;
4056
- border: 0;
4057
- border-radius: var(--radius-lg);
4058
- background: var(--color-primary);
4059
- color: var(--text-on-accent);
4060
- box-shadow: var(--mint-shadow-pop);
4061
- cursor: pointer;
4062
- transition: background var(--mint-transition);
4063
- }
4064
-
4065
- .mint-jobs-tray__trigger:hover {
4066
- background: var(--color-primary-hover);
4067
- }
4068
-
4069
- .mint-jobs-tray__trigger:focus-visible,
4070
- .mint-jobs-tray__panel:focus-visible,
4071
- .mint-jobs-tray button:focus-visible {
4072
- outline: none;
4073
- box-shadow: var(--focus-ring-offset);
4074
- }
4075
-
4076
- .mint-jobs-tray__trigger-icon {
4077
- width: 1.125rem;
4078
- height: 1.125rem;
4079
- stroke-width: 1.8;
4080
- stroke-linecap: round;
4081
- stroke-linejoin: round;
4082
- }
4083
-
4084
- .mint-jobs-tray__trigger-icon--active {
4085
- animation: mint-jobs-tray-pulse 1.8s ease-in-out infinite;
4086
- }
4087
-
4088
- .mint-jobs-tray__trigger-label {
4089
- font-size: 0.875rem;
4090
- font-weight: 600;
4091
- }
4092
-
4093
- .mint-jobs-tray__count,
4094
- .mint-jobs-tray__tab-count {
4095
- display: inline-flex;
4096
- min-width: 1.25rem;
4097
- height: 1.25rem;
4098
- align-items: center;
4099
- justify-content: center;
4100
- padding: 0 0.375rem;
4101
- border-radius: var(--radius-sm);
4102
- font: 600 0.6875rem/1 var(--font-mono);
4103
- }
4104
-
4105
- /* Inverted on the accent fill: accent ink on the on-accent colour, in both themes. */
4106
- .mint-jobs-tray__count {
4107
- background: var(--text-on-accent);
4108
- color: var(--_ink-primary);
4109
- }
4110
-
4111
- .mint-jobs-tray__backdrop {
4359
+ /* Transparent: catches clicks outside the panel. */
4360
+ .mint-jobs-tray__scrim {
4112
4361
  position: fixed;
4113
4362
  inset: 0;
4114
- z-index: -2;
4115
- background: rgb(15 23 42 / 0.22);
4363
+ z-index: calc(var(--mint-z-tray) - 1);
4116
4364
  }
4117
4365
 
4118
4366
  .mint-jobs-tray__panel {
4119
- position: absolute;
4120
- right: 0;
4121
- bottom: 3.75rem;
4367
+ position: fixed;
4368
+ top: calc(4.5rem + env(safe-area-inset-top));
4369
+ right: max(1rem, env(safe-area-inset-right));
4370
+ z-index: var(--mint-z-tray);
4122
4371
  display: flex;
4123
- width: min(21.25rem, calc(100vw - 2rem));
4124
- max-height: min(42rem, calc(100vh - 7rem));
4372
+ width: min(360px, calc(100vw - 2rem));
4373
+ max-height: 75vh;
4125
4374
  flex-direction: column;
4126
4375
  overflow: hidden;
4127
4376
  border: 1px solid var(--border-color);
4128
4377
  border-radius: var(--radius-lg);
4129
4378
  background: var(--bg-card);
4130
4379
  box-shadow: var(--mint-shadow-pop);
4380
+ font-size: 0.8125rem;
4131
4381
  }
4132
4382
 
4133
- .mint-jobs-tray__header,
4134
- .mint-jobs-tray__job-heading,
4135
- .mint-jobs-tray__job-footer,
4136
- .mint-jobs-tray__header-actions,
4137
- .mint-jobs-tray__clear-row {
4138
- display: flex;
4139
- align-items: center;
4383
+ /* The panel takes focus only so Escape and Tab start inside it; it shows no ring. */
4384
+ .mint-jobs-tray__panel:focus {
4385
+ outline: none;
4140
4386
  }
4141
4387
 
4142
- .mint-jobs-tray__header {
4143
- justify-content: space-between;
4144
- height: 2.5rem;
4145
- padding: 0 0.5rem 0 0.75rem;
4146
- border-bottom: 1px solid var(--border-color);
4388
+ .mint-jobs-tray button:focus-visible {
4389
+ outline: none;
4390
+ box-shadow: var(--focus-ring);
4147
4391
  }
4148
4392
 
4149
- .mint-jobs-tray__header > div:first-child {
4393
+ .mint-jobs-tray__head {
4150
4394
  display: flex;
4151
- align-items: baseline;
4395
+ flex-shrink: 0;
4396
+ align-items: center;
4152
4397
  gap: 0.5rem;
4153
- min-width: 0;
4398
+ height: 40px;
4399
+ padding: 0 0.5rem 0 0.75rem;
4400
+ border-bottom: 1px solid var(--border-color);
4154
4401
  }
4155
4402
 
4156
4403
  .mint-jobs-tray__title {
4157
- flex-shrink: 0;
4158
4404
  margin: 0;
4159
- color: var(--text-primary);
4160
4405
  font-size: 0.8125rem;
4161
4406
  font-weight: 600;
4162
4407
  white-space: nowrap;
4163
4408
  }
4164
4409
 
4165
- .mint-jobs-tray__subtitle {
4410
+ .mint-jobs-tray__head-count {
4411
+ flex: 1;
4166
4412
  min-width: 0;
4167
- margin: 0;
4168
4413
  overflow: hidden;
4169
- color: var(--text-muted);
4170
- font: 0.6875rem/1.3 var(--font-mono);
4414
+ color: var(--text-secondary);
4415
+ font-family: var(--font-mono);
4416
+ font-size: 0.6875rem;
4171
4417
  text-overflow: ellipsis;
4172
4418
  white-space: nowrap;
4173
4419
  }
4174
4420
 
4175
- .mint-jobs-tray__header-actions {
4176
- gap: 0.25rem;
4177
- }
4178
-
4179
4421
  .mint-jobs-tray__icon-button {
4180
- display: inline-flex;
4181
- width: 2rem;
4182
- height: 2rem;
4183
- align-items: center;
4184
- justify-content: center;
4422
+ display: inline-grid;
4423
+ width: 28px;
4424
+ height: 28px;
4425
+ flex-shrink: 0;
4426
+ place-items: center;
4185
4427
  padding: 0;
4186
4428
  border: 0;
4187
4429
  border-radius: var(--radius-md);
4188
4430
  background: transparent;
4189
- color: var(--text-secondary-strong);
4431
+ color: var(--text-secondary);
4190
4432
  cursor: pointer;
4191
4433
  transition: background var(--mint-transition), color var(--mint-transition);
4192
4434
  }
@@ -4196,175 +4438,143 @@ button, input, select, textarea {
4196
4438
  color: var(--text-primary);
4197
4439
  }
4198
4440
 
4199
- .mint-jobs-tray__icon-button svg {
4200
- width: 1rem;
4201
- height: 1rem;
4202
- stroke-width: 1.8;
4203
- stroke-linecap: round;
4204
- stroke-linejoin: round;
4441
+ .mint-jobs-tray__icon-button--danger,
4442
+ .mint-jobs-tray__icon-button--danger:hover {
4443
+ color: var(--mint-error);
4205
4444
  }
4206
4445
 
4207
- .mint-jobs-tray__icon-button--danger {
4208
- color: var(--mint-error);
4446
+ .mint-jobs-tray__error {
4447
+ margin: 0.5rem 0.75rem 0;
4448
+ padding: 0.5rem 0.75rem;
4449
+ border: 1px solid var(--mint-error-border);
4450
+ border-radius: var(--radius-md);
4451
+ background: var(--mint-error-bg);
4452
+ color: var(--_ink-error);
4453
+ font-size: 0.75rem;
4209
4454
  }
4210
4455
 
4211
- .mint-jobs-tray__tabs {
4212
- display: grid;
4213
- grid-template-columns: 1fr 1fr;
4214
- border-bottom: 1px solid var(--border-color);
4456
+ .mint-jobs-tray__body {
4457
+ flex: 1;
4458
+ min-height: 0;
4459
+ overflow-y: auto;
4460
+ scrollbar-color: var(--scrollbar-thumb) transparent;
4215
4461
  }
4216
4462
 
4217
- .mint-jobs-tray__tab {
4218
- position: relative;
4219
- display: inline-flex;
4220
- min-height: 2.75rem;
4221
- align-items: center;
4222
- justify-content: center;
4223
- gap: 0.375rem;
4224
- padding: 0.5rem 1rem;
4225
- border: 0;
4226
- background: transparent;
4227
- color: var(--text-secondary-strong);
4228
- font: 500 0.8125rem/1 var(--font-sans);
4229
- cursor: pointer;
4463
+ .mint-jobs-tray__empty {
4464
+ margin: 0;
4465
+ padding: 1.5rem 0.75rem;
4466
+ color: var(--text-secondary);
4467
+ text-align: center;
4230
4468
  }
4231
4469
 
4232
- .mint-jobs-tray__tab--active {
4233
- color: var(--_ink-primary);
4470
+ .mint-jobs-tray__section {
4471
+ display: flex;
4472
+ align-items: center;
4473
+ gap: 0.375rem;
4474
+ padding: 0.625rem 0.75rem 0.25rem;
4475
+ color: var(--text-secondary);
4476
+ font-size: 0.6875rem;
4477
+ font-weight: 600;
4234
4478
  }
4235
4479
 
4236
- .mint-jobs-tray__tab--active::after {
4237
- position: absolute;
4238
- right: 1rem;
4239
- bottom: 0;
4240
- left: 1rem;
4241
- height: 2px;
4242
- background: var(--color-primary);
4243
- content: '';
4480
+ .mint-jobs-tray__section-count {
4481
+ color: var(--text-muted);
4482
+ font-family: var(--font-mono);
4483
+ font-weight: 500;
4244
4484
  }
4245
4485
 
4246
- .mint-jobs-tray__tab-count {
4247
- background: var(--bg-tertiary);
4248
- color: currentColor;
4486
+ .mint-jobs-tray__section-action {
4487
+ margin-left: auto;
4488
+ padding: 0;
4489
+ border: 0;
4490
+ border-radius: var(--radius-sm);
4491
+ background: transparent;
4492
+ color: var(--text-secondary);
4493
+ font: inherit;
4494
+ font-weight: 500;
4495
+ cursor: pointer;
4249
4496
  }
4250
4497
 
4251
- .mint-jobs-tray__error {
4252
- margin: 0.75rem 1rem;
4253
- padding: 0.625rem 0.75rem;
4254
- border: 1px solid var(--mint-error-border);
4255
- border-radius: var(--radius-md);
4256
- background: var(--mint-error-bg);
4498
+ .mint-jobs-tray__section-action:hover {
4257
4499
  color: var(--mint-error);
4258
- font-size: 0.75rem;
4259
4500
  }
4260
4501
 
4261
- .mint-jobs-tray__body {
4262
- flex: 1;
4263
- overflow-y: auto;
4264
- scrollbar-color: var(--scrollbar-thumb) transparent;
4265
- }
4266
-
4267
- .mint-jobs-tray__empty {
4268
- margin: 0;
4269
- padding: 3rem 1rem;
4270
- color: var(--text-secondary);
4271
- text-align: center;
4272
- font-size: 0.8125rem;
4502
+ /* Rows + hairlines, no card per job. */
4503
+ .mint-jobs-tray__row {
4504
+ display: grid;
4505
+ grid-template-columns: 16px minmax(0, 1fr) auto;
4506
+ align-items: center;
4507
+ gap: 0.25rem 0.625rem;
4508
+ padding: 0.5rem 0.5rem 0.5rem 0.75rem;
4509
+ border-bottom: 1px solid var(--border-light);
4273
4510
  }
4274
4511
 
4275
- /* 2f: rows + hairlines, no card per job. */
4276
- .mint-jobs-tray__job {
4277
- padding: 0.625rem 0.75rem;
4278
- border-bottom: 1px solid var(--border-light);
4512
+ .mint-jobs-tray__row:hover {
4513
+ background: var(--bg-hover);
4279
4514
  }
4280
4515
 
4281
4516
  /* The one state that needs a person: tinted and pinned first. */
4282
- .mint-jobs-tray__job--awaiting-input {
4517
+ .mint-jobs-tray__row--awaiting-input,
4518
+ .mint-jobs-tray__row--awaiting-input:hover {
4283
4519
  background: var(--mint-warning-bg);
4284
4520
  }
4285
4521
 
4286
- .mint-jobs-tray__job-heading,
4287
- .mint-jobs-tray__job-footer {
4288
- justify-content: space-between;
4289
- gap: 0.75rem;
4522
+ .mint-jobs-tray__status {
4523
+ color: var(--text-muted);
4290
4524
  }
4291
4525
 
4292
- .mint-jobs-tray__job-identity {
4293
- flex: 1;
4294
- min-width: 0;
4526
+ .mint-jobs-tray__status--running {
4527
+ color: var(--color-primary);
4528
+ animation: mint-jobs-tray-spin 1s linear infinite;
4295
4529
  }
4296
4530
 
4297
- .mint-jobs-tray__job-select {
4298
- display: block;
4299
- max-width: 100%;
4531
+ .mint-jobs-tray__status--awaiting-input { color: var(--mint-warning); }
4532
+ .mint-jobs-tray__status--completed { color: var(--mint-success); }
4533
+ .mint-jobs-tray__status--failed { color: var(--mint-error); }
4534
+
4535
+ @keyframes mint-jobs-tray-spin {
4536
+ to { transform: rotate(360deg); }
4537
+ }
4538
+
4539
+ .mint-jobs-tray__row-title {
4540
+ min-width: 0;
4300
4541
  padding: 0;
4301
4542
  overflow: hidden;
4302
4543
  border: 0;
4544
+ border-radius: var(--radius-sm);
4303
4545
  background: transparent;
4304
4546
  color: var(--text-primary);
4305
- cursor: pointer;
4306
- font-size: 0.8125rem;
4547
+ font: inherit;
4307
4548
  font-weight: 500;
4308
4549
  text-align: left;
4309
4550
  text-overflow: ellipsis;
4310
4551
  white-space: nowrap;
4552
+ cursor: pointer;
4311
4553
  }
4312
4554
 
4313
- .mint-jobs-tray__kind {
4314
- display: block;
4315
- margin-top: 0.125rem;
4316
- color: var(--text-secondary);
4317
- font: 0.6875rem/1.3 var(--font-mono);
4318
- }
4319
-
4320
- /* Status: tone dot + neutral text. Only "waiting for input" and "failed"
4321
- color their text. */
4322
- .mint-jobs-tray__status {
4323
- display: inline-flex;
4324
- flex: 0 0 auto;
4555
+ .mint-jobs-tray__tools {
4556
+ display: flex;
4325
4557
  align-items: center;
4326
- gap: 0.375rem;
4327
- color: var(--text-secondary-strong);
4328
- font-size: 0.75rem;
4329
- --mint-jobs-tray-tone: var(--text-muted);
4330
- }
4331
-
4332
- .mint-jobs-tray__status-dot {
4333
- width: 0.375rem;
4334
- height: 0.375rem;
4335
- border-radius: 9999px;
4336
- background: var(--mint-jobs-tray-tone);
4337
- }
4338
-
4339
- .mint-jobs-tray__status--running { --mint-jobs-tray-tone: var(--color-primary); }
4340
- .mint-jobs-tray__status--completed { --mint-jobs-tray-tone: var(--mint-success); }
4341
-
4342
- .mint-jobs-tray__status--awaiting-input {
4343
- --mint-jobs-tray-tone: var(--mint-warning);
4344
- color: var(--mint-warning-text);
4345
- font-weight: 600;
4346
- }
4347
-
4348
- .mint-jobs-tray__status--failed {
4349
- --mint-jobs-tray-tone: var(--mint-error);
4350
- color: var(--_ink-error);
4558
+ gap: 2px;
4351
4559
  }
4352
4560
 
4353
- .mint-jobs-tray__percent {
4354
- flex: 0 0 auto;
4355
- min-width: 2.125rem;
4356
- color: var(--text-primary);
4561
+ .mint-jobs-tray__value {
4562
+ margin-right: 0.375rem;
4563
+ color: var(--text-secondary);
4357
4564
  font-family: var(--font-mono);
4358
- font-size: 0.75rem;
4565
+ font-size: 0.6875rem;
4359
4566
  font-variant-numeric: tabular-nums;
4360
- text-align: right;
4567
+ }
4568
+
4569
+ .mint-jobs-tray__progress,
4570
+ .mint-jobs-tray__detail {
4571
+ grid-column: 2 / 4;
4361
4572
  }
4362
4573
 
4363
4574
  .mint-jobs-tray__progress {
4364
- height: 4px;
4365
- margin-top: 0.375rem;
4575
+ height: 2px;
4366
4576
  overflow: hidden;
4367
- border-radius: 2px;
4577
+ border-radius: 1px;
4368
4578
  background: var(--bg-tertiary);
4369
4579
  }
4370
4580
 
@@ -4375,56 +4585,17 @@ button, input, select, textarea {
4375
4585
  transition: width var(--mint-transition);
4376
4586
  }
4377
4587
 
4378
- .mint-jobs-tray__job-footer {
4379
- min-height: 1.75rem;
4380
- margin-top: 0.375rem;
4588
+ .mint-jobs-tray__detail {
4589
+ min-width: 0;
4590
+ overflow: hidden;
4381
4591
  color: var(--text-secondary);
4382
4592
  font-size: 0.75rem;
4593
+ text-overflow: ellipsis;
4594
+ white-space: nowrap;
4383
4595
  }
4384
4596
 
4385
- .mint-jobs-tray__action {
4386
- min-height: 1.75rem;
4387
- padding: 0.375rem 0.625rem;
4388
- border: 1px solid var(--border-color);
4389
- border-radius: var(--radius);
4390
- background: var(--bg-secondary);
4391
- color: var(--text-secondary-strong);
4392
- font: 500 0.75rem/1 var(--font-sans);
4393
- cursor: pointer;
4394
- transition: background var(--mint-transition), border-color var(--mint-transition), color var(--mint-transition);
4395
- }
4396
-
4397
- .mint-jobs-tray__job-actions {
4398
- display: inline-flex;
4399
- align-items: center;
4400
- gap: 0.25rem;
4401
- }
4402
-
4403
- /* 2f: the inline action of a row waiting for input is the primary one. */
4404
- .mint-jobs-tray__job--awaiting-input .mint-jobs-tray__action:not(.mint-jobs-tray__action--danger) {
4405
- border-color: var(--color-primary);
4406
- background: var(--color-primary);
4407
- color: var(--text-on-accent);
4408
- }
4409
-
4410
- .mint-jobs-tray__job--awaiting-input .mint-jobs-tray__action:not(.mint-jobs-tray__action--danger):hover {
4411
- border-color: var(--color-primary-hover);
4412
- background: var(--color-primary-hover);
4413
- }
4414
-
4415
- .mint-jobs-tray__action--danger {
4416
- border-color: var(--mint-error-border);
4417
- color: var(--mint-error);
4418
- }
4419
-
4420
- .mint-jobs-tray__action--danger:hover {
4421
- background: var(--mint-error-bg);
4422
- }
4423
-
4424
- .mint-jobs-tray__clear-row {
4425
- justify-content: flex-end;
4426
- padding: 0.5rem 0.75rem;
4427
- border-bottom: 1px solid var(--border-light);
4597
+ .mint-jobs-tray__detail--error {
4598
+ color: var(--_ink-error);
4428
4599
  }
4429
4600
 
4430
4601
  .mint-jobs-tray button:disabled {
@@ -4432,12 +4603,10 @@ button, input, select, textarea {
4432
4603
  cursor: not-allowed;
4433
4604
  }
4434
4605
 
4435
- /* Overlays fade in 180ms; no lift or scale (v2). */
4606
+ /* Overlays fade in; no lift or scale (v2). */
4436
4607
  .mint-jobs-tray-fade-enter-active,
4437
- .mint-jobs-tray-fade-leave-active,
4438
- .mint-jobs-tray-slide-enter-active,
4439
- .mint-jobs-tray-slide-leave-active {
4440
- transition: opacity 180ms ease;
4608
+ .mint-jobs-tray-fade-leave-active {
4609
+ transition: opacity 150ms ease;
4441
4610
  }
4442
4611
 
4443
4612
  .mint-jobs-tray-fade-enter-from,
@@ -4445,31 +4614,6 @@ button, input, select, textarea {
4445
4614
  opacity: 0;
4446
4615
  }
4447
4616
 
4448
- .mint-jobs-tray-slide-enter-from,
4449
- .mint-jobs-tray-slide-leave-to {
4450
- opacity: 0;
4451
- }
4452
-
4453
- @keyframes mint-jobs-tray-pulse {
4454
- 50% { opacity: 0.55; }
4455
- }
4456
-
4457
- @media (max-width: 480px) {
4458
- .mint-jobs-tray {
4459
- right: max(1rem, env(safe-area-inset-right));
4460
- bottom: max(1rem, env(safe-area-inset-bottom));
4461
- }
4462
-
4463
- .mint-jobs-tray__panel {
4464
- position: fixed;
4465
- right: 1rem;
4466
- bottom: 4.75rem;
4467
- left: 1rem;
4468
- width: auto;
4469
- max-height: calc(100vh - 6.75rem - env(safe-area-inset-bottom));
4470
- }
4471
- }
4472
-
4473
4617
  @media (prefers-reduced-motion: reduce) {
4474
4618
  .mint-jobs-tray *,
4475
4619
  .mint-jobs-tray *::before,
@@ -4481,29 +4625,79 @@ button, input, select, textarea {
4481
4625
  }
4482
4626
  }
4483
4627
 
4628
+ /* The tray's confirm dialog sits above the tray and its scrim (BaseModal drops class fallthrough). */
4629
+ .mint-modal:has(.mint-jobs-tray__confirm) {
4630
+ z-index: calc(var(--mint-z-tray) + 1);
4631
+ }
4632
+ /* The handle is the gap between two panels: its layout width (horizontal: height)
4633
+ is the gap, --mint-layout-resize-gap or else --mint-gutter (8px compact, 12px
4634
+ normal). It stretches along the panels, and its bar and a 12px hit area are
4635
+ centred in it, the hit area drawn above the neighbouring panels. */
4484
4636
  .mint-layout-resize-handle {
4485
- display: flex;
4486
- flex-shrink: 0;
4487
- align-items: center;
4488
- justify-content: center;
4637
+ --_size: var(--mint-layout-resize-gap, var(--mint-gutter, 0.75rem));
4638
+ --_hit: 0.75rem;
4639
+ position: relative;
4640
+ z-index: 10;
4641
+ flex: 0 0 auto;
4642
+ align-self: stretch;
4489
4643
  background: transparent;
4490
4644
  cursor: col-resize;
4645
+ outline: none;
4646
+ }
4647
+
4648
+ .mint-layout-resize-handle--vertical {
4649
+ justify-self: center;
4650
+ width: var(--_size);
4651
+ min-height: 2.75rem;
4652
+ }
4653
+
4654
+ .mint-layout-resize-handle--horizontal {
4655
+ justify-self: stretch;
4656
+ min-width: 2.75rem;
4657
+ height: var(--_size);
4658
+ cursor: row-resize;
4659
+ }
4660
+
4661
+ /* Hit area and focus ring. Pointer events on it go to the handle. */
4662
+ .mint-layout-resize-handle::before {
4663
+ position: absolute;
4664
+ border-radius: var(--radius-sm);
4665
+ content: '';
4666
+ }
4667
+
4668
+ .mint-layout-resize-handle--vertical::before {
4669
+ top: 0;
4670
+ bottom: 0;
4671
+ left: 50%;
4672
+ width: var(--_hit);
4673
+ transform: translateX(-50%);
4674
+ }
4675
+
4676
+ .mint-layout-resize-handle--horizontal::before {
4677
+ top: 50%;
4678
+ right: 0;
4679
+ left: 0;
4680
+ height: var(--_hit);
4681
+ transform: translateY(-50%);
4491
4682
  }
4492
4683
 
4493
- .mint-layout-resize-handle--vertical { width: 1rem; min-height: 2.75rem; }
4494
- .mint-layout-resize-handle--horizontal { min-width: 2.75rem; height: 1rem; cursor: row-resize; }
4684
+ /* Edge handles lie outside the edge and cover exactly the gap. */
4495
4685
  .mint-layout-resize-handle--edge-left,
4496
- .mint-layout-resize-handle--edge-right { position: absolute; top: 0; bottom: 0; z-index: 10; height: auto; }
4686
+ .mint-layout-resize-handle--edge-right { position: absolute; top: 0; bottom: 0; }
4497
4687
  .mint-layout-resize-handle--edge-left { left: 0; transform: translateX(-100%); }
4498
4688
  .mint-layout-resize-handle--edge-right { right: 0; transform: translateX(100%); }
4499
4689
 
4500
4690
  .mint-layout-resize-handle__bar {
4691
+ position: absolute;
4692
+ top: 50%;
4693
+ left: 50%;
4501
4694
  display: block;
4502
4695
  width: 0.25rem;
4503
4696
  height: 2.75rem;
4504
4697
  border-radius: 999px;
4505
4698
  background: var(--border-color);
4506
4699
  opacity: 0.72;
4700
+ transform: translate(-50%, -50%);
4507
4701
  transition: background-color 150ms ease, opacity 150ms ease, transform 150ms ease;
4508
4702
  }
4509
4703
 
@@ -4519,29 +4713,25 @@ button, input, select, textarea {
4519
4713
  }
4520
4714
 
4521
4715
  .mint-layout-resize-handle--vertical:hover .mint-layout-resize-handle__bar,
4522
- .mint-layout-resize-handle--vertical:focus-visible .mint-layout-resize-handle__bar { transform: scaleX(1.35); }
4716
+ .mint-layout-resize-handle--vertical:focus-visible .mint-layout-resize-handle__bar { transform: translate(-50%, -50%) scaleX(1.35); }
4523
4717
  .mint-layout-resize-handle--horizontal:hover .mint-layout-resize-handle__bar,
4524
- .mint-layout-resize-handle--horizontal:focus-visible .mint-layout-resize-handle__bar { transform: scaleY(1.35); }
4718
+ .mint-layout-resize-handle--horizontal:focus-visible .mint-layout-resize-handle__bar { transform: translate(-50%, -50%) scaleY(1.35); }
4525
4719
 
4526
- .mint-layout-resize-handle:focus-visible {
4720
+ .mint-layout-resize-handle:focus-visible::before {
4527
4721
  outline: 2px solid var(--color-primary);
4528
- outline-offset: 2px;
4722
+ outline-offset: -2px;
4529
4723
  }
4530
4724
 
4531
- .mint-layout-resize-handle--edge-left:focus-visible,
4532
- .mint-layout-resize-handle--edge-right:focus-visible { outline-offset: -2px; }
4533
-
4534
4725
  .mint-layout-resize-handle[aria-disabled='true'] { cursor: not-allowed; opacity: 0.5; }
4535
4726
 
4536
4727
  @media (prefers-reduced-motion: reduce) {
4537
4728
  .mint-layout-resize-handle__bar { transition: none; }
4538
4729
  }
4539
4730
 
4731
+ /* Touch: the handle reserves its full 2.75rem hit area in the layout. */
4540
4732
  @media (pointer: coarse) {
4541
- .mint-layout-resize-handle--vertical { width: 2.75rem; }
4542
- .mint-layout-resize-handle--horizontal { height: 2.75rem; }
4733
+ .mint-layout-resize-handle { --_size: 2.75rem; --_hit: 2.75rem; }
4543
4734
  }
4544
-
4545
4735
  /* BaseInput Component Styles */
4546
4736
 
4547
4737
  .mint-input {
@@ -4711,7 +4901,7 @@ button, input, select, textarea {
4711
4901
  .mint-modal {
4712
4902
  position: fixed;
4713
4903
  inset: 0;
4714
- z-index: 50;
4904
+ z-index: var(--mint-z-modal);
4715
4905
  display: flex;
4716
4906
  padding: 1rem;
4717
4907
  }
@@ -4815,7 +5005,7 @@ button, input, select, textarea {
4815
5005
  width: 2.5rem;
4816
5006
  height: 3px;
4817
5007
  background-color: var(--border-color);
4818
- border-radius: 9999px;
5008
+ border-radius: var(--radius-sm);
4819
5009
  margin: 0.5rem auto 0;
4820
5010
  flex-shrink: 0;
4821
5011
  }
@@ -4863,7 +5053,7 @@ button, input, select, textarea {
4863
5053
  width: 1.75rem;
4864
5054
  height: 1.75rem;
4865
5055
  padding: 0;
4866
- border-radius: 0.4375rem;
5056
+ border-radius: var(--radius-md);
4867
5057
  color: var(--text-secondary);
4868
5058
  background: none;
4869
5059
  border: none;
@@ -5477,7 +5667,7 @@ button, input, select, textarea {
5477
5667
  /* Horizontal padding matches BaseInput canonical scale (10/12/16) so FormField's
5478
5668
  12px label indent aligns with the numeric text across all input types. */
5479
5669
  .mint-number-input__input--sm { padding: 0.25rem 0.625rem; font-size: 0.8125rem; }
5480
- .mint-number-input__input--md { padding: 0.375rem 0.75rem; font-size: 0.75rem; }
5670
+ .mint-number-input__input--md { padding: 0.375rem 0.75rem; font-size: 0.875rem; }
5481
5671
  .mint-number-input__input--lg { padding: 0.5rem 1rem; font-size: 1rem; }
5482
5672
 
5483
5673
  /* ---------- Unit suffix ---------- */
@@ -5493,54 +5683,423 @@ button, input, select, textarea {
5493
5683
  white-space: nowrap;
5494
5684
  }
5495
5685
 
5496
- /* ---------- Steppers — always visible, stacked (increase on top), hairline-divided ---------- */
5686
+ /* ---------- Steppers — always visible, stacked (increase on top), hairline-divided ---------- */
5687
+
5688
+ .mint-number-input__steppers {
5689
+ display: flex;
5690
+ flex-direction: column-reverse; /* markup is decrease, increase */
5691
+ flex-shrink: 0;
5692
+ width: 22px;
5693
+ border-left: 1px solid var(--border-color);
5694
+ }
5695
+
5696
+ .mint-number-input__stepper {
5697
+ display: flex;
5698
+ flex: 1;
5699
+ align-items: center;
5700
+ justify-content: center;
5701
+ padding: 0;
5702
+ background: var(--bg-primary);
5703
+ color: var(--text-muted);
5704
+ border: none;
5705
+ cursor: pointer;
5706
+ transition: background-color var(--mint-transition), color var(--mint-transition);
5707
+ }
5708
+
5709
+ .mint-number-input__stepper--down {
5710
+ border-top: 1px solid var(--border-color);
5711
+ }
5712
+
5713
+ .mint-number-input__stepper:hover:not(:disabled) {
5714
+ background: var(--bg-hover);
5715
+ color: var(--text-primary);
5716
+ }
5717
+
5718
+ .mint-number-input__stepper:disabled {
5719
+ color: var(--text-muted);
5720
+ opacity: 0.45;
5721
+ cursor: not-allowed;
5722
+ }
5723
+
5724
+ .mint-number-input__stepper svg {
5725
+ width: 0.75rem;
5726
+ height: 0.75rem;
5727
+ }
5728
+
5729
+ @media (prefers-reduced-motion: reduce) {
5730
+ .mint-number-input__field,
5731
+ .mint-number-input__wash,
5732
+ .mint-number-input__rule,
5733
+ .mint-number-input__stepper {
5734
+ transition: none;
5735
+ }
5736
+ }
5737
+
5738
+ /* Onboarding: the top-bar Help button and checklist chip, the Help panel,
5739
+ * the tour layer (scrim, hole, card) and the what's-new dots. */
5740
+
5741
+ :root {
5742
+ --mint-onboarding-scrim: rgba(15, 23, 42, 0.45);
5743
+ }
5744
+
5745
+ html.dark {
5746
+ --mint-onboarding-scrim: rgba(2, 6, 23, 0.62);
5747
+ }
5748
+
5749
+ /* ---- Top bar ---- */
5750
+
5751
+ .mint-onboarding-help {
5752
+ position: relative;
5753
+ display: inline-flex;
5754
+ align-items: center;
5755
+ gap: 0.375rem;
5756
+ }
5757
+
5758
+ .mint-topbar__settings-btn--open {
5759
+ background: var(--color-primary-soft);
5760
+ color: var(--_ink-primary);
5761
+ }
5762
+
5763
+ .mint-onboarding-help__chip {
5764
+ display: inline-flex;
5765
+ align-items: center;
5766
+ gap: 0.375rem;
5767
+ height: 2rem;
5768
+ padding: 0 0.625rem;
5769
+ border: 1px solid var(--border-color);
5770
+ border-radius: var(--radius-md);
5771
+ background: transparent;
5772
+ color: var(--text-primary);
5773
+ font: 500 0.8125rem/1 var(--font-sans);
5774
+ white-space: nowrap;
5775
+ cursor: pointer;
5776
+ transition: background-color var(--mint-transition), border-color var(--mint-transition);
5777
+ }
5778
+
5779
+ .mint-onboarding-help__chip:hover {
5780
+ background: var(--bg-hover);
5781
+ }
5782
+
5783
+ .mint-onboarding-help__chip--open {
5784
+ border-color: var(--color-primary);
5785
+ background: var(--color-primary-soft);
5786
+ color: var(--_ink-primary);
5787
+ }
5788
+
5789
+ .mint-onboarding-help__chip:focus-visible {
5790
+ outline: none;
5791
+ box-shadow: var(--focus-ring-offset);
5792
+ }
5793
+
5794
+ .mint-onboarding-help__count {
5795
+ color: var(--text-muted);
5796
+ font: 500 0.75rem/1 var(--font-mono);
5797
+ }
5798
+
5799
+ .mint-onboarding-help__bar {
5800
+ width: 1.75rem;
5801
+ height: 3px;
5802
+ border-radius: 2px;
5803
+ background: var(--bg-tertiary);
5804
+ overflow: hidden;
5805
+ }
5806
+
5807
+ .mint-onboarding-help__bar > span {
5808
+ display: block;
5809
+ height: 100%;
5810
+ background: var(--color-primary);
5811
+ transition: width var(--mint-transition);
5812
+ }
5813
+
5814
+ .mint-onboarding-help__badge {
5815
+ position: absolute;
5816
+ top: -4px;
5817
+ right: -4px;
5818
+ min-width: 16px;
5819
+ height: 16px;
5820
+ padding: 0 4px;
5821
+ box-sizing: border-box;
5822
+ border-radius: 8px;
5823
+ background: var(--color-primary);
5824
+ color: var(--text-on-accent);
5825
+ font: 600 11px/16px var(--font-sans);
5826
+ text-align: center;
5827
+ box-shadow: 0 0 0 2px var(--bg-card);
5828
+ }
5829
+
5830
+ /* ---- Help panel ---- */
5831
+
5832
+ .mint-onboarding-help__panel {
5833
+ position: fixed;
5834
+ z-index: var(--mint-z-tray);
5835
+ width: 18rem;
5836
+ padding: 0 0 4px;
5837
+ overflow: hidden;
5838
+ }
5839
+
5840
+ .mint-onboarding-help__header {
5841
+ display: flex;
5842
+ align-items: center;
5843
+ justify-content: space-between;
5844
+ padding: 0.75rem 0.75rem 0.5rem;
5845
+ }
5846
+
5847
+ .mint-onboarding-help__heading {
5848
+ color: var(--text-secondary);
5849
+ font-size: 0.6875rem;
5850
+ font-weight: 600;
5851
+ }
5852
+
5853
+ .mint-onboarding-help__progress {
5854
+ height: 3px;
5855
+ margin: 0 0.75rem 0.25rem;
5856
+ border-radius: 2px;
5857
+ background: var(--bg-tertiary);
5858
+ overflow: hidden;
5859
+ }
5860
+
5861
+ .mint-onboarding-help__progress > span {
5862
+ display: block;
5863
+ height: 100%;
5864
+ background: var(--color-primary);
5865
+ transition: width var(--mint-transition);
5866
+ }
5867
+
5868
+ .mint-onboarding-help__todos {
5869
+ margin: 0;
5870
+ padding: 0;
5871
+ list-style: none;
5872
+ }
5873
+
5874
+ .mint-onboarding-help__todo {
5875
+ display: grid;
5876
+ grid-template-columns: 1rem 1fr auto;
5877
+ align-items: center;
5878
+ gap: 0.5rem;
5879
+ min-height: 1.875rem;
5880
+ padding: 0 0.75rem;
5881
+ color: var(--text-primary);
5882
+ font-size: 0.8125rem;
5883
+ }
5884
+
5885
+ .mint-onboarding-help__check {
5886
+ display: grid;
5887
+ place-items: center;
5888
+ width: 1rem;
5889
+ height: 1rem;
5890
+ box-sizing: border-box;
5891
+ border: 1.5px solid var(--border-color);
5892
+ border-radius: 50%;
5893
+ }
5894
+
5895
+ .mint-onboarding-help__todo--done .mint-onboarding-help__check {
5896
+ border: 0;
5897
+ background: var(--color-primary);
5898
+ color: var(--text-on-accent);
5899
+ }
5900
+
5901
+ .mint-onboarding-help__todo--done .mint-onboarding-help__todo-title {
5902
+ color: var(--text-muted);
5903
+ }
5904
+
5905
+ .mint-onboarding-help__link {
5906
+ padding: 0;
5907
+ border: 0;
5908
+ background: transparent;
5909
+ color: var(--_ink-primary);
5910
+ font-size: 0.75rem;
5911
+ font-weight: 500;
5912
+ white-space: nowrap;
5913
+ cursor: pointer;
5914
+ }
5915
+
5916
+ .mint-onboarding-help__link:hover {
5917
+ text-decoration: underline;
5918
+ }
5919
+
5920
+ .mint-onboarding-help__link:focus-visible {
5921
+ outline: none;
5922
+ border-radius: var(--radius-sm);
5923
+ box-shadow: var(--focus-ring-offset);
5924
+ }
5925
+
5926
+ .mint-onboarding-help__hide {
5927
+ display: block;
5928
+ text-align: left;
5929
+ margin: 0.25rem 0.75rem 0.5rem;
5930
+ color: var(--text-secondary);
5931
+ }
5932
+
5933
+ .mint-onboarding-help__section {
5934
+ padding: 0.625rem 0.75rem 0.25rem;
5935
+ border-top: 1px solid var(--border-color);
5936
+ color: var(--text-secondary);
5937
+ font-size: 0.6875rem;
5938
+ font-weight: 600;
5939
+ }
5940
+
5941
+ .mint-onboarding-help__icon {
5942
+ width: 0.8125rem;
5943
+ height: 0.8125rem;
5944
+ flex-shrink: 0;
5945
+ color: var(--text-muted);
5946
+ }
5947
+
5948
+ .mint-onboarding-help__panel > .mint-menu-item {
5949
+ width: calc(100% - 8px);
5950
+ margin: 0 4px;
5951
+ }
5952
+
5953
+ .mint-onboarding-help__new {
5954
+ margin-left: auto;
5955
+ padding: 3px 4px;
5956
+ border-radius: var(--radius-sm);
5957
+ background: var(--color-primary);
5958
+ color: var(--text-on-accent);
5959
+ font-size: 0.6875rem;
5960
+ font-weight: 600;
5961
+ line-height: 1;
5962
+ }
5963
+
5964
+ /* ---- Tour layer ---- */
5965
+
5966
+ .mint-onboarding {
5967
+ position: fixed;
5968
+ inset: 0;
5969
+ z-index: var(--mint-z-tour);
5970
+ pointer-events: none;
5971
+ }
5972
+
5973
+ /* Takes every click outside the card. An advanceOn 'click' step cuts the hole out of it. */
5974
+ .mint-onboarding__blocker {
5975
+ position: absolute;
5976
+ inset: 0;
5977
+ pointer-events: auto;
5978
+ }
5979
+
5980
+ .mint-onboarding__hole {
5981
+ position: fixed;
5982
+ border-radius: var(--radius-lg);
5983
+ box-shadow: 0 0 0 2px var(--color-primary), 0 0 0 9999px var(--mint-onboarding-scrim);
5984
+ pointer-events: none;
5985
+ transition: left 200ms ease, top 200ms ease, width 200ms ease, height 200ms ease;
5986
+ }
5987
+
5988
+ .mint-onboarding__card {
5989
+ position: fixed;
5990
+ display: grid;
5991
+ gap: 0.5rem;
5992
+ box-sizing: border-box;
5993
+ width: 17rem;
5994
+ max-width: calc(100vw - 24px);
5995
+ padding: 0.875rem;
5996
+ border: 1px solid var(--border-color);
5997
+ border-radius: var(--radius-lg);
5998
+ background: var(--bg-card);
5999
+ box-shadow: var(--shadow-lg);
6000
+ color: var(--text-primary);
6001
+ pointer-events: auto;
6002
+ }
6003
+
6004
+ .mint-onboarding__card:focus {
6005
+ outline: none;
6006
+ }
6007
+
6008
+ .mint-onboarding__close {
6009
+ position: absolute;
6010
+ top: 0.5rem;
6011
+ right: 0.5rem;
6012
+ display: grid;
6013
+ place-items: center;
6014
+ width: 1.5rem;
6015
+ height: 1.5rem;
6016
+ padding: 0;
6017
+ border: 0;
6018
+ border-radius: var(--radius);
6019
+ background: transparent;
6020
+ color: var(--text-muted);
6021
+ cursor: pointer;
6022
+ }
6023
+
6024
+ .mint-onboarding__close:hover {
6025
+ background: var(--bg-hover);
6026
+ color: var(--text-primary);
6027
+ }
6028
+
6029
+ .mint-onboarding__close:focus-visible {
6030
+ outline: none;
6031
+ box-shadow: var(--focus-ring-offset);
6032
+ }
6033
+
6034
+ .mint-onboarding__title {
6035
+ margin: 0;
6036
+ padding-right: 1.5rem;
6037
+ font-size: 0.875rem;
6038
+ font-weight: 600;
6039
+ }
5497
6040
 
5498
- .mint-number-input__steppers {
5499
- display: flex;
5500
- flex-direction: column-reverse; /* markup is decrease, increase */
5501
- flex-shrink: 0;
5502
- width: 22px;
5503
- border-left: 1px solid var(--border-color);
6041
+ .mint-onboarding__body {
6042
+ margin: 0;
6043
+ color: var(--text-secondary);
6044
+ font-size: 0.8125rem;
6045
+ line-height: 1.45;
5504
6046
  }
5505
6047
 
5506
- .mint-number-input__stepper {
6048
+ .mint-onboarding__footer {
5507
6049
  display: flex;
5508
- flex: 1;
5509
6050
  align-items: center;
5510
- justify-content: center;
5511
- padding: 0;
5512
- background: var(--bg-primary);
5513
- color: var(--text-muted);
5514
- border: none;
5515
- cursor: pointer;
5516
- transition: background-color var(--mint-transition), color var(--mint-transition);
6051
+ justify-content: flex-end;
6052
+ gap: 0.375rem;
6053
+ margin-top: 0.25rem;
5517
6054
  }
5518
6055
 
5519
- .mint-number-input__stepper--down {
5520
- border-top: 1px solid var(--border-color);
6056
+ .mint-onboarding__count {
6057
+ color: var(--text-muted);
6058
+ font: 500 0.75rem/1.5rem var(--font-mono);
6059
+ margin-top: -0.375rem;
5521
6060
  }
5522
6061
 
5523
- .mint-number-input__stepper:hover:not(:disabled) {
5524
- background: var(--bg-hover);
5525
- color: var(--text-primary);
6062
+ /* Read by screen readers only. */
6063
+ .mint-onboarding__sr {
6064
+ position: absolute;
6065
+ width: 1px;
6066
+ height: 1px;
6067
+ overflow: hidden;
6068
+ clip-path: inset(50%);
6069
+ white-space: nowrap;
5526
6070
  }
5527
6071
 
5528
- .mint-number-input__stepper:disabled {
6072
+ .mint-onboarding__hint {
6073
+ margin-right: auto;
5529
6074
  color: var(--text-muted);
5530
- opacity: 0.45;
5531
- cursor: not-allowed;
6075
+ font-size: 0.75rem;
5532
6076
  }
5533
6077
 
5534
- .mint-number-input__stepper svg {
5535
- width: 0.75rem;
5536
- height: 0.75rem;
6078
+ /* A dot at the top-right corner of an element with unseen news. */
6079
+ .mint-onboarding__dot {
6080
+ position: fixed;
6081
+ z-index: 40;
6082
+ width: 8px;
6083
+ height: 8px;
6084
+ padding: 0;
6085
+ border: 0;
6086
+ border-radius: 50%;
6087
+ background: var(--color-primary);
6088
+ box-shadow: 0 0 0 2px var(--bg-card);
6089
+ transform: translate(-50%, -50%);
6090
+ cursor: pointer;
6091
+ }
6092
+
6093
+ .mint-onboarding__dot:focus-visible {
6094
+ outline: none;
6095
+ box-shadow: var(--focus-ring-offset);
5537
6096
  }
5538
6097
 
5539
6098
  @media (prefers-reduced-motion: reduce) {
5540
- .mint-number-input__field,
5541
- .mint-number-input__wash,
5542
- .mint-number-input__rule,
5543
- .mint-number-input__stepper {
6099
+ .mint-onboarding-help__chip,
6100
+ .mint-onboarding-help__bar > span,
6101
+ .mint-onboarding-help__progress > span,
6102
+ .mint-onboarding__hole {
5544
6103
  transition: none;
5545
6104
  }
5546
6105
  }
@@ -6282,6 +6841,11 @@ button, input, select, textarea {
6282
6841
  */
6283
6842
 
6284
6843
  .mint-section-card {
6844
+ /* The left grid that the header and the rows share: header icon (or row
6845
+ lead) width, then this gap. Set --mint-section-card-gap on the card to
6846
+ change both. */
6847
+ --mint-section-card-lead-width: 1rem;
6848
+ --mint-section-card-gap: 0.625rem;
6285
6849
  display: flex;
6286
6850
  flex-direction: column;
6287
6851
  border-radius: var(--radius-lg);
@@ -6307,10 +6871,12 @@ button, input, select, textarea {
6307
6871
  .mint-section-card__header {
6308
6872
  display: flex;
6309
6873
  align-items: center;
6310
- gap: 0.625rem;
6874
+ gap: var(--mint-section-card-gap);
6311
6875
  box-sizing: border-box;
6312
6876
  min-height: 2.5rem;
6313
- padding: 0.375rem 0.625rem 0.375rem 0.75rem;
6877
+ /* 4px block padding: a 28px header control plus padding plus the 1px rule
6878
+ stays inside the 40px strip (6px made it 41px). */
6879
+ padding: 0.25rem 0.625rem 0.25rem 0.75rem;
6314
6880
  border-bottom: 1px solid var(--border-color);
6315
6881
  flex-shrink: 0;
6316
6882
  }
@@ -6325,8 +6891,8 @@ button, input, select, textarea {
6325
6891
  align-items: center;
6326
6892
  justify-content: center;
6327
6893
  flex-shrink: 0;
6328
- width: 1rem;
6329
- height: 1rem;
6894
+ width: var(--mint-section-card-lead-width);
6895
+ height: var(--mint-section-card-lead-width);
6330
6896
  color: var(--text-muted);
6331
6897
  }
6332
6898
 
@@ -6386,12 +6952,27 @@ button, input, select, textarea {
6386
6952
  .mint-section-card__row {
6387
6953
  display: flex;
6388
6954
  align-items: center;
6389
- gap: 0.625rem;
6955
+ gap: var(--mint-section-card-gap);
6390
6956
  padding: 0.375rem 0.75rem;
6391
6957
  background: var(--bg-secondary);
6392
6958
  transition: background-color var(--mint-transition);
6393
6959
  }
6394
6960
 
6961
+ /* Leading glyph slot of a row: as wide as the header icon, so the glyph
6962
+ * centres under it and the row text starts at the header title. Leave it
6963
+ * empty to keep the text on the grid. It is one title line high (1lh at the
6964
+ * title size), so a two-line row keeps its glyph on the first line. */
6965
+ .mint-section-card__row-lead {
6966
+ display: inline-flex;
6967
+ align-items: center;
6968
+ justify-content: center;
6969
+ flex-shrink: 0;
6970
+ align-self: flex-start;
6971
+ width: var(--mint-section-card-lead-width);
6972
+ height: 1lh;
6973
+ font-size: 0.8125rem;
6974
+ }
6975
+
6395
6976
  a.mint-section-card__row,
6396
6977
  button.mint-section-card__row {
6397
6978
  cursor: pointer;
@@ -6407,12 +6988,14 @@ button.mint-section-card__row:hover {
6407
6988
  /* Comfortable density gives the header and rows back their height. */
6408
6989
  [data-density="comfortable"] .mint-section-card__header {
6409
6990
  min-height: 2.75rem;
6410
- padding: 0.5rem 0.75rem 0.5rem 0.875rem;
6991
+ padding: 0.25rem 0.75rem 0.25rem 0.875rem;
6411
6992
  }
6412
6993
 
6413
6994
  [data-density="comfortable"] .mint-section-card__row {
6414
6995
  padding-top: 0.5rem;
6415
6996
  padding-bottom: 0.5rem;
6997
+ /* Same left inset as the header, so row content lines up under the header. */
6998
+ padding-left: 0.875rem;
6416
6999
  }
6417
7000
 
6418
7001
  /* SecretInput — plugin secret settings field with a set / not set / environment status.
@@ -6594,14 +7177,10 @@ button.mint-section-card__row:hover {
6594
7177
  .mint-searchable-select__value { flex: 1; min-width: 0; overflow: hidden; text-align: left; text-overflow: ellipsis; white-space: nowrap; }
6595
7178
  .mint-searchable-select__value--placeholder { color: var(--text-muted); }
6596
7179
 
6597
- /* Surface = .mint-popover (2d); this alias keeps only placement. */
7180
+ /* Surface = .mint-popover (2d). useFloatingPanel sets the fixed position and width. */
6598
7181
  .mint-searchable-select__panel {
6599
- position: absolute;
6600
- top: calc(100% + 0.25rem);
6601
- right: 0;
6602
- left: 0;
6603
- z-index: 30;
6604
- max-height: min(38rem, 80vh);
7182
+ z-index: var(--mint-z-popover);
7183
+ max-height: min(38rem, 80vh, var(--mint-floating-available-height, 100vh));
6605
7184
  overflow: hidden;
6606
7185
  }
6607
7186
 
@@ -7190,7 +7769,7 @@ button.mint-section-card__row:hover {
7190
7769
  /* AppTopBar publishes its bottom edge + 1rem so toasts clear its controls. */
7191
7770
  top: var(--mint-toast-offset-top, 1rem);
7192
7771
  right: 1rem;
7193
- z-index: 9999;
7772
+ z-index: var(--mint-z-toast);
7194
7773
  display: flex;
7195
7774
  flex-direction: column;
7196
7775
  gap: 0.5rem;
@@ -7921,26 +8500,69 @@ html.dark .mint-toast__item {
7921
8500
  box-sizing: border-box;
7922
8501
  border-bottom: 1px solid var(--border-light);
7923
8502
  font-size: 0.8125rem;
8503
+ /* The header compacts when it is narrow (sidebars); see the query below. */
8504
+ container-type: inline-size;
7924
8505
  }
7925
8506
 
7926
8507
  .mint-sample-selector__title {
8508
+ flex-shrink: 0;
8509
+ white-space: nowrap;
7927
8510
  font-weight: 600;
7928
8511
  color: var(--text-primary);
7929
8512
  }
7930
8513
 
7931
8514
  .mint-sample-selector__selected {
8515
+ /* Without the query (or with a long count) the count gives way, never the row. */
8516
+ min-width: 0;
8517
+ overflow: hidden;
8518
+ text-overflow: ellipsis;
8519
+ white-space: nowrap;
7932
8520
  font-size: 0.75rem;
7933
8521
  font-weight: 500;
7934
8522
  color: var(--text-muted);
7935
8523
  }
7936
8524
 
7937
8525
  .mint-sample-selector__header-actions {
8526
+ flex-shrink: 0;
7938
8527
  display: flex;
7939
8528
  align-items: center;
7940
8529
  gap: 0.125rem;
7941
8530
  margin-left: auto;
7942
8531
  }
7943
8532
 
8533
+ .mint-sample-selector__selected-short {
8534
+ display: none;
8535
+ }
8536
+
8537
+ /* Narrow selector: the header stays one row and keeps its height. The grouping
8538
+ button shows only its icon (the label stays its accessible name and tooltip)
8539
+ and the count shortens to "N sel." (screen readers keep "N selected"). */
8540
+ /* Measured: the full row (title, "N selected", Smart group, Clear groups) needs
8541
+ about 17.55rem of header content width with Fira Sans. */
8542
+ @container (max-width: 17.625rem) {
8543
+ .mint-sample-selector__group-btn .mint-button__label,
8544
+ .mint-sample-selector__selected-full {
8545
+ position: absolute;
8546
+ width: 1px;
8547
+ height: 1px;
8548
+ margin: -1px;
8549
+ padding: 0;
8550
+ overflow: hidden;
8551
+ clip: rect(0, 0, 0, 0);
8552
+ white-space: nowrap;
8553
+ border: 0;
8554
+ }
8555
+
8556
+ .mint-sample-selector__selected-short {
8557
+ display: inline;
8558
+ }
8559
+
8560
+ .mint-sample-selector__group-btn {
8561
+ min-width: var(--form-height-sm);
8562
+ padding-inline: 0.25rem;
8563
+ }
8564
+ }
8565
+
7944
8566
  .mint-sample-selector__grouped,
7945
8567
  .mint-sample-selector__flat,
7946
8568
  .mint-sample-selector__state {
@@ -11204,7 +11826,7 @@ html.dark .mint-pill--soft {
11204
11826
  }
11205
11827
 
11206
11828
  .mint-dataframe__row:last-child .mint-dataframe__td {
11207
- border-bottom: none;
11829
+ border-bottom: none !important;
11208
11830
  }
11209
11831
 
11210
11832
  /* Empty / error placeholder host (content comes from EmptyState) */
@@ -11421,12 +12043,12 @@ html.dark .mint-dataframe__loading {
11421
12043
  .mint-well-edit-popup__backdrop {
11422
12044
  position: fixed;
11423
12045
  inset: 0;
11424
- z-index: 40;
12046
+ z-index: calc(var(--mint-z-popover) - 1);
11425
12047
  }
11426
12048
 
11427
12049
  .mint-well-edit-popup {
11428
12050
  position: fixed;
11429
- z-index: 50;
12051
+ z-index: var(--mint-z-popover);
11430
12052
  width: 300px;
11431
12053
  padding: 0;
11432
12054
  overflow: hidden;
@@ -11763,13 +12385,13 @@ html.dark .mint-dataframe__loading {
11763
12385
  }
11764
12386
 
11765
12387
  /* ========================================================================
11766
- Rail variant (default) — single filled track, pill ends
12388
+ Rail variant (default) — single filled track, square-ish ends (v2: no capsules)
11767
12389
  ======================================================================== */
11768
12390
 
11769
12391
  .mint-progress__track {
11770
12392
  width: 100%;
11771
12393
  background-color: var(--bg-tertiary);
11772
- border-radius: 9999px; /* pill ends — spec */
12394
+ border-radius: var(--radius-sm);
11773
12395
  overflow: hidden;
11774
12396
  }
11775
12397
 
@@ -11779,7 +12401,7 @@ html.dark .mint-dataframe__loading {
11779
12401
 
11780
12402
  .mint-progress__bar {
11781
12403
  height: 100%;
11782
- border-radius: 9999px;
12404
+ border-radius: var(--radius-sm);
11783
12405
  transition: width 0.3s ease;
11784
12406
  }
11785
12407
 
@@ -12299,8 +12921,8 @@ html.dark .mint-dataframe__loading {
12299
12921
  }
12300
12922
 
12301
12923
  .mint-tooltip__content {
12302
- position: absolute;
12303
- z-index: 9999;
12924
+ position: fixed;
12925
+ z-index: var(--mint-z-toast);
12304
12926
  display: inline-flex;
12305
12927
  align-items: center;
12306
12928
  gap: 0.5rem;
@@ -12835,6 +13457,12 @@ html.dark .mint-stale-banner {
12835
13457
  border-bottom-color: var(--border-color);
12836
13458
  }
12837
13459
 
13460
+ /* The pane ends after the last group's last row: no closing hairline there,
13461
+ it would sit on the footer rule with nothing between them. */
13462
+ .mint-settings-modal__group:last-of-type > .mint-settings-modal__group-grid > .mint-settings-modal__row:last-child {
13463
+ border-bottom: none;
13464
+ }
13465
+
12838
13466
  /* The field cell anchors the ↺ reset, which sits just left of the control (5d).
12839
13467
  --_settings-control-w is the control's width; stacked fields (text, custom slots)
12840
13468
  keep 0 and put the reset at the right end of their label line. */
@@ -13453,10 +14081,9 @@ html.dark .mint-stale-banner {
13453
14081
  .mint-settings-modal__density-preview {
13454
14082
  --_density-row: 2.125rem;
13455
14083
 
14084
+ /* A hairline table in the setting row, not a bordered box inside the modal. */
13456
14085
  grid-column: 1 / -1;
13457
14086
  overflow: hidden;
13458
- border: 1px solid var(--border-color);
13459
- border-radius: var(--radius-md);
13460
14087
  font-size: 0.75rem;
13461
14088
  }
13462
14089
 
@@ -14271,7 +14898,7 @@ button.mint-unit-input__unit:focus-visible {
14271
14898
 
14272
14899
  .mint-unit-input__menu {
14273
14900
  position: fixed;
14274
- z-index: 1000;
14901
+ z-index: var(--mint-z-popover);
14275
14902
  width: 148px;
14276
14903
  }
14277
14904
 
@@ -15058,13 +15685,10 @@ button.mint-unit-input__unit:focus-visible {
15058
15685
  height: 0.875rem;
15059
15686
  }
15060
15687
 
15061
- /* Dropdown — placement only; the look is .mint-popover. Spans the field width. */
15688
+ /* Dropdown — the look is .mint-popover; useFloatingPanel sets the fixed position and the field width. */
15062
15689
  .mint-time-picker__dropdown {
15063
- position: absolute;
15064
- z-index: 50;
15065
- margin-top: 0.25rem;
15066
- width: 100%;
15067
- min-width: 100%;
15690
+ z-index: var(--mint-z-popover);
15691
+ max-height: var(--mint-floating-available-height, none);
15068
15692
  overflow: hidden;
15069
15693
  }
15070
15694
 
@@ -15247,12 +15871,12 @@ button.mint-unit-input__unit:focus-visible {
15247
15871
  color: var(--text-muted);
15248
15872
  }
15249
15873
 
15250
- /* Dropdown — placement only; the look is .mint-popover. */
15874
+ /* Dropdown — the look is .mint-popover; useFloatingPanel sets the fixed position. */
15251
15875
  .mint-datetime-picker__dropdown {
15252
- position: absolute;
15253
- z-index: 50;
15254
- margin-top: 0.25rem;
15876
+ z-index: var(--mint-z-popover);
15255
15877
  width: 18rem;
15878
+ max-height: var(--mint-floating-available-height, none);
15879
+ overflow-y: auto;
15256
15880
  padding: 0.625rem;
15257
15881
  }
15258
15882
 
@@ -16663,13 +17287,26 @@ button.mint-unit-input__unit:focus-visible {
16663
17287
  }
16664
17288
 
16665
17289
  /* Footer with clear selection */
17290
+ .mint-experiment-selector__description {
17291
+ padding: 0 1.25rem 0.75rem;
17292
+ font-size: 0.8125rem;
17293
+ color: var(--text-secondary);
17294
+ }
17295
+
16666
17296
  .mint-experiment-selector__footer {
16667
17297
  display: flex;
17298
+ align-items: center;
17299
+ gap: 0.75rem;
16668
17300
  justify-content: flex-start;
16669
17301
  padding: 0.5rem 1.25rem 0.75rem;
16670
17302
  border-top: 1px solid var(--border-light);
16671
17303
  }
16672
17304
 
17305
+ .mint-experiment-selector__footer-slot {
17306
+ flex: 1;
17307
+ min-width: 0;
17308
+ }
17309
+
16673
17310
  .mint-experiment-selector__clear-btn {
16674
17311
  padding: 0.25rem 0;
16675
17312
  border: none;
@@ -17210,54 +17847,79 @@ button.mint-unit-input__unit:focus-visible {
17210
17847
  animation: none;
17211
17848
  }
17212
17849
  }
17213
- /* AppTopBar page selector — left-side route/page dropdown.
17214
- Trigger speaks the field language (5a): 36px (the identity tile height), hover changes the background
17215
- only, open = field focus, inline 12px chevron. The menu keeps the 1.2 panel
17216
- (own card, tinted active row) rather than .mint-popover + .mint-menu-item. */
17850
+ /* AppTopBar page selector — design v2 option C: "<plugin> / <page>" as one switcher.
17851
+ The crumb holds the plugin name, a slash and the tinted 32px trigger. The menu keeps its own
17852
+ card (not .mint-popover): a "<plugin> pages" title, then one row per page with its hint and number key. */
17853
+
17854
+ /* Shrinks with the bar: the plugin name and the page label truncate instead of overlapping the nav. */
17855
+ .mint-page-selector__crumb {
17856
+ display: inline-flex;
17857
+ align-items: center;
17858
+ gap: 0.375rem;
17859
+ min-width: 0;
17860
+ flex-shrink: 1;
17861
+ }
17862
+
17863
+ .mint-page-selector__plugin {
17864
+ min-width: 0;
17865
+ font-size: 0.875rem;
17866
+ font-weight: 600;
17867
+ color: var(--text-primary);
17868
+ white-space: nowrap;
17869
+ overflow: hidden;
17870
+ text-overflow: ellipsis;
17871
+ }
17872
+
17873
+ .mint-page-selector__slash {
17874
+ flex-shrink: 0;
17875
+ font-size: 1.125rem;
17876
+ font-weight: 300;
17877
+ line-height: 1;
17878
+ color: var(--text-muted);
17879
+ }
17217
17880
 
17218
- /* Shrinks down to its inline min-width (11.25rem) so a crowded bar truncates the label instead of overlapping the nav. */
17881
+ /* Anchors the menu under the trigger, not under the plugin name. */
17219
17882
  .mint-page-selector {
17220
17883
  position: relative;
17221
- flex-shrink: 1;
17884
+ display: flex;
17885
+ min-width: 0;
17222
17886
  }
17223
17887
 
17224
17888
  .mint-page-selector__trigger {
17225
17889
  display: inline-flex;
17226
17890
  align-items: center;
17227
- gap: 0.5rem;
17228
- width: 100%;
17229
- height: 2.25rem;
17230
- padding: 0 0.5rem 0 0.4375rem;
17231
- border: 1px solid var(--border-color);
17232
- background: var(--bg-card);
17891
+ gap: 0.375rem;
17892
+ min-width: 0;
17893
+ max-width: 100%;
17894
+ height: 2rem;
17895
+ padding: 0 0.5rem 0 0.375rem;
17896
+ border: 0;
17897
+ background: var(--color-primary-soft);
17233
17898
  color: var(--text-primary);
17234
17899
  border-radius: var(--radius-md);
17235
17900
  font-size: 0.8125rem;
17236
- font-weight: 500;
17901
+ font-weight: 600;
17237
17902
  font-family: inherit;
17238
17903
  cursor: pointer;
17239
17904
  transition:
17240
17905
  background-color var(--mint-transition),
17241
- border-color var(--mint-transition),
17242
17906
  box-shadow var(--mint-transition);
17243
17907
  }
17244
17908
 
17245
- .mint-page-selector__trigger:hover:not(.mint-page-selector__trigger--open) {
17246
- background: var(--bg-hover);
17909
+ .mint-page-selector__trigger:hover {
17910
+ background: color-mix(in srgb, var(--color-primary) 16%, transparent);
17247
17911
  }
17248
17912
 
17249
- .mint-page-selector__trigger:focus-visible,
17250
- .mint-page-selector__trigger--open {
17913
+ .mint-page-selector__trigger:focus-visible {
17251
17914
  outline: none;
17252
- border-color: var(--color-primary);
17253
- box-shadow: var(--focus-ring-soft);
17915
+ box-shadow: var(--focus-ring-offset);
17254
17916
  }
17255
17917
 
17256
17918
  /* Page icon tile is neutral; the plugin carries the color. */
17257
17919
  .mint-page-selector__icon {
17258
17920
  width: 1.25rem;
17259
17921
  height: 1.25rem;
17260
- border-radius: var(--radius-sm);
17922
+ border-radius: var(--radius);
17261
17923
  background: var(--bg-tertiary);
17262
17924
  color: var(--text-secondary-strong);
17263
17925
  display: grid;
@@ -17278,7 +17940,7 @@ button.mint-unit-input__unit:focus-visible {
17278
17940
  .mint-page-selector__trigger-metadata-icon.mint-plugin-icon--sm {
17279
17941
  width: 1.25rem;
17280
17942
  height: 1.25rem;
17281
- border-radius: var(--radius-sm);
17943
+ border-radius: var(--radius);
17282
17944
  }
17283
17945
 
17284
17946
  .mint-page-selector__icon-fallback {
@@ -17288,7 +17950,6 @@ button.mint-unit-input__unit:focus-visible {
17288
17950
  }
17289
17951
 
17290
17952
  .mint-page-selector__label {
17291
- flex: 1;
17292
17953
  min-width: 0;
17293
17954
  text-align: left;
17294
17955
  white-space: nowrap;
@@ -17296,7 +17957,6 @@ button.mint-unit-input__unit:focus-visible {
17296
17957
  text-overflow: ellipsis;
17297
17958
  }
17298
17959
 
17299
- /* The chevron sits inline; the wrap no longer draws a tile. */
17300
17960
  .mint-page-selector__chevron-wrap {
17301
17961
  display: inline-flex;
17302
17962
  color: var(--text-secondary);
@@ -17313,38 +17973,46 @@ button.mint-unit-input__unit:focus-visible {
17313
17973
  transform: rotate(180deg);
17314
17974
  }
17315
17975
 
17976
+ /* max-height: 8 two-line hint rows (8 x 68px) + title (~25px) + padding (8px) = ~577px; a 9th row scrolls. A short window caps it. */
17316
17977
  .mint-page-selector__menu {
17317
17978
  position: absolute;
17979
+ box-sizing: border-box;
17318
17980
  top: calc(100% + 0.375rem);
17319
17981
  left: 0;
17320
- width: 16.25rem;
17982
+ width: 18.75rem;
17983
+ max-height: min(36.25rem, calc(100vh - 6rem));
17984
+ overflow-y: auto;
17321
17985
  background: var(--bg-card);
17322
17986
  border: 1px solid var(--border-color);
17323
17987
  border-radius: var(--radius-lg);
17324
17988
  box-shadow: var(--shadow-md);
17325
- padding: 0.375rem;
17989
+ padding: 0.25rem;
17326
17990
  z-index: 50;
17327
17991
  }
17328
17992
 
17993
+ /* The mockup's 10px uppercase eyebrow breaks rules 2a (no uppercase) and 8d (UI text >= 11px): 11px, sentence case. */
17329
17994
  .mint-page-selector__menu-title {
17330
- padding: 0.375rem 0.625rem 0.5rem;
17331
- font-size: 0.75rem;
17995
+ padding: 0.375rem 0.5rem 0.25rem;
17996
+ font-family: var(--font-mono);
17997
+ font-size: 0.6875rem;
17332
17998
  font-weight: 500;
17333
- color: var(--text-secondary);
17999
+ letter-spacing: 0.06em;
18000
+ color: var(--text-muted);
17334
18001
  }
17335
18002
 
17336
18003
  .mint-page-selector__item {
17337
18004
  display: flex;
17338
- align-items: center;
18005
+ box-sizing: border-box;
18006
+ align-items: flex-start;
17339
18007
  gap: 0.625rem;
17340
18008
  width: 100%;
17341
- padding: 0.5rem 0.625rem;
18009
+ padding: 0.5rem;
17342
18010
  border: 0;
17343
18011
  background: transparent;
17344
- border-radius: 0.4375rem;
18012
+ border-radius: var(--radius);
17345
18013
  color: var(--text-primary);
17346
18014
  font-size: 0.8125rem;
17347
- font-weight: 500;
18015
+ line-height: 1.4;
17348
18016
  font-family: inherit;
17349
18017
  text-align: left;
17350
18018
  text-decoration: none;
@@ -17352,13 +18020,22 @@ button.mint-unit-input__unit:focus-visible {
17352
18020
  transition: background-color var(--mint-transition);
17353
18021
  }
17354
18022
 
17355
- .mint-page-selector__item:hover:not(.mint-page-selector__item--disabled) {
18023
+ /* A row without a hint has one line: centre it on the icon tile. */
18024
+ .mint-page-selector__item:not(:has(.mint-page-selector__item-hint)) {
18025
+ align-items: center;
18026
+ }
18027
+
18028
+ .mint-page-selector__item:hover:not(.mint-page-selector__item--disabled):not(.mint-page-selector__item--active) {
17356
18029
  background: var(--bg-hover);
17357
18030
  }
17358
18031
 
18032
+ .mint-page-selector__item:focus-visible {
18033
+ outline: 2px solid var(--color-primary);
18034
+ outline-offset: -2px;
18035
+ }
18036
+
17359
18037
  .mint-page-selector__item--active {
17360
- background: var(--bg-tertiary);
17361
- font-weight: 600;
18038
+ background: var(--color-primary-soft);
17362
18039
  }
17363
18040
 
17364
18041
  .mint-page-selector__item--disabled {
@@ -17367,9 +18044,9 @@ button.mint-unit-input__unit:focus-visible {
17367
18044
  }
17368
18045
 
17369
18046
  .mint-page-selector__item-icon {
17370
- width: 1.375rem;
17371
- height: 1.375rem;
17372
- border-radius: 0.3125rem;
18047
+ width: 1.75rem;
18048
+ height: 1.75rem;
18049
+ border-radius: var(--radius-md);
17373
18050
  background: var(--bg-tertiary);
17374
18051
  color: var(--text-secondary);
17375
18052
  display: grid;
@@ -17377,6 +18054,10 @@ button.mint-unit-input__unit:focus-visible {
17377
18054
  flex-shrink: 0;
17378
18055
  }
17379
18056
 
18057
+ .mint-page-selector__item-icon .mint-page-selector__icon-fallback {
18058
+ font-size: 0.8125rem;
18059
+ }
18060
+
17380
18061
  .mint-page-selector__item--active .mint-page-selector__item-icon {
17381
18062
  background: var(--color-primary-soft);
17382
18063
  color: var(--color-primary);
@@ -17389,24 +18070,55 @@ button.mint-unit-input__unit:focus-visible {
17389
18070
  }
17390
18071
 
17391
18072
  .mint-page-selector__item-icon svg {
17392
- width: 0.8125rem;
17393
- height: 0.8125rem;
18073
+ width: 0.9375rem;
18074
+ height: 0.9375rem;
17394
18075
  }
17395
18076
 
17396
18077
  .mint-page-selector__metadata-icon.mint-plugin-icon--sm {
17397
- width: 1.375rem;
17398
- height: 1.375rem;
17399
- border-radius: 0.3125rem;
18078
+ width: 1.75rem;
18079
+ height: 1.75rem;
18080
+ border-radius: var(--radius-md);
17400
18081
  }
17401
18082
 
17402
- .mint-page-selector__item-label {
18083
+ .mint-page-selector__item-text {
17403
18084
  flex: 1;
17404
18085
  min-width: 0;
18086
+ display: grid;
18087
+ gap: 1px;
18088
+ }
18089
+
18090
+ .mint-page-selector__item-label {
18091
+ font-weight: 600;
17405
18092
  overflow: hidden;
17406
18093
  text-overflow: ellipsis;
17407
18094
  white-space: nowrap;
17408
18095
  }
17409
18096
 
18097
+ /* --_ink-primary is --color-primary-hover in light mode and stays legible in dark mode. */
18098
+ .mint-page-selector__item--active .mint-page-selector__item-label {
18099
+ color: var(--_ink-primary);
18100
+ }
18101
+
18102
+ .mint-page-selector__item-hint {
18103
+ font-size: 0.75rem;
18104
+ line-height: 1.35;
18105
+ color: var(--text-secondary);
18106
+ }
18107
+
18108
+ /* 11px, the rule 8d floor (the mockup has 10.5px). */
18109
+ .mint-page-selector__item-key {
18110
+ flex-shrink: 0;
18111
+ margin-top: 0.125rem;
18112
+ padding: 0 0.25rem;
18113
+ border: 1px solid var(--border-color);
18114
+ border-radius: var(--radius);
18115
+ font-family: var(--font-mono);
18116
+ font-size: 0.6875rem;
18117
+ font-weight: 500;
18118
+ line-height: 1rem;
18119
+ color: var(--text-muted);
18120
+ }
18121
+
17410
18122
  @media (prefers-reduced-motion: reduce) {
17411
18123
  .mint-page-selector__trigger,
17412
18124
  .mint-page-selector__chevron {