@conduction/nextcloud-vue 2.62.0 → 2.64.0

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 (209) hide show
  1. package/dist/esm/components/CnAdminActionCard/CnAdminActionCard.vue.js +10 -0
  2. package/dist/esm/components/CnAdminActionCard/CnAdminActionCard.vue.js.map +1 -0
  3. package/dist/esm/components/CnAdminActionCard/CnAdminActionCard.vue2.js +189 -0
  4. package/dist/esm/components/CnAdminActionCard/CnAdminActionCard.vue2.js.map +1 -0
  5. package/dist/esm/components/CnAdminActionCard/CnAdminActionCard.vue3.js +72 -0
  6. package/dist/esm/components/CnAdminActionCard/CnAdminActionCard.vue3.js.map +1 -0
  7. package/dist/esm/components/CnAppNav/CnAppNav.vue2.js +425 -39
  8. package/dist/esm/components/CnAppNav/CnAppNav.vue2.js.map +1 -1
  9. package/dist/esm/components/CnAppNav/CnAppNav.vue3.js +119 -42
  10. package/dist/esm/components/CnAppNav/CnAppNav.vue3.js.map +1 -1
  11. package/dist/esm/components/CnAppRoot/CnAppRoot.vue2.js +186 -9
  12. package/dist/esm/components/CnAppRoot/CnAppRoot.vue2.js.map +1 -1
  13. package/dist/esm/components/CnAppRoot/CnAppRoot.vue3.js +65 -42
  14. package/dist/esm/components/CnAppRoot/CnAppRoot.vue3.js.map +1 -1
  15. package/dist/esm/components/CnAuditTrailCard/CnAuditTrailCard.vue2.js +61 -16
  16. package/dist/esm/components/CnAuditTrailCard/CnAuditTrailCard.vue2.js.map +1 -1
  17. package/dist/esm/components/CnAuditTrailCard/CnAuditTrailCard.vue3.js.map +1 -1
  18. package/dist/esm/components/CnAuditTrailWidget/CnAuditTrailWidget.vue2.js +20 -0
  19. package/dist/esm/components/CnAuditTrailWidget/CnAuditTrailWidget.vue2.js.map +1 -1
  20. package/dist/esm/components/CnAuditTrailWidget/CnAuditTrailWidget.vue3.js +3 -2
  21. package/dist/esm/components/CnAuditTrailWidget/CnAuditTrailWidget.vue3.js.map +1 -1
  22. package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue2.js +33 -2
  23. package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue2.js.map +1 -1
  24. package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue3.js.map +1 -1
  25. package/dist/esm/components/CnChoiceCards/CnChoiceCards.vue2.js.map +1 -1
  26. package/dist/esm/components/CnChoiceCards/CnChoiceCards.vue3.js +53 -37
  27. package/dist/esm/components/CnChoiceCards/CnChoiceCards.vue3.js.map +1 -1
  28. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js +29 -0
  29. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js.map +1 -1
  30. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js +152 -135
  31. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js.map +1 -1
  32. package/dist/esm/components/CnDataTable/CnColumnFilterPopover.vue.js +10 -0
  33. package/dist/esm/components/CnDataTable/CnColumnFilterPopover.vue.js.map +1 -0
  34. package/dist/esm/components/CnDataTable/CnColumnFilterPopover.vue2.js +293 -0
  35. package/dist/esm/components/CnDataTable/CnColumnFilterPopover.vue2.js.map +1 -0
  36. package/dist/esm/components/CnDataTable/CnColumnFilterPopover.vue3.js +189 -0
  37. package/dist/esm/components/CnDataTable/CnColumnFilterPopover.vue3.js.map +1 -0
  38. package/dist/esm/components/CnDataTable/CnDataTable.vue2.js +253 -9
  39. package/dist/esm/components/CnDataTable/CnDataTable.vue2.js.map +1 -1
  40. package/dist/esm/components/CnDataTable/CnDataTable.vue3.js +126 -50
  41. package/dist/esm/components/CnDataTable/CnDataTable.vue3.js.map +1 -1
  42. package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js +66 -14
  43. package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js.map +1 -1
  44. package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js +23 -14
  45. package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js.map +1 -1
  46. package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue2.js.map +1 -1
  47. package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue3.js +2 -1
  48. package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue3.js.map +1 -1
  49. package/dist/esm/components/CnFieldHelper/CnFieldHelper.vue2.js +3 -1
  50. package/dist/esm/components/CnFieldHelper/CnFieldHelper.vue2.js.map +1 -1
  51. package/dist/esm/components/CnFieldHelper/CnFieldHelper.vue3.js +1 -1
  52. package/dist/esm/components/CnFieldHelper/CnFieldHelper.vue3.js.map +1 -1
  53. package/dist/esm/components/CnFormDialog/CnFormDialog.vue2.js +234 -9
  54. package/dist/esm/components/CnFormDialog/CnFormDialog.vue2.js.map +1 -1
  55. package/dist/esm/components/CnFormDialog/CnFormDialog.vue3.js +96 -57
  56. package/dist/esm/components/CnFormDialog/CnFormDialog.vue3.js.map +1 -1
  57. package/dist/esm/components/CnHeaderWidget/CnHeaderWidget.vue2.js +81 -4
  58. package/dist/esm/components/CnHeaderWidget/CnHeaderWidget.vue2.js.map +1 -1
  59. package/dist/esm/components/CnHeaderWidget/CnHeaderWidget.vue3.js +22 -5
  60. package/dist/esm/components/CnHeaderWidget/CnHeaderWidget.vue3.js.map +1 -1
  61. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +81 -2
  62. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
  63. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js +7 -3
  64. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
  65. package/dist/esm/components/CnIndexPage/selfModeActions.js +3 -3
  66. package/dist/esm/components/CnIndexPage/selfModeActions.js.map +1 -1
  67. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue2.js +41 -2
  68. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue2.js.map +1 -1
  69. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue3.js +8 -3
  70. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue3.js.map +1 -1
  71. package/dist/esm/components/CnResourceSelect/CnResourceSelect.vue2.js +121 -12
  72. package/dist/esm/components/CnResourceSelect/CnResourceSelect.vue2.js.map +1 -1
  73. package/dist/esm/components/CnResourceSelect/CnResourceSelect.vue3.js +3 -1
  74. package/dist/esm/components/CnResourceSelect/CnResourceSelect.vue3.js.map +1 -1
  75. package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue2.js +326 -1
  76. package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue2.js.map +1 -1
  77. package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue3.js +112 -26
  78. package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue3.js.map +1 -1
  79. package/dist/esm/components/CnStagesWidget/CnStagesWidget.vue2.js +63 -2
  80. package/dist/esm/components/CnStagesWidget/CnStagesWidget.vue2.js.map +1 -1
  81. package/dist/esm/components/CnStagesWidget/CnStagesWidget.vue3.js +96 -37
  82. package/dist/esm/components/CnStagesWidget/CnStagesWidget.vue3.js.map +1 -1
  83. package/dist/esm/components/CnStagesWidget/stagesModel.js +5 -2
  84. package/dist/esm/components/CnStagesWidget/stagesModel.js.map +1 -1
  85. package/dist/esm/components/CnStatWidget/CnStatWidget.vue2.js +52 -2
  86. package/dist/esm/components/CnStatWidget/CnStatWidget.vue2.js.map +1 -1
  87. package/dist/esm/components/CnStatWidget/CnStatWidget.vue3.js +6 -6
  88. package/dist/esm/components/CnStatWidget/CnStatWidget.vue3.js.map +1 -1
  89. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue2.js +14 -2
  90. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue2.js.map +1 -1
  91. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue3.js +2 -1
  92. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue3.js.map +1 -1
  93. package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue.js +10 -0
  94. package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue.js.map +1 -0
  95. package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue2.js +337 -0
  96. package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue2.js.map +1 -0
  97. package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue3.js +102 -0
  98. package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue3.js.map +1 -0
  99. package/dist/esm/components/CnTimelineWidget/dashboardRegistration.js +34 -0
  100. package/dist/esm/components/CnTimelineWidget/dashboardRegistration.js.map +1 -0
  101. package/dist/esm/components/CnWalkthrough/CnWalkthrough.vue2.js +131 -8
  102. package/dist/esm/components/CnWalkthrough/CnWalkthrough.vue2.js.map +1 -1
  103. package/dist/esm/components/CnWalkthrough/CnWalkthrough.vue3.js +40 -38
  104. package/dist/esm/components/CnWalkthrough/CnWalkthrough.vue3.js.map +1 -1
  105. package/dist/esm/components/CnWidgetGrid/builtInWidgets.js +8 -6
  106. package/dist/esm/components/CnWidgetGrid/builtInWidgets.js.map +1 -1
  107. package/dist/esm/components/CnWidgetGrid/registerDashboardWidgets.js +1 -0
  108. package/dist/esm/components/CnWidgetGrid/registerDashboardWidgets.js.map +1 -1
  109. package/dist/esm/components/CnWidgetWrapper/CnWidgetWrapper.vue2.js +73 -1
  110. package/dist/esm/components/CnWidgetWrapper/CnWidgetWrapper.vue2.js.map +1 -1
  111. package/dist/esm/components/CnWidgetWrapper/CnWidgetWrapper.vue3.js +14 -2
  112. package/dist/esm/components/CnWidgetWrapper/CnWidgetWrapper.vue3.js.map +1 -1
  113. package/dist/esm/components/CnWizardDialog/CnWizardDialog.vue2.js +19 -0
  114. package/dist/esm/components/CnWizardDialog/CnWizardDialog.vue2.js.map +1 -1
  115. package/dist/esm/components/CnWizardDialog/CnWizardDialog.vue3.js +1 -1
  116. package/dist/esm/components/CnWizardDialog/CnWizardDialog.vue3.js.map +1 -1
  117. package/dist/esm/composables/useDependencyCheck.js +65 -0
  118. package/dist/esm/composables/useDependencyCheck.js.map +1 -0
  119. package/dist/esm/composables/useWalkthrough.js +218 -6
  120. package/dist/esm/composables/useWalkthrough.js.map +1 -1
  121. package/dist/esm/index.js +2 -0
  122. package/dist/esm/index.js.map +1 -1
  123. package/dist/esm/l10n/en.json.js +45 -1
  124. package/dist/esm/l10n/en.json.js.map +1 -1
  125. package/dist/esm/l10n/nl.json.js +45 -1
  126. package/dist/esm/l10n/nl.json.js.map +1 -1
  127. package/dist/esm/nextcloud-vue.css +780 -81
  128. package/dist/esm/store/useObjectStore.js +8 -0
  129. package/dist/esm/store/useObjectStore.js.map +1 -1
  130. package/dist/esm/utils/columnFilters.js +311 -0
  131. package/dist/esm/utils/columnFilters.js.map +1 -0
  132. package/dist/esm/utils/groupAutocomplete.js +123 -0
  133. package/dist/esm/utils/groupAutocomplete.js.map +1 -0
  134. package/dist/esm/utils/libraryWidgetKeys.js +2 -0
  135. package/dist/esm/utils/libraryWidgetKeys.js.map +1 -1
  136. package/dist/esm/utils/pickerOptions.js +198 -0
  137. package/dist/esm/utils/pickerOptions.js.map +1 -0
  138. package/dist/esm/utils/schema.js +83 -7
  139. package/dist/esm/utils/schema.js.map +1 -1
  140. package/dist/esm/utils/schemaRefSlug.js +19 -3
  141. package/dist/esm/utils/schemaRefSlug.js.map +1 -1
  142. package/dist/esm/utils/timelineEvents.js +174 -0
  143. package/dist/esm/utils/timelineEvents.js.map +1 -0
  144. package/dist/esm/utils/validateManifestV2.compiled.js +2 -2
  145. package/dist/esm/utils/validateManifestV2.compiled.js.map +1 -1
  146. package/dist/esm/utils/walkthroughSignals.js +88 -0
  147. package/dist/esm/utils/walkthroughSignals.js.map +1 -0
  148. package/dist/nextcloud-vue.cjs.js +13088 -7937
  149. package/dist/nextcloud-vue.cjs.js.map +2 -2
  150. package/dist/nextcloud-vue.css +780 -81
  151. package/l10n/en.json +45 -0
  152. package/l10n/nl.json +45 -0
  153. package/package.json +1 -1
  154. package/src/components/CnAdminActionCard/CnAdminActionCard.vue +234 -0
  155. package/src/components/CnAdminActionCard/index.js +4 -0
  156. package/src/components/CnAppNav/CnAppNav.vue +568 -43
  157. package/src/components/CnAppRoot/CnAppRoot.md +4 -0
  158. package/src/components/CnAppRoot/CnAppRoot.vue +223 -16
  159. package/src/components/CnAuditTrailCard/CnAuditTrailCard.vue +61 -16
  160. package/src/components/CnAuditTrailWidget/CnAuditTrailWidget.vue +22 -1
  161. package/src/components/CnCellRenderer/CnCellRenderer.vue +33 -2
  162. package/src/components/CnChoiceCards/CnChoiceCards.vue +56 -31
  163. package/src/components/CnDashboardPage/CnDashboardPage.vue +45 -4
  164. package/src/components/CnDataTable/CnColumnFilterPopover.vue +524 -0
  165. package/src/components/CnDataTable/CnDataTable.md +3 -0
  166. package/src/components/CnDataTable/CnDataTable.vue +305 -5
  167. package/src/components/CnDetailPage/CnDetailPage.md +4 -0
  168. package/src/components/CnDetailPage/CnDetailPage.vue +60 -1
  169. package/src/components/CnDetailWidgetHost/CnDetailWidgetHost.vue +2 -2
  170. package/src/components/CnFieldHelper/CnFieldHelper.vue +4 -2
  171. package/src/components/CnFormDialog/CnFormDialog.vue +290 -31
  172. package/src/components/CnHeaderWidget/CnHeaderWidget.vue +116 -6
  173. package/src/components/CnIndexPage/CnIndexPage.vue +87 -4
  174. package/src/components/CnIndexPage/selfModeActions.js +3 -3
  175. package/src/components/CnObjectListWidget/CnObjectListWidget.vue +46 -2
  176. package/src/components/CnResourceSelect/CnResourceSelect.vue +123 -12
  177. package/src/components/CnSetupWizard/CnSetupWizard.vue +392 -3
  178. package/src/components/CnStagesWidget/CnStagesWidget.vue +180 -2
  179. package/src/components/CnStagesWidget/stagesModel.js +5 -2
  180. package/src/components/CnStatWidget/CnStatWidget.vue +57 -3
  181. package/src/components/CnTabsWidget/CnTabsWidget.vue +15 -2
  182. package/src/components/CnTimelineWidget/CnTimelineWidget.vue +477 -0
  183. package/src/components/CnTimelineWidget/dashboardRegistration.js +32 -0
  184. package/src/components/CnTimelineWidget/index.js +4 -0
  185. package/src/components/CnWalkthrough/CnWalkthrough.vue +143 -10
  186. package/src/components/CnWidgetGrid/builtInWidgets.js +2 -0
  187. package/src/components/CnWidgetGrid/registerDashboardWidgets.js +1 -0
  188. package/src/components/CnWidgetWrapper/CnWidgetWrapper.md +4 -0
  189. package/src/components/CnWidgetWrapper/CnWidgetWrapper.vue +107 -1
  190. package/src/components/CnWizardDialog/CnWizardDialog.vue +20 -1
  191. package/src/components/index.js +2 -0
  192. package/src/composables/useDependencyCheck.js +61 -0
  193. package/src/composables/useWalkthrough.js +217 -5
  194. package/src/css/dashboard.css +49 -0
  195. package/src/css/detail-page.css +29 -4
  196. package/src/css/kpi-card.css +24 -1
  197. package/src/css/table.css +99 -6
  198. package/src/index.js +2 -0
  199. package/src/schemas/app-manifest-v2.schema.json +135 -3
  200. package/src/store/useObjectStore.js +8 -0
  201. package/src/utils/columnFilters.js +324 -0
  202. package/src/utils/groupAutocomplete.js +119 -0
  203. package/src/utils/libraryWidgetKeys.js +2 -0
  204. package/src/utils/pickerOptions.js +194 -0
  205. package/src/utils/schema.js +83 -7
  206. package/src/utils/schemaRefSlug.js +19 -3
  207. package/src/utils/timelineEvents.js +171 -0
  208. package/src/utils/validateManifestV2.compiled.js +2 -2
  209. package/src/utils/walkthroughSignals.js +94 -0
@@ -185,7 +185,7 @@
185
185
  .cn-data-table th,
186
186
  .cn-data-table td {
187
187
  padding: calc(3 * var(--default-grid-baseline));
188
- text-align: left;
188
+ text-align: start;
189
189
  border-bottom: 1px solid var(--color-border);
190
190
  vertical-align: middle;
191
191
  max-width: var(--cn-table-cell-max-width, 22rem);
@@ -204,6 +204,18 @@
204
204
  white-space: normal;
205
205
  }
206
206
 
207
+ /* The secondary line of a cell (`columns[].secondary`): muted, smaller, on its
208
+ own line under the value. Theme hooks: --cn-table-secondary-size and
209
+ --cn-table-secondary-color. */
210
+ .cn-data-table .cn-table-cell__secondary {
211
+ display: block;
212
+ color: var(--cn-table-secondary-color, var(--color-text-maxcontrast));
213
+ font-size: var(--cn-table-secondary-size, 0.9em);
214
+ line-height: 1.35;
215
+ overflow: hidden;
216
+ text-overflow: ellipsis;
217
+ }
218
+
207
219
  /* Back to wrapping, for a column holding prose rather than a label:
208
220
  `columns: [{ key: 'description', cellClass: 'cn-cell--wrap' }]`. */
209
221
  .cn-data-table th.cn-cell--wrap,
@@ -265,7 +277,7 @@
265
277
  }
266
278
 
267
279
  .cn-data-table td.cn-cell--end {
268
- text-align: right;
280
+ text-align: end;
269
281
  white-space: nowrap;
270
282
  }
271
283
 
@@ -303,7 +315,7 @@
303
315
  }
304
316
 
305
317
  .cn-table-sort-indicator {
306
- margin-left: var(--default-grid-baseline);
318
+ margin-inline-start: var(--default-grid-baseline);
307
319
  opacity: 0.6;
308
320
  }
309
321
 
@@ -325,6 +337,87 @@
325
337
  outline-offset: -2px;
326
338
  }
327
339
 
340
+ /* Header filter button (CnDataTable `filterable`). 24px hit area with the
341
+ 16px icon; the filled icon plus the primary colour marks an active filter,
342
+ so the state never rests on colour alone. */
343
+ .cn-table-header__filter {
344
+ display: inline-flex;
345
+ align-items: center;
346
+ justify-content: center;
347
+ width: 24px;
348
+ min-width: 24px;
349
+ height: 24px;
350
+ min-height: 24px;
351
+ margin: 0 0 0 4px;
352
+ padding: 0;
353
+ border: none;
354
+ border-radius: var(--border-radius, 4px);
355
+ background: transparent;
356
+ color: var(--color-text-maxcontrast);
357
+ vertical-align: middle;
358
+ cursor: pointer;
359
+ }
360
+
361
+ .cn-table-header__filter:hover {
362
+ background-color: var(--color-background-hover);
363
+ color: var(--color-main-text);
364
+ }
365
+
366
+ .cn-table-header__filter:focus-visible {
367
+ outline: 2px solid var(--color-main-text);
368
+ outline-offset: 0;
369
+ }
370
+
371
+ .cn-table-header__filter--active {
372
+ color: var(--color-primary-element);
373
+ }
374
+
375
+ /* Active header filters above the table, one removable chip each. */
376
+ .cn-data-table__filter-chips {
377
+ display: flex;
378
+ flex-wrap: wrap;
379
+ gap: 6px;
380
+ margin: 0 0 8px;
381
+ padding: 0;
382
+ list-style: none;
383
+ }
384
+
385
+ .cn-data-table__filter-chip {
386
+ display: inline-flex;
387
+ align-items: center;
388
+ gap: 4px;
389
+ padding: 2px 4px 2px 10px;
390
+ border: 1px solid var(--color-border-dark);
391
+ border-radius: var(--border-radius-pill, 16px);
392
+ background-color: var(--color-background-dark);
393
+ color: var(--color-main-text);
394
+ }
395
+
396
+ .cn-data-table__filter-chip-remove {
397
+ display: inline-flex;
398
+ align-items: center;
399
+ justify-content: center;
400
+ width: 24px;
401
+ min-width: 24px;
402
+ height: 24px;
403
+ min-height: 24px;
404
+ margin: 0;
405
+ padding: 0;
406
+ border: none;
407
+ border-radius: 50%;
408
+ background: transparent;
409
+ color: var(--color-main-text);
410
+ cursor: pointer;
411
+ }
412
+
413
+ .cn-data-table__filter-chip-remove:hover {
414
+ background-color: var(--color-background-hover);
415
+ }
416
+
417
+ .cn-data-table__filter-chip-remove:focus-visible {
418
+ outline: 2px solid var(--color-main-text);
419
+ }
420
+
328
421
  /* Multi-column sort priority badge (1, 2, 3), rendered only when two or more rendered, sortable columns are sorted. */
329
422
  .cn-table-sort-badge {
330
423
  display: inline-flex;
@@ -332,7 +425,7 @@
332
425
  justify-content: center;
333
426
  min-width: 14px;
334
427
  height: 14px;
335
- margin-left: 2px;
428
+ margin-inline-start: 2px;
336
429
  padding: 0 3px;
337
430
  border-radius: 7px;
338
431
  background-color: var(--color-primary-element);
@@ -397,7 +490,7 @@
397
490
 
398
491
  .cn-table-col--icon {
399
492
  width: 40px;
400
- padding-right: 0;
493
+ padding-inline-end: 0;
401
494
  text-align: center;
402
495
  color: var(--color-text-maxcontrast);
403
496
  }
@@ -460,7 +553,7 @@
460
553
 
461
554
  .viewTable { width: 100%; border-collapse: collapse; background-color: var(--color-main-background); }
462
555
 
463
- .viewTable th, .viewTable td { padding: calc(3 * var(--default-grid-baseline)); text-align: left; border-bottom: 1px solid var(--color-border); vertical-align: middle; }
556
+ .viewTable th, .viewTable td { padding: calc(3 * var(--default-grid-baseline)); text-align: start; border-bottom: 1px solid var(--color-border); vertical-align: middle; }
464
557
 
465
558
  .viewTable th { background: var(--color-background-hover); font-weight: 500; color: var(--color-text-maxcontrast); background-color: var(--color-background-dark); }
466
559
 
@@ -956,7 +1049,7 @@
956
1049
  padding: var(--cn-kpi-padding-flat, 8px);
957
1050
  box-sizing: border-box;
958
1051
  overflow: hidden;
959
- text-align: left;
1052
+ text-align: start;
960
1053
  text-decoration: none;
961
1054
  color: inherit;
962
1055
  background: transparent;
@@ -1071,6 +1164,29 @@
1071
1164
  white-space: nowrap;
1072
1165
  }
1073
1166
 
1167
+ /* A caption coloured by a rule (`captionVariant` / `overrides[].captionVariant`):
1168
+ "1 due today" in the error colour. Foreground tokens, which stay readable in
1169
+ dark mode. */
1170
+ .cn-kpi-card__label--primary {
1171
+ color: var(--color-primary-element);
1172
+ font-weight: 600;
1173
+ }
1174
+
1175
+ .cn-kpi-card__label--success {
1176
+ color: var(--color-text-success, var(--color-success-text));
1177
+ font-weight: 600;
1178
+ }
1179
+
1180
+ .cn-kpi-card__label--warning {
1181
+ color: var(--color-element-warning, var(--color-warning-text));
1182
+ font-weight: 600;
1183
+ }
1184
+
1185
+ .cn-kpi-card__label--error {
1186
+ color: var(--color-text-error, var(--color-error-text));
1187
+ font-weight: 600;
1188
+ }
1189
+
1074
1190
  /* Semantic variants. Each re-points the ONE accent token, so the icon tint
1075
1191
  and the number move together by construction — there is no second place to
1076
1192
  forget. The inline KPI below shares the same modifiers for the same reason:
@@ -2584,6 +2700,55 @@
2584
2700
  .cn-dashboard-list__item:hover {
2585
2701
  background: var(--color-background-hover);
2586
2702
  }
2703
+
2704
+ /* "Install <app>" placeholder in a widget whose app is missing.
2705
+ *
2706
+ * NcEmptyContent centres its content with `justify-content: center`. In a
2707
+ * two-row dashboard tile (about 150px inside an `overflow: hidden` wrapper)
2708
+ * the icon, name, description and button are taller than the tile, and plain
2709
+ * `center` overflows on BOTH sides, so the top ran out of the widget and the
2710
+ * name was cut off. `safe center` falls back to the start edge when the
2711
+ * content does not fit, the spacing is compact, and what still does not fit
2712
+ * scrolls instead of being clipped. Shared by CnDashboardPage and
2713
+ * CnDetailWidgetHost (`cn-requires-app`). The class is doubled to outrank
2714
+ * NcEmptyContent's own scoped rules (`.empty-content[data-v-…]`) whatever
2715
+ * order the stylesheets load in. */
2716
+ .cn-requires-app.cn-requires-app.empty-content,
2717
+ .cn-requires-app.cn-requires-app .empty-content {
2718
+ justify-content: safe center;
2719
+ min-height: 0;
2720
+ max-height: 100%;
2721
+ overflow: auto;
2722
+ margin: 0;
2723
+ padding: calc(2 * var(--default-grid-baseline, 4px));
2724
+ gap: var(--default-grid-baseline, 4px);
2725
+ box-sizing: border-box;
2726
+ }
2727
+
2728
+ .cn-requires-app.cn-requires-app .empty-content__icon {
2729
+ width: auto;
2730
+ height: auto;
2731
+ min-height: 0;
2732
+ margin: 0;
2733
+ opacity: 0.7;
2734
+ }
2735
+
2736
+ .cn-requires-app.cn-requires-app .empty-content__name {
2737
+ margin: 0;
2738
+ font-size: var(--default-font-size, 15px);
2739
+ font-weight: 600;
2740
+ text-align: center;
2741
+ }
2742
+
2743
+ .cn-requires-app.cn-requires-app .empty-content__description {
2744
+ margin: 0;
2745
+ text-align: center;
2746
+ font-size: 0.9em;
2747
+ }
2748
+
2749
+ .cn-requires-app.cn-requires-app .empty-content__action {
2750
+ margin-top: var(--default-grid-baseline, 4px);
2751
+ }
2587
2752
  /* ========================================
2588
2753
  @conduction/nextcloud-vue — CnDetailPage Styles
2589
2754
  ======================================== */
@@ -2594,6 +2759,12 @@
2594
2759
  position: relative;
2595
2760
  }
2596
2761
 
2762
+ /* The breadcrumb line above the header (`config.breadcrumb`). */
2763
+ .cn-detail-page__breadcrumbs {
2764
+ margin-bottom: calc(2 * var(--default-grid-baseline));
2765
+ color: var(--color-text-maxcontrast);
2766
+ }
2767
+
2597
2768
  /* Header */
2598
2769
  .cn-detail-page__header {
2599
2770
  display: flex;
@@ -2692,6 +2863,25 @@
2692
2863
  flex-shrink: 0;
2693
2864
  }
2694
2865
 
2866
+ /* Every control in the header sits on one line at one height. The lifecycle
2867
+ bar carries `margin: 0 0 8px` for its place above a page body; in the
2868
+ header that margin pushed its buttons up and made the row 8px taller, so
2869
+ the Edit button beside it read as the bigger one. A consumer's actions
2870
+ component can bring its own margins too, so they are reset here as well. */
2871
+ .cn-detail-page .cn-detail-page__header-actions .cn-lifecycle-actions {
2872
+ margin: 0;
2873
+ flex-wrap: nowrap;
2874
+ }
2875
+
2876
+ .cn-detail-page .cn-detail-page__header-actions > * {
2877
+ margin-block: 0;
2878
+ }
2879
+
2880
+ .cn-detail-page .cn-detail-page__header-actions .button-vue {
2881
+ min-height: var(--default-clickable-area);
2882
+ block-size: var(--default-clickable-area);
2883
+ }
2884
+
2695
2885
  /* The sentence a refused lock acquire left behind, under the locked banner. */
2696
2886
  .cn-detail-page__lock-refusal {
2697
2887
  margin: 0 0 calc(3 * var(--default-grid-baseline));
@@ -2742,7 +2932,7 @@
2742
2932
 
2743
2933
  .cn-detail-page__stats-table thead th {
2744
2934
  padding: calc(1.5 * var(--default-grid-baseline)) calc(2 * var(--default-grid-baseline));
2745
- text-align: left;
2935
+ text-align: start;
2746
2936
  font-weight: 600;
2747
2937
  font-size: 0.9em;
2748
2938
  color: var(--color-text-maxcontrast);
@@ -2767,7 +2957,7 @@
2767
2957
  }
2768
2958
 
2769
2959
  .cn-detail-page__stats-cell--indented {
2770
- padding-left: calc(5 * var(--default-grid-baseline)) !important;
2960
+ padding-inline-start: calc(5 * var(--default-grid-baseline)) !important;
2771
2961
  }
2772
2962
 
2773
2963
  .cn-detail-page__stats-cell--center {
@@ -2775,7 +2965,7 @@
2775
2965
  }
2776
2966
 
2777
2967
  .cn-detail-page__stats-cell--right {
2778
- text-align: right;
2968
+ text-align: end;
2779
2969
  }
2780
2970
 
2781
2971
  /* Body & content */
@@ -2909,7 +3099,7 @@
2909
3099
 
2910
3100
  .cn-detail-page__sidebar-toggle {
2911
3101
  position: fixed;
2912
- right: calc(5 * var(--default-grid-baseline));
3102
+ inset-inline-end: calc(5 * var(--default-grid-baseline));
2913
3103
  top: 80px;
2914
3104
  z-index: 10;
2915
3105
  }
@@ -5959,6 +6149,101 @@ svg.leaflet-image-layer.leaflet-interactive path {
5959
6149
  }
5960
6150
 
5961
6151
 
6152
+ .cn-column-filter[data-v-2cb54356] {
6153
+ z-index: 10000;
6154
+ display: flex;
6155
+ flex-direction: column;
6156
+ gap: 8px;
6157
+ box-sizing: border-box;
6158
+ max-height: 60vh;
6159
+ overflow-y: auto;
6160
+ padding: 12px;
6161
+ background: var(--color-main-background);
6162
+ color: var(--color-main-text);
6163
+ border: 1px solid var(--color-border-dark);
6164
+ border-radius: var(--border-radius-large, 8px);
6165
+ box-shadow: 0 2px 8px var(--color-box-shadow);
6166
+ font-weight: normal;
6167
+ text-align: start;
6168
+ }
6169
+ .cn-column-filter__heading[data-v-2cb54356] {
6170
+ margin: 0;
6171
+ font-weight: bold;
6172
+ }
6173
+ .cn-column-filter__options[data-v-2cb54356] {
6174
+ display: flex;
6175
+ flex-direction: column;
6176
+ gap: 4px;
6177
+ margin: 0;
6178
+ padding: 0;
6179
+ border: none;
6180
+ }
6181
+ .cn-column-filter__option[data-v-2cb54356] {
6182
+ display: flex;
6183
+ align-items: center;
6184
+ gap: 8px;
6185
+ min-height: 32px;
6186
+ cursor: pointer;
6187
+ }
6188
+ .cn-column-filter__range[data-v-2cb54356] {
6189
+ display: flex;
6190
+ gap: 8px;
6191
+ }
6192
+ .cn-column-filter__field[data-v-2cb54356] {
6193
+ display: flex;
6194
+ flex: 1 1 0;
6195
+ flex-direction: column;
6196
+ gap: 4px;
6197
+ min-width: 0;
6198
+ }
6199
+ .cn-column-filter__label[data-v-2cb54356] {
6200
+ font-size: var(--font-size-small, 13px);
6201
+ color: var(--color-text-maxcontrast);
6202
+ }
6203
+ .cn-column-filter__input[data-v-2cb54356] {
6204
+ width: 100%;
6205
+ box-sizing: border-box;
6206
+ margin: 0;
6207
+ }
6208
+ .cn-column-filter__hint[data-v-2cb54356] {
6209
+ margin: 0;
6210
+ color: var(--color-text-maxcontrast);
6211
+ }
6212
+ .cn-column-filter__actions[data-v-2cb54356] {
6213
+ display: flex;
6214
+ justify-content: flex-end;
6215
+ gap: 8px;
6216
+ }
6217
+ .cn-column-filter__button[data-v-2cb54356] {
6218
+ min-height: 34px;
6219
+ padding: 0 12px;
6220
+ border: 1px solid var(--color-border-dark);
6221
+ border-radius: var(--border-radius-element, 8px);
6222
+ background: var(--color-main-background);
6223
+ color: var(--color-main-text);
6224
+ cursor: pointer;
6225
+ }
6226
+ .cn-column-filter__button--primary[data-v-2cb54356] {
6227
+ border-color: var(--color-primary-element);
6228
+ background: var(--color-primary-element);
6229
+ color: var(--color-primary-element-text);
6230
+ }
6231
+ .cn-column-filter__button[data-v-2cb54356]:focus-visible,
6232
+ .cn-column-filter__input[data-v-2cb54356]:focus-visible,
6233
+ .cn-column-filter__option input[data-v-2cb54356]:focus-visible {
6234
+ outline: 2px solid var(--color-primary-element);
6235
+ outline-offset: 2px;
6236
+ }
6237
+ .cn-column-filter__sr-only[data-v-2cb54356] {
6238
+ position: absolute;
6239
+ width: 1px;
6240
+ height: 1px;
6241
+ overflow: hidden;
6242
+ clip-path: inset(50%);
6243
+ white-space: nowrap;
6244
+ }
6245
+
6246
+
5962
6247
  .cn-fk-resolve-cell[data-v-471db666] {
5963
6248
  white-space: nowrap;
5964
6249
  overflow: hidden;
@@ -6219,7 +6504,7 @@ svg.leaflet-image-layer.leaflet-interactive path {
6219
6504
  .cn-data-table th,
6220
6505
  .cn-data-table td {
6221
6506
  padding: calc(3 * var(--default-grid-baseline));
6222
- text-align: left;
6507
+ text-align: start;
6223
6508
  border-bottom: 1px solid var(--color-border);
6224
6509
  vertical-align: middle;
6225
6510
  max-width: var(--cn-table-cell-max-width, 22rem);
@@ -6238,6 +6523,18 @@ svg.leaflet-image-layer.leaflet-interactive path {
6238
6523
  white-space: normal;
6239
6524
  }
6240
6525
 
6526
+ /* The secondary line of a cell (`columns[].secondary`): muted, smaller, on its
6527
+ own line under the value. Theme hooks: --cn-table-secondary-size and
6528
+ --cn-table-secondary-color. */
6529
+ .cn-data-table .cn-table-cell__secondary {
6530
+ display: block;
6531
+ color: var(--cn-table-secondary-color, var(--color-text-maxcontrast));
6532
+ font-size: var(--cn-table-secondary-size, 0.9em);
6533
+ line-height: 1.35;
6534
+ overflow: hidden;
6535
+ text-overflow: ellipsis;
6536
+ }
6537
+
6241
6538
  /* Back to wrapping, for a column holding prose rather than a label:
6242
6539
  `columns: [{ key: 'description', cellClass: 'cn-cell--wrap' }]`. */
6243
6540
  .cn-data-table th.cn-cell--wrap,
@@ -6299,7 +6596,7 @@ svg.leaflet-image-layer.leaflet-interactive path {
6299
6596
  }
6300
6597
 
6301
6598
  .cn-data-table td.cn-cell--end {
6302
- text-align: right;
6599
+ text-align: end;
6303
6600
  white-space: nowrap;
6304
6601
  }
6305
6602
 
@@ -6337,7 +6634,7 @@ svg.leaflet-image-layer.leaflet-interactive path {
6337
6634
  }
6338
6635
 
6339
6636
  .cn-table-sort-indicator {
6340
- margin-left: var(--default-grid-baseline);
6637
+ margin-inline-start: var(--default-grid-baseline);
6341
6638
  opacity: 0.6;
6342
6639
  }
6343
6640
 
@@ -6359,6 +6656,87 @@ svg.leaflet-image-layer.leaflet-interactive path {
6359
6656
  outline-offset: -2px;
6360
6657
  }
6361
6658
 
6659
+ /* Header filter button (CnDataTable `filterable`). 24px hit area with the
6660
+ 16px icon; the filled icon plus the primary colour marks an active filter,
6661
+ so the state never rests on colour alone. */
6662
+ .cn-table-header__filter {
6663
+ display: inline-flex;
6664
+ align-items: center;
6665
+ justify-content: center;
6666
+ width: 24px;
6667
+ min-width: 24px;
6668
+ height: 24px;
6669
+ min-height: 24px;
6670
+ margin: 0 0 0 4px;
6671
+ padding: 0;
6672
+ border: none;
6673
+ border-radius: var(--border-radius, 4px);
6674
+ background: transparent;
6675
+ color: var(--color-text-maxcontrast);
6676
+ vertical-align: middle;
6677
+ cursor: pointer;
6678
+ }
6679
+
6680
+ .cn-table-header__filter:hover {
6681
+ background-color: var(--color-background-hover);
6682
+ color: var(--color-main-text);
6683
+ }
6684
+
6685
+ .cn-table-header__filter:focus-visible {
6686
+ outline: 2px solid var(--color-main-text);
6687
+ outline-offset: 0;
6688
+ }
6689
+
6690
+ .cn-table-header__filter--active {
6691
+ color: var(--color-primary-element);
6692
+ }
6693
+
6694
+ /* Active header filters above the table, one removable chip each. */
6695
+ .cn-data-table__filter-chips {
6696
+ display: flex;
6697
+ flex-wrap: wrap;
6698
+ gap: 6px;
6699
+ margin: 0 0 8px;
6700
+ padding: 0;
6701
+ list-style: none;
6702
+ }
6703
+
6704
+ .cn-data-table__filter-chip {
6705
+ display: inline-flex;
6706
+ align-items: center;
6707
+ gap: 4px;
6708
+ padding: 2px 4px 2px 10px;
6709
+ border: 1px solid var(--color-border-dark);
6710
+ border-radius: var(--border-radius-pill, 16px);
6711
+ background-color: var(--color-background-dark);
6712
+ color: var(--color-main-text);
6713
+ }
6714
+
6715
+ .cn-data-table__filter-chip-remove {
6716
+ display: inline-flex;
6717
+ align-items: center;
6718
+ justify-content: center;
6719
+ width: 24px;
6720
+ min-width: 24px;
6721
+ height: 24px;
6722
+ min-height: 24px;
6723
+ margin: 0;
6724
+ padding: 0;
6725
+ border: none;
6726
+ border-radius: 50%;
6727
+ background: transparent;
6728
+ color: var(--color-main-text);
6729
+ cursor: pointer;
6730
+ }
6731
+
6732
+ .cn-data-table__filter-chip-remove:hover {
6733
+ background-color: var(--color-background-hover);
6734
+ }
6735
+
6736
+ .cn-data-table__filter-chip-remove:focus-visible {
6737
+ outline: 2px solid var(--color-main-text);
6738
+ }
6739
+
6362
6740
  /* Multi-column sort priority badge (1, 2, 3), rendered only when two or more rendered, sortable columns are sorted. */
6363
6741
  .cn-table-sort-badge {
6364
6742
  display: inline-flex;
@@ -6366,7 +6744,7 @@ svg.leaflet-image-layer.leaflet-interactive path {
6366
6744
  justify-content: center;
6367
6745
  min-width: 14px;
6368
6746
  height: 14px;
6369
- margin-left: 2px;
6747
+ margin-inline-start: 2px;
6370
6748
  padding: 0 3px;
6371
6749
  border-radius: 7px;
6372
6750
  background-color: var(--color-primary-element);
@@ -6431,7 +6809,7 @@ svg.leaflet-image-layer.leaflet-interactive path {
6431
6809
 
6432
6810
  .cn-table-col--icon {
6433
6811
  width: 40px;
6434
- padding-right: 0;
6812
+ padding-inline-end: 0;
6435
6813
  text-align: center;
6436
6814
  color: var(--color-text-maxcontrast);
6437
6815
  }
@@ -6494,7 +6872,7 @@ svg.leaflet-image-layer.leaflet-interactive path {
6494
6872
 
6495
6873
  .viewTable { width: 100%; border-collapse: collapse; background-color: var(--color-main-background); }
6496
6874
 
6497
- .viewTable th, .viewTable td { padding: calc(3 * var(--default-grid-baseline)); text-align: left; border-bottom: 1px solid var(--color-border); vertical-align: middle; }
6875
+ .viewTable th, .viewTable td { padding: calc(3 * var(--default-grid-baseline)); text-align: start; border-bottom: 1px solid var(--color-border); vertical-align: middle; }
6498
6876
 
6499
6877
  .viewTable th { background: var(--color-background-hover); font-weight: 500; color: var(--color-text-maxcontrast); background-color: var(--color-background-dark); }
6500
6878
 
@@ -15141,6 +15519,10 @@ a.cn-xwiki-card__title[data-v-54e85fe3]:hover {
15141
15519
  font-size: 0.9em;
15142
15520
  margin-inline-end: auto;
15143
15521
  }
15522
+ .cn-form-dialog__switch-wrapper[data-v-c3eeb0a2] {
15523
+ display: flex;
15524
+ flex-direction: column;
15525
+ }
15144
15526
  .cn-form-dialog__form[data-v-c3eeb0a2] {
15145
15527
  display: flex;
15146
15528
  flex-direction: column;
@@ -15729,6 +16111,27 @@ a.cn-xwiki-card__title[data-v-54e85fe3]:hover {
15729
16111
  flex-shrink: 0;
15730
16112
  }
15731
16113
 
16114
+ /* The header's text link (`headerLink`). Theme hooks: --cn-widget-header-link-size
16115
+ and --cn-widget-header-link-weight. */
16116
+ .cn-widget-wrapper__header-link[data-v-4dd77f59] {
16117
+ align-self: center;
16118
+ padding: 0 calc(1 * var(--default-grid-baseline));
16119
+ color: var(--color-primary-element);
16120
+ font-size: var(--cn-widget-header-link-size, 14px);
16121
+ font-weight: var(--cn-widget-header-link-weight, 600);
16122
+ text-decoration: none;
16123
+ white-space: nowrap;
16124
+ }
16125
+ .cn-widget-wrapper__header-link[data-v-4dd77f59]:hover,
16126
+ .cn-widget-wrapper__header-link[data-v-4dd77f59]:focus-visible {
16127
+ text-decoration: underline;
16128
+ }
16129
+ .cn-widget-wrapper__header-link[data-v-4dd77f59]:focus-visible {
16130
+ outline: 2px solid var(--color-primary-element);
16131
+ outline-offset: 2px;
16132
+ border-radius: var(--border-radius-small, 4px);
16133
+ }
16134
+
15732
16135
  /* Every widget's header icon is coloured — `--cn-widget-icon-color` is set on
15733
16136
  the header from titleIconStyle, and defaults to the theme colour if a
15734
16137
  wrapper is ever rendered without it. Material-design-icon components paint
@@ -16428,6 +16831,74 @@ a.cn-xwiki-card__title[data-v-54e85fe3]:hover {
16428
16831
  color: var(--color-text-maxcontrast);
16429
16832
  }
16430
16833
 
16834
+ /* The bars variant: equal columns, a thin bar per step. Theme hooks:
16835
+ --cn-stages-bar-height, --cn-stages-bar-radius, --cn-stages-bar-done,
16836
+ --cn-stages-bar-current, --cn-stages-bar-todo. */
16837
+ .cn-stages-widget__bars[data-v-358fde0f] {
16838
+ display: grid;
16839
+ grid-template-columns: repeat(auto-fit, minmax(0, 1fr));
16840
+ grid-auto-flow: column;
16841
+ gap: 8px;
16842
+ margin: 0;
16843
+ padding: 0;
16844
+ list-style: none;
16845
+ }
16846
+ .cn-stages-widget__bar-step[data-v-358fde0f] {
16847
+ display: flex;
16848
+ flex-direction: column;
16849
+ gap: 8px;
16850
+ min-width: 0;
16851
+ }
16852
+ .cn-stages-widget__bar[data-v-358fde0f] {
16853
+ display: block;
16854
+ height: var(--cn-stages-bar-height, 6px);
16855
+ border-radius: var(--cn-stages-bar-radius, 3px);
16856
+ background: var(--cn-stages-bar-todo, var(--color-border));
16857
+ }
16858
+ .cn-stages-widget__bar-step--done .cn-stages-widget__bar[data-v-358fde0f] {
16859
+ background: var(--cn-stages-bar-done, var(--color-primary-element));
16860
+ }
16861
+ .cn-stages-widget__bar-step--current .cn-stages-widget__bar[data-v-358fde0f] {
16862
+ background: var(--cn-stages-bar-current, var(--color-error));
16863
+ }
16864
+ .cn-stages-widget__bar-label[data-v-358fde0f] {
16865
+ display: block;
16866
+ margin: 0;
16867
+ padding: 0;
16868
+ border: 0;
16869
+ background: none;
16870
+ color: var(--color-text-maxcontrast);
16871
+ font: inherit;
16872
+ font-size: 14px;
16873
+ text-align: start;
16874
+ overflow: hidden;
16875
+ text-overflow: ellipsis;
16876
+ white-space: nowrap;
16877
+ }
16878
+ button.cn-stages-widget__bar-label[data-v-358fde0f] {
16879
+ cursor: pointer;
16880
+ }
16881
+ button.cn-stages-widget__bar-label[aria-disabled="true"][data-v-358fde0f] {
16882
+ cursor: not-allowed;
16883
+ }
16884
+ button.cn-stages-widget__bar-label[data-v-358fde0f]:focus-visible {
16885
+ outline: 2px solid var(--color-primary-element);
16886
+ outline-offset: 2px;
16887
+ border-radius: var(--border-radius-small, 4px);
16888
+ }
16889
+ .cn-stages-widget__bar-step--done .cn-stages-widget__bar-label[data-v-358fde0f] {
16890
+ color: var(--color-main-text);
16891
+ font-weight: 600;
16892
+ }
16893
+ .cn-stages-widget__bar-step--current .cn-stages-widget__bar-label[data-v-358fde0f] {
16894
+ color: var(--color-main-text);
16895
+ font-weight: 700;
16896
+ }
16897
+ .cn-stages-widget__bar-date[data-v-358fde0f] {
16898
+ font-size: 12px;
16899
+ color: var(--color-text-maxcontrast);
16900
+ }
16901
+
16431
16902
  /* Text for screen readers only. */
16432
16903
  .cn-stages-widget__sr-only[data-v-358fde0f] {
16433
16904
  position: absolute;
@@ -16605,7 +17076,7 @@ a.cn-xwiki-card__title[data-v-54e85fe3]:hover {
16605
17076
  padding: var(--cn-kpi-padding-flat, 8px);
16606
17077
  box-sizing: border-box;
16607
17078
  overflow: hidden;
16608
- text-align: left;
17079
+ text-align: start;
16609
17080
  text-decoration: none;
16610
17081
  color: inherit;
16611
17082
  background: transparent;
@@ -16720,6 +17191,29 @@ a.cn-xwiki-card__title[data-v-54e85fe3]:hover {
16720
17191
  white-space: nowrap;
16721
17192
  }
16722
17193
 
17194
+ /* A caption coloured by a rule (`captionVariant` / `overrides[].captionVariant`):
17195
+ "1 due today" in the error colour. Foreground tokens, which stay readable in
17196
+ dark mode. */
17197
+ .cn-kpi-card__label--primary {
17198
+ color: var(--color-primary-element);
17199
+ font-weight: 600;
17200
+ }
17201
+
17202
+ .cn-kpi-card__label--success {
17203
+ color: var(--color-text-success, var(--color-success-text));
17204
+ font-weight: 600;
17205
+ }
17206
+
17207
+ .cn-kpi-card__label--warning {
17208
+ color: var(--color-element-warning, var(--color-warning-text));
17209
+ font-weight: 600;
17210
+ }
17211
+
17212
+ .cn-kpi-card__label--error {
17213
+ color: var(--color-text-error, var(--color-error-text));
17214
+ font-weight: 600;
17215
+ }
17216
+
16723
17217
  /* Semantic variants. Each re-points the ONE accent token, so the icon tint
16724
17218
  and the number move together by construction — there is no second place to
16725
17219
  forget. The inline KPI below shares the same modifiers for the same reason:
@@ -17674,6 +18168,68 @@ to { background-position: -200% 0;
17674
18168
  }
17675
18169
 
17676
18170
 
18171
+ .cn-segmented-control[data-v-7b344b4f] {
18172
+ display: inline-flex;
18173
+ gap: 4px;
18174
+ max-width: 100%;
18175
+ padding: 4px;
18176
+ border-radius: var(--border-radius-container, var(--border-radius-large, 10px));
18177
+ background-color: var(--color-background-dark);
18178
+ overflow-x: auto;
18179
+ }
18180
+ .cn-segmented-control--stretch[data-v-7b344b4f] {
18181
+ display: flex;
18182
+ }
18183
+ .cn-segmented-control--stretch .cn-segmented-control__option[data-v-7b344b4f] {
18184
+ flex: 1 1 0;
18185
+ }
18186
+
18187
+ /* The parent class outscores Nextcloud's server rule that gives every plain
18188
+ `button` a margin and a border. */
18189
+ .cn-segmented-control .cn-segmented-control__option[data-v-7b344b4f] {
18190
+ display: inline-flex;
18191
+ align-items: center;
18192
+ justify-content: center;
18193
+ gap: 8px;
18194
+ box-sizing: border-box;
18195
+ min-height: 36px;
18196
+ margin: 0;
18197
+ padding: 0 16px;
18198
+ border: 1px solid transparent;
18199
+ border-radius: var(--border-radius-element, var(--border-radius-large, 8px));
18200
+ background-color: transparent;
18201
+ /* Full-contrast label on every option: the choice is carried by the
18202
+ raised surface, not by dimming the others. */
18203
+ color: var(--color-main-text);
18204
+ font: inherit;
18205
+ font-weight: 600;
18206
+ white-space: nowrap;
18207
+ cursor: pointer;
18208
+ }
18209
+ .cn-segmented-control .cn-segmented-control__option[data-v-7b344b4f]:hover {
18210
+ background-color: var(--color-background-hover);
18211
+ }
18212
+ .cn-segmented-control .cn-segmented-control__option[data-v-7b344b4f]:focus-visible {
18213
+ outline: 2px solid var(--color-primary-element);
18214
+ outline-offset: 2px;
18215
+ }
18216
+
18217
+ /* The border survives forced-colours mode, which drops background and shadow. */
18218
+ .cn-segmented-control .cn-segmented-control__option--checked[data-v-7b344b4f],
18219
+ .cn-segmented-control .cn-segmented-control__option--checked[data-v-7b344b4f]:hover {
18220
+ border-color: var(--color-border-dark);
18221
+ background-color: var(--color-main-background);
18222
+ box-shadow: 0 1px 2px var(--color-box-shadow);
18223
+ }
18224
+ .cn-segmented-control .cn-segmented-control__option[disabled][data-v-7b344b4f] {
18225
+ cursor: default;
18226
+ opacity: 0.5;
18227
+ }
18228
+ .cn-segmented-control__count[data-v-7b344b4f] {
18229
+ font-weight: 400;
18230
+ }
18231
+
18232
+
17677
18233
  .cn-header-widget[data-v-1b97430f] {
17678
18234
  width: 100%;
17679
18235
  height: 100%;
@@ -17685,6 +18241,27 @@ to { background-position: -200% 0;
17685
18241
  min-height: 0;
17686
18242
  border-radius: 0;
17687
18243
  }
18244
+
18245
+ /* With a view switch the heading and the switch share one row, the switch
18246
+ at the right and bottom-aligned with the heading; on a narrow card the
18247
+ switch wraps under it. */
18248
+ .cn-header-widget--with-views[data-v-1b97430f] {
18249
+ display: flex;
18250
+ flex-wrap: wrap;
18251
+ align-items: flex-end;
18252
+ justify-content: space-between;
18253
+ gap: calc(2 * var(--default-grid-baseline)) calc(4 * var(--default-grid-baseline));
18254
+ }
18255
+ .cn-header-widget--with-views .cn-header-widget__content[data-v-1b97430f] {
18256
+ flex: 1 1 320px;
18257
+ width: auto;
18258
+ }
18259
+ .cn-header-widget__views[data-v-1b97430f] {
18260
+ position: relative;
18261
+ z-index: 1;
18262
+ flex: 0 0 auto;
18263
+ padding: 16px;
18264
+ }
17688
18265
  .cn-header-widget__date[data-v-1b97430f] {
17689
18266
  font-size: 14px;
17690
18267
  line-height: 1.4;
@@ -17746,7 +18323,7 @@ to { background-position: -200% 0;
17746
18323
  height: 1px;
17747
18324
  opacity: 0;
17748
18325
  pointer-events: none;
17749
- left: -9999px;
18326
+ inset-inline-start: -9999px;
17750
18327
  top: -9999px;
17751
18328
  }
17752
18329
  @media print {
@@ -18032,6 +18609,83 @@ to { background-position: -200% 0;
18032
18609
  }
18033
18610
 
18034
18611
 
18612
+ .cn-timeline-widget[data-v-621fcccf] {
18613
+ display: flex;
18614
+ flex-direction: column;
18615
+ gap: 8px;
18616
+ }
18617
+ .cn-timeline-widget__title[data-v-621fcccf] {
18618
+ margin: 0;
18619
+ font-size: var(--font-size-large, 1.1em);
18620
+ }
18621
+ .cn-timeline-widget__loading[data-v-621fcccf] {
18622
+ display: flex;
18623
+ align-items: center;
18624
+ gap: 8px;
18625
+ color: var(--color-text-maxcontrast);
18626
+ }
18627
+ .cn-timeline-widget__empty[data-v-621fcccf] {
18628
+ margin: 0;
18629
+ color: var(--color-text-maxcontrast);
18630
+ }
18631
+ .cn-timeline-widget__list[data-v-621fcccf] {
18632
+ margin: 0;
18633
+ padding: 0;
18634
+ list-style: none;
18635
+ }
18636
+ .cn-timeline-widget__event[data-v-621fcccf] {
18637
+ position: relative;
18638
+ display: flex;
18639
+ gap: 12px;
18640
+ padding-block-end: 12px;
18641
+ }
18642
+
18643
+ /* The line between dots: drawn from each dot down to the next event. */
18644
+ .cn-timeline-widget__event[data-v-621fcccf]:not(:last-child)::before {
18645
+ content: '';
18646
+ position: absolute;
18647
+ inset-block: 14px 0;
18648
+ inset-inline-start: 5px;
18649
+ border-inline-start: 2px solid var(--color-border-dark);
18650
+ }
18651
+ .cn-timeline-widget__dot[data-v-621fcccf] {
18652
+ flex: 0 0 auto;
18653
+ width: 12px;
18654
+ height: 12px;
18655
+ margin-block-start: 4px;
18656
+ border-radius: 50%;
18657
+ background-color: var(--color-primary-element);
18658
+ }
18659
+
18660
+ /* Upcoming: a hollow dot, plus the word "Upcoming" beside the date. */
18661
+ .cn-timeline-widget__event--upcoming .cn-timeline-widget__dot[data-v-621fcccf] {
18662
+ box-sizing: border-box;
18663
+ border: 2px solid var(--color-primary-element);
18664
+ background-color: var(--color-main-background);
18665
+ }
18666
+ .cn-timeline-widget__body[data-v-621fcccf] {
18667
+ min-width: 0;
18668
+ }
18669
+ .cn-timeline-widget__when[data-v-621fcccf] {
18670
+ font-size: var(--font-size-small, 13px);
18671
+ color: var(--color-text-maxcontrast);
18672
+ }
18673
+ .cn-timeline-widget__badge[data-v-621fcccf] {
18674
+ margin-inline-start: 8px;
18675
+ font-size: var(--font-size-small, 13px);
18676
+ font-weight: bold;
18677
+ color: var(--color-main-text);
18678
+ }
18679
+ .cn-timeline-widget__label[data-v-621fcccf] {
18680
+ margin: 0;
18681
+ font-weight: bold;
18682
+ }
18683
+ .cn-timeline-widget__detail[data-v-621fcccf] {
18684
+ margin: 0;
18685
+ overflow-wrap: anywhere;
18686
+ }
18687
+
18688
+
18035
18689
  .cn-object-card[data-v-6f672c8f] {
18036
18690
  display: flex;
18037
18691
  gap: 12px;
@@ -23314,6 +23968,17 @@ a.cn-flow-runs-widget__row-content:hover .cn-flow-runs-widget__name[data-v-75628
23314
23968
  }
23315
23969
 
23316
23970
 
23971
+ .cn-admin-action-card__description[data-v-57907ee5] {
23972
+ margin: 0 0 12px;
23973
+ color: var(--color-text-maxcontrast);
23974
+ }
23975
+ .cn-admin-action-card__footer[data-v-57907ee5] {
23976
+ display: flex;
23977
+ gap: 8px;
23978
+ margin-block: 8px;
23979
+ }
23980
+
23981
+
23317
23982
  .cn-version-info__card[data-v-3dc855b2] {
23318
23983
  background: var(--color-background-hover);
23319
23984
  border: 1px solid var(--color-border);
@@ -23698,6 +24363,19 @@ a.cn-flow-runs-widget__row-content:hover .cn-flow-runs-widget__name[data-v-75628
23698
24363
  padding: 12px;
23699
24364
  }
23700
24365
 
24366
+ .cn-choice-cards__cell[data-v-93473002] {
24367
+ display: flex;
24368
+ flex-direction: column;
24369
+ gap: 8px;
24370
+ min-inline-size: 0;
24371
+ }
24372
+
24373
+ .cn-choice-cards__actions[data-v-93473002] {
24374
+ display: flex;
24375
+ flex-direction: column;
24376
+ gap: 4px;
24377
+ }
24378
+
23701
24379
  .cn-choice-cards__option[data-v-93473002] {
23702
24380
  position: relative;
23703
24381
  display: block;
@@ -23860,6 +24538,16 @@ a.cn-flow-runs-widget__row-content:hover .cn-flow-runs-widget__name[data-v-75628
23860
24538
  padding: 24px 0;
23861
24539
  color: var(--color-text-maxcontrast);
23862
24540
  }
24541
+ .cn-setup-load-result[data-v-75b2078b] {
24542
+ margin: 0;
24543
+ font-size: var(--font-size-small, 13px);
24544
+ }
24545
+ .cn-setup-load-result--success[data-v-75b2078b] {
24546
+ color: var(--color-success-text, var(--color-success));
24547
+ }
24548
+ .cn-setup-load-result--error[data-v-75b2078b] {
24549
+ color: var(--color-error-text, var(--color-error));
24550
+ }
23863
24551
  .cn-setup-field[data-v-75b2078b] {
23864
24552
  display: flex;
23865
24553
  flex-direction: column;
@@ -28690,6 +29378,10 @@ to {
28690
29378
  padding: 16px;
28691
29379
  pointer-events: auto;
28692
29380
  }
29381
+ .cn-walkthrough__card--docked[data-v-5691d49a] {
29382
+ inset-block-end: 16px;
29383
+ inset-inline-start: 16px;
29384
+ }
28693
29385
  .cn-walkthrough__close[data-v-5691d49a] {
28694
29386
  /* !important beats NcButton's own `position: relative`, which would otherwise
28695
29387
  leave the close button in-flow at the card's top-left. */
@@ -32439,6 +33131,70 @@ a.cn-integration-card__title[data-v-f7e9bbfa]:hover {
32439
33131
  }
32440
33132
 
32441
33133
 
33134
+ /* The emblem beside the app name (`nav.brand.emblem`). A theme sets
33135
+ --nldesign-emblem-url for `emblem: true`, and --cn-nav-emblem-size for both. */
33136
+ .cn-app-nav__brand-emblem {
33137
+ flex: none;
33138
+ height: var(--cn-nav-emblem-size, 34px);
33139
+ width: auto;
33140
+ object-fit: contain;
33141
+ }
33142
+ .cn-app-nav__brand-emblem--theme {
33143
+ display: inline-block;
33144
+ width: var(--cn-nav-emblem-size, 34px);
33145
+ background: var(--nldesign-emblem-url) center / contain no-repeat;
33146
+ }
33147
+
33148
+ /* The solid primary action (`solid: true`, or an action that dispatches):
33149
+ one full-width primary button, as the board draws "New case". */
33150
+ .cn-app-nav__primary-action--solid .cn-action-buttons,
33151
+ .cn-app-nav__primary-action--solid .cn-action-buttons .button-vue,
33152
+ .cn-app-nav__primary-action--solid .button-vue {
33153
+ width: 100%;
33154
+ justify-content: center;
33155
+ }
33156
+
33157
+ /* The card above the footer entries (`nav.card`). Theme hooks:
33158
+ --cn-nav-card-background and --cn-nav-card-radius. */
33159
+ .cn-app-nav__card {
33160
+ display: flex;
33161
+ flex-direction: column;
33162
+ gap: calc(2 * var(--default-grid-baseline));
33163
+ margin: calc(2 * var(--default-grid-baseline));
33164
+ padding: calc(4 * var(--default-grid-baseline));
33165
+ border-radius: var(--cn-nav-card-radius, var(--border-radius-large));
33166
+ background: var(--cn-nav-card-background, var(--color-background-hover));
33167
+ }
33168
+ .cn-app-nav__card-title {
33169
+ color: var(--color-main-text);
33170
+ font-weight: 700;
33171
+ }
33172
+ .cn-app-nav__card-text {
33173
+ color: var(--color-text-maxcontrast);
33174
+ line-height: 1.4;
33175
+ }
33176
+ .cn-app-nav__card-link {
33177
+ align-self: flex-start;
33178
+ margin: 0;
33179
+ padding: 0;
33180
+ border: 0;
33181
+ background: none;
33182
+ color: var(--color-primary-element);
33183
+ font: inherit;
33184
+ font-weight: 600;
33185
+ text-decoration: none;
33186
+ cursor: pointer;
33187
+ }
33188
+ .cn-app-nav__card-link:hover,
33189
+ .cn-app-nav__card-link:focus-visible {
33190
+ text-decoration: underline;
33191
+ }
33192
+ .cn-app-nav__card-link:focus-visible {
33193
+ outline: 2px solid var(--color-primary-element);
33194
+ outline-offset: 2px;
33195
+ border-radius: var(--border-radius-small, 4px);
33196
+ }
33197
+
32442
33198
  /* The brand block at the top of the navigation. */
32443
33199
  .cn-app-nav__brand {
32444
33200
  align-items: center;
@@ -33713,6 +34469,11 @@ a.cn-integration-card__title[data-v-f7e9bbfa]:hover {
33713
34469
  margin-bottom: 12px;
33714
34470
  color: var(--color-text-maxcontrast);
33715
34471
  }
34472
+ .cn-app-root__walkthrough-actions {
34473
+ display: flex;
34474
+ flex-wrap: wrap;
34475
+ gap: 8px;
34476
+ }
33716
34477
  .cn-app-root__integrations-hint {
33717
34478
  margin-bottom: 12px;
33718
34479
  color: var(--color-text-maxcontrast);
@@ -34322,68 +35083,6 @@ a.cn-integration-card__title[data-v-f7e9bbfa]:hover {
34322
35083
  }
34323
35084
 
34324
35085
 
34325
- .cn-segmented-control[data-v-7b344b4f] {
34326
- display: inline-flex;
34327
- gap: 4px;
34328
- max-width: 100%;
34329
- padding: 4px;
34330
- border-radius: var(--border-radius-container, var(--border-radius-large, 10px));
34331
- background-color: var(--color-background-dark);
34332
- overflow-x: auto;
34333
- }
34334
- .cn-segmented-control--stretch[data-v-7b344b4f] {
34335
- display: flex;
34336
- }
34337
- .cn-segmented-control--stretch .cn-segmented-control__option[data-v-7b344b4f] {
34338
- flex: 1 1 0;
34339
- }
34340
-
34341
- /* The parent class outscores Nextcloud's server rule that gives every plain
34342
- `button` a margin and a border. */
34343
- .cn-segmented-control .cn-segmented-control__option[data-v-7b344b4f] {
34344
- display: inline-flex;
34345
- align-items: center;
34346
- justify-content: center;
34347
- gap: 8px;
34348
- box-sizing: border-box;
34349
- min-height: 36px;
34350
- margin: 0;
34351
- padding: 0 16px;
34352
- border: 1px solid transparent;
34353
- border-radius: var(--border-radius-element, var(--border-radius-large, 8px));
34354
- background-color: transparent;
34355
- /* Full-contrast label on every option: the choice is carried by the
34356
- raised surface, not by dimming the others. */
34357
- color: var(--color-main-text);
34358
- font: inherit;
34359
- font-weight: 600;
34360
- white-space: nowrap;
34361
- cursor: pointer;
34362
- }
34363
- .cn-segmented-control .cn-segmented-control__option[data-v-7b344b4f]:hover {
34364
- background-color: var(--color-background-hover);
34365
- }
34366
- .cn-segmented-control .cn-segmented-control__option[data-v-7b344b4f]:focus-visible {
34367
- outline: 2px solid var(--color-primary-element);
34368
- outline-offset: 2px;
34369
- }
34370
-
34371
- /* The border survives forced-colours mode, which drops background and shadow. */
34372
- .cn-segmented-control .cn-segmented-control__option--checked[data-v-7b344b4f],
34373
- .cn-segmented-control .cn-segmented-control__option--checked[data-v-7b344b4f]:hover {
34374
- border-color: var(--color-border-dark);
34375
- background-color: var(--color-main-background);
34376
- box-shadow: 0 1px 2px var(--color-box-shadow);
34377
- }
34378
- .cn-segmented-control .cn-segmented-control__option[disabled][data-v-7b344b4f] {
34379
- cursor: default;
34380
- opacity: 0.5;
34381
- }
34382
- .cn-segmented-control__count[data-v-7b344b4f] {
34383
- font-weight: 400;
34384
- }
34385
-
34386
-
34387
35086
  .cn-brand-stripe[data-v-6fdfa763] {
34388
35087
  --cn-brand-stripe-first: var(--cn-brand-stripe-ratio-1, 1);
34389
35088
  --cn-brand-stripe-second: var(--cn-brand-stripe-ratio-2, 1);