@tiba-spark/client-shared-lib 26.3.0-628 → 26.3.0-628.a11y.13

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 (89) hide show
  1. package/esm2022/libraries/components/cloud-confirm-dialog/cloud-confirm-dialog.component.mjs +3 -3
  2. package/esm2022/libraries/components/common-pages/error-page/error-page.component.mjs +35 -7
  3. package/esm2022/libraries/components/field-label/field-label.component.mjs +39 -6
  4. package/esm2022/libraries/components/field-validations/field-validations.component.mjs +8 -5
  5. package/esm2022/libraries/components/guest-open-ticket-dialog/guest-open-ticket-dialog.component.mjs +2 -2
  6. package/esm2022/libraries/components/intercom/intercom.component.mjs +2 -2
  7. package/esm2022/libraries/components/logo/logo.component.mjs +3 -3
  8. package/esm2022/libraries/components/message-bar/float-message-bar.service.mjs +30 -6
  9. package/esm2022/libraries/components/modal-buttons-wrapper/modal-buttons-wrapper.component.mjs +9 -4
  10. package/esm2022/libraries/components/notification/alert-notification/alert-notification.component.mjs +3 -3
  11. package/esm2022/libraries/components/notification/command-notification/command-notification.component.mjs +3 -3
  12. package/esm2022/libraries/components/notification/notification-type-label/notification-type-label.component.mjs +2 -2
  13. package/esm2022/libraries/components/notification/notification.service.mjs +6 -3
  14. package/esm2022/libraries/components/overlay-loading-container/empty-results/empty-results.component.mjs +3 -3
  15. package/esm2022/libraries/components/overlay-loading-container/error-results/error-results.component.mjs +2 -2
  16. package/esm2022/libraries/components/restart-link/restart-link.component.mjs +2 -2
  17. package/esm2022/libraries/constants/global-constants.mjs +2 -1
  18. package/esm2022/libraries/directives/clear-all-button.directive.mjs +49 -0
  19. package/esm2022/libraries/directives/disabled.directive.mjs +121 -0
  20. package/esm2022/libraries/directives/icon-button.directive.mjs +36 -0
  21. package/esm2022/libraries/directives/index.mjs +4 -1
  22. package/esm2022/libraries/directives/shared-directives.module.mjs +16 -1
  23. package/esm2022/libraries/enums/localization.enum.mjs +45 -5
  24. package/esm2022/libraries/enums/message-bar-duration.enum.mjs +4 -2
  25. package/esm2022/libraries/interfaces/table-column.interface.mjs +1 -1
  26. package/esm2022/libraries/modules/layout/layout.state.mjs +2 -2
  27. package/esm2022/libraries/services/can-deactivate.service.mjs +4 -3
  28. package/esm2022/libraries/services/modal.service.mjs +94 -1
  29. package/esm2022/libraries/utils/error.util.mjs +12 -1
  30. package/fesm2022/tiba-spark-client-shared-lib.mjs +543 -93
  31. package/fesm2022/tiba-spark-client-shared-lib.mjs.map +1 -1
  32. package/libraries/components/common-pages/error-page/error-page.component.d.ts +11 -2
  33. package/libraries/components/common-pages/error-page/error-page.component.d.ts.map +1 -1
  34. package/libraries/components/field-label/field-label.component.d.ts +8 -3
  35. package/libraries/components/field-label/field-label.component.d.ts.map +1 -1
  36. package/libraries/components/field-validations/field-validations.component.d.ts +2 -4
  37. package/libraries/components/field-validations/field-validations.component.d.ts.map +1 -1
  38. package/libraries/components/message-bar/float-message-bar.service.d.ts +2 -0
  39. package/libraries/components/message-bar/float-message-bar.service.d.ts.map +1 -1
  40. package/libraries/components/modal-buttons-wrapper/modal-buttons-wrapper.component.d.ts.map +1 -1
  41. package/libraries/components/notification/alert-notification/alert-notification.component.d.ts.map +1 -1
  42. package/libraries/components/notification/command-notification/command-notification.component.d.ts.map +1 -1
  43. package/libraries/components/notification/notification.service.d.ts.map +1 -1
  44. package/libraries/constants/global-constants.d.ts +1 -0
  45. package/libraries/constants/global-constants.d.ts.map +1 -1
  46. package/libraries/directives/clear-all-button.directive.d.ts +19 -0
  47. package/libraries/directives/clear-all-button.directive.d.ts.map +1 -0
  48. package/libraries/directives/disabled.directive.d.ts +30 -0
  49. package/libraries/directives/disabled.directive.d.ts.map +1 -0
  50. package/libraries/directives/icon-button.directive.d.ts +14 -0
  51. package/libraries/directives/icon-button.directive.d.ts.map +1 -0
  52. package/libraries/directives/index.d.ts +3 -0
  53. package/libraries/directives/index.d.ts.map +1 -1
  54. package/libraries/directives/shared-directives.module.d.ts +7 -4
  55. package/libraries/directives/shared-directives.module.d.ts.map +1 -1
  56. package/libraries/enums/localization.enum.d.ts +44 -4
  57. package/libraries/enums/localization.enum.d.ts.map +1 -1
  58. package/libraries/enums/message-bar-duration.enum.d.ts +3 -1
  59. package/libraries/enums/message-bar-duration.enum.d.ts.map +1 -1
  60. package/libraries/interfaces/table-column.interface.d.ts +1 -0
  61. package/libraries/interfaces/table-column.interface.d.ts.map +1 -1
  62. package/libraries/services/can-deactivate.service.d.ts.map +1 -1
  63. package/libraries/services/modal.service.d.ts +8 -0
  64. package/libraries/services/modal.service.d.ts.map +1 -1
  65. package/libraries/utils/error.util.d.ts +6 -0
  66. package/libraries/utils/error.util.d.ts.map +1 -1
  67. package/package.json +1 -1
  68. package/src/libraries/theme/_calendar.scss +2 -1
  69. package/src/libraries/theme/_card.scss +6 -5
  70. package/src/libraries/theme/_forms.scss +1 -1
  71. package/src/libraries/theme/_mixins.scss +0 -1
  72. package/src/libraries/theme/_modals.scss +25 -3
  73. package/src/libraries/theme/_ngx.scss +0 -1
  74. package/src/libraries/theme/_tables.scss +3 -2
  75. package/src/libraries/theme/_tabs.scss +6 -4
  76. package/src/libraries/theme/_utils.scss +196 -4
  77. package/src/libraries/theme/_variables.scss +42 -10
  78. package/src/libraries/theme/components/_carousel.scss +10 -4
  79. package/src/libraries/theme/components/_tb-search.scss +10 -4
  80. package/src/libraries/theme/mat-components/_mat-checkbox.scss +1 -1
  81. package/src/libraries/theme/mat-components/_mat-date-picker.scss +4 -0
  82. package/src/libraries/theme/mat-components/_mat-input.scss +5 -0
  83. package/src/libraries/theme/mat-components/_mat-menu.scss +42 -16
  84. package/src/libraries/theme/mat-components/_mat-radio-group.scss +5 -0
  85. package/src/libraries/theme/mat-components/_mat-select.scss +35 -9
  86. package/src/libraries/theme/mat-components/_mat-selection-list.scss +2 -3
  87. package/src/libraries/theme/mat-components/_mat-slide-toggle.scss +1 -1
  88. package/src/libraries/theme/mat-components/_mat-step.scss +41 -2
  89. package/src/libraries/theme/theme.scss +119 -0
@@ -68,7 +68,9 @@
68
68
 
69
69
  .mat-mdc-tab-group.mat-primary.primary-nav,
70
70
  .mat-mdc-tab-nav-bar.mat-primary.primary-nav {
71
- min-width: variables.$primary-router-min-width;
71
+ // Never wider than the viewport; the tabs scroll with their arrows at 320 px (WCAG 1.4.10).
72
+ min-width: min(variables.$primary-router-min-width, 100%);
73
+ max-width: 100%;
72
74
 
73
75
  .mat-mdc-tab-link-container,
74
76
  .mat-mdc-tab-label-container {
@@ -79,7 +81,7 @@
79
81
  &.nav-bottom-border {
80
82
  .mat-mdc-tab-header::after {
81
83
  content: ' ';
82
- border-bottom: 1px solid variables.$form-field-border;
84
+ border-bottom: 1px solid variables.$border-color;
83
85
  display: flex;
84
86
  flex: 1;
85
87
  }
@@ -138,7 +140,7 @@
138
140
  &.mat-mdc-tab-nav-bar.mat-mdc-tab-header::after,
139
141
  &.nav-bottom-border .mat-mdc-tab-header::after {
140
142
  content: ' ';
141
- border-bottom: 1px solid variables.$form-field-border;
143
+ border-bottom: 1px solid variables.$border-color;
142
144
  display: flex;
143
145
  flex: 1;
144
146
  }
@@ -358,7 +360,7 @@ mat-tab-group.mat-mdc-tab-group.mat-tab-welcome-page {
358
360
  }
359
361
  }
360
362
 
361
- @media (max-width: 600px) {
363
+ @media (max-width: 640px) {
362
364
  mat-tab-group.mat-mdc-tab-group.mat-tab-welcome-page {
363
365
  .mat-mdc-tab-header {
364
366
  .mat-mdc-tab-label-container {
@@ -170,7 +170,42 @@
170
170
  }
171
171
 
172
172
  // Mobile width
173
- @media only screen and (max-width: 600px) {
173
+ @media only screen and (max-width: 640px) {
174
+ // Wrapped filter and form controls stretch to fill their line; two in one group share it.
175
+ // A field selector paired with its search keeps its own width.
176
+ .tb-flex-wrap > :is(tb-drop-down, tb-search, tb-search-facilities, tb-company-input, tb-sub-company-input, tb-datetime-picker),
177
+ .tb-flex-wrap > .tb-flex > :is(tb-drop-down, tb-search, tb-search-facilities, tb-company-input, tb-sub-company-input, tb-datetime-picker) {
178
+ &:not(:has(+ .select-paired)) {
179
+ flex: 1 1 140px;
180
+ min-width: 0;
181
+ width: auto !important;
182
+ }
183
+
184
+ // The group's gap spaces them, so a line ends on the edge.
185
+ &:not(:has(+ .tb-filters-toggle)) {
186
+ margin-right: 0;
187
+ }
188
+ }
189
+
190
+ .tb-flex-wrap:has(> :is(tb-drop-down, tb-search, tb-search-facilities, tb-company-input, tb-sub-company-input, tb-datetime-picker)) {
191
+ column-gap: 15px;
192
+ }
193
+
194
+ .tb-flex-wrap > .tb-flex:has(> :is(tb-drop-down, tb-search, tb-search-facilities, tb-company-input, tb-sub-company-input, tb-datetime-picker)) {
195
+ flex: 1 1 100%;
196
+ column-gap: 15px;
197
+
198
+ // A search paired with its field selector stays joined to it.
199
+ > .select-paired {
200
+ margin-left: -15px;
201
+ }
202
+ }
203
+
204
+ // With the 15px gap, the search keeps its 10px from the filter toggle.
205
+ .tb-flex-wrap tb-search:has(+ .tb-filters-toggle) {
206
+ margin-right: -5px;
207
+ }
208
+
174
209
  .cdk-global-overlay-wrapper {
175
210
  justify-content: unset !important;
176
211
  margin: 0 10px;
@@ -180,6 +215,11 @@
180
215
  width: calc(100vw - 20px) !important;
181
216
  }
182
217
 
218
+ // Same 10px gap above and below a dialog as at its sides.
219
+ .cdk-overlay-pane.mat-mdc-dialog-panel {
220
+ max-height: calc(100% - 20px) !important;
221
+ }
222
+
183
223
  .tb-login-modal {
184
224
  margin: unset !important;
185
225
  max-width: 370px;
@@ -187,7 +227,7 @@
187
227
  }
188
228
 
189
229
  mat-dialog-container.mat-mdc-dialog-container {
190
- min-width: 355px !important; // narrowest modal possible in mobile
230
+ min-width: min(355px, 100%) !important; // narrowest modal possible in mobile, never wider than the screen
191
231
  margin: auto;
192
232
  }
193
233
  }
@@ -203,7 +243,8 @@
203
243
  }
204
244
 
205
245
  .tb-primary-router-width {
206
- min-width: variables.$primary-router-min-width;
246
+ // Never wider than the viewport, so the page reflows at 320 px (WCAG 1.4.10).
247
+ min-width: min(variables.$primary-router-min-width, 100%);
207
248
  }
208
249
 
209
250
  .tb-sidebar {
@@ -218,6 +259,127 @@
218
259
  }
219
260
  }
220
261
 
262
+ // Narrow layout / high zoom: the side panel goes under the page instead of beside it (WCAG 1.4.10).
263
+ @media only screen and (max-width: variables.$reflow-max-width) {
264
+ .tb-flex:has(> .tb-sidebar),
265
+ .tb-flex-row:has(> .tb-sidebar) {
266
+ flex-direction: column;
267
+ flex-wrap: nowrap;
268
+
269
+ // The page keeps the same room as the stacked side panel instead of shrinking to what is left.
270
+ > :not(.tb-sidebar) {
271
+ flex-shrink: 0;
272
+ min-height: max(480px, 75vh);
273
+ }
274
+ }
275
+
276
+ .tb-sidebar {
277
+ width: 100%;
278
+
279
+ // An open side panel sizes its scroll area from its own height, so stacked it needs one.
280
+ &:has(> :not(router-outlet)) {
281
+ height: max(480px, 75vh);
282
+ flex-shrink: 0;
283
+
284
+ mat-card.tb-card {
285
+ min-height: 0;
286
+ }
287
+ }
288
+
289
+ tb-parker,
290
+ tb-parker-search,
291
+ tb-parker-search-results,
292
+ tb-global-counters {
293
+ width: 100%;
294
+ margin-left: 0;
295
+ }
296
+ }
297
+
298
+ // Filter bars: the groups inside a wrapping row wrap too, instead of one group widening the page,
299
+ // with 10px between wrapped lines unless the controls bring their own bottom spacing.
300
+ .tb-flex-wrap > .tb-flex {
301
+ flex-wrap: wrap;
302
+
303
+ &:not([class*='tb-mb-']):not(:has(> [class*='tb-pb-'], > [class*='tb-mb-'])),
304
+ &.tb-h-30 {
305
+ row-gap: 10px;
306
+ }
307
+
308
+ &.tb-h-30 {
309
+ height: auto;
310
+ }
311
+ }
312
+
313
+ // Section headers (title left, buttons right) wrap their buttons under the title.
314
+ .tb-flex-center.tb-space-between {
315
+ flex-wrap: wrap;
316
+ row-gap: 10px;
317
+
318
+ > .tb-flex {
319
+ flex-wrap: wrap;
320
+ row-gap: 10px;
321
+ }
322
+ }
323
+
324
+ // The min-width utilities are !important; the wide ones still give way to a narrow window.
325
+ @each $i in 280, 290, 315, 320, 460, 470 {
326
+ .tb-min-w-#{$i}.tb-min-w-#{$i} {
327
+ min-width: min(#{$i}px, 100%) !important;
328
+ }
329
+ }
330
+
331
+ // A spinner centred in a tall stacked page stays at mid-screen instead of below the fold.
332
+ .tb-loading > .tb-loading-overlay > .tb-margin-auto {
333
+ position: sticky;
334
+ bottom: calc(50vh - 20px);
335
+ }
336
+
337
+ // Fixed-width fields and fill areas give way to the window instead of widening the page or dialog.
338
+ main.tb-content [class*='tb-w-'],
339
+ .mat-mdc-dialog-container [class*='tb-w-'] {
340
+ max-width: 100%;
341
+ }
342
+
343
+ main.tb-content .tb-flex > .tb-flex-grow {
344
+ min-width: 0;
345
+ }
346
+
347
+ // Radio options with long hints wrap instead of sizing the group to one line.
348
+ mat-radio-group.tb-elem-radio {
349
+ max-width: 100%;
350
+ flex-wrap: wrap;
351
+
352
+ > * {
353
+ min-width: 0;
354
+ max-width: 100%;
355
+ }
356
+ }
357
+
358
+ // Collapsible filter bars (tbCollapsibleFilters): only the search and the toggle show until it opens.
359
+ .toggle-filters-button.tb-filters-toggle {
360
+ display: block;
361
+ flex: none;
362
+ margin-right: 0;
363
+ }
364
+
365
+ // The search before it gives up width, so the toggle stays on the search's line.
366
+ tb-search:has(+ .tb-filters-toggle) {
367
+ flex: 1 1 120px;
368
+ min-width: 0;
369
+ width: auto !important;
370
+ margin-right: 10px;
371
+ }
372
+
373
+ .tb-filters-collapsed .tb-collapsible-filter {
374
+ display: none !important;
375
+ }
376
+
377
+ // Short zoomed windows: pages scroll instead of squeezing tables; a basis keeps the fit-content minimum.
378
+ main.tb-content > router-outlet + * {
379
+ flex: 1 0 480px;
380
+ }
381
+ }
382
+
221
383
  .side-text .tb-field-label {
222
384
  padding-left: 0;
223
385
  }
@@ -848,6 +1010,10 @@ a.clickable-link {
848
1010
  overflow: auto;
849
1011
  }
850
1012
 
1013
+ .tb-filters-toggle {
1014
+ display: none;
1015
+ }
1016
+
851
1017
  .toggle-filters-button tb-icon {
852
1018
  outline: 1px solid variables.$border-color;
853
1019
  outline-offset: -1px;
@@ -857,6 +1023,11 @@ a.clickable-link {
857
1023
  &.active {
858
1024
  background-color: variables.$button-active-background;
859
1025
  }
1026
+
1027
+ // The grey border is an outline, so focus recolours it instead of drawing a second ring.
1028
+ &:focus-visible {
1029
+ outline-color: variables.$focus-ring-color;
1030
+ }
860
1031
  }
861
1032
 
862
1033
  .active-button-text {
@@ -936,6 +1107,9 @@ a.clickable-link {
936
1107
 
937
1108
  .print-container {
938
1109
  position: absolute;
1110
+ // The hidden frame must not widen the page at 320 px (WCAG 1.4.10).
1111
+ left: 0;
1112
+ max-width: 100%;
939
1113
  z-index: -1;
940
1114
  overflow: auto;
941
1115
  height: 0px;
@@ -973,7 +1147,8 @@ a.clickable-link {
973
1147
  }
974
1148
 
975
1149
  .tb-rate-tables-container {
976
- min-width: 1268px;
1150
+ // The table scrolls inside its own box when narrower; headings and buttons stay in view (WCAG 1.4.10).
1151
+ min-width: min(1268px, 100% - 10px);
977
1152
  padding-right: 10px;
978
1153
  }
979
1154
 
@@ -1023,3 +1198,20 @@ a.clickable-link {
1023
1198
  height: calc(550px * (450 / 930)) !important; // ≈ 290px
1024
1199
  aspect-ratio: unset !important;
1025
1200
  }
1201
+
1202
+ // Narrow layout / high zoom: the rate image previews shrink to the window, keeping their shape (WCAG 1.4.10).
1203
+ @media only screen and (max-width: variables.$reflow-max-width) {
1204
+ .tb-upload-rate-on-display-image-vertical,
1205
+ .tb-upload-rate-on-display-image-horizontal {
1206
+ max-width: 100%;
1207
+ height: auto !important;
1208
+ }
1209
+
1210
+ .tb-upload-rate-on-display-image-vertical {
1211
+ aspect-ratio: 510 / 750 !important;
1212
+ }
1213
+
1214
+ .tb-upload-rate-on-display-image-horizontal {
1215
+ aspect-ratio: 930 / 450 !important;
1216
+ }
1217
+ }
@@ -14,8 +14,8 @@ $scrollbar-background-color: #0000004d;
14
14
  $big-shadow-color: #00000014;
15
15
  $title-color: #2c3e50;
16
16
  $text-color: #2c3e50;
17
- $secondary-text-color: #919eab;
18
- $error-color: #ff0e4d;
17
+ $secondary-text-color: #5f6b78;
18
+ $error-color: #e2003b;
19
19
  $error-light-color: #ffdbe4;
20
20
  $error-background-color: #ffdbe4;
21
21
  $success-background-color: #def9e1;
@@ -29,11 +29,11 @@ $inactive-color: #ecedf0;
29
29
  $white-color: #ffffff;
30
30
  $black-color: #000000;
31
31
  $grey-color: #9a9a9a;
32
- $form-field-border: #dee2e6;
33
- $form-field-border-hover: #919eab;
34
- $form-field-title: #919eab;
35
- $form-field-placeholder: #bdc3c7;
36
- $primary-color: #0985eb;
32
+ $form-field-border: #8a939c;
33
+ $form-field-border-hover: #2c3e50;
34
+ $form-field-title: #5f6b78;
35
+ $form-field-placeholder: #6b7785;
36
+ $primary-color: #0670c7;
37
37
  $blue-hover-backgroung-color: #0079dc;
38
38
  $secondary-color: #ffffff;
39
39
  $secondary-color-hover: #0985eb10;
@@ -64,16 +64,42 @@ $tab-inactive-color: #ecedf0;
64
64
  $disabled-color: #bdc3c7;
65
65
  $disabled-field: #ecedf0;
66
66
  $disabled-background: #eeeeee;
67
- $checkbox-border-color: #dee2e6;
68
- $radio-border-color: #dee2e6;
67
+ // Unchecked checkbox and radio edges need 3:1, the same as field borders.
68
+ $checkbox-border-color: $form-field-border;
69
+ $radio-border-color: $form-field-border;
69
70
  $summary-background-color: #daedfc;
70
71
  $drop-down-menu-background-color: #f9f9f9;
71
72
  $modules-background-color: #f9f9f9;
72
73
  $sidenav-input-search-color: #3c4957;
74
+ $sidenav-input-text-color: #d8dbe0;
75
+ $sidenav-input-placeholder-color: #bdc3c7; // the light-theme placeholder is unreadable on the dark side menu
73
76
  $sidenav-child-background-color: #ffffff0d;
74
77
  $ngx-slider-background-color: #035aa1;
75
78
  $light-error-color: #ff0e4d40;
76
79
  $focus-border-color: #0985eb;
80
+ $focus-ring-color: #0670c7;
81
+ $focus-ring-color-on-dark: #ffffff;
82
+
83
+ // Focused dropdown option: blue bar plus a 1px ring.
84
+ $option-focus-shadow: inset 2px 0 0 $focus-ring-color, inset 0 0 0 1px $focus-ring-color;
85
+ // Selected option of a single-choice list: light tint plus a 3px blue bar.
86
+ $option-selected-shadow: inset 3px 0 0 $focus-ring-color;
87
+ // Focused selected option: the bar plus a 1px ring.
88
+ $option-selected-focus-shadow: inset 3px 0 0 $focus-ring-color, inset 0 0 0 1px $focus-ring-color;
89
+
90
+ // The bar, not the tint (about 1.2:1 on white), marks the selection (WCAG 1.4.1, 1.4.11).
91
+ @mixin single-choice-selected {
92
+ background: $active-background;
93
+ color: $text-color;
94
+ --mdc-list-list-item-label-text-color: #{$text-color};
95
+ --mdc-list-list-item-hover-label-text-color: #{$text-color};
96
+ --mdc-list-list-item-focus-label-text-color: #{$text-color};
97
+ box-shadow: $option-selected-shadow;
98
+
99
+ &:focus-visible {
100
+ box-shadow: $option-selected-focus-shadow;
101
+ }
102
+ }
77
103
  $ngx-slider-full-bar-background: #dee2e6;
78
104
  $ngx-slider-selection-background: #0985eb80;
79
105
  $ngx-slider-pointer-color: #0985eb;
@@ -93,6 +119,9 @@ $green-color: #e8fce4;
93
119
  // Alerts
94
120
  $tb-critical-color: #ff0e4d;
95
121
  $tb-high-color: #e3554c;
122
+ // Badge fills / text with white: the shades above give 3.7-3.9:1 on 13px text, these 4.5:1.
123
+ $tb-critical-badge-color: #ec003e;
124
+ $tb-high-badge-color: #dd3329;
96
125
  $tb-medium-color: #ffd362;
97
126
  $tb-low-color: #c1e0fa;
98
127
  $tb-information-color: #0985eb;
@@ -119,6 +148,8 @@ $primary-router-min-width: 335px; // Changed to support mobile compatability
119
148
 
120
149
  $sidebar-container-width: 528px;
121
150
  $sidebar-width: 518px;
151
+ // Narrow layout (side panels stack, filters wrap): 400% zoom, and wide screens zoomed to 200-300% (WCAG 1.4.10).
152
+ $reflow-max-width: 999px;
122
153
  $sidebar-margin-left: 10px;
123
154
  $sidenav-width: 240px;
124
155
 
@@ -166,10 +197,11 @@ $progress-bar-yellow: #ffd362;
166
197
 
167
198
  // special-days
168
199
  $special-day-1: #e488ff;
169
- $special-day-2: #8da0fe;
200
+ $special-day-2: #94a6fe;
170
201
  $special-day-3: #ffd362;
171
202
  $special-day-4: #09c4eb;
172
203
  $special-day-5: #0eff77;
204
+ $special-day-past-overlay: #ffffff80;
173
205
 
174
206
 
175
207
  //Monthlies
@@ -2,7 +2,7 @@
2
2
  @use 'variables';
3
3
 
4
4
  owl-carousel-o.full, owl-carousel-o.thumbnail, owl-carousel-o.section, owl-carousel-o.modal {
5
- min-width: 380px;
5
+ min-width: min(380px, 100%);
6
6
 
7
7
  .owl-carousel {
8
8
  padding: 10px 0;
@@ -80,9 +80,12 @@ owl-carousel-o.full {
80
80
  }
81
81
 
82
82
  .owl-item {
83
+ // A narrow window shrinks the image, keeping its shape.
83
84
  img {
84
85
  width: 580px;
85
- height: 340px;
86
+ max-width: 100%;
87
+ height: auto;
88
+ aspect-ratio: 580 / 340;
86
89
  }
87
90
  }
88
91
  }
@@ -93,9 +96,12 @@ owl-carousel-o.modal {
93
96
  }
94
97
 
95
98
  .owl-item {
99
+ // A narrow window shrinks the image, keeping its shape.
96
100
  img {
97
101
  width: 470px;
98
- height: 270px;
102
+ max-width: 100%;
103
+ height: auto;
104
+ aspect-ratio: 470 / 270;
99
105
  }
100
106
  }
101
107
  }
@@ -164,7 +170,7 @@ tb-update-plate-id-dialog owl-carousel-o.full {
164
170
  }
165
171
  }
166
172
 
167
- @media (max-width: 600px) {
173
+ @media (max-width: 640px) {
168
174
  owl-carousel-o.section .owl-carousel {
169
175
  height: 70vw;
170
176
  }
@@ -18,6 +18,12 @@ tb-search {
18
18
  &:hover {
19
19
  opacity: .9;
20
20
  }
21
+
22
+ // A blue ring is invisible on the blue button; draw it white, inside.
23
+ &:focus-visible {
24
+ outline-color: variables.$focus-ring-color-on-dark;
25
+ outline-offset: -3px;
26
+ }
21
27
  }
22
28
  }
23
29
  }
@@ -50,18 +56,18 @@ tb-search.tb-sidenav-search {
50
56
  background-color: variables.$sidenav-input-search-color;
51
57
 
52
58
  &:focus-within {
53
- border-color: variables.$input-border-on-focus;
59
+ border-color: variables.$focus-ring-color-on-dark;
54
60
  }
55
61
 
56
62
  .mat-mdc-form-field-infix {
57
63
  input.mat-mdc-input-element {
58
64
  font-size: 13px;
59
- color: variables.$form-field-title;
60
- caret-color: variables.$form-field-title;
65
+ color: variables.$sidenav-input-text-color;
66
+ caret-color: variables.$sidenav-input-text-color;
61
67
  background-color: transparent;
62
68
 
63
69
  &::placeholder {
64
- color: variables.$form-field-placeholder;
70
+ color: variables.$sidenav-input-placeholder-color;
65
71
  opacity: 1;
66
72
  }
67
73
  }
@@ -8,7 +8,7 @@ mat-checkbox.mat-mdc-checkbox.tb-elem-checkbox {
8
8
  width: fit-content;
9
9
  --mdc-checkbox-state-layer-size: 16px;
10
10
  --mat-checkbox-label-text-color: #{variables.$text-color};
11
- --mdc-checkbox-disabled-unselected-icon-color: #{variables.$checkbox-border-color};
11
+ --mdc-checkbox-disabled-unselected-icon-color: #{variables.$divider};
12
12
  --mdc-checkbox-unselected-focus-icon-color: #{variables.$form-field-border-hover};
13
13
  --mdc-checkbox-unselected-hover-icon-color: #{variables.$form-field-border-hover};
14
14
  --mdc-checkbox-unselected-icon-color: #{variables.$checkbox-border-color};
@@ -170,6 +170,10 @@ mat-form-field.mat-mdc-form-field.tb-elem-date-picker {
170
170
  mat-form-field.mat-mdc-form-field.tb-elem-date-picker.mat-form-field-invalid {
171
171
  .mat-mdc-text-field-wrapper .mat-mdc-form-field-flex {
172
172
  border-color: variables.$error-color;
173
+
174
+ &:focus-within {
175
+ border-color: variables.$input-border-on-focus;
176
+ }
173
177
  }
174
178
  }
175
179
 
@@ -194,6 +194,11 @@ mat-form-field.mat-mdc-form-field.tb-elem-input.mat-form-field-invalid:not(.mat-
194
194
  .mat-mdc-text-field-wrapper .mat-mdc-form-field-flex {
195
195
  border-color: variables.$error-color;
196
196
 
197
+ // Focus stays visible on an invalid field, like tb-mat-select.
198
+ &:focus-within {
199
+ border-color: variables.$input-border-on-focus;
200
+ }
201
+
197
202
  .mat-mdc-form-field-label {
198
203
  color: variables.$form-field-placeholder;
199
204
  }
@@ -86,8 +86,10 @@
86
86
  background-color: variables.$hover-background;
87
87
  }
88
88
 
89
- &[aria-selected="true"] {
90
- background-color: variables.$active-background;
89
+ // Inside a menu the current option is a checked radio item (tb-menu-icon useMenuRoles).
90
+ &[aria-selected="true"],
91
+ &[aria-checked="true"] {
92
+ @include variables.single-choice-selected;
91
93
  }
92
94
 
93
95
  .mdc-list-item__content {
@@ -140,6 +142,13 @@
140
142
  background-color: variables.$drawer-item-hover-background;
141
143
  }
142
144
 
145
+ // The blue ring barely shows on the dark panel; white inside the row, as in the side menu.
146
+ &:focus-visible {
147
+ outline: 1px solid variables.$focus-ring-color-on-dark;
148
+ outline-offset: -3px;
149
+ background-color: variables.$drawer-item-hover-background;
150
+ }
151
+
143
152
  .mat-mdc-list-item-unscoped-content {
144
153
  span {
145
154
  color: variables.$white-color;
@@ -272,7 +281,6 @@
272
281
  overflow-y: auto;
273
282
  overflow-x: hidden;
274
283
  max-height: calc(100vh - 400px);
275
- outline: none;
276
284
 
277
285
  mat-list-option.mat-mdc-list-option {
278
286
  height: 40px;
@@ -397,8 +405,8 @@ mat-selection-list.mat-mdc-selection-list {
397
405
  }
398
406
 
399
407
  .mat-mdc-menu-panel.car-plate-camera-icon {
400
- min-width: 650px;
401
- min-height: 430px;
408
+ min-width: min(650px, 100vw - 20px);
409
+ min-height: min(430px, 100vh - 20px);
402
410
  }
403
411
 
404
412
  .mat-mdc-list-item .mdc-list-item__content-reverse,
@@ -551,11 +559,9 @@ mat-selection-list.mat-mdc-selection-list {
551
559
  }
552
560
 
553
561
  .mat-mdc-selection-list {
554
- outline: none;
555
562
  padding: 0;
556
563
 
557
564
  .mat-mdc-list-option {
558
- outline: none;
559
565
  font-size: 13px;
560
566
  height: 40px;
561
567
 
@@ -594,6 +600,11 @@ mat-selection-list.mat-mdc-selection-list {
594
600
  .mat-mdc-menu-item {
595
601
  background: transparent;
596
602
  opacity: 1 !important;
603
+
604
+ // Material drops the outline on focus; mark it like a focused option.
605
+ &:focus-visible {
606
+ box-shadow: variables.$option-focus-shadow;
607
+ }
597
608
  }
598
609
 
599
610
  .tb-menu.tb-header-menu.tb-module-menu {
@@ -615,6 +626,21 @@ mat-selection-list.mat-mdc-selection-list {
615
626
  border-bottom-left-radius: 4px;
616
627
  border-bottom-right-radius: 4px;
617
628
  }
629
+
630
+ // The current module is a place, not a chosen value: light tint plus a blue bar, not the strong fill.
631
+ mat-selection-list.mat-mdc-selection-list .mat-mdc-list-option[aria-selected='true'],
632
+ mat-selection-list.mat-mdc-selection-list .mat-mdc-list-option[aria-checked='true'] {
633
+ background: variables.$active-background;
634
+ color: variables.$text-color;
635
+ --mdc-list-list-item-label-text-color: #{variables.$text-color};
636
+ --mdc-list-list-item-hover-label-text-color: #{variables.$text-color};
637
+ --mdc-list-list-item-focus-label-text-color: #{variables.$text-color};
638
+ box-shadow: inset 3px 0 0 variables.$focus-ring-color;
639
+
640
+ &:focus-visible {
641
+ box-shadow: variables.$option-focus-shadow;
642
+ }
643
+ }
618
644
  }
619
645
  }
620
646
 
@@ -754,32 +780,32 @@ tb-sidenav {
754
780
  opacity: 0.5;
755
781
  }
756
782
 
757
- &.parent-node[aria-level='1'] .list-option-item,
758
- &.parent-node[aria-level='1'] .mat-mdc-checkbox {
783
+ &.parent-node:is([aria-level='1'], [data-level='1']) .list-option-item,
784
+ &.parent-node:is([aria-level='1'], [data-level='1']) .mat-mdc-checkbox {
759
785
  font-weight: 600;
760
786
  }
761
787
 
762
- &[aria-level='2'] .mdc-list-item__content {
788
+ &:is([aria-level='2'], [data-level='2']) .mdc-list-item__content {
763
789
  padding-left: 17px;
764
790
  }
765
791
 
766
- &.expendable-disabled[aria-level='3'] .mdc-list-item__content {
792
+ &.expendable-disabled:is([aria-level='3'], [data-level='3']) .mdc-list-item__content {
767
793
  padding-left: 64px;
768
794
  }
769
795
 
770
- &.expendable-disabled[aria-level='2'] .mdc-list-item__content {
796
+ &.expendable-disabled:is([aria-level='2'], [data-level='2']) .mdc-list-item__content {
771
797
  padding-left: 43px;
772
798
  }
773
799
 
774
- &.expendable-disabled[aria-level='1'] .mdc-list-item__content {
800
+ &.expendable-disabled:is([aria-level='1'], [data-level='1']) .mdc-list-item__content {
775
801
  padding-left: 26px;
776
802
  }
777
803
 
778
- &[aria-level='1'].tb-pointer-event-none~[aria-level='2'] .mdc-list-item__content {
804
+ &:is([aria-level='1'], [data-level='1']).tb-pointer-event-none~:is([aria-level='2'], [data-level='2']) .mdc-list-item__content {
779
805
  padding-left: 7px;
780
806
  }
781
807
 
782
- &[aria-level='2'] tb-icon .tb-icon {
808
+ &:is([aria-level='2'], [data-level='2']) tb-icon .tb-icon {
783
809
  margin-left: 18px;
784
810
  }
785
811
 
@@ -789,7 +815,7 @@ tb-sidenav {
789
815
  }
790
816
 
791
817
  &:not(.has-children) mat-tree-node.mat-tree-node {
792
- &[aria-level='1'] .mdc-list-item__content {
818
+ &:is([aria-level='1'], [data-level='1']) .mdc-list-item__content {
793
819
  padding-left: 10px;
794
820
 
795
821
  mat-checkbox {
@@ -107,6 +107,8 @@ mat-radio-group.mat-mdc-radio-group.tb-elem-radio.select-module {
107
107
  mat-radio-button.mat-mdc-radio-button {
108
108
  height: 60px;
109
109
  width: 310px;
110
+ // Narrow dialogs: the card shrinks to the dialog instead of scrolling sideways.
111
+ max-width: 100%;
110
112
 
111
113
  .mdc-label {
112
114
  display: flex;
@@ -128,6 +130,7 @@ mat-radio-group.mat-mdc-radio-group.tb-elem-radio.access-profile-types {
128
130
  mat-radio-button.mat-mdc-radio-button {
129
131
  flex: 1;
130
132
  width: 430px;
133
+ max-width: 100%;
131
134
 
132
135
  .mdc-label {
133
136
  display: flex;
@@ -263,11 +266,13 @@ mat-radio-group.mat-mdc-radio-group.tb-elem-radio.card-box.tb-radio-card-fill {
263
266
  // Default Tenant Settings — Vend Gate presents its interaction modes as cards.
264
267
  mat-radio-group.mat-mdc-radio-group.tb-elem-radio.command-interaction-modes {
265
268
  display: flex;
269
+ flex-wrap: wrap;
266
270
  gap: 10px;
267
271
 
268
272
  mat-radio-button.mat-mdc-radio-button {
269
273
  height: 48px;
270
274
  width: 220px;
275
+ max-width: 100%;
271
276
 
272
277
  .mdc-label {
273
278
  font-weight: variables.$font-weight-semi-bold;