@dereekb/dbx-web 13.16.0 → 13.18.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 (40) hide show
  1. package/_index.scss +4 -1
  2. package/eslint/package.json +4 -4
  3. package/fesm2022/dereekb-dbx-web-mapbox.mjs +2 -2
  4. package/fesm2022/dereekb-dbx-web-mapbox.mjs.map +1 -1
  5. package/fesm2022/dereekb-dbx-web-style-demo.mjs +1698 -0
  6. package/fesm2022/dereekb-dbx-web-style-demo.mjs.map +1 -0
  7. package/fesm2022/dereekb-dbx-web-table.mjs +1 -1
  8. package/fesm2022/dereekb-dbx-web-table.mjs.map +1 -1
  9. package/fesm2022/dereekb-dbx-web.mjs +460 -333
  10. package/fesm2022/dereekb-dbx-web.mjs.map +1 -1
  11. package/lib/button/_button.scss +74 -98
  12. package/lib/extension/pdf/_pdf.scss +5 -5
  13. package/lib/extension/table/_table.scss +2 -2
  14. package/lib/interaction/detach/_detach.scss +22 -2
  15. package/lib/interaction/dialog/_dialog.scss +4 -8
  16. package/lib/interaction/popup/_popup.scss +1 -2
  17. package/lib/interaction/prompt/_prompt.scss +7 -2
  18. package/lib/layout/avatar/_avatar.scss +8 -0
  19. package/lib/layout/bar/_bar.scss +41 -2
  20. package/lib/layout/card/_card.scss +191 -3
  21. package/lib/layout/column/_column.scss +3 -3
  22. package/lib/layout/content/_content.scss +24 -9
  23. package/lib/layout/list/_list.scss +87 -10
  24. package/lib/layout/section/_section.scss +7 -8
  25. package/lib/layout/style/_style.scss +44 -9
  26. package/lib/layout/text/_text.scss +73 -29
  27. package/lib/loading/_loading.scss +9 -2
  28. package/lib/router/layout/navbar/_navbar.scss +14 -0
  29. package/lib/router/layout/sidenav/_sidenav.scss +2 -2
  30. package/lib/style/_core.scss +4 -0
  31. package/lib/style/_corners.scss +79 -0
  32. package/lib/style/_root-variables.scss +17 -0
  33. package/lib/style/_shapes.scss +56 -0
  34. package/lib/style/_style-demo.scss +183 -0
  35. package/lib/style/_variables.scss +8 -1
  36. package/package.json +11 -7
  37. package/style-demo/README.md +12 -0
  38. package/types/dereekb-dbx-web-style-demo.d.ts +883 -0
  39. package/types/dereekb-dbx-web.d.ts +170 -79
  40. package/lib/style/_m2-visual-compat.scss +0 -120
@@ -5,18 +5,57 @@
5
5
  // MARK: Mixin
6
6
  @mixin core() {
7
7
  /// @dbx-utility mat-card-dbx-color
8
- /// @intent re-emits the dbx-color background paint at higher specificity than MDC's `.mat-mdc-card` `background-color` rule, so a host-level `[dbxColor]` on `<mat-card>` shows through every appearance variant (elevated / outlined / filled). Tonal opacity is honoured via the existing `--dbx-color-bg-tone` channel; in tonal mode the text color flips to the vibrant theme color so contrast survives the light wash.
8
+ /// @intent re-emits the dbx-color background paint at higher specificity than MDC's `.mat-mdc-card` `background-color` rule, so a host-level `[dbxColor]` on `<mat-card>` shows through every appearance variant (elevated / outlined / filled). Tonal opacity is honoured via the existing `--dbx-color-bg-tone` channel; in tonal mode the text color flips to the vibrant theme color so contrast survives the light wash. A zero-specificity `:where(:not(.dbx-card-color-accent))` guard exempts the `.dbx-card-color-accent` card so its body stays unpainted while only its left edge takes the bound color.
9
9
  /// @role color
10
- /// @see-also color, color-bg, color-tonal
11
- mat-card.dbx-color {
10
+ /// @see-also color, color-bg, color-tonal, card-color-accent
11
+ mat-card.dbx-color:where(:not(.dbx-card-color-accent)) {
12
12
  background: color-mix(in srgb, var(#{theming.$dbx-bg-color-var}) var(#{theming.$dbx-bg-tone-var}, 100%), transparent);
13
13
  color: var(#{theming.$dbx-color-var});
14
14
 
15
+ // outlined buttons inside the painted card follow the card's contrast color — the M3 default
16
+ // primary label/outline may be illegible on the painted surface (e.g. an inverse-surface card).
17
+ --mat-button-outlined-label-text-color: var(#{theming.$dbx-color-var});
18
+ --mat-button-outlined-outline-color: color-mix(in srgb, var(#{theming.$dbx-color-var}) 30%, transparent);
19
+
15
20
  &.dbx-color-tonal {
16
21
  color: var(#{theming.$dbx-bg-color-var});
22
+ --mat-button-outlined-label-text-color: var(#{theming.$dbx-bg-color-var});
23
+ --mat-button-outlined-outline-color: color-mix(in srgb, var(#{theming.$dbx-bg-color-var}) 30%, transparent);
17
24
  }
18
25
  }
19
26
 
27
+ /// @dbx-utility mat-card-content-flex-column
28
+ /// @intent re-emits the `.dbx-flex-column` display at higher specificity than MDC's `.mat-mdc-card-content` `display: block` rule, so the flex utilities work on `<mat-card-content>` — pair with `.dbx-flex-fill` on the content (fills the card's stretched height) and on a child (absorbs the remaining height).
29
+ /// @role flex
30
+ /// @see-also flex-column, flex-fill, mat-card-dbx-color
31
+ mat-card-content.dbx-flex-column {
32
+ display: flex;
33
+ flex-direction: column;
34
+ }
35
+
36
+ /// @dbx-utility card-accent
37
+ /// @intent accent-edged `<mat-card>` — paints a solid border down the card's left edge to flag or categorize the card. Defaults to the M3 primary color; override `--dbx-card-accent-color` for a different hue or `--dbx-card-accent-border-width` for thickness.
38
+ /// @role layout
39
+ /// @see-also card-banner, card-select, color
40
+ // The extra `mat-card.`-qualified selector out-specifies MDC's later-emitted
41
+ // `.mdc-card--outlined` border shorthand, which would otherwise reset the
42
+ // accent edge back to the 1px outline on outlined cards.
43
+ .dbx-card-accent,
44
+ mat-card.dbx-card-accent {
45
+ border-left: var(--dbx-card-accent-border-width, 4px) solid var(--dbx-card-accent-color, var(--mat-sys-primary));
46
+ }
47
+
48
+ /// @dbx-utility card-color-accent
49
+ /// @intent accent-edged status `<mat-card>` driven by `[dbxColor]` — the left edge paints from the bound color's `--dbx-bg-color-current` token while the card body keeps its normal unpainted surface (the `mat-card.dbx-color` surface paint exempts this class via its `:where()` guard). Always pair with `[dbxColor]` (e.g. `dbxColor="success"`); override `--dbx-card-accent-border-width` for thickness. Caveat: the theme root declares a default `--dbx-bg-color-current`, so without a bound `[dbxColor]` the edge shows that inherited default, not the `--mat-sys-primary` fallback.
50
+ /// @role layout
51
+ /// @see-also card-accent, color, mat-card-dbx-color
52
+ // `mat-card.`-qualified for the same `.mdc-card--outlined` border-shorthand
53
+ // reason as `.dbx-card-accent` above.
54
+ .dbx-card-color-accent,
55
+ mat-card.dbx-card-color-accent {
56
+ border-left: var(--dbx-card-accent-border-width, 4px) solid var(--dbx-bg-color-current, var(--dbx-card-accent-color, var(--mat-sys-primary)));
57
+ }
58
+
20
59
  /// @dbx-utility card-banner
21
60
  /// @intent banner-style `<mat-card>` — pair with `[dbxColor]` (+ `[dbxColorTone]`) for the tonal surface. Drop `<mat-card-header>` entirely; put the icon + `<mat-card-title>` row inside `<mat-card-content>` via a `.dbx-card-banner-header` child, and the action buttons inside `<mat-card-footer>`.
22
61
  /// @role layout
@@ -89,6 +128,155 @@
89
128
  --mat-outlined-card-outline-width: 2px;
90
129
  }
91
130
  }
131
+
132
+ /// @dbx-utility card-horizontal
133
+ /// @intent horizontally scrolling row of fixed-width, equal-height `.dbx-card-horizontal-item` cards — `align-items: stretch` keeps the cards equal-height while `overflow-x: auto` scrolls the row on narrow viewports. Because `overflow-x: auto` forces vertical overflow to clip, the row reserves headroom via `padding-top` so a `.dbx-card-horizontal-tab` chip poking above a card stays inside the scrollable padding box instead of being clipped; override `--dbx-card-horizontal-tab-overlap` to change the headroom together with the tab.
134
+ /// @role layout
135
+ /// @see-also card-horizontal-item, flex-bar, chip
136
+ .dbx-card-horizontal {
137
+ display: flex;
138
+ align-items: stretch;
139
+ gap: var(--dbx-padding-3);
140
+ overflow-x: auto;
141
+ // overflow-x:auto computes overflow-y to auto — anything above the row's
142
+ // padding box is scroll-clipped and unreachable, so a poking tab must live
143
+ // INSIDE the padding box: reserve its overlap height as top padding.
144
+ padding-top: calc(var(--dbx-card-horizontal-tab-overlap, 10px) + var(--dbx-padding-1));
145
+ padding-bottom: var(--dbx-padding-2);
146
+ }
147
+
148
+ /// @dbx-utility card-horizontal-item
149
+ /// @intent fixed-width card for a `.dbx-card-horizontal` row — apply to `<mat-card appearance="outlined">`. Children: an optional `.dbx-card-horizontal-tab` `<dbx-chip>` (absolutely positioned poking above the top edge), an optional full-bleed `.dbx-card-horizontal-header` status bar (plain `<div>` placed BEFORE `<mat-card-content>` — mat-card children stack in a padding-less flex column, so the bar is edge-to-edge for free), the `<mat-card-content>` body, and a `<mat-card-footer>` CTA pushed to the card bottom via `margin-top: auto` so stretch-aligned cards keep their buttons on one line. Toggle `.dbx-card-horizontal-item-highlight` to repaint the outlined-card border in the primary color. Override `--dbx-card-horizontal-item-width` for a different card width.
150
+ /// @role layout
151
+ /// @see-also card-horizontal, card-horizontal-header, card-select, chip, color
152
+ .dbx-card-horizontal-item {
153
+ position: relative;
154
+ flex: 0 0 var(--dbx-card-horizontal-item-width, 300px);
155
+ width: var(--dbx-card-horizontal-item-width, 300px);
156
+
157
+ // the header div is the first child, so MDC's
158
+ // `mat-card-content:first-child { padding-top: 16px }` no longer fires —
159
+ // restore the body's top inset.
160
+ > mat-card-content {
161
+ padding-top: var(--dbx-padding-3);
162
+ }
163
+
164
+ // mat-card is already a flex column — anchor the CTA to the card bottom.
165
+ > mat-card-footer {
166
+ margin-top: auto;
167
+ padding: var(--dbx-padding-2) var(--dbx-padding-3) var(--dbx-padding-3);
168
+
169
+ > button,
170
+ > a {
171
+ width: 100%;
172
+ }
173
+ }
174
+
175
+ // highlight (e.g. "today") — repaint the outlined-card border (same
176
+ // pattern as `.dbx-card-select.dbx-card-selected`).
177
+ &.dbx-card-horizontal-item-highlight {
178
+ --mat-outlined-card-outline-color: var(--mat-sys-primary);
179
+ --mat-outlined-card-outline-width: 2px;
180
+ }
181
+ }
182
+
183
+ /// @dbx-utility card-horizontal-header
184
+ /// @intent full-bleed status bar across the top of a `.dbx-card-horizontal-item` — a plain `<div>` direct child of `<mat-card>` before `<mat-card-content>`. Pair with `[dbxColor]` for a solid bar or `[dbxColor]` + `[dbxColorTone]` for a tonal wash (tonal mode flips the label to the vibrant theme color). Compose the label from `.dbx-text-label-medium .dbx-uppercase .dbx-tracked-wide`; lead with a `<mat-icon>` or a `.dbx-card-horizontal-header-dot`.
185
+ /// @role layout
186
+ /// @see-also card-horizontal-item, card-horizontal-header-dot, color, color-tonal
187
+ .dbx-card-horizontal-header {
188
+ display: flex;
189
+ align-items: center;
190
+ gap: var(--dbx-padding-2);
191
+ padding: var(--dbx-padding-2) var(--dbx-padding-3);
192
+ border-top-left-radius: inherit;
193
+ border-top-right-radius: inherit;
194
+ }
195
+
196
+ // `[dbxColor]` provides the tokens + the `.dbx-color` marker; the header paints
197
+ // itself from them (mirrors `mat-card.dbx-color`). The `:not(.dbx-default)` guard
198
+ // keeps an uncolored header from painting (the marker is always applied). Tonal
199
+ // mode flips the label to the vibrant color.
200
+ .dbx-card-horizontal-header.dbx-color:not(.dbx-default) {
201
+ background: color-mix(in srgb, var(#{theming.$dbx-bg-color-var}) var(#{theming.$dbx-bg-tone-var}, 100%), transparent);
202
+ color: var(#{theming.$dbx-color-var});
203
+
204
+ &.dbx-color-tonal {
205
+ color: var(#{theming.$dbx-bg-color-var});
206
+ }
207
+ }
208
+
209
+ /// @dbx-utility card-horizontal-header-dot
210
+ /// @intent small status dot inside a `.dbx-card-horizontal-header` — painted from `currentColor` so it follows the header's (tonal) text color with no extra color wiring.
211
+ /// @role layout
212
+ /// @see-also card-horizontal-header
213
+ .dbx-card-horizontal-header-dot {
214
+ flex-shrink: 0;
215
+ width: var(--dbx-card-horizontal-header-dot-size, 8px);
216
+ height: var(--dbx-card-horizontal-header-dot-size, 8px);
217
+ border-radius: 50%;
218
+ background: currentColor;
219
+ }
220
+
221
+ /// @dbx-utility card-horizontal-tab
222
+ /// @intent "TODAY"-style tab — apply to a `<dbx-chip [tone]="100" [small]="true">` inside a `.dbx-card-horizontal-item`; absolutely positioned so it pokes above the card's top edge by `--dbx-card-horizontal-tab-overlap` (which the `.dbx-card-horizontal` row also reserves as top padding so the scroll container does not clip it).
223
+ /// @role layout
224
+ /// @see-also card-horizontal, card-horizontal-item, chip
225
+ // Scoped under the item (0,2,0 specificity) so `position: absolute` beats
226
+ // `.dbx-chip`'s later-emitted `position: relative` (text.core() runs after
227
+ // card.core() in all-layout-core).
228
+ .dbx-card-horizontal-item .dbx-card-horizontal-tab {
229
+ position: absolute;
230
+ top: calc(-1 * var(--dbx-card-horizontal-tab-overlap, 10px));
231
+ left: var(--dbx-padding-3);
232
+ z-index: 1;
233
+ }
234
+
235
+ /// @dbx-utility card-horizontal-detail
236
+ /// @intent compact icon + text detail row (location / dates / time) inside a `.dbx-card-horizontal-item` body — muted `on-surface-variant` text with a small leading `<mat-icon>`; also fits a label/value row when composed with `.dbx-spacer`.
237
+ /// @role layout
238
+ /// @see-also card-horizontal-item, spacer, hint
239
+ .dbx-card-horizontal-detail {
240
+ display: flex;
241
+ align-items: center;
242
+ gap: var(--dbx-padding-2);
243
+ padding: var(--dbx-padding-1) 0;
244
+ color: var(--mat-sys-on-surface-variant);
245
+
246
+ > mat-icon {
247
+ flex-shrink: 0;
248
+ width: var(--dbx-card-horizontal-detail-icon-size, 18px);
249
+ height: var(--dbx-card-horizontal-detail-icon-size, 18px);
250
+ font-size: var(--dbx-card-horizontal-detail-icon-size, 18px);
251
+ }
252
+ }
253
+
254
+ /// @dbx-utility card-horizontal-divider
255
+ /// @intent hairline divider between `.dbx-card-horizontal-item` body sections — the standard `--mat-sys-outline-variant` border-bottom pattern with vertical rhythm baked in.
256
+ /// @role layout
257
+ /// @see-also card-horizontal-item
258
+ .dbx-card-horizontal-divider {
259
+ border-bottom: 1px solid var(--mat-sys-outline-variant);
260
+ margin: var(--dbx-padding-2) 0;
261
+ }
262
+
263
+ /// @dbx-utility card-horizontal-mini
264
+ /// @intent small outlined "mini card" row inside a `.dbx-card-horizontal-item` body (e.g. a recommended job: name + detail left, price right) — outline-variant border, corner-small radius, space-between flex row.
265
+ /// @role layout
266
+ /// @see-also card-horizontal-item, color-text
267
+ .dbx-card-horizontal-mini {
268
+ display: flex;
269
+ align-items: center;
270
+ justify-content: space-between;
271
+ gap: var(--dbx-padding-2);
272
+ padding: var(--dbx-padding-2) var(--dbx-padding-3);
273
+ border: 1px solid var(--mat-sys-outline-variant);
274
+ border-radius: var(--mat-sys-corner-small, 8px);
275
+
276
+ & + & {
277
+ margin-top: var(--dbx-padding-2);
278
+ }
279
+ }
92
280
  }
93
281
 
94
282
  @mixin theme($theme-config) {
@@ -4,7 +4,7 @@
4
4
  $two-column-left-width-var: theming.$two-column-left-width-var;
5
5
  $two-column-left-width: theming.$two-column-left-width;
6
6
  $two-column-navbar-height: theming.$content-navbar-height;
7
- $two-columns-right-padding-size: 6px;
7
+ $two-columns-right-padding-size: var(--dbx-padding-2);
8
8
 
9
9
  // MARK: Mixin
10
10
  @mixin core() {
@@ -83,8 +83,8 @@ $two-columns-right-padding-size: 6px;
83
83
  }
84
84
 
85
85
  .dbx-two-column-head {
86
- padding: 0 6px; // only padded on the left
87
- border-bottom: 1px solid rgba(0, 0, 0, 0.14);
86
+ padding: 0 var(--dbx-padding-2); // only padded on the left
87
+ border-bottom: 1px solid var(--mat-sys-outline-variant);
88
88
  height: $two-column-navbar-height;
89
89
 
90
90
  display: flex;
@@ -57,18 +57,26 @@ $dbx-border-opacity-default: 20%;
57
57
  }
58
58
 
59
59
  /// @dbx-utility content-pit
60
- /// @intent recessed surface pit — `--mat-sys-surface-container` background with a `padding-4` inset, used to visually nest content (e.g. logs, JSON, quoted blocks)
60
+ /// @intent recessed surface pit — `--mat-sys-surface-container` background with a `padding-4` inset, used to visually nest content (e.g. logs, JSON, quoted blocks); rounded by default, opt out with `.dbx-corners-none`
61
61
  /// @role layout
62
- /// @see-also dbx-content-pit-rounded, dbx-content-pit-scrollable, dbx-content-border, dbx-content-elevate
62
+ /// @see-also dbx-content-pit-scrollable, dbx-content-border, dbx-content-elevate, dbx-corners-none
63
63
  .dbx-content-pit {
64
64
  padding: $pit-padding;
65
65
  }
66
66
 
67
+ // Pits round by default. Kept OUT of the `.dbx-content-pit` rule and wrapped
68
+ // in `:where()` so specificity stays at 0 — any single-class utility
69
+ // (`.dbx-corners-none`, `.dbx-corners-large`, or an app class) overrides it.
70
+ :where(.dbx-content-pit) {
71
+ border-radius: theming.$dbx-content-pit-rounded-border-radius;
72
+ }
73
+
67
74
  /// @dbx-utility content-pit-rounded
68
75
  /// @intent rounded modifier for `.dbx-content-pit` — applies the `theming.$dbx-content-pit-rounded-border-radius` corner radius
69
76
  /// @role layout
70
77
  /// @parent content-pit
71
- /// @see-also dbx-content-pit
78
+ /// @see-also dbx-content-pit, dbx-corners-none
79
+ /// @deprecated Pits round by default now; this modifier is a harmless back-compat alias emitting the same radius. To square a pit use `.dbx-corners-none`.
72
80
  .dbx-content-pit-rounded {
73
81
  border-radius: theming.$dbx-content-pit-rounded-border-radius;
74
82
  }
@@ -135,7 +143,7 @@ $dbx-border-opacity-default: 20%;
135
143
  .dbx-content-scroll-lock {
136
144
  height: 100%;
137
145
  overflow: hidden;
138
- padding: 0 2px; // Override padding
146
+ padding: 0 var(--dbx-padding-1); // Override padding
139
147
  }
140
148
 
141
149
  /// @dbx-utility content-container
@@ -153,7 +161,7 @@ $dbx-border-opacity-default: 20%;
153
161
  }
154
162
 
155
163
  &.container-padding-min {
156
- padding: 0 2px;
164
+ padding: 0 var(--dbx-padding-1);
157
165
  }
158
166
 
159
167
  &.container-padding-small {
@@ -165,15 +173,15 @@ $dbx-border-opacity-default: 20%;
165
173
  }
166
174
 
167
175
  &.container-top-padding-min {
168
- padding-top: 2px;
176
+ padding-top: var(--dbx-padding-1);
169
177
  }
170
178
 
171
179
  &.container-top-padding-small {
172
- padding-top: 6px;
180
+ padding-top: var(--dbx-padding-2);
173
181
  }
174
182
 
175
183
  &.container-top-padding-normal {
176
- padding-top: 12px;
184
+ padding-top: var(--dbx-padding-3);
177
185
  }
178
186
 
179
187
  // width
@@ -214,13 +222,20 @@ $dbx-border-opacity-default: 20%;
214
222
  /// @role spacing
215
223
  /// @see-also dbx-content-container, dbx-content-page, dbx-content-pit-scrollable
216
224
  .dbx-scroll-content {
217
- padding-bottom: $scroll-content-bottom-padding;
225
+ padding-bottom: var(--dbx-scroll-content-bottom-padding, #{$scroll-content-bottom-padding});
218
226
  }
219
227
 
220
228
  .dbx-content-pit {
221
229
  background: var(--mat-sys-surface-container);
222
230
  }
223
231
 
232
+ // pits on a [dbxColor]-painted surface wash from the current contrast color instead of the
233
+ // surface-container token, which would clash with the painted background (e.g. a dark inverse
234
+ // card). Override --dbx-content-pit-color-tone (percentage) to tune the wash.
235
+ .dbx-color .dbx-content-pit {
236
+ background: color-mix(in srgb, #{theming.$dbx-color} var(--dbx-content-pit-color-tone, 11%), transparent);
237
+ }
238
+
224
239
  .dbx-content-border {
225
240
  border: 3px dashed color-mix(in srgb, var(--dbx-border-color, var(--mat-sys-outline-variant)) var(--dbx-border-opacity, $dbx-border-opacity-default), transparent);
226
241
  }
@@ -8,6 +8,50 @@ $list-item-padded-min-height: 42px;
8
8
  .dbx-list {
9
9
  overflow: hidden;
10
10
  height: 100%;
11
+
12
+ // dbx-list (selection/standard) rows default to an M3 medium corner via the overridable
13
+ // `--dbx-list-item-border-radius` token; `.dbx-list-square-items` zeroes it and the style-demo
14
+ // `list-corner-*` levers re-point it. Both shape tokens resolve to the same value, so no
15
+ // `border-radius` redeclaration is needed; the more specific `.dbx-list-card-items-list` item rule
16
+ // deliberately wins for card lists.
17
+ --mat-list-active-indicator-shape: var(--dbx-list-item-border-radius, var(--mat-sys-corner-medium, 12px));
18
+ --mat-list-list-item-container-shape: var(--dbx-list-item-border-radius, var(--mat-sys-corner-medium, 12px));
19
+
20
+ .mat-mdc-list-item {
21
+ --mat-focus-indicator-border-radius: var(--mat-list-list-item-container-shape);
22
+ }
23
+ }
24
+
25
+ // dbx-anchor-list (nav) rows default to an M3 medium corner via their OWN
26
+ // `--dbx-anchor-list-item-border-radius` token — separate from `.dbx-list` so the style-demo
27
+ // `anchor-list-corner-*` levers control anchor lists independently. `.dbx-list-square-items`
28
+ // zeroes this token too. The `.dbx-anchor-list` class lives on the inner `mat-nav-list`.
29
+ .dbx-anchor-list {
30
+ --mat-list-active-indicator-shape: var(--dbx-anchor-list-item-border-radius, var(--mat-sys-corner-medium, 12px));
31
+ --mat-list-list-item-container-shape: var(--dbx-anchor-list-item-border-radius, var(--mat-sys-corner-medium, 12px));
32
+
33
+ .mat-mdc-list-item {
34
+ --mat-focus-indicator-border-radius: var(--mat-list-list-item-container-shape);
35
+ }
36
+ }
37
+
38
+ // The sidenav anchor list rows sit flush against the left screen edge, so only the RIGHT corners round —
39
+ // the radius is composed into a `0 r r 0` shorthand (top-left / top-right / bottom-right / bottom-left),
40
+ // leaving the left corners square. The "how round" radius defaults to the regular anchor-list radius
41
+ // (`--dbx-anchor-list-item-border-radius`) so the sidenav tracks the `anchor-list-corner-*` lever by default,
42
+ // but `--dbx-sidenav-anchor-list-item-border-radius` overrides it for sidenav-specific tuning. Higher
43
+ // specificity than `.dbx-anchor-list`, so it wins for the inner nav-list inside a sidenav host.
44
+ .dbx-sidenav-anchor-list .dbx-anchor-list {
45
+ --mat-list-active-indicator-shape: 0 var(--dbx-sidenav-anchor-list-item-border-radius, var(--dbx-anchor-list-item-border-radius, var(--mat-sys-corner-medium, 12px))) var(--dbx-sidenav-anchor-list-item-border-radius, var(--dbx-anchor-list-item-border-radius, var(--mat-sys-corner-medium, 12px))) 0;
46
+ --mat-list-list-item-container-shape: 0 var(--dbx-sidenav-anchor-list-item-border-radius, var(--dbx-anchor-list-item-border-radius, var(--mat-sys-corner-medium, 12px))) var(--dbx-sidenav-anchor-list-item-border-radius, var(--dbx-anchor-list-item-border-radius, var(--mat-sys-corner-medium, 12px))) 0;
47
+ }
48
+
49
+ // MDC's two-line + leading-icon variant sizes the primary-text baseline-spacer `::before` to 32px, taller than
50
+ // the 28px the two-line (no-leading-icon) rule uses, which over-tall the title box and pushes the title/hint
51
+ // group off-center in dbx-anchor custom-anchor rows (reads as top-aligned). Pin the spacer back to 28px within
52
+ // anchor lists so the rows center vertically (selection lists, which keep MDC's structure, are untouched).
53
+ .dbx-anchor-list .mdc-list-item--with-leading-icon.mdc-list-item--with-two-lines .mdc-list-item__primary-text::before {
54
+ height: 28px;
11
55
  }
12
56
 
13
57
  .dbx-list-empty-content {
@@ -94,7 +138,7 @@ $list-item-padded-min-height: 42px;
94
138
  .dbx-list-view-group {
95
139
  .dbx-list-view-group-header {
96
140
  .dbx-list-two-line-item .dbx-list-two-line-item-with-icon {
97
- padding: 2px 0; // override the padding when there is an icon
141
+ padding: var(--dbx-padding-1) 0; // override the padding when there is an icon
98
142
  }
99
143
  }
100
144
  }
@@ -122,8 +166,8 @@ $list-item-padded-min-height: 42px;
122
166
  /// @role spacing
123
167
  /// @see-also dbx-list-item-padded-thick, dbx-list-item-p0
124
168
  .dbx-list-item-padded {
125
- min-height: $list-item-padded-min-height;
126
- padding: 2px 6px;
169
+ min-height: var(--dbx-list-item-padded-min-height, #{$list-item-padded-min-height});
170
+ padding: var(--dbx-padding-1) var(--dbx-padding-2);
127
171
  }
128
172
 
129
173
  /// @dbx-utility list-item-padded-thick
@@ -131,10 +175,16 @@ $list-item-padded-min-height: 42px;
131
175
  /// @role spacing
132
176
  /// @see-also dbx-list-item-padded
133
177
  .dbx-list-item-padded-thick {
134
- min-height: $list-item-padded-min-height;
178
+ min-height: var(--dbx-list-item-padded-min-height, #{$list-item-padded-min-height});
135
179
  padding: theming.$padding-3;
136
180
  }
137
181
 
182
+ // No side padding if the parent list component has the dbx-list-no-item-padding class.
183
+ .dbx-list-no-item-padding .dbx-list-item-padded {
184
+ padding-left: 0;
185
+ padding-right: 0;
186
+ }
187
+
138
188
  // Card-style list — each row becomes a tinted, rounded surface that lives
139
189
  // on the actual `.mat-mdc-list-item`, not on a nested template `<div>`.
140
190
  // Apply this modifier as the host class on the list wrapper component so
@@ -178,12 +228,26 @@ $list-item-padded-min-height: 42px;
178
228
  }
179
229
  }
180
230
 
231
+ // Opts a list out of the default medium-rounded rows back to square (0). Custom properties inherit, so
232
+ // applying this on a `dbx-list` / `dbx-anchor-list` host (or any ancestor) squares selection and nav rows
233
+ // alike by zeroing both the `.dbx-list` (`--dbx-list-item-border-radius`) and `.dbx-anchor-list`
234
+ // (`--dbx-anchor-list-item-border-radius`) row tokens. The sidenav keeps its own token; the card-list
235
+ // (`.dbx-list-card-items-list`) item rule is more specific and keeps its own shape.
236
+ /// @dbx-utility list-square-items
237
+ /// @intent opts a `.dbx-list` / `.dbx-anchor-list` out of the default medium-rounded rows back to square (0 radius) by zeroing their row radius tokens
238
+ /// @role layout
239
+ /// @see-also dbx-list-card-items-list
240
+ .dbx-list-square-items {
241
+ --dbx-list-item-border-radius: 0;
242
+ --dbx-anchor-list-item-border-radius: 0;
243
+ }
244
+
181
245
  // When the tile is the leading icon in a two-line list item, override the
182
246
  // default `.item-icon` flat spacing with tile-appropriate margins. The
183
247
  // base `.dbx-icon-tile` rule lives in `_text.scss` next to its component.
184
248
  .dbx-list-two-line-item .item-icon.dbx-icon-tile {
185
- padding: 8px;
186
- margin: 0 12px 0 4px;
249
+ padding: var(--dbx-icon-tile-padding, 8px);
250
+ margin: 0 var(--dbx-padding-3) 0 0;
187
251
  }
188
252
 
189
253
  /// @dbx-utility list-two-line-item
@@ -243,20 +307,33 @@ $list-item-padded-min-height: 42px;
243
307
  }
244
308
 
245
309
  /// @dbx-utility list-no-item-padding
246
- /// @intent zero the inner `.mat-mdc-list-item-content` padding on every nav-list row in a `.dbx-list`
310
+ /// @intent zero the padding on every list row in a `.dbx-list` — container-scope complement to `dbx-list-item-p0`
247
311
  /// @role spacing
248
312
  /// @see-also dbx-list-item-p0
249
- .dbx-list-no-item-padding .dbx-list > .dbx-list-content .dbx-list-view > .mat-mdc-nav-list .dbx-list-view-item.mat-mdc-list-item > .mat-mdc-list-item-content {
313
+ .dbx-list-no-item-padding .dbx-list > .dbx-list-content .dbx-list-view .mat-mdc-list-item {
250
314
  padding: 0;
251
315
  }
252
316
 
317
+ // `.dbx-list` defaults to `height: 100%` so it fills a fixed-height scroll
318
+ // container. When a list instead flows inline with other content (e.g. card
319
+ // content rendered below it), that percentage resolves against the stretched
320
+ // ancestor and pushes the trailing content out of the card. This modifier
321
+ // lets the list size to its rows.
322
+ /// @dbx-utility list-auto-height
323
+ /// @intent size a `.dbx-list` to its rows instead of filling its container — apply on the list wrapper host when content flows below the list (the default `height: 100%` would push that content out of a stretched card)
324
+ /// @role layout
325
+ /// @see-also list-no-hover-effects, list-no-item-padding
326
+ .dbx-list-auto-height .dbx-list {
327
+ height: auto;
328
+ }
329
+
253
330
  // Zeros all padding on the underlying Material list item. Per-item utility
254
331
  // (apply as host class on the value-list view) for templates that supply
255
332
  // their own padding/leading element — e.g. a `.dbx-icon-tile` in a
256
333
  // `.dbx-list-two-line-item-with-icon` — where Material's default item
257
334
  // padding would otherwise double up. Complements the container-scope
258
- // `.dbx-list-no-item-padding`, which zeros the inner
259
- // `.mat-mdc-list-item-content` padding for all items in the list.
335
+ // `.dbx-list-no-item-padding`, which zeros the same `.mat-mdc-list-item`
336
+ // padding for every row in the list.
260
337
  /// @dbx-utility list-item-p0
261
338
  /// @intent zero all padding on the host `.mat-mdc-list-item` — per-item complement to `.dbx-list-no-item-padding` for templates that supply their own padding/leading element
262
339
  /// @role spacing
@@ -7,7 +7,6 @@ $content-navbar-height: theming.$content-navbar-height;
7
7
 
8
8
  $page-h1-height: 32px;
9
9
 
10
- $header-bottom-margin: 16px;
11
10
  $header-left-reserved-space: 200px;
12
11
  $header-left-reserved-space-small-screen: 120px;
13
12
 
@@ -33,7 +32,7 @@ $header-left-reserved-space-small-screen: 120px;
33
32
  h5 {
34
33
  padding-top: 4px;
35
34
  padding-bottom: 1px;
36
- min-height: $page-h1-height;
35
+ min-height: var(--dbx-section-header-title-height, #{$page-h1-height});
37
36
  display: inline-flex;
38
37
  align-items: center;
39
38
  margin: 0;
@@ -41,8 +40,8 @@ $header-left-reserved-space-small-screen: 120px;
41
40
 
42
41
  > .mat-icon {
43
42
  flex-shrink: 0;
44
- padding-right: 2px;
45
- padding-bottom: 2px;
43
+ padding-right: var(--dbx-padding-1);
44
+ padding-bottom: var(--dbx-padding-1);
46
45
  }
47
46
  }
48
47
 
@@ -58,7 +57,7 @@ $header-left-reserved-space-small-screen: 120px;
58
57
  h3,
59
58
  h4,
60
59
  h5 {
61
- height: $page-h1-height;
60
+ height: var(--dbx-section-header-title-height, #{$page-h1-height});
62
61
  }
63
62
  }
64
63
  }
@@ -78,7 +77,7 @@ $header-left-reserved-space-small-screen: 120px;
78
77
  .dbx-section-hint,
79
78
  .dbx-section-hint-inline {
80
79
  margin: 0;
81
- font-size: 16px;
80
+ font-size: var(--mat-sys-body-large-size);
82
81
  }
83
82
 
84
83
  // MARK: Page
@@ -106,7 +105,7 @@ $header-left-reserved-space-small-screen: 120px;
106
105
  max-width: 100%;
107
106
 
108
107
  .dbx-section-header-content-title {
109
- max-width: calc(80% - #{$header-left-reserved-space});
108
+ max-width: calc(80% - var(--dbx-section-page-header-reserved-space, #{$header-left-reserved-space}));
110
109
  min-width: 48px;
111
110
  flex-shrink: 1;
112
111
 
@@ -227,7 +226,7 @@ $header-left-reserved-space-small-screen: 120px;
227
226
  > .dbx-section-header > .dbx-section-header-content {
228
227
  .dbx-section-header-content-title {
229
228
  @include theming.if-small-screen($theme-config) {
230
- max-width: calc(80% - #{$header-left-reserved-space-small-screen});
229
+ max-width: calc(80% - var(--dbx-section-page-header-reserved-space-small-screen, #{$header-left-reserved-space-small-screen}));
231
230
  }
232
231
  }
233
232
  }
@@ -160,28 +160,48 @@
160
160
  @include define-dbx-color-class($color, map.get($colorConfig, 'color'), map.get($colorConfig, 'contrast'));
161
161
  }
162
162
 
163
+ /// @dbx-utility color-bg
164
+ /// @intent the painting utility — paints `background` (a `color-mix` of `--dbx-bg-color-current` with `--dbx-color-bg-tone`) plus the contrast `color` from `--dbx-color-current`. Pair with `[dbxColor]` (or a static `dbx-{color}-bg` token class) on the same element to supply those tokens. `[dbxColor]` itself never paints; this class (or a component's own `.dbx-color`-scoped SCSS) is what turns the tokens into a visible surface.
165
+ /// @role color
166
+ /// @see-also color-text, color-tonal
167
+ .dbx-color-bg {
168
+ @include dbx-color-bg-body();
169
+ }
170
+
163
171
  // tonal mode: use the vibrant theme color as text instead of the contrast color.
164
172
  // Applied via CSS class (not [style.color]) to avoid conflicting with [ngStyle] on buttons.
173
+ // Declared after `.dbx-color-bg` so the tonal `color:` wins the same-specificity
174
+ // cascade when both classes are present on the painted surface.
165
175
  /// @dbx-utility color-tonal
166
- /// @intent paint text with the vibrant `--dbx-bg-color` (tonal mode) instead of the contrast color — pair with `[dbxColor]` + `[dbxColorTone]` for the muted background variant
176
+ /// @intent paint text with the vibrant `--dbx-bg-color` (tonal mode) instead of the contrast color — pair with `.dbx-color-bg` + `[dbxColor]` + `[dbxColorTone]` for the muted background variant
167
177
  /// @role state
178
+ /// @see-also color-bg
168
179
  .dbx-color-tonal {
169
180
  color: var(#{theming.$dbx-bg-color-var});
170
181
  }
171
182
 
172
- /// @dbx-utility color-bg
173
- /// @intent generic themed-background class — pair with `[dbxColor]="config"` to drive `--dbx-bg-color-current` / `--dbx-color-current` from arbitrary CSS color values
174
- /// @role color
175
- .dbx-color-bg {
176
- @include dbx-color-bg-body();
177
- }
178
-
179
183
  /// @dbx-utility color-text
180
184
  /// @intent generic themed-text class — pair with `[dbxTextColor]="config"` to drive `--dbx-color-current` from an arbitrary CSS color value
181
185
  /// @role color
182
186
  .dbx-color-text {
183
187
  color: #{theming.$dbx-color};
184
188
  }
189
+
190
+ /// @dbx-utility color-border
191
+ /// @intent subtle themed solid border derived from the current dbxColor text color (`--dbx-color-current`) — pair with `[dbxColor]`/`[dbxTextColor]` on the element or any ancestor (custom properties inherit); override `--dbx-color-border-tone` (percentage) for subtlety or `--dbx-color-border-width` for thickness
192
+ /// @role color
193
+ /// @see-also color-bg, color-text, color-tonal
194
+ .dbx-color-border {
195
+ border: var(--dbx-color-border-width, 1px) solid color-mix(in srgb, #{theming.$dbx-color} var(--dbx-color-border-tone, 25%), transparent);
196
+ }
197
+
198
+ /// @dbx-utility color-text-dim
199
+ /// @intent de-emphasized themed text — paints text with a partially-transparent mix of the current dbxColor text color (`--dbx-color-current`), for secondary lines (eyebrows, hints, labels) on painted surfaces where a fixed grey would clash; override `--dbx-color-text-dim-tone` (percentage) to tune the emphasis
200
+ /// @role color
201
+ /// @see-also color-text, color-border, hint
202
+ .dbx-color-text-dim {
203
+ color: color-mix(in srgb, #{theming.$dbx-color} var(--dbx-color-text-dim-tone, 72%), transparent);
204
+ }
185
205
  }
186
206
 
187
207
  @mixin dbx-color-bg-body($default-bg-tone: 100%) {
@@ -190,6 +210,19 @@
190
210
  color: #{theming.$dbx-color};
191
211
  }
192
212
 
213
+ // Paints a colored surface from the inherited dbx color tokens
214
+ // (`--dbx-bg-color-current` / `--dbx-color-current` / `--dbx-color-bg-tone`).
215
+ // Unlike `dbx-color-bg-body`, the tone fallback lives inside the `var(...)`
216
+ // rather than being declared as a property, so the surface does not leak an
217
+ // inheritable `--dbx-color-bg-tone` to nested elements. Scope this on a
218
+ // `.dbx-color` marker (the model is `mat-card.dbx-color` in `_card.scss`) so
219
+ // only hosts directly marked with `[dbxColor]` repaint — token inheritance
220
+ // alone never triggers a repaint.
221
+ @mixin dbx-color-surface($default-bg-tone: 100%) {
222
+ background: color-mix(in srgb, #{theming.$dbx-bg-color} var(#{theming.$dbx-bg-tone-var}, #{$default-bg-tone}), transparent);
223
+ color: #{theming.$dbx-color};
224
+ }
225
+
193
226
  @mixin define-dbx-color-class($name, $color, $contrast, $swap-bg: false) {
194
227
  .dbx-#{$name} {
195
228
  #{theming.$dbx-color-var}: #{$color};
@@ -199,10 +232,12 @@
199
232
  $bg-color: if($swap-bg, $contrast, $color);
200
233
  $bg-text: if($swap-bg, $color, $contrast);
201
234
 
235
+ // Token-only: a `-bg` class declares the color tokens but paints nothing.
236
+ // Painting happens via the `.dbx-color-bg` utility or a component's own
237
+ // `.dbx-color`-scoped SCSS reading these tokens.
202
238
  .dbx-#{$name}-bg {
203
239
  #{theming.$dbx-color-var}: #{$bg-text};
204
240
  #{theming.$dbx-bg-color-var}: #{$bg-color};
205
- @include dbx-color-bg-body();
206
241
  }
207
242
  }
208
243