actual-css 0.4.0 → 0.4.2
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.
- package/CHANGELOG.md +84 -35
- package/dist/actual.css +1 -20
- package/dist/actual.full.css +692 -221
- package/dist/actual.full.js +1 -1
- package/dist/actual.full.min.css +1 -1
- package/dist/actual.min.css +1 -1
- package/docs/design-notes/app-ui.md +33 -0
- package/docs/design-notes/enhancement-contract.md +25 -0
- package/docs/design-notes/grid.md +177 -4
- package/docs/design-notes/references.md +1 -1
- package/docs/navigation.json +7 -1
- package/docs/pages/components/alert.md +5 -0
- package/docs/pages/components/app-navigation.md +34 -0
- package/docs/pages/components/avatar.md +10 -0
- package/docs/pages/components/badge.md +2 -0
- package/docs/pages/components/button.md +30 -0
- package/docs/pages/components/card.md +5 -1
- package/docs/pages/components/fab.md +2 -0
- package/docs/pages/components/indicator.md +52 -0
- package/docs/pages/components/list.md +62 -0
- package/docs/pages/components/navbar.md +6 -0
- package/docs/pages/components/rating.md +68 -0
- package/docs/pages/components/steps.md +57 -0
- package/docs/pages/enhancements/flyout.md +2 -2
- package/docs/pages/enhancements/tabs.md +1 -2
- package/docs/pages/examples/overview.md +8 -0
- package/docs/pages/forms/otp.md +32 -0
- package/docs/pages/forms/states-and-sizes.md +3 -3
- package/docs/pages/guides/integrating-actual-css.md +6 -0
- package/docs/pages/layout/app-layout.md +57 -0
- package/docs/pages/layout/app-shell.md +28 -7
- package/docs/pages/layout/center.md +12 -1
- package/docs/pages/layout/choosing.md +15 -0
- package/docs/pages/layout/grid.md +41 -8
- package/docs/pages/layout/sidebar-layout.md +19 -0
- package/docs/pages/layout/stack.md +17 -0
- package/docs/pages/patterns/icon-slot.md +61 -0
- package/docs/pages/patterns/structured-lists.md +38 -40
- package/package.json +3 -2
- package/scripts/reserved-classes.json +17 -0
- package/src/css/components/actions.css +1 -0
- package/src/css/components/app-nav.css +76 -0
- package/src/css/components/avatar.css +4 -0
- package/src/css/components/badge.css +1 -13
- package/src/css/components/breadcrumb.css +1 -0
- package/src/css/components/button.css +8 -38
- package/src/css/components/card.css +11 -11
- package/src/css/components/chat.css +0 -6
- package/src/css/components/drawer.css +0 -6
- package/src/css/components/fab.css +1 -7
- package/src/css/components/index.css +5 -0
- package/src/css/components/indicator.css +47 -0
- package/src/css/components/list.css +83 -0
- package/src/css/components/menu.css +0 -7
- package/src/css/components/modal.css +0 -17
- package/src/css/components/navbar.css +8 -15
- package/src/css/components/pagination.css +1 -0
- package/src/css/components/rating.css +101 -0
- package/src/css/components/steps.css +123 -0
- package/src/css/components/tab.css +21 -22
- package/src/css/components/tooltip.css +1 -10
- package/src/css/core/focus.css +0 -8
- package/src/css/core/theme.css +0 -10
- package/src/css/core/tokens.css +1 -2
- package/src/css/effects/aura.css +1 -10
- package/src/css/forms/choice-card.css +6 -15
- package/src/css/forms/form-actions.css +1 -0
- package/src/css/forms/otp.css +7 -2
- package/src/css/forms/range.css +14 -4
- package/src/css/layout/app-layout.css +102 -0
- package/src/css/layout/app-shell.css +1 -1
- package/src/css/layout/center.css +1 -0
- package/src/css/layout/cluster.css +1 -0
- package/src/css/layout/container-query.css +6 -4
- package/src/css/layout/grid.css +25 -11
- package/src/css/layout/index.css +4 -2
- package/src/css/layout/scroll-snap.css +1 -0
- package/src/css/layout/sidebar-layout.css +23 -1
- package/src/css/layout/switcher.css +1 -0
- package/src/css/layout/topbar.css +1 -0
- package/src/css/typography/prose.css +4 -0
- package/src/js/tooltip.js +2 -1
- package/docs/pages/layout/list.md +0 -41
package/dist/actual.full.css
CHANGED
|
@@ -208,9 +208,8 @@ select {
|
|
|
208
208
|
@media (forced-colors: active) {
|
|
209
209
|
:root,
|
|
210
210
|
[data-theme] {
|
|
211
|
-
--state-selected: Highlight;
|
|
212
|
-
--state-selected-fg: HighlightText;
|
|
213
211
|
--state-disabled: GrayText;
|
|
212
|
+
--disabled-opacity: 1;
|
|
214
213
|
}
|
|
215
214
|
}
|
|
216
215
|
|
|
@@ -436,16 +435,6 @@ select {
|
|
|
436
435
|
}
|
|
437
436
|
}
|
|
438
437
|
|
|
439
|
-
@media (forced-colors: active) {
|
|
440
|
-
:root,
|
|
441
|
-
[data-theme] {
|
|
442
|
-
--focus-outline-color: Highlight;
|
|
443
|
-
--focus-ring-shadow: none;
|
|
444
|
-
|
|
445
|
-
--backdrop-fill: Canvas;
|
|
446
|
-
}
|
|
447
|
-
}
|
|
448
|
-
|
|
449
438
|
@media (prefers-contrast: more) {
|
|
450
439
|
:root,
|
|
451
440
|
/* The repeated attribute intentionally outranks single-attribute preset
|
|
@@ -680,14 +669,6 @@ small {
|
|
|
680
669
|
:focus:not(:focus-visible) {
|
|
681
670
|
outline: none;
|
|
682
671
|
}
|
|
683
|
-
|
|
684
|
-
/* Pointer focus must still signal in high-contrast mode, where the shared
|
|
685
|
-
box-shadow rings are disabled (--focus-ring-shadow: none). */
|
|
686
|
-
@media (forced-colors: active) {
|
|
687
|
-
:focus:not(:focus-visible) {
|
|
688
|
-
outline: var(--focus-outline);
|
|
689
|
-
}
|
|
690
|
-
}
|
|
691
672
|
}
|
|
692
673
|
|
|
693
674
|
@media print {
|
|
@@ -750,6 +731,10 @@ small {
|
|
|
750
731
|
/* Vertical rhythm belongs to the direct block that participates in the
|
|
751
732
|
document, so it must not be injected into the internals of a nested
|
|
752
733
|
component (e.g. a .table-wrap around a .table would trap the margin). */
|
|
734
|
+
.prose > * {
|
|
735
|
+
margin-block-end: 0;
|
|
736
|
+
}
|
|
737
|
+
|
|
753
738
|
.prose > * + * {
|
|
754
739
|
margin-block-start: var(--prose-flow);
|
|
755
740
|
}
|
|
@@ -1044,12 +1029,13 @@ small {
|
|
|
1044
1029
|
* .center centered content column
|
|
1045
1030
|
* .frame fixed-ratio media frame
|
|
1046
1031
|
* .app-shell full-height application shell
|
|
1032
|
+
* .app-layout topbar + scrolling main + bottom/side app navigation
|
|
1047
1033
|
* .media fixed media + flexible content
|
|
1048
1034
|
* .switcher peer regions: all horizontal or all stacked
|
|
1049
1035
|
* .sidebar-layout main content + secondary aside
|
|
1050
1036
|
* .grid responsive collection; item width is the contract
|
|
1051
|
-
*
|
|
1052
|
-
*
|
|
1037
|
+
* .grid-N structural density of N; balanced inside a container named
|
|
1038
|
+
* actual-grid (in grid.css)
|
|
1053
1039
|
* .column-layout explicit 12-column region composition; the author owns
|
|
1054
1040
|
* narrow-container recomposition
|
|
1055
1041
|
* .scroller theme-aware scrollbar density and colour
|
|
@@ -1060,10 +1046,12 @@ small {
|
|
|
1060
1046
|
*
|
|
1061
1047
|
* Prefer these compositions over viewport breakpoint utilities.
|
|
1062
1048
|
*/
|
|
1063
|
-
/*
|
|
1049
|
+
/* Convenience helper: establishes a query container named actual-grid for
|
|
1064
1050
|
descendants. Use it for a component that changes representation according
|
|
1065
|
-
to its allocated inline size, and to
|
|
1066
|
-
(see grid.css).
|
|
1051
|
+
to its allocated inline size, and to give .grid-N the named context it needs
|
|
1052
|
+
for balanced subdivision (see grid.css). The name matters: grids only respond
|
|
1053
|
+
to an explicitly actual-grid-named container, never to an incidental
|
|
1054
|
+
query container. Layout primitives are responsive without it; this adds
|
|
1067
1055
|
precision, it is never a prerequisite.
|
|
1068
1056
|
|
|
1069
1057
|
The element takes inline-size containment, so put it on a normal
|
|
@@ -1071,7 +1059,7 @@ small {
|
|
|
1071
1059
|
float, an inline-block): its contents would stop contributing to its own
|
|
1072
1060
|
inline size and it would collapse. */
|
|
1073
1061
|
.container-query {
|
|
1074
|
-
container
|
|
1062
|
+
container: actual-grid / inline-size;
|
|
1075
1063
|
}
|
|
1076
1064
|
|
|
1077
1065
|
/* Vertical flow. .stack owns the block axis only: block margins reset, inline
|
|
@@ -1108,6 +1096,7 @@ small {
|
|
|
1108
1096
|
*/
|
|
1109
1097
|
.cluster {
|
|
1110
1098
|
display: flex;
|
|
1099
|
+
flex-direction: row;
|
|
1111
1100
|
flex-wrap: var(--cluster-wrap, wrap);
|
|
1112
1101
|
align-items: var(--cluster-align, center);
|
|
1113
1102
|
justify-content: var(--cluster-justify, flex-start);
|
|
@@ -1127,6 +1116,7 @@ small {
|
|
|
1127
1116
|
*/
|
|
1128
1117
|
.center {
|
|
1129
1118
|
box-sizing: content-box;
|
|
1119
|
+
inline-size: calc(100% - var(--center-pad, 1rem) * 2);
|
|
1130
1120
|
max-inline-size: var(--center-size, 72rem);
|
|
1131
1121
|
margin-inline: auto;
|
|
1132
1122
|
padding-inline: var(--center-pad, 1rem);
|
|
@@ -1152,13 +1142,116 @@ small {
|
|
|
1152
1142
|
object-fit: cover;
|
|
1153
1143
|
}
|
|
1154
1144
|
|
|
1155
|
-
/* Full-height
|
|
1145
|
+
/* Full-height single-column document shell. */
|
|
1156
1146
|
.app-shell {
|
|
1157
1147
|
min-block-size: var(--viewport-block);
|
|
1158
1148
|
display: flex;
|
|
1159
1149
|
flex-direction: column;
|
|
1160
1150
|
}
|
|
1161
1151
|
|
|
1152
|
+
/*
|
|
1153
|
+
* Specialized application shell recipe: one exact DOM structure uses a
|
|
1154
|
+
* bottom navigation bar when narrow and a labelled side navigation when space
|
|
1155
|
+
* permits. The main region owns scrolling, keeping both pieces of application
|
|
1156
|
+
* chrome available without fixed offsets. This is not a generic page wrapper
|
|
1157
|
+
* or a public-site layout; all three direct regions are part of the contract.
|
|
1158
|
+
*
|
|
1159
|
+
* Public hook:
|
|
1160
|
+
* --app-nav-side-size
|
|
1161
|
+
*/
|
|
1162
|
+
.app-layout {
|
|
1163
|
+
--app-nav-side-size: 12rem;
|
|
1164
|
+
|
|
1165
|
+
display: grid;
|
|
1166
|
+
grid-template:
|
|
1167
|
+
"topbar" auto
|
|
1168
|
+
"main" minmax(0, 1fr)
|
|
1169
|
+
"nav" auto
|
|
1170
|
+
/ minmax(0, 1fr);
|
|
1171
|
+
block-size: var(--viewport-block);
|
|
1172
|
+
min-inline-size: 0;
|
|
1173
|
+
overflow: hidden;
|
|
1174
|
+
}
|
|
1175
|
+
|
|
1176
|
+
.app-layout > .topbar {
|
|
1177
|
+
grid-area: topbar;
|
|
1178
|
+
padding-block-start: calc(var(--space-30) + env(safe-area-inset-top));
|
|
1179
|
+
}
|
|
1180
|
+
|
|
1181
|
+
.app-layout > .app-main {
|
|
1182
|
+
grid-area: main;
|
|
1183
|
+
min-inline-size: 0;
|
|
1184
|
+
min-block-size: 0;
|
|
1185
|
+
overflow: auto;
|
|
1186
|
+
}
|
|
1187
|
+
|
|
1188
|
+
.app-layout > .app-nav {
|
|
1189
|
+
grid-area: nav;
|
|
1190
|
+
}
|
|
1191
|
+
|
|
1192
|
+
/* The main grid area keeps the FAB clear of bottom navigation without making
|
|
1193
|
+
either component copy the other's geometry. */
|
|
1194
|
+
.app-layout > .fab {
|
|
1195
|
+
position: relative;
|
|
1196
|
+
grid-area: main;
|
|
1197
|
+
place-self: end;
|
|
1198
|
+
inset: auto;
|
|
1199
|
+
margin: var(--fab-offset);
|
|
1200
|
+
}
|
|
1201
|
+
|
|
1202
|
+
@media (min-width: 48rem) {
|
|
1203
|
+
.app-layout {
|
|
1204
|
+
grid-template:
|
|
1205
|
+
"nav topbar" auto
|
|
1206
|
+
"nav main" minmax(0, 1fr)
|
|
1207
|
+
/ var(--app-nav-side-size) minmax(0, 1fr);
|
|
1208
|
+
}
|
|
1209
|
+
|
|
1210
|
+
.app-layout > .app-nav {
|
|
1211
|
+
position: sticky;
|
|
1212
|
+
inset-block: 0;
|
|
1213
|
+
grid-auto-flow: row;
|
|
1214
|
+
grid-auto-rows: minmax(var(--control-size-lg), auto);
|
|
1215
|
+
grid-auto-columns: auto;
|
|
1216
|
+
align-content: start;
|
|
1217
|
+
gap: var(--space-20);
|
|
1218
|
+
min-block-size: 0;
|
|
1219
|
+
padding-block: max(var(--space-20), env(safe-area-inset-top))
|
|
1220
|
+
max(var(--space-20), env(safe-area-inset-bottom));
|
|
1221
|
+
padding-inline: var(--space-20);
|
|
1222
|
+
border-block-start: 0;
|
|
1223
|
+
border-inline-end: var(--border-width) solid var(--ui-border, var(--border));
|
|
1224
|
+
}
|
|
1225
|
+
|
|
1226
|
+
.app-layout > .app-nav > a {
|
|
1227
|
+
grid-template-rows: auto;
|
|
1228
|
+
grid-template-columns: 1.5rem minmax(0, 1fr);
|
|
1229
|
+
place-content: center start;
|
|
1230
|
+
align-items: center;
|
|
1231
|
+
justify-items: start;
|
|
1232
|
+
gap: var(--space-30);
|
|
1233
|
+
padding-inline: var(--space-30);
|
|
1234
|
+
text-align: start;
|
|
1235
|
+
}
|
|
1236
|
+
|
|
1237
|
+
/* Side navigation no longer occupies the viewport's bottom safe area. */
|
|
1238
|
+
.app-layout > .fab {
|
|
1239
|
+
margin-block-end: max(var(--fab-offset), env(safe-area-inset-bottom));
|
|
1240
|
+
}
|
|
1241
|
+
}
|
|
1242
|
+
|
|
1243
|
+
@media print {
|
|
1244
|
+
.app-layout {
|
|
1245
|
+
display: block;
|
|
1246
|
+
block-size: auto;
|
|
1247
|
+
overflow: visible;
|
|
1248
|
+
}
|
|
1249
|
+
|
|
1250
|
+
.app-layout > .app-main {
|
|
1251
|
+
overflow: visible;
|
|
1252
|
+
}
|
|
1253
|
+
}
|
|
1254
|
+
|
|
1162
1255
|
/* Media object: fixed-width leading element (avatar, icon, image) + flexible
|
|
1163
1256
|
trailing content. Replaces the repeated "auto minmax(0, 1fr)" pattern in
|
|
1164
1257
|
author cards, comments, meta rows, and similar compositions.
|
|
@@ -1184,6 +1277,7 @@ small {
|
|
|
1184
1277
|
*/
|
|
1185
1278
|
.switcher {
|
|
1186
1279
|
display: flex;
|
|
1280
|
+
flex-direction: row;
|
|
1187
1281
|
flex-wrap: wrap;
|
|
1188
1282
|
gap: var(--gap);
|
|
1189
1283
|
}
|
|
@@ -1206,24 +1300,46 @@ small {
|
|
|
1206
1300
|
* --sidebar-content-min
|
|
1207
1301
|
* --sidebar-layout-size
|
|
1208
1302
|
*
|
|
1209
|
-
* Child contract: the first and
|
|
1303
|
+
* Child contract: the main region is first and the aside second by default
|
|
1304
|
+
* (aside on the inline end). .reverse expects the aside first in the DOM, so
|
|
1305
|
+
* visual, reading and keyboard order all agree — the role rules swap so the
|
|
1306
|
+
* aside still takes its preferred width and the main still reclaims the row.
|
|
1210
1307
|
*/
|
|
1211
1308
|
.sidebar-layout {
|
|
1212
1309
|
display: flex;
|
|
1310
|
+
flex-direction: row;
|
|
1213
1311
|
flex-wrap: wrap;
|
|
1214
1312
|
gap: var(--gap);
|
|
1215
1313
|
align-items: flex-start;
|
|
1216
1314
|
}
|
|
1217
1315
|
|
|
1316
|
+
/* Main region — flexible, reclaims the full row when the aside wraps. */
|
|
1218
1317
|
.sidebar-layout > :first-child {
|
|
1219
1318
|
flex-basis: 0;
|
|
1220
1319
|
flex-grow: 999;
|
|
1221
1320
|
min-inline-size: min(100%, var(--sidebar-content-min, 30rem));
|
|
1222
1321
|
}
|
|
1223
1322
|
|
|
1323
|
+
/* Aside region — preferred width, never forces content min-width. */
|
|
1224
1324
|
.sidebar-layout > :last-child {
|
|
1225
1325
|
flex-basis: var(--sidebar-layout-size, 18rem);
|
|
1226
1326
|
flex-grow: 1;
|
|
1327
|
+
min-inline-size: 0;
|
|
1328
|
+
}
|
|
1329
|
+
|
|
1330
|
+
/* .reverse: the aside is first in the DOM and the main last, so each role
|
|
1331
|
+
rule above would hit the wrong element. Swap the sizing per child; the
|
|
1332
|
+
higher-specificity reverse rules outrank the positional defaults. */
|
|
1333
|
+
.sidebar-layout.reverse > :last-child {
|
|
1334
|
+
flex-basis: 0;
|
|
1335
|
+
flex-grow: 999;
|
|
1336
|
+
min-inline-size: min(100%, var(--sidebar-content-min, 30rem));
|
|
1337
|
+
}
|
|
1338
|
+
|
|
1339
|
+
.sidebar-layout.reverse > :first-child {
|
|
1340
|
+
flex-basis: var(--sidebar-layout-size, 18rem);
|
|
1341
|
+
flex-grow: 1;
|
|
1342
|
+
min-inline-size: 0;
|
|
1227
1343
|
}
|
|
1228
1344
|
|
|
1229
1345
|
/*
|
|
@@ -1252,7 +1368,8 @@ small {
|
|
|
1252
1368
|
/* Recipe:
|
|
1253
1369
|
- collection whose item width is the contract -> .grid, tune --grid-min
|
|
1254
1370
|
- collection whose column density is the contract -> .grid-2/3/4/6
|
|
1255
|
-
- balanced subdivision of that density ->
|
|
1371
|
+
- balanced subdivision of that density -> place it inside any size query
|
|
1372
|
+
container (.container-query is the convenience helper for that context)
|
|
1256
1373
|
- peer regions that switch as a group -> .switcher
|
|
1257
1374
|
- content + aside -> .sidebar-layout
|
|
1258
1375
|
- exact custom track templates -> --grid-columns with an explicit collapse
|
|
@@ -1313,7 +1430,13 @@ small {
|
|
|
1313
1430
|
min-inline-size: 0;
|
|
1314
1431
|
}
|
|
1315
1432
|
|
|
1316
|
-
/* Balanced subdivision,
|
|
1433
|
+
/* Balanced subdivision, activated by an ancestor container named actual-grid.
|
|
1434
|
+
* A .grid-N inside such a container enters only divisor states of N. The name
|
|
1435
|
+
* is deliberate: a grid must not key off the nearest anonymous query container,
|
|
1436
|
+
* or a region that sets container-type: inline-size for an unrelated reason
|
|
1437
|
+
* would silently change the grid. The author opts the grid in by naming the
|
|
1438
|
+
* context — .container-query is the official helper, or declare
|
|
1439
|
+
* container: actual-grid / inline-size on your own region.
|
|
1317
1440
|
*
|
|
1318
1441
|
* .grid-2 2 -> 1
|
|
1319
1442
|
* .grid-3 3 -> 1
|
|
@@ -1330,6 +1453,11 @@ small {
|
|
|
1330
1453
|
* inline contribution and collapses it inside .cluster, .topbar, floats, and
|
|
1331
1454
|
* any shrink-to-fit box. See docs/design-notes/grid.md.
|
|
1332
1455
|
*
|
|
1456
|
+
* Without an actual-grid ancestor none of these @container rules resolve, so
|
|
1457
|
+
* the auto-fill baseline above stays. The min-width: 0 rule is the lowest
|
|
1458
|
+
* step: it pins the grid to one column inside a container before any larger
|
|
1459
|
+
* threshold fires (a bare grid would otherwise show a 2 + 1 orphan at 28-48rem).
|
|
1460
|
+
*
|
|
1333
1461
|
* Three shared thresholds, not one calibrated per preset: 28rem opens the
|
|
1334
1462
|
* first horizontal density, 48rem opens three columns, 64rem opens the dense
|
|
1335
1463
|
* 4 and 6. N already carries the author's statement about item size, so
|
|
@@ -1341,28 +1469,30 @@ small {
|
|
|
1341
1469
|
* Ascending min-width only: the last matching step wins by cascade order.
|
|
1342
1470
|
*/
|
|
1343
1471
|
@supports (container-type: inline-size) {
|
|
1344
|
-
|
|
1345
|
-
grid-
|
|
1472
|
+
@container actual-grid (min-width: 0px) {
|
|
1473
|
+
:where(.grid-2, .grid-3, .grid-4, .grid-6) {
|
|
1474
|
+
grid-template-columns: 1fr;
|
|
1475
|
+
}
|
|
1346
1476
|
}
|
|
1347
1477
|
|
|
1348
|
-
@container (min-width: 28rem) {
|
|
1349
|
-
|
|
1478
|
+
@container actual-grid (min-width: 28rem) {
|
|
1479
|
+
:where(.grid-2, .grid-4, .grid-6) {
|
|
1350
1480
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
1351
1481
|
}
|
|
1352
1482
|
}
|
|
1353
1483
|
|
|
1354
|
-
@container (min-width: 48rem) {
|
|
1355
|
-
|
|
1484
|
+
@container actual-grid (min-width: 48rem) {
|
|
1485
|
+
:where(.grid-3, .grid-6) {
|
|
1356
1486
|
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|
1357
1487
|
}
|
|
1358
1488
|
}
|
|
1359
1489
|
|
|
1360
|
-
@container (min-width: 64rem) {
|
|
1361
|
-
|
|
1490
|
+
@container actual-grid (min-width: 64rem) {
|
|
1491
|
+
:where(.grid-4) {
|
|
1362
1492
|
grid-template-columns: repeat(4, minmax(0, 1fr));
|
|
1363
1493
|
}
|
|
1364
1494
|
|
|
1365
|
-
|
|
1495
|
+
:where(.grid-6) {
|
|
1366
1496
|
grid-template-columns: repeat(6, minmax(0, 1fr));
|
|
1367
1497
|
}
|
|
1368
1498
|
}
|
|
@@ -1575,6 +1705,7 @@ small {
|
|
|
1575
1705
|
--scroll-snap-item-size: auto;
|
|
1576
1706
|
|
|
1577
1707
|
display: flex;
|
|
1708
|
+
flex-direction: row;
|
|
1578
1709
|
gap: var(--scroll-snap-gap);
|
|
1579
1710
|
overflow-x: auto;
|
|
1580
1711
|
}
|
|
@@ -1646,6 +1777,7 @@ small {
|
|
|
1646
1777
|
z-index: var(--z-sticky);
|
|
1647
1778
|
isolation: isolate;
|
|
1648
1779
|
display: flex;
|
|
1780
|
+
flex-direction: row;
|
|
1649
1781
|
align-items: center;
|
|
1650
1782
|
gap: var(--gap);
|
|
1651
1783
|
padding-block: var(--space-30);
|
|
@@ -2293,6 +2425,7 @@ small {
|
|
|
2293
2425
|
*/
|
|
2294
2426
|
.form-actions {
|
|
2295
2427
|
display: flex;
|
|
2428
|
+
flex-direction: row;
|
|
2296
2429
|
flex-wrap: wrap;
|
|
2297
2430
|
gap: var(--gap);
|
|
2298
2431
|
align-items: var(--form-actions-align, center);
|
|
@@ -2610,12 +2743,22 @@ small {
|
|
|
2610
2743
|
opacity: var(--disabled-opacity);
|
|
2611
2744
|
}
|
|
2612
2745
|
|
|
2613
|
-
/* Forced colors:
|
|
2614
|
-
|
|
2746
|
+
/* Forced colors: the track must stay a visible line against the page (Canvas
|
|
2747
|
+
would merge with it) and the thumb needs a real boundary to remain
|
|
2748
|
+
distinguishable from the track. Disabled keeps GrayText via :disabled.
|
|
2749
|
+
Focus stays on the transparent outline of :focus-visible. */
|
|
2615
2750
|
@media (forced-colors: active) {
|
|
2616
2751
|
.range {
|
|
2617
|
-
--range-
|
|
2618
|
-
--range-
|
|
2752
|
+
--range-track-bg: CanvasText;
|
|
2753
|
+
--range-thumb-bg: ButtonFace;
|
|
2754
|
+
}
|
|
2755
|
+
|
|
2756
|
+
.range::-webkit-slider-thumb {
|
|
2757
|
+
border: var(--border-width) solid ButtonText;
|
|
2758
|
+
}
|
|
2759
|
+
|
|
2760
|
+
.range::-moz-range-thumb {
|
|
2761
|
+
border: var(--border-width) solid ButtonText;
|
|
2619
2762
|
}
|
|
2620
2763
|
}
|
|
2621
2764
|
|
|
@@ -2752,28 +2895,19 @@ small {
|
|
|
2752
2895
|
transform: scale(1);
|
|
2753
2896
|
}
|
|
2754
2897
|
|
|
2898
|
+
/* The native input is hidden and the checked marker is custom-drawn: without
|
|
2899
|
+
this repair, forced colors pushes disc and check to the same system color
|
|
2900
|
+
and the state disappears. Highlight/Canvas/HighlightText are preserved as-is,
|
|
2901
|
+
so no forced-color-adjust is needed. The pseudo is not focusable — the
|
|
2902
|
+
outline is a separator against the card, not a focus channel. */
|
|
2755
2903
|
@media (forced-colors: active) {
|
|
2756
|
-
.choice-card {
|
|
2757
|
-
--choice-card-border: ButtonText;
|
|
2758
|
-
--choice-card-bg: Canvas;
|
|
2759
|
-
}
|
|
2760
|
-
|
|
2761
|
-
.choice-card:has(:checked) {
|
|
2762
|
-
--choice-card-border: Highlight;
|
|
2763
|
-
/* Pin the selected surface to the system canvas: only the essential
|
|
2764
|
-
marker pseudos opt out of remapping, never the interactive card host. */
|
|
2765
|
-
--choice-card-bg: Canvas;
|
|
2766
|
-
}
|
|
2767
|
-
|
|
2768
2904
|
.choice-card:has(:checked)::before {
|
|
2769
2905
|
background: Highlight;
|
|
2770
|
-
|
|
2771
|
-
forced-color-adjust: none;
|
|
2906
|
+
outline: 2px solid Canvas;
|
|
2772
2907
|
}
|
|
2773
2908
|
|
|
2774
2909
|
.choice-card:has(:checked)::after {
|
|
2775
2910
|
background: HighlightText;
|
|
2776
|
-
forced-color-adjust: none;
|
|
2777
2911
|
}
|
|
2778
2912
|
}
|
|
2779
2913
|
|
|
@@ -3058,7 +3192,12 @@ small {
|
|
|
3058
3192
|
but it sits in the clipped input extension once every cell is filled, so
|
|
3059
3193
|
the focused edge must be unambiguous on its own — hence the doubled width,
|
|
3060
3194
|
not only the color swap. Width is safe to change: box-sizing is border-box
|
|
3061
|
-
and the cells have a fixed inline/block size, so nothing reflows.
|
|
3195
|
+
and the cells have a fixed inline/block size, so nothing reflows.
|
|
3196
|
+
|
|
3197
|
+
The <input> must be the first direct child, with one cell <span> per
|
|
3198
|
+
character after it: the state rules select the cells as following siblings
|
|
3199
|
+
(input:focus ~ span, input:disabled ~ span, …), so that order is part of the
|
|
3200
|
+
contract. */
|
|
3062
3201
|
.otp > input:focus ~ span {
|
|
3063
3202
|
--otp-cell-border: var(--focus);
|
|
3064
3203
|
--otp-cell-border-width: calc(var(--border-width) * 2);
|
|
@@ -3082,7 +3221,7 @@ small {
|
|
|
3082
3221
|
|
|
3083
3222
|
.otp > input:disabled ~ span {
|
|
3084
3223
|
--otp-cell-bg: var(--surface-subtle);
|
|
3085
|
-
|
|
3224
|
+
--otp-cell-border: var(--state-disabled);
|
|
3086
3225
|
opacity: var(--disabled-opacity);
|
|
3087
3226
|
}
|
|
3088
3227
|
|
|
@@ -3192,7 +3331,8 @@ small {
|
|
|
3192
3331
|
|
|
3193
3332
|
.btn.icon-only {
|
|
3194
3333
|
inline-size: var(--btn-min-size);
|
|
3195
|
-
|
|
3334
|
+
block-size: var(--btn-min-size);
|
|
3335
|
+
padding: 0;
|
|
3196
3336
|
}
|
|
3197
3337
|
|
|
3198
3338
|
@supports (color: color-mix(in oklch, red, white)) {
|
|
@@ -3264,14 +3404,15 @@ small {
|
|
|
3264
3404
|
--ui-fg: var(--intent, currentColor);
|
|
3265
3405
|
--ui-border: transparent;
|
|
3266
3406
|
--btn-radius: var(--radius-sm);
|
|
3267
|
-
--btn-border-block-end-color: transparent;
|
|
3268
|
-
--btn-border-block-end-width: var(--border-width);
|
|
3269
3407
|
|
|
3270
3408
|
min-block-size: auto;
|
|
3271
3409
|
padding-inline: 0;
|
|
3272
3410
|
inline-size: fit-content;
|
|
3273
3411
|
max-inline-size: 100%;
|
|
3274
|
-
border
|
|
3412
|
+
/* No border at all: a link reads through its underline, and the inherited
|
|
3413
|
+
.btn border made transparent would turn into a visible box in forced
|
|
3414
|
+
colors. :focus-visible keeps its own outline. */
|
|
3415
|
+
border: 0;
|
|
3275
3416
|
text-decoration: underline;
|
|
3276
3417
|
text-underline-offset: 0.18em;
|
|
3277
3418
|
}
|
|
@@ -3332,44 +3473,12 @@ a.btn[aria-disabled="true"] {
|
|
|
3332
3473
|
}
|
|
3333
3474
|
|
|
3334
3475
|
@media (forced-colors: active) {
|
|
3335
|
-
.btn {
|
|
3336
|
-
border-color: ButtonText;
|
|
3337
|
-
background: ButtonFace;
|
|
3338
|
-
color: ButtonText;
|
|
3339
|
-
box-shadow: none;
|
|
3340
|
-
}
|
|
3341
|
-
|
|
3342
|
-
.btn.link {
|
|
3343
|
-
border-color: transparent;
|
|
3344
|
-
background: Canvas;
|
|
3345
|
-
color: LinkText;
|
|
3346
|
-
}
|
|
3347
|
-
|
|
3348
|
-
.btn:is([aria-pressed="true"], [aria-current="page"]):not(.link) {
|
|
3349
|
-
border-color: Highlight;
|
|
3350
|
-
background: Highlight;
|
|
3351
|
-
color: HighlightText;
|
|
3352
|
-
forced-color-adjust: none;
|
|
3353
|
-
}
|
|
3354
|
-
|
|
3355
|
-
.btn:is([aria-pressed="true"], [aria-current="page"]):not(.link):focus-visible {
|
|
3356
|
-
outline: var(--focus-outline);
|
|
3357
|
-
box-shadow: none;
|
|
3358
|
-
}
|
|
3359
|
-
|
|
3360
|
-
.btn:hover:not(:where(:disabled, [aria-disabled="true"], .link)) {
|
|
3361
|
-
outline: var(--border-width) solid ButtonText;
|
|
3362
|
-
outline-offset: 2px;
|
|
3363
|
-
}
|
|
3364
|
-
|
|
3365
|
-
.btn:disabled,
|
|
3366
3476
|
a.btn[aria-disabled="true"] {
|
|
3367
|
-
border-color: GrayText;
|
|
3368
|
-
background: Canvas;
|
|
3369
3477
|
color: GrayText;
|
|
3370
|
-
|
|
3478
|
+
border-color: GrayText;
|
|
3371
3479
|
}
|
|
3372
3480
|
}
|
|
3481
|
+
|
|
3373
3482
|
@media print {
|
|
3374
3483
|
:is(button, input[type="button"], input[type="submit"], input[type="reset"]).btn {
|
|
3375
3484
|
display: none !important;
|
|
@@ -3563,21 +3672,9 @@ a.badge[aria-disabled="true"] {
|
|
|
3563
3672
|
background: ButtonText;
|
|
3564
3673
|
}
|
|
3565
3674
|
|
|
3566
|
-
:where(a.badge, button.badge):hover:not(:where(:disabled, [aria-disabled="true"])) {
|
|
3567
|
-
outline: var(--border-width) solid ButtonText;
|
|
3568
|
-
outline-offset: 2px;
|
|
3569
|
-
}
|
|
3570
|
-
|
|
3571
|
-
.badge > button:not(:disabled):hover {
|
|
3572
|
-
outline: var(--border-width) solid currentColor;
|
|
3573
|
-
outline-offset: 1px;
|
|
3574
|
-
}
|
|
3575
|
-
|
|
3576
|
-
button.badge:disabled,
|
|
3577
3675
|
.badge[aria-disabled="true"] {
|
|
3578
|
-
border-color: GrayText;
|
|
3579
|
-
background: Canvas;
|
|
3580
3676
|
color: GrayText;
|
|
3677
|
+
border-color: GrayText;
|
|
3581
3678
|
}
|
|
3582
3679
|
}
|
|
3583
3680
|
@media print {
|
|
@@ -3874,6 +3971,7 @@ a.badge[aria-disabled="true"] {
|
|
|
3874
3971
|
--gap: var(--space-20);
|
|
3875
3972
|
|
|
3876
3973
|
display: flex;
|
|
3974
|
+
flex-direction: row;
|
|
3877
3975
|
flex-wrap: wrap;
|
|
3878
3976
|
align-items: center;
|
|
3879
3977
|
gap: var(--gap);
|
|
@@ -3894,11 +3992,14 @@ a.badge[aria-disabled="true"] {
|
|
|
3894
3992
|
* Surface, border, radius, padding, density, and elevation stay local here.
|
|
3895
3993
|
* Direct header/footer children are structural slots; a direct footer is
|
|
3896
3994
|
* anchored to the card's bottom edge when extra block space is available (so
|
|
3897
|
-
* price/action rows align across equal-height cards in a grid).
|
|
3898
|
-
*
|
|
3995
|
+
* price/action rows align across equal-height cards in a grid). A bare card
|
|
3996
|
+
* owns its direct-child rhythm; a layout primitive on the same element takes
|
|
3997
|
+
* over that layout. Page layout remains the job of markup and layout
|
|
3998
|
+
* primitives outside the card.
|
|
3899
3999
|
*
|
|
3900
4000
|
* Public hooks:
|
|
3901
4001
|
* --card-pad
|
|
4002
|
+
* --card-gap
|
|
3902
4003
|
* --card-radius
|
|
3903
4004
|
* --card-max-inline-size
|
|
3904
4005
|
*
|
|
@@ -3922,6 +4023,7 @@ a.badge[aria-disabled="true"] {
|
|
|
3922
4023
|
|
|
3923
4024
|
.card {
|
|
3924
4025
|
--card-pad: var(--space-40);
|
|
4026
|
+
--card-gap: var(--space-30);
|
|
3925
4027
|
--card-radius: var(--radius-lg);
|
|
3926
4028
|
--card-max-inline-size: none;
|
|
3927
4029
|
--card-bg: var(--ui-bg, var(--surface-raised));
|
|
@@ -3948,10 +4050,14 @@ a.badge[aria-disabled="true"] {
|
|
|
3948
4050
|
:where(.card) {
|
|
3949
4051
|
display: flex;
|
|
3950
4052
|
flex-direction: column;
|
|
4053
|
+
gap: var(--card-gap);
|
|
3951
4054
|
}
|
|
3952
4055
|
|
|
3953
|
-
|
|
4056
|
+
/* Native block margins would add to flex gap because flex-item margins never
|
|
4057
|
+
collapse. Zero specificity keeps intentional child utilities available. */
|
|
4058
|
+
:where(.card) > * {
|
|
3954
4059
|
min-inline-size: 0;
|
|
4060
|
+
margin-block: 0;
|
|
3955
4061
|
}
|
|
3956
4062
|
|
|
3957
4063
|
.card > :where(header, footer) {
|
|
@@ -3978,14 +4084,6 @@ a.badge[aria-disabled="true"] {
|
|
|
3978
4084
|
margin-block-start: auto;
|
|
3979
4085
|
}
|
|
3980
4086
|
|
|
3981
|
-
.card > :first-child {
|
|
3982
|
-
margin-block-start: 0;
|
|
3983
|
-
}
|
|
3984
|
-
|
|
3985
|
-
.card > :last-child {
|
|
3986
|
-
margin-block-end: 0;
|
|
3987
|
-
}
|
|
3988
|
-
|
|
3989
4087
|
.card.raised {
|
|
3990
4088
|
box-shadow: var(--shadow);
|
|
3991
4089
|
}
|
|
@@ -4331,23 +4429,6 @@ html.has-modal-open.had-scrollbar {
|
|
|
4331
4429
|
}
|
|
4332
4430
|
}
|
|
4333
4431
|
|
|
4334
|
-
@media (forced-colors: active) {
|
|
4335
|
-
dialog.modal {
|
|
4336
|
-
border-color: ButtonText;
|
|
4337
|
-
background: Canvas;
|
|
4338
|
-
color: CanvasText;
|
|
4339
|
-
box-shadow: none;
|
|
4340
|
-
}
|
|
4341
|
-
|
|
4342
|
-
dialog.modal::backdrop {
|
|
4343
|
-
background: Canvas;
|
|
4344
|
-
}
|
|
4345
|
-
|
|
4346
|
-
.dialog-icon {
|
|
4347
|
-
border: var(--border-width) solid CanvasText;
|
|
4348
|
-
}
|
|
4349
|
-
}
|
|
4350
|
-
|
|
4351
4432
|
/* Close controls. A close button is an action attached to a surface, so it
|
|
4352
4433
|
never participates in the content flow. The modal and the drawer share the
|
|
4353
4434
|
same simple placement — absolute at the panel's top inline-end, inside the
|
|
@@ -4553,12 +4634,6 @@ dialog.drawer nav {
|
|
|
4553
4634
|
}
|
|
4554
4635
|
}
|
|
4555
4636
|
|
|
4556
|
-
@media (forced-colors: active) {
|
|
4557
|
-
dialog.drawer::backdrop {
|
|
4558
|
-
background: Canvas;
|
|
4559
|
-
}
|
|
4560
|
-
}
|
|
4561
|
-
|
|
4562
4637
|
@media (prefers-reduced-motion: no-preference) {
|
|
4563
4638
|
dialog.drawer.is-static {
|
|
4564
4639
|
animation: actual-dialog-static var(--duration-slow) var(--ease);
|
|
@@ -4887,13 +4962,6 @@ dialog.drawer > form > header {
|
|
|
4887
4962
|
border-block-start: var(--border-width) solid var(--border);
|
|
4888
4963
|
}
|
|
4889
4964
|
|
|
4890
|
-
@media (forced-colors: active) {
|
|
4891
|
-
.menu-item:focus-visible {
|
|
4892
|
-
outline: var(--border-width) solid ButtonText;
|
|
4893
|
-
outline-offset: -1px;
|
|
4894
|
-
}
|
|
4895
|
-
}
|
|
4896
|
-
|
|
4897
4965
|
/*
|
|
4898
4966
|
* Tooltip — supplemental label overlaid near a trigger.
|
|
4899
4967
|
*
|
|
@@ -4920,6 +4988,7 @@ dialog.drawer > form > header {
|
|
|
4920
4988
|
max-inline-size: min(24rem, calc(var(--viewport-inline) - 2rem));
|
|
4921
4989
|
padding: 0.25em 0.6em;
|
|
4922
4990
|
border-radius: var(--radius-sm);
|
|
4991
|
+
border: var(--border-width) solid transparent;
|
|
4923
4992
|
background: var(--tooltip-bg);
|
|
4924
4993
|
color: var(--tooltip-fg);
|
|
4925
4994
|
font-size: var(--font-size-xs);
|
|
@@ -4998,16 +5067,6 @@ dialog.drawer > form > header {
|
|
|
4998
5067
|
clip-path: polygon(0 50%, 100% 0, 100% 100%);
|
|
4999
5068
|
}
|
|
5000
5069
|
|
|
5001
|
-
@media (forced-colors: active) {
|
|
5002
|
-
.tooltip {
|
|
5003
|
-
--tooltip-bg: Canvas;
|
|
5004
|
-
--tooltip-fg: CanvasText;
|
|
5005
|
-
}
|
|
5006
|
-
|
|
5007
|
-
.tooltip::before {
|
|
5008
|
-
display: none;
|
|
5009
|
-
}
|
|
5010
|
-
}
|
|
5011
5070
|
@media print {
|
|
5012
5071
|
.tooltip {
|
|
5013
5072
|
display: none !important;
|
|
@@ -5556,6 +5615,9 @@ dialog.drawer > form > header {
|
|
|
5556
5615
|
}
|
|
5557
5616
|
}
|
|
5558
5617
|
|
|
5618
|
+
/* The initials element (a span or an accessible <abbr title="…">) fills the box.
|
|
5619
|
+
text-decoration: none neutralizes the UA dotted underline on <abbr title="…">
|
|
5620
|
+
inside the circular avatar. */
|
|
5559
5621
|
.avatar > :first-child:not(:where(img, picture, .badge)) {
|
|
5560
5622
|
display: inline-grid;
|
|
5561
5623
|
place-items: center;
|
|
@@ -5563,6 +5625,7 @@ dialog.drawer > form > header {
|
|
|
5563
5625
|
block-size: 100%;
|
|
5564
5626
|
overflow: hidden;
|
|
5565
5627
|
border-radius: inherit;
|
|
5628
|
+
text-decoration: none;
|
|
5566
5629
|
}
|
|
5567
5630
|
|
|
5568
5631
|
.avatar > img,
|
|
@@ -5691,6 +5754,54 @@ a.avatar[aria-disabled="true"] {
|
|
|
5691
5754
|
z-index: 1;
|
|
5692
5755
|
}
|
|
5693
5756
|
|
|
5757
|
+
/*
|
|
5758
|
+
* Indicator — generic corner positioning for overlaid component content.
|
|
5759
|
+
*
|
|
5760
|
+
* The container only establishes the containing block. The item owns no
|
|
5761
|
+
* paint, size, or ring so badges and other components keep their own visual
|
|
5762
|
+
* contract.
|
|
5763
|
+
*
|
|
5764
|
+
* Internal:
|
|
5765
|
+
* --indicator-translate-x
|
|
5766
|
+
* --indicator-translate-y
|
|
5767
|
+
*/
|
|
5768
|
+
.indicator {
|
|
5769
|
+
position: relative;
|
|
5770
|
+
}
|
|
5771
|
+
|
|
5772
|
+
.indicator-item {
|
|
5773
|
+
--indicator-translate-x: 50%;
|
|
5774
|
+
--indicator-translate-y: -50%;
|
|
5775
|
+
|
|
5776
|
+
position: absolute;
|
|
5777
|
+
inset-block-start: 0;
|
|
5778
|
+
inset-inline-end: 0;
|
|
5779
|
+
z-index: 1;
|
|
5780
|
+
transform: translate(var(--indicator-translate-x), var(--indicator-translate-y));
|
|
5781
|
+
}
|
|
5782
|
+
|
|
5783
|
+
.indicator-item.start {
|
|
5784
|
+
--indicator-translate-x: -50%;
|
|
5785
|
+
|
|
5786
|
+
inset-inline-start: 0;
|
|
5787
|
+
inset-inline-end: auto;
|
|
5788
|
+
}
|
|
5789
|
+
|
|
5790
|
+
.indicator-item.bottom {
|
|
5791
|
+
--indicator-translate-y: 50%;
|
|
5792
|
+
|
|
5793
|
+
inset-block-start: auto;
|
|
5794
|
+
inset-block-end: 0;
|
|
5795
|
+
}
|
|
5796
|
+
|
|
5797
|
+
.indicator-item:dir(rtl) {
|
|
5798
|
+
--indicator-translate-x: -50%;
|
|
5799
|
+
}
|
|
5800
|
+
|
|
5801
|
+
.indicator-item.start:dir(rtl) {
|
|
5802
|
+
--indicator-translate-x: 50%;
|
|
5803
|
+
}
|
|
5804
|
+
|
|
5694
5805
|
/*
|
|
5695
5806
|
* Key — keyboard keys and shortcut tokens for UI chrome.
|
|
5696
5807
|
*
|
|
@@ -5821,12 +5932,6 @@ a.avatar[aria-disabled="true"] {
|
|
|
5821
5932
|
}
|
|
5822
5933
|
}
|
|
5823
5934
|
|
|
5824
|
-
@media (forced-colors: active) {
|
|
5825
|
-
.chat-bubble {
|
|
5826
|
-
border-color: CanvasText;
|
|
5827
|
-
}
|
|
5828
|
-
}
|
|
5829
|
-
|
|
5830
5935
|
/*
|
|
5831
5936
|
* Fixed floating action placement and a native-details speed dial.
|
|
5832
5937
|
* Button owns the action's size, shape, and intent; FAB only owns placement.
|
|
@@ -5897,6 +6002,7 @@ a.avatar[aria-disabled="true"] {
|
|
|
5897
6002
|
max-inline-size: 16rem;
|
|
5898
6003
|
padding: var(--space-10) var(--space-20);
|
|
5899
6004
|
border-radius: var(--radius);
|
|
6005
|
+
border: var(--border-width) solid transparent;
|
|
5900
6006
|
background: var(--surface);
|
|
5901
6007
|
color: var(--text);
|
|
5902
6008
|
box-shadow: var(--shadow);
|
|
@@ -5919,21 +6025,317 @@ a.avatar[aria-disabled="true"] {
|
|
|
5919
6025
|
transform: rotate(45deg);
|
|
5920
6026
|
}
|
|
5921
6027
|
|
|
6028
|
+
@media print {
|
|
6029
|
+
.fab {
|
|
6030
|
+
display: none;
|
|
6031
|
+
}
|
|
6032
|
+
}
|
|
6033
|
+
|
|
6034
|
+
/*
|
|
6035
|
+
* Rating — integer star rating drawn on native radio inputs.
|
|
6036
|
+
*
|
|
6037
|
+
* The checked radio remains the functional baseline. :has() progressively
|
|
6038
|
+
* fills preceding stars without reversing DOM or keyboard order. Forced
|
|
6039
|
+
* colors restores the platform radio presentation.
|
|
6040
|
+
*
|
|
6041
|
+
* Public hooks:
|
|
6042
|
+
* --rating-size
|
|
6043
|
+
* --rating-gap
|
|
6044
|
+
* --rating-color
|
|
6045
|
+
* --rating-empty
|
|
6046
|
+
* --rating-star
|
|
6047
|
+
*/
|
|
6048
|
+
:where(.rating) {
|
|
6049
|
+
--intent: initial;
|
|
6050
|
+
}
|
|
6051
|
+
|
|
6052
|
+
.rating {
|
|
6053
|
+
--rating-size: 1.25rem;
|
|
6054
|
+
--rating-gap: 0.1rem;
|
|
6055
|
+
--rating-color: var(--intent, var(--warning));
|
|
6056
|
+
--rating-empty: var(--border);
|
|
6057
|
+
--rating-star: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='2 2 16 16'%3E%3Cpath d='M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 0 0 .95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 0 0-.364 1.118l1.07 3.292c.3.922-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 0 0-1.175 0l-2.8 2.034c-.783.57-1.838-.196-1.539-1.118l1.07-3.292a1 1 0 0 0-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 0 0 .951-.69l1.07-3.292Z'/%3E%3C/svg%3E");
|
|
6058
|
+
|
|
6059
|
+
display: inline-flex;
|
|
6060
|
+
gap: 0;
|
|
6061
|
+
color: var(--rating-color);
|
|
6062
|
+
}
|
|
6063
|
+
|
|
6064
|
+
.rating > input[type="radio"] {
|
|
6065
|
+
appearance: none;
|
|
6066
|
+
flex: 0 0 auto;
|
|
6067
|
+
inline-size: calc(var(--rating-size) + var(--rating-gap));
|
|
6068
|
+
block-size: var(--rating-size);
|
|
6069
|
+
margin: 0;
|
|
6070
|
+
border: 0;
|
|
6071
|
+
background: var(--rating-empty);
|
|
6072
|
+
/* Contiguous radio boxes own hit-testing; the centered mask preserves the
|
|
6073
|
+
star's proportions while leaving a purely visual gap between values. */
|
|
6074
|
+
-webkit-mask: var(--rating-star) center / var(--rating-size) var(--rating-size) no-repeat;
|
|
6075
|
+
mask: var(--rating-star) center / var(--rating-size) var(--rating-size) no-repeat;
|
|
6076
|
+
cursor: pointer;
|
|
6077
|
+
transition: background-color var(--duration);
|
|
6078
|
+
}
|
|
6079
|
+
|
|
6080
|
+
.rating > input[type="radio"]:checked {
|
|
6081
|
+
background: var(--rating-color);
|
|
6082
|
+
}
|
|
6083
|
+
|
|
6084
|
+
.rating > input[type="radio"]:disabled {
|
|
6085
|
+
cursor: not-allowed;
|
|
6086
|
+
opacity: var(--disabled-opacity);
|
|
6087
|
+
}
|
|
6088
|
+
|
|
6089
|
+
.rating > input[type="radio"]:focus-visible {
|
|
6090
|
+
outline: var(--focus-outline);
|
|
6091
|
+
outline-offset: var(--focus-outline-offset);
|
|
6092
|
+
background: var(--rating-color);
|
|
6093
|
+
}
|
|
6094
|
+
|
|
6095
|
+
/* Browsers without :has() still show the selected native radio as one filled
|
|
6096
|
+
star. The enhancement only adds cumulative checked and hover previews. */
|
|
6097
|
+
@supports selector(:has(*)) {
|
|
6098
|
+
.rating > input[type="radio"]:has(~ input[type="radio"]:checked) {
|
|
6099
|
+
background: var(--rating-color);
|
|
6100
|
+
}
|
|
6101
|
+
|
|
6102
|
+
@media (hover: hover) {
|
|
6103
|
+
.rating > input[type="radio"]:not(:disabled):hover,
|
|
6104
|
+
.rating > input[type="radio"]:has(~ input[type="radio"]:not(:disabled):hover) {
|
|
6105
|
+
background: var(--rating-color);
|
|
6106
|
+
}
|
|
6107
|
+
|
|
6108
|
+
/* A hovered value previews exactly that value: later stars are emptied,
|
|
6109
|
+
including a previously checked star beyond the pointer. */
|
|
6110
|
+
.rating > input[type="radio"]:not(:disabled):hover ~ input[type="radio"] {
|
|
6111
|
+
background: var(--rating-empty);
|
|
6112
|
+
}
|
|
6113
|
+
}
|
|
6114
|
+
}
|
|
6115
|
+
|
|
6116
|
+
.rating.sm {
|
|
6117
|
+
--rating-size: 1rem;
|
|
6118
|
+
}
|
|
6119
|
+
|
|
6120
|
+
.rating.lg {
|
|
6121
|
+
--rating-size: 1.75rem;
|
|
6122
|
+
}
|
|
6123
|
+
|
|
5922
6124
|
@media (forced-colors: active) {
|
|
5923
|
-
.
|
|
5924
|
-
|
|
5925
|
-
|
|
6125
|
+
.rating > input[type="radio"] {
|
|
6126
|
+
appearance: auto;
|
|
6127
|
+
inline-size: auto;
|
|
6128
|
+
block-size: auto;
|
|
6129
|
+
background: Canvas;
|
|
6130
|
+
-webkit-mask: none;
|
|
6131
|
+
mask: none;
|
|
6132
|
+
opacity: 1;
|
|
5926
6133
|
}
|
|
5927
6134
|
}
|
|
5928
6135
|
|
|
6136
|
+
/*
|
|
6137
|
+
* Steps — semantic ordered-list progression. One intrinsic layout: items fill
|
|
6138
|
+
* the row when they fit and hold a minimum width otherwise, so the sequence
|
|
6139
|
+
* scrolls horizontally only when it genuinely cannot fit. No breakpoint decides
|
|
6140
|
+
* this — the item minimum tracks the real content, not an arbitrary width.
|
|
6141
|
+
*
|
|
6142
|
+
* Markers come from the list counter; state stays in .complete and
|
|
6143
|
+
* aria-current="step", so the component needs no runtime.
|
|
6144
|
+
*
|
|
6145
|
+
* Public hooks:
|
|
6146
|
+
* --step-size
|
|
6147
|
+
* --step-min
|
|
6148
|
+
* --step-gap
|
|
6149
|
+
* --step-line-size
|
|
6150
|
+
* --step-marker-radius
|
|
6151
|
+
* --step-complete-mark
|
|
6152
|
+
* --step-connector
|
|
6153
|
+
*
|
|
6154
|
+
* Internal:
|
|
6155
|
+
* --step-marker-bg
|
|
6156
|
+
* --step-marker-border
|
|
6157
|
+
* --step-marker-fg
|
|
6158
|
+
* --step-line
|
|
6159
|
+
*/
|
|
6160
|
+
.steps {
|
|
6161
|
+
--step-size: 1.75rem;
|
|
6162
|
+
--step-min: 7rem;
|
|
6163
|
+
--step-gap: var(--space-20);
|
|
6164
|
+
--step-line-size: var(--border-width);
|
|
6165
|
+
--step-marker-bg: var(--surface);
|
|
6166
|
+
--step-marker-border: var(--border);
|
|
6167
|
+
--step-marker-fg: var(--text-muted);
|
|
6168
|
+
--step-marker-radius: var(--radius-full);
|
|
6169
|
+
--step-line: var(--border);
|
|
6170
|
+
|
|
6171
|
+
counter-reset: actual-step;
|
|
6172
|
+
display: flex;
|
|
6173
|
+
flex-direction: row;
|
|
6174
|
+
inline-size: 100%;
|
|
6175
|
+
margin: 0;
|
|
6176
|
+
padding: 0;
|
|
6177
|
+
list-style: none;
|
|
6178
|
+
/* Fill when it fits, scroll when it cannot: items never shrink below
|
|
6179
|
+
--step-min, so labels keep a readable width and the sequence scrolls
|
|
6180
|
+
horizontally instead of squishing. overscroll-behavior keeps the scroll
|
|
6181
|
+
from chaining to the page. */
|
|
6182
|
+
overflow-x: auto;
|
|
6183
|
+
overscroll-behavior-inline: contain;
|
|
6184
|
+
}
|
|
6185
|
+
|
|
6186
|
+
.steps > li {
|
|
6187
|
+
position: relative;
|
|
6188
|
+
display: grid;
|
|
6189
|
+
flex: 1 0 var(--step-min);
|
|
6190
|
+
grid-template-rows: var(--step-size) auto;
|
|
6191
|
+
gap: var(--step-gap);
|
|
6192
|
+
justify-items: center;
|
|
6193
|
+
min-inline-size: max(var(--step-size), var(--step-min));
|
|
6194
|
+
color: var(--text-muted);
|
|
6195
|
+
text-align: center;
|
|
6196
|
+
counter-increment: actual-step;
|
|
6197
|
+
}
|
|
6198
|
+
|
|
6199
|
+
.steps > li::before {
|
|
6200
|
+
content: counter(actual-step);
|
|
6201
|
+
position: relative;
|
|
6202
|
+
z-index: 1;
|
|
6203
|
+
display: inline-grid;
|
|
6204
|
+
place-items: center;
|
|
6205
|
+
inline-size: var(--step-size);
|
|
6206
|
+
block-size: var(--step-size);
|
|
6207
|
+
border: var(--border-width) solid var(--step-marker-border);
|
|
6208
|
+
border-radius: var(--step-marker-radius);
|
|
6209
|
+
background: var(--step-marker-bg);
|
|
6210
|
+
color: var(--step-marker-fg);
|
|
6211
|
+
font-size: var(--font-size-sm);
|
|
6212
|
+
font-weight: var(--font-weight-strong);
|
|
6213
|
+
line-height: 1;
|
|
6214
|
+
}
|
|
6215
|
+
|
|
6216
|
+
.steps > li::after {
|
|
6217
|
+
content: "";
|
|
6218
|
+
position: absolute;
|
|
6219
|
+
inset-block-start: calc((var(--step-size) - var(--step-line-size)) / 2);
|
|
6220
|
+
inset-inline-start: calc(50% + var(--step-size) / 2);
|
|
6221
|
+
inline-size: calc(100% - var(--step-size));
|
|
6222
|
+
block-size: var(--step-line-size);
|
|
6223
|
+
/* A custom property resolves its var() before inheritance, so a default
|
|
6224
|
+
--step-connector: var(--step-line) on .steps would freeze the parent line
|
|
6225
|
+
color and a .complete child's connector would never follow its own line.
|
|
6226
|
+
Falling back to the local --step-line here keeps each connector in sync;
|
|
6227
|
+
an explicit --step-connector still wins when the author sets one. */
|
|
6228
|
+
background: var(--step-connector, var(--step-line));
|
|
6229
|
+
}
|
|
6230
|
+
|
|
6231
|
+
.steps > li:last-child::after {
|
|
6232
|
+
content: none;
|
|
6233
|
+
}
|
|
6234
|
+
|
|
6235
|
+
.steps > :is(.complete, [aria-current="step"]) {
|
|
6236
|
+
--step-marker-bg: var(--state-selected);
|
|
6237
|
+
--step-marker-border: var(--state-selected);
|
|
6238
|
+
--step-marker-fg: var(--state-selected-fg);
|
|
6239
|
+
|
|
6240
|
+
color: var(--text);
|
|
6241
|
+
}
|
|
6242
|
+
|
|
6243
|
+
/* Thicker border is the selected affordance in every mode — structural, and it
|
|
6244
|
+
never competes with the outline channel owned by focus. */
|
|
6245
|
+
.steps > :is(.complete, [aria-current="step"])::before {
|
|
6246
|
+
border-width: calc(var(--border-width) * 2);
|
|
6247
|
+
}
|
|
6248
|
+
|
|
6249
|
+
.steps > .complete {
|
|
6250
|
+
--step-line: var(--state-selected);
|
|
6251
|
+
}
|
|
6252
|
+
|
|
6253
|
+
/* A finished step may replace its number with a mark (e.g. a check glyph):
|
|
6254
|
+
--step-complete-mark accepts any content value and falls back to the
|
|
6255
|
+
counter, so existing numbered steppers are unchanged. */
|
|
6256
|
+
.steps > .complete::before {
|
|
6257
|
+
content: var(--step-complete-mark, counter(actual-step));
|
|
6258
|
+
}
|
|
6259
|
+
|
|
6260
|
+
|
|
6261
|
+
/* Navigation */
|
|
6262
|
+
/*
|
|
6263
|
+
* Primary application navigation. The component owns the navigation surface
|
|
6264
|
+
* and item states; app-layout owns whether that surface is a bottom bar or
|
|
6265
|
+
* labelled side navigation.
|
|
6266
|
+
*
|
|
6267
|
+
* Public hooks:
|
|
6268
|
+
* --app-nav-size
|
|
6269
|
+
* --app-nav-gap
|
|
6270
|
+
*/
|
|
6271
|
+
:where(.app-nav) {
|
|
6272
|
+
--ui-bg: initial;
|
|
6273
|
+
--ui-fg: initial;
|
|
6274
|
+
--ui-border: initial;
|
|
6275
|
+
}
|
|
6276
|
+
|
|
6277
|
+
.app-nav {
|
|
6278
|
+
--app-nav-size: 4rem;
|
|
6279
|
+
--app-nav-gap: var(--space-10);
|
|
6280
|
+
|
|
6281
|
+
position: sticky;
|
|
6282
|
+
inset-block-end: 0;
|
|
6283
|
+
z-index: var(--z-sticky);
|
|
6284
|
+
display: grid;
|
|
6285
|
+
grid-auto-flow: column;
|
|
6286
|
+
grid-auto-columns: minmax(0, 1fr);
|
|
6287
|
+
gap: var(--app-nav-gap);
|
|
6288
|
+
min-block-size: calc(var(--app-nav-size) + env(safe-area-inset-bottom));
|
|
6289
|
+
padding-block: var(--space-10) max(var(--space-10), env(safe-area-inset-bottom));
|
|
6290
|
+
padding-inline: var(--space-10);
|
|
6291
|
+
border-block-start: var(--border-width) solid var(--ui-border, var(--border));
|
|
6292
|
+
background: var(--ui-bg, var(--surface));
|
|
6293
|
+
color: var(--ui-fg, var(--text-muted));
|
|
6294
|
+
}
|
|
6295
|
+
|
|
6296
|
+
.app-nav > a {
|
|
6297
|
+
display: grid;
|
|
6298
|
+
grid-template-rows: auto auto;
|
|
6299
|
+
place-content: center;
|
|
6300
|
+
justify-items: center;
|
|
6301
|
+
gap: var(--space-10);
|
|
6302
|
+
min-inline-size: 0;
|
|
6303
|
+
min-block-size: var(--control-size-lg);
|
|
6304
|
+
padding-inline: var(--space-10);
|
|
6305
|
+
border-radius: var(--radius);
|
|
6306
|
+
color: inherit;
|
|
6307
|
+
font-size: var(--font-size-xs);
|
|
6308
|
+
font-weight: var(--font-weight-medium);
|
|
6309
|
+
line-height: var(--line-height-tight);
|
|
6310
|
+
text-align: center;
|
|
6311
|
+
text-decoration: none;
|
|
6312
|
+
overflow-wrap: anywhere;
|
|
6313
|
+
}
|
|
6314
|
+
|
|
6315
|
+
.app-nav > a > :where(svg, img, [aria-hidden="true"]) {
|
|
6316
|
+
inline-size: 1.5rem;
|
|
6317
|
+
block-size: 1.5rem;
|
|
6318
|
+
font-size: 1.5rem;
|
|
6319
|
+
line-height: 1;
|
|
6320
|
+
}
|
|
6321
|
+
|
|
6322
|
+
.app-nav > a:hover {
|
|
6323
|
+
background: var(--surface-subtle);
|
|
6324
|
+
color: var(--text);
|
|
6325
|
+
}
|
|
6326
|
+
|
|
6327
|
+
.app-nav > a:where([aria-current]:not([aria-current="false"])) {
|
|
6328
|
+
background: var(--state-selected);
|
|
6329
|
+
color: var(--state-selected-fg);
|
|
6330
|
+
font-weight: var(--font-weight-bold);
|
|
6331
|
+
}
|
|
6332
|
+
|
|
5929
6333
|
@media print {
|
|
5930
|
-
.
|
|
6334
|
+
.app-nav {
|
|
5931
6335
|
display: none;
|
|
5932
6336
|
}
|
|
5933
6337
|
}
|
|
5934
6338
|
|
|
5935
|
-
|
|
5936
|
-
/* Navigation */
|
|
5937
6339
|
/*
|
|
5938
6340
|
* Navbar — top-level navigation bar.
|
|
5939
6341
|
*
|
|
@@ -5954,6 +6356,7 @@ a.avatar[aria-disabled="true"] {
|
|
|
5954
6356
|
|
|
5955
6357
|
.navbar {
|
|
5956
6358
|
display: flex;
|
|
6359
|
+
flex-direction: row;
|
|
5957
6360
|
flex-wrap: wrap;
|
|
5958
6361
|
align-items: center;
|
|
5959
6362
|
justify-content: space-between;
|
|
@@ -5981,6 +6384,7 @@ a.avatar[aria-disabled="true"] {
|
|
|
5981
6384
|
|
|
5982
6385
|
.navbar-nav {
|
|
5983
6386
|
display: flex;
|
|
6387
|
+
flex-direction: row;
|
|
5984
6388
|
flex-wrap: wrap;
|
|
5985
6389
|
align-items: center;
|
|
5986
6390
|
gap: var(--space-10);
|
|
@@ -6003,6 +6407,7 @@ a.avatar[aria-disabled="true"] {
|
|
|
6003
6407
|
.nav-link:where([aria-current]:not([aria-current="false"])) {
|
|
6004
6408
|
background: var(--surface-subtle);
|
|
6005
6409
|
color: var(--text);
|
|
6410
|
+
font-weight: var(--font-weight-bold);
|
|
6006
6411
|
}
|
|
6007
6412
|
|
|
6008
6413
|
.nav-link:hover {
|
|
@@ -6010,7 +6415,9 @@ a.avatar[aria-disabled="true"] {
|
|
|
6010
6415
|
color: var(--text);
|
|
6011
6416
|
}
|
|
6012
6417
|
|
|
6013
|
-
/* Nav list — a vertical navigation list. Used by .drawer for stacked links.
|
|
6418
|
+
/* Nav list — a vertical navigation list. Used by .drawer for stacked links.
|
|
6419
|
+
Links fill each row so the whole line is an interactive target; the
|
|
6420
|
+
horizontal .navbar-nav links keep their intrinsic size. */
|
|
6014
6421
|
.nav-list {
|
|
6015
6422
|
display: grid;
|
|
6016
6423
|
--gap: var(--space-20);
|
|
@@ -6024,20 +6431,8 @@ a.avatar[aria-disabled="true"] {
|
|
|
6024
6431
|
margin: 0;
|
|
6025
6432
|
}
|
|
6026
6433
|
|
|
6027
|
-
|
|
6028
|
-
|
|
6029
|
-
outline: var(--border-width) solid Highlight;
|
|
6030
|
-
background: Highlight;
|
|
6031
|
-
color: HighlightText;
|
|
6032
|
-
forced-color-adjust: none;
|
|
6033
|
-
}
|
|
6034
|
-
|
|
6035
|
-
.nav-link:hover:not(:where([aria-current]:not([aria-current="false"]))) {
|
|
6036
|
-
outline: var(--border-width) solid ButtonText;
|
|
6037
|
-
outline-offset: 2px;
|
|
6038
|
-
background: Canvas;
|
|
6039
|
-
color: CanvasText;
|
|
6040
|
-
}
|
|
6434
|
+
.nav-list .nav-link {
|
|
6435
|
+
inline-size: 100%;
|
|
6041
6436
|
}
|
|
6042
6437
|
|
|
6043
6438
|
/*
|
|
@@ -6048,6 +6443,7 @@ a.avatar[aria-disabled="true"] {
|
|
|
6048
6443
|
*/
|
|
6049
6444
|
.breadcrumb {
|
|
6050
6445
|
display: flex;
|
|
6446
|
+
flex-direction: row;
|
|
6051
6447
|
flex-wrap: wrap;
|
|
6052
6448
|
align-items: center;
|
|
6053
6449
|
gap: var(--space-10);
|
|
@@ -6101,6 +6497,7 @@ a.avatar[aria-disabled="true"] {
|
|
|
6101
6497
|
*/
|
|
6102
6498
|
.pagination {
|
|
6103
6499
|
display: flex;
|
|
6500
|
+
flex-direction: row;
|
|
6104
6501
|
flex-wrap: wrap;
|
|
6105
6502
|
align-items: center;
|
|
6106
6503
|
gap: var(--space-10);
|
|
@@ -6149,6 +6546,7 @@ a.avatar[aria-disabled="true"] {
|
|
|
6149
6546
|
|
|
6150
6547
|
.tabs {
|
|
6151
6548
|
display: flex;
|
|
6549
|
+
flex-direction: row;
|
|
6152
6550
|
flex-wrap: wrap;
|
|
6153
6551
|
gap: var(--space-10);
|
|
6154
6552
|
margin: 0;
|
|
@@ -6166,13 +6564,14 @@ a.avatar[aria-disabled="true"] {
|
|
|
6166
6564
|
}
|
|
6167
6565
|
|
|
6168
6566
|
.tab {
|
|
6567
|
+
/* Positioning context for the selected indicator pseudo. */
|
|
6568
|
+
position: relative;
|
|
6169
6569
|
display: inline-flex;
|
|
6170
6570
|
align-items: center;
|
|
6171
6571
|
gap: var(--tab-gap, 0.375em);
|
|
6172
6572
|
min-block-size: var(--control-size);
|
|
6173
6573
|
padding-inline: var(--space-30);
|
|
6174
6574
|
border: 0;
|
|
6175
|
-
border-block-end: 2px solid transparent;
|
|
6176
6575
|
border-radius: 0;
|
|
6177
6576
|
background: transparent;
|
|
6178
6577
|
color: var(--text-muted);
|
|
@@ -6184,8 +6583,6 @@ a.avatar[aria-disabled="true"] {
|
|
|
6184
6583
|
|
|
6185
6584
|
.tabs[aria-orientation="vertical"] .tab {
|
|
6186
6585
|
justify-content: flex-start;
|
|
6187
|
-
border-block-end: 0;
|
|
6188
|
-
border-inline-end: 2px solid transparent;
|
|
6189
6586
|
padding-inline-end: var(--space-40);
|
|
6190
6587
|
}
|
|
6191
6588
|
|
|
@@ -6206,30 +6603,29 @@ a.avatar[aria-disabled="true"] {
|
|
|
6206
6603
|
}
|
|
6207
6604
|
|
|
6208
6605
|
.tab[aria-selected="true"] {
|
|
6209
|
-
border-block-end-color: var(--intent, var(--state-selected));
|
|
6210
6606
|
color: var(--intent, var(--state-selected));
|
|
6607
|
+
/* Second, layout-free selected cue — the underline alone is color-only in
|
|
6608
|
+
forced colors. */
|
|
6609
|
+
font-weight: var(--font-weight-bold);
|
|
6211
6610
|
}
|
|
6212
6611
|
|
|
6213
|
-
|
|
6214
|
-
|
|
6215
|
-
|
|
6612
|
+
/* The selected indicator lives on a positioned pseudo so that only the active
|
|
6613
|
+
tab owns an underline: a transparent border on every tab would surface in
|
|
6614
|
+
forced colors and erase the distinction. currentColor follows the palette the
|
|
6615
|
+
UA forces, so no forced-colors block is needed. */
|
|
6616
|
+
.tab[aria-selected="true"]::after {
|
|
6617
|
+
content: "";
|
|
6618
|
+
position: absolute;
|
|
6619
|
+
inset-inline: 0;
|
|
6620
|
+
inset-block-end: 0;
|
|
6621
|
+
border-block-end: 2px solid currentColor;
|
|
6216
6622
|
}
|
|
6217
6623
|
|
|
6218
|
-
|
|
6219
|
-
|
|
6220
|
-
|
|
6221
|
-
|
|
6222
|
-
|
|
6223
|
-
|
|
6224
|
-
.tab[aria-selected="true"] {
|
|
6225
|
-
border-block-end-color: Highlight;
|
|
6226
|
-
color: Highlight;
|
|
6227
|
-
}
|
|
6228
|
-
|
|
6229
|
-
.tabs[aria-orientation="vertical"] .tab[aria-selected="true"] {
|
|
6230
|
-
border-block-end-color: transparent;
|
|
6231
|
-
border-inline-end-color: Highlight;
|
|
6232
|
-
}
|
|
6624
|
+
.tabs[aria-orientation="vertical"] .tab[aria-selected="true"]::after {
|
|
6625
|
+
inset-block: 0;
|
|
6626
|
+
inset-inline: auto 0;
|
|
6627
|
+
border-block-end: 0;
|
|
6628
|
+
border-inline-end: 2px solid currentColor;
|
|
6233
6629
|
}
|
|
6234
6630
|
|
|
6235
6631
|
/*
|
|
@@ -6262,6 +6658,90 @@ a.avatar[aria-disabled="true"] {
|
|
|
6262
6658
|
|
|
6263
6659
|
|
|
6264
6660
|
/* Data */
|
|
6661
|
+
/*
|
|
6662
|
+
* Application list — repeated rows with optional leading and trailing regions.
|
|
6663
|
+
* Content determines the number of lines; the component only owns the row
|
|
6664
|
+
* geometry, dividers, and supporting-text treatment.
|
|
6665
|
+
*
|
|
6666
|
+
* Public hooks:
|
|
6667
|
+
* --list-item-min-size
|
|
6668
|
+
* --list-item-pad-block
|
|
6669
|
+
* --list-item-pad-inline
|
|
6670
|
+
* --list-item-gap
|
|
6671
|
+
* --list-divider
|
|
6672
|
+
*/
|
|
6673
|
+
.list {
|
|
6674
|
+
--list-item-min-size: var(--control-size-lg);
|
|
6675
|
+
--list-item-pad-block: var(--space-30);
|
|
6676
|
+
--list-item-pad-inline: 0;
|
|
6677
|
+
--list-item-gap: var(--gap);
|
|
6678
|
+
--list-divider: var(--border-width) solid var(--border);
|
|
6679
|
+
|
|
6680
|
+
display: grid;
|
|
6681
|
+
gap: 0;
|
|
6682
|
+
margin: 0;
|
|
6683
|
+
padding: 0;
|
|
6684
|
+
border-block-start: var(--list-divider);
|
|
6685
|
+
list-style: none;
|
|
6686
|
+
}
|
|
6687
|
+
|
|
6688
|
+
.list > li {
|
|
6689
|
+
margin: 0;
|
|
6690
|
+
}
|
|
6691
|
+
|
|
6692
|
+
.list > :where(.list-item),
|
|
6693
|
+
.list > li > .list-item {
|
|
6694
|
+
display: grid;
|
|
6695
|
+
grid-template-columns: auto minmax(0, 1fr) auto;
|
|
6696
|
+
align-items: center;
|
|
6697
|
+
gap: var(--list-item-gap);
|
|
6698
|
+
min-block-size: var(--list-item-min-size);
|
|
6699
|
+
padding-block: var(--list-item-pad-block);
|
|
6700
|
+
padding-inline: var(--list-item-pad-inline);
|
|
6701
|
+
}
|
|
6702
|
+
|
|
6703
|
+
.list > .list-item + .list-item,
|
|
6704
|
+
.list > li + li {
|
|
6705
|
+
border-block-start: var(--list-divider);
|
|
6706
|
+
}
|
|
6707
|
+
|
|
6708
|
+
a.list-item {
|
|
6709
|
+
color: inherit;
|
|
6710
|
+
text-decoration: none;
|
|
6711
|
+
}
|
|
6712
|
+
|
|
6713
|
+
a.list-item:hover {
|
|
6714
|
+
background: var(--surface-subtle);
|
|
6715
|
+
}
|
|
6716
|
+
|
|
6717
|
+
.list-item-content {
|
|
6718
|
+
min-inline-size: 0;
|
|
6719
|
+
}
|
|
6720
|
+
|
|
6721
|
+
.list-item-title,
|
|
6722
|
+
.list-item-text {
|
|
6723
|
+
display: block;
|
|
6724
|
+
margin: 0;
|
|
6725
|
+
}
|
|
6726
|
+
|
|
6727
|
+
.list-item-text {
|
|
6728
|
+
color: var(--text-muted);
|
|
6729
|
+
font-size: var(--font-size-sm);
|
|
6730
|
+
overflow-wrap: anywhere;
|
|
6731
|
+
}
|
|
6732
|
+
|
|
6733
|
+
.list-item-trailing {
|
|
6734
|
+
justify-self: end;
|
|
6735
|
+
min-inline-size: 0;
|
|
6736
|
+
}
|
|
6737
|
+
|
|
6738
|
+
@media print {
|
|
6739
|
+
.list > :where(.list-item),
|
|
6740
|
+
.list > li > .list-item {
|
|
6741
|
+
break-inside: avoid;
|
|
6742
|
+
}
|
|
6743
|
+
}
|
|
6744
|
+
|
|
6265
6745
|
/*
|
|
6266
6746
|
* Table — structured tabular data.
|
|
6267
6747
|
*
|
|
@@ -6560,6 +7040,7 @@ a.avatar[aria-disabled="true"] {
|
|
|
6560
7040
|
display: inline-grid;
|
|
6561
7041
|
padding: var(--aura-width);
|
|
6562
7042
|
border-radius: calc(var(--aura-radius) + var(--aura-width));
|
|
7043
|
+
border: var(--border-width) solid transparent;
|
|
6563
7044
|
background: var(--aura-color);
|
|
6564
7045
|
background: conic-gradient(from var(--aura-angle), transparent 0 65%, var(--aura-color));
|
|
6565
7046
|
}
|
|
@@ -6610,16 +7091,6 @@ a.avatar[aria-disabled="true"] {
|
|
|
6610
7091
|
}
|
|
6611
7092
|
}
|
|
6612
7093
|
|
|
6613
|
-
@media (forced-colors: active) {
|
|
6614
|
-
.aura {
|
|
6615
|
-
background: CanvasText;
|
|
6616
|
-
}
|
|
6617
|
-
|
|
6618
|
-
.aura::before {
|
|
6619
|
-
display: none;
|
|
6620
|
-
}
|
|
6621
|
-
}
|
|
6622
|
-
|
|
6623
7094
|
/* Utilities — small, single-purpose escape hatches. */
|
|
6624
7095
|
/*
|
|
6625
7096
|
* Small, single-purpose utilities for common escape hatches.
|