@matteoaliano/forest-ui 1.2.3 → 1.2.5
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/dist/{chunk-NXIZI6F7.mjs → chunk-B5MZMBLL.mjs} +188 -107
- package/dist/chunk-B5MZMBLL.mjs.map +1 -0
- package/dist/index.d.mts +27 -6
- package/dist/index.d.ts +27 -6
- package/dist/index.js +504 -206
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +525 -308
- package/dist/index.mjs.map +1 -1
- package/dist/theme.d.mts +1 -0
- package/dist/theme.d.ts +1 -0
- package/dist/theme.js +187 -106
- package/dist/theme.js.map +1 -1
- package/dist/theme.mjs +1 -1
- package/package.json +1 -1
- package/skills/forest-alkemy-plus/SKILL.md +2 -2
- package/skills/forest-alkemy-plus/references/components.md +3 -3
- package/skills/forest-alkemy-plus/references/patterns.md +2 -1
- package/dist/chunk-NXIZI6F7.mjs.map +0 -1
package/dist/theme.d.mts
CHANGED
package/dist/theme.d.ts
CHANGED
package/dist/theme.js
CHANGED
|
@@ -350,19 +350,13 @@ function buildComponents(tokens2) {
|
|
|
350
350
|
}
|
|
351
351
|
};
|
|
352
352
|
const bevelHover = {
|
|
353
|
-
borderTopWidth:
|
|
354
|
-
borderBottomWidth: 1
|
|
355
|
-
borderTopLeftRadius: radius4.lg,
|
|
356
|
-
borderTopRightRadius: radius4.lg,
|
|
357
|
-
borderBottomLeftRadius: radius4.md,
|
|
358
|
-
borderBottomRightRadius: radius4.md
|
|
353
|
+
borderTopWidth: 3,
|
|
354
|
+
borderBottomWidth: 1
|
|
359
355
|
};
|
|
360
356
|
const bevelPress = {
|
|
361
357
|
// Snap the press faster than the 300ms hover flip so it feels tactile.
|
|
362
358
|
transition: "border-width 120ms ease, border-radius 120ms ease, opacity 120ms ease",
|
|
363
359
|
borderTopWidth: 1,
|
|
364
|
-
borderTopLeftRadius: radius4.md,
|
|
365
|
-
borderTopRightRadius: radius4.md,
|
|
366
360
|
opacity: 0.75
|
|
367
361
|
};
|
|
368
362
|
const bevel3D = {
|
|
@@ -373,9 +367,7 @@ function buildComponents(tokens2) {
|
|
|
373
367
|
borderTopWidth: 1,
|
|
374
368
|
borderRightWidth: 1,
|
|
375
369
|
borderLeftWidth: 1,
|
|
376
|
-
borderBottomWidth:
|
|
377
|
-
borderBottomLeftRadius: radius4.lg,
|
|
378
|
-
borderBottomRightRadius: radius4.lg,
|
|
370
|
+
borderBottomWidth: 3,
|
|
379
371
|
"&::before": {
|
|
380
372
|
content: '""',
|
|
381
373
|
position: "absolute",
|
|
@@ -412,6 +404,21 @@ function buildComponents(tokens2) {
|
|
|
412
404
|
}
|
|
413
405
|
}
|
|
414
406
|
},
|
|
407
|
+
// ─── ButtonBase (global) ────────────────────────────────────────
|
|
408
|
+
// Kills MUI's TouchRipple everywhere in one place. Every clickable in the
|
|
409
|
+
// library renders through ButtonBase, so this reaches Button, IconButton,
|
|
410
|
+
// Fab, ToggleButton, CardActionArea, ListItemButton, MenuItem, Tab, Chip,
|
|
411
|
+
// PaginationItem, StepButton, BottomNavigationAction, SpeedDialAction and
|
|
412
|
+
// the Pickers' day/month/year cells without a per-component opt-out.
|
|
413
|
+
//
|
|
414
|
+
// The press feedback is the faux-3D bevel instead: the raised bottom edge
|
|
415
|
+
// collapses and the face dims on :active (see `bevelPress`). An expanding
|
|
416
|
+
// circle on top of that reads as a second, competing press affordance.
|
|
417
|
+
MuiButtonBase: {
|
|
418
|
+
defaultProps: {
|
|
419
|
+
disableRipple: true
|
|
420
|
+
}
|
|
421
|
+
},
|
|
415
422
|
// ─── Button ─────────────────────────────────────────────────────
|
|
416
423
|
MuiButton: {
|
|
417
424
|
defaultProps: {
|
|
@@ -431,7 +438,7 @@ function buildComponents(tokens2) {
|
|
|
431
438
|
const colorScales = { error: error2, warning: warning2, success: success2, info: info2 };
|
|
432
439
|
const faceScale = ownerState.color ? colorScales[ownerState.color] : void 0;
|
|
433
440
|
return {
|
|
434
|
-
borderRadius: radius4.
|
|
441
|
+
borderRadius: radius4.lg,
|
|
435
442
|
fontWeight: 600,
|
|
436
443
|
boxShadow: tokenShadows.xs,
|
|
437
444
|
height: 32,
|
|
@@ -449,12 +456,7 @@ function buildComponents(tokens2) {
|
|
|
449
456
|
borderTopWidth: 1,
|
|
450
457
|
borderRightWidth: 1,
|
|
451
458
|
borderLeftWidth: 1,
|
|
452
|
-
borderBottomWidth:
|
|
453
|
-
// Round the thick-bevel side more than the rest so the inner
|
|
454
|
-
// surface isn't squared off. Follows the bevel: bottom at rest,
|
|
455
|
-
// top on hover.
|
|
456
|
-
borderBottomLeftRadius: radius4.lg,
|
|
457
|
-
borderBottomRightRadius: radius4.lg,
|
|
459
|
+
borderBottomWidth: 3,
|
|
458
460
|
// Contained buttons have no border of their own — give them a
|
|
459
461
|
// translucent bevel. Outlined keeps its own border color.
|
|
460
462
|
...isContained && {
|
|
@@ -479,12 +481,8 @@ function buildComponents(tokens2) {
|
|
|
479
481
|
transition: "top 500ms ease-in-out"
|
|
480
482
|
},
|
|
481
483
|
"&:hover": {
|
|
482
|
-
borderTopWidth:
|
|
484
|
+
borderTopWidth: 3,
|
|
483
485
|
borderBottomWidth: 1,
|
|
484
|
-
borderTopLeftRadius: radius4.lg,
|
|
485
|
-
borderTopRightRadius: radius4.lg,
|
|
486
|
-
borderBottomLeftRadius: radius4.md,
|
|
487
|
-
borderBottomRightRadius: radius4.md,
|
|
488
486
|
// One step lighter than the default bevel (60% → 70%) so it
|
|
489
487
|
// stays visible against the brightened face on hover.
|
|
490
488
|
...isContained && {
|
|
@@ -511,8 +509,6 @@ function buildComponents(tokens2) {
|
|
|
511
509
|
// like a tactile click rather than a slow settle.
|
|
512
510
|
transition: "border-width 120ms ease, border-radius 120ms ease, opacity 120ms ease",
|
|
513
511
|
borderTopWidth: 1,
|
|
514
|
-
borderTopLeftRadius: radius4.md,
|
|
515
|
-
borderTopRightRadius: radius4.md,
|
|
516
512
|
opacity: 0.75
|
|
517
513
|
},
|
|
518
514
|
// Unified disabled treatment across the button family (Button,
|
|
@@ -527,7 +523,7 @@ function buildComponents(tokens2) {
|
|
|
527
523
|
borderTopWidth: 1,
|
|
528
524
|
borderRightWidth: 1,
|
|
529
525
|
borderLeftWidth: 1,
|
|
530
|
-
borderBottomWidth:
|
|
526
|
+
borderBottomWidth: 3
|
|
531
527
|
},
|
|
532
528
|
"@media (prefers-reduced-motion: reduce)": {
|
|
533
529
|
transition: "none",
|
|
@@ -562,7 +558,7 @@ function buildComponents(tokens2) {
|
|
|
562
558
|
},
|
|
563
559
|
styleOverrides: {
|
|
564
560
|
root: {
|
|
565
|
-
borderRadius: radius4.
|
|
561
|
+
borderRadius: radius4.lg,
|
|
566
562
|
// contained group → children already render as contained Buttons; only
|
|
567
563
|
// re-pin the bevel border color, which MUI's own grouped-contained
|
|
568
564
|
// default (palette grey) otherwise overrides away from the standalone
|
|
@@ -602,7 +598,7 @@ function buildComponents(tokens2) {
|
|
|
602
598
|
backgroundColor: "transparent",
|
|
603
599
|
color: buttonColors4.tertiaryColor.fg,
|
|
604
600
|
borderWidth: 0,
|
|
605
|
-
borderRadius: radius4.
|
|
601
|
+
borderRadius: radius4.lg,
|
|
606
602
|
boxShadow: "none",
|
|
607
603
|
"&::before": { display: "none" },
|
|
608
604
|
"&:active": { opacity: 1 },
|
|
@@ -634,17 +630,17 @@ function buildComponents(tokens2) {
|
|
|
634
630
|
MuiIconButton: {
|
|
635
631
|
styleOverrides: {
|
|
636
632
|
root: ({ theme }) => ({
|
|
637
|
-
borderRadius: radius4.
|
|
633
|
+
borderRadius: radius4.lg,
|
|
638
634
|
padding: 6,
|
|
639
635
|
"& .MuiSvgIcon-root": {
|
|
640
636
|
fontSize: 20
|
|
641
637
|
},
|
|
642
638
|
"&.ForestIconButton": {
|
|
643
639
|
...bevel3D,
|
|
644
|
-
// Square 32×32 with border-box so the faux-3D bevel (1px top +
|
|
640
|
+
// Square 32×32 with border-box so the faux-3D bevel (1px top + 3px
|
|
645
641
|
// bottom, 1px left/right) is absorbed rather than added on top —
|
|
646
|
-
// otherwise it rendered
|
|
647
|
-
// standalone Button's 32px height.
|
|
642
|
+
// otherwise it rendered an oversized control instead of matching
|
|
643
|
+
// the standalone Button's 32px height.
|
|
648
644
|
height: 32,
|
|
649
645
|
width: 32,
|
|
650
646
|
boxSizing: "border-box",
|
|
@@ -701,8 +697,7 @@ function buildComponents(tokens2) {
|
|
|
701
697
|
// ─── FAB ────────────────────────────────────────────────────────
|
|
702
698
|
// A Fab is a round contained Button: same faux-3D bevel, light sweep,
|
|
703
699
|
// brightness lift, and press. The border radii are left untouched so the
|
|
704
|
-
// circular / extended silhouettes survive the bevel flip
|
|
705
|
-
// like Button/IconButton do on their rounded corners).
|
|
700
|
+
// circular / extended silhouettes survive the bevel flip.
|
|
706
701
|
MuiFab: {
|
|
707
702
|
styleOverrides: {
|
|
708
703
|
root: ({ theme, ownerState }) => ({
|
|
@@ -718,7 +713,7 @@ function buildComponents(tokens2) {
|
|
|
718
713
|
borderTopWidth: 1,
|
|
719
714
|
borderRightWidth: 1,
|
|
720
715
|
borderLeftWidth: 1,
|
|
721
|
-
borderBottomWidth:
|
|
716
|
+
borderBottomWidth: 3,
|
|
722
717
|
"&::before": {
|
|
723
718
|
content: '""',
|
|
724
719
|
position: "absolute",
|
|
@@ -736,7 +731,7 @@ function buildComponents(tokens2) {
|
|
|
736
731
|
},
|
|
737
732
|
"&:hover": {
|
|
738
733
|
boxShadow: tokenShadows.xs,
|
|
739
|
-
borderTopWidth:
|
|
734
|
+
borderTopWidth: 3,
|
|
740
735
|
borderBottomWidth: 1,
|
|
741
736
|
// Light mode: dark face, brightness lift reads as hover. Dark
|
|
742
737
|
// mode: the face is already light — a lift blows out the top
|
|
@@ -951,7 +946,10 @@ function buildComponents(tokens2) {
|
|
|
951
946
|
MuiAutocomplete: {
|
|
952
947
|
styleOverrides: {
|
|
953
948
|
paper: {
|
|
954
|
-
borderRadius
|
|
949
|
+
// No borderRadius here on purpose — it inherits MuiPaper's `rounded`
|
|
950
|
+
// (radius.lg), so the popup matches Menu, Popover and every other
|
|
951
|
+
// Paper surface. It used to set radius.md and was the one popup in
|
|
952
|
+
// the system with a sharper corner.
|
|
955
953
|
boxShadow: tokenShadows.lg,
|
|
956
954
|
border: `1px solid ${border4.secondary}`,
|
|
957
955
|
marginTop: 4
|
|
@@ -965,10 +963,42 @@ function buildComponents(tokens2) {
|
|
|
965
963
|
lineHeight: "20px"
|
|
966
964
|
}
|
|
967
965
|
},
|
|
966
|
+
// MUI hardcodes this slot's own padding/marginRight in its source
|
|
967
|
+
// (padding: 2, marginRight: -2), which wins over the global
|
|
968
|
+
// MuiIconButton root override at equal specificity — left alone, the
|
|
969
|
+
// popup toggle renders as a small 24px button that doesn't fill the
|
|
970
|
+
// 32px input row and stops short of the edge. Restated here at the
|
|
971
|
+
// same size/inset as the DatePicker's open-picker button (32px,
|
|
972
|
+
// padding 6, flush against the input's 12px right padding) so both
|
|
973
|
+
// end-of-input icon buttons match.
|
|
974
|
+
popupIndicator: {
|
|
975
|
+
padding: 6,
|
|
976
|
+
// Not a straight copy of the DatePicker's -12px: that value cancels
|
|
977
|
+
// the input row's 12px padding directly, but this button's
|
|
978
|
+
// grandparent (`.MuiAutocomplete-endAdornment`) is itself inset 9px
|
|
979
|
+
// from the input's true right edge by MUI's own variant styles.
|
|
980
|
+
// -9px reaches through that inset to land flush, matching the
|
|
981
|
+
// DatePicker's open-picker button exactly.
|
|
982
|
+
marginRight: -9
|
|
983
|
+
},
|
|
984
|
+
// Same MUI-hardcoded-slot problem as popupIndicator, one size down
|
|
985
|
+
// (padding: 4, marginRight: -2) — sized to match it here. The
|
|
986
|
+
// popupIndicator's own marginRight anchors it to the input edge
|
|
987
|
+
// independent of clearIndicator's box, so this needs no matching
|
|
988
|
+
// offset: with both buttons the same size, 0 sits them edge-to-edge,
|
|
989
|
+
// and their equal padding already reads as the gap between the icons.
|
|
990
|
+
clearIndicator: {
|
|
991
|
+
padding: 6,
|
|
992
|
+
marginRight: 0
|
|
993
|
+
},
|
|
968
994
|
option: {
|
|
969
995
|
fontSize: 14,
|
|
970
996
|
lineHeight: "20px",
|
|
971
|
-
|
|
997
|
+
// An Autocomplete option is a plain <li class="MuiAutocomplete-option">,
|
|
998
|
+
// not a MenuItem, so MuiMenuItem's radius never reaches it. Match it
|
|
999
|
+
// here so the hover/selected highlight reads as the same pill a Select
|
|
1000
|
+
// draws, inset by the listbox's 4px padding.
|
|
1001
|
+
borderRadius: radius4.md,
|
|
972
1002
|
// Hover + selected backgrounds come from MUI's theme-aware action
|
|
973
1003
|
// overlays (a light overlay on dark, so they stay visible — a solid
|
|
974
1004
|
// dark-grey tier here reads as "no hover"). Selected keeps the text
|
|
@@ -978,7 +1008,14 @@ function buildComponents(tokens2) {
|
|
|
978
1008
|
}
|
|
979
1009
|
},
|
|
980
1010
|
listbox: {
|
|
981
|
-
padding: 4
|
|
1011
|
+
padding: 4,
|
|
1012
|
+
// Padding has to live here, not in the `option` slot: MUI nests its
|
|
1013
|
+
// own option styles under the listbox, so a rule from `option` ties
|
|
1014
|
+
// on specificity and loses on source order. This selector outranks
|
|
1015
|
+
// it. 6px 8px matches MuiMenuItem.
|
|
1016
|
+
"& .MuiAutocomplete-option": {
|
|
1017
|
+
padding: "6px 8px"
|
|
1018
|
+
}
|
|
982
1019
|
}
|
|
983
1020
|
}
|
|
984
1021
|
},
|
|
@@ -990,7 +1027,7 @@ function buildComponents(tokens2) {
|
|
|
990
1027
|
styleOverrides: {
|
|
991
1028
|
root: {
|
|
992
1029
|
color: border4.primary,
|
|
993
|
-
borderRadius: radius4.
|
|
1030
|
+
borderRadius: radius4.sm,
|
|
994
1031
|
padding: 0,
|
|
995
1032
|
width: 20,
|
|
996
1033
|
height: 20,
|
|
@@ -1007,7 +1044,7 @@ function buildComponents(tokens2) {
|
|
|
1007
1044
|
"&.Mui-focusVisible": {
|
|
1008
1045
|
outline: "none",
|
|
1009
1046
|
boxShadow: focusRings4.brand,
|
|
1010
|
-
borderRadius: radius4.
|
|
1047
|
+
borderRadius: radius4.sm
|
|
1011
1048
|
},
|
|
1012
1049
|
"&.Mui-disabled": {
|
|
1013
1050
|
color: border4.primary
|
|
@@ -1143,12 +1180,18 @@ function buildComponents(tokens2) {
|
|
|
1143
1180
|
color: buttonColors4.primary.fg,
|
|
1144
1181
|
borderTopWidth: 1,
|
|
1145
1182
|
borderBottomWidth: 1,
|
|
1146
|
-
borderTopLeftRadius: radius4.
|
|
1147
|
-
borderTopRightRadius: radius4.
|
|
1148
|
-
borderBottomLeftRadius: radius4.
|
|
1149
|
-
borderBottomRightRadius: radius4.
|
|
1183
|
+
borderTopLeftRadius: radius4.lg,
|
|
1184
|
+
borderTopRightRadius: radius4.lg,
|
|
1185
|
+
borderBottomLeftRadius: radius4.lg,
|
|
1186
|
+
borderBottomRightRadius: radius4.lg,
|
|
1150
1187
|
opacity: 0.75,
|
|
1151
|
-
|
|
1188
|
+
// The pressed-in cue is carried by the flattened bevel (bottom
|
|
1189
|
+
// border 3px -> 1px) alone in light mode. On the dark-mode face
|
|
1190
|
+
// that geometry reads too faintly, so it keeps the inner shadow.
|
|
1191
|
+
boxShadow: "none",
|
|
1192
|
+
...theme.applyStyles("dark", {
|
|
1193
|
+
boxShadow: "inset 0 2px 4px 0 rgba(0,0,0,0.3)"
|
|
1194
|
+
}),
|
|
1152
1195
|
"&::before": { display: "none" },
|
|
1153
1196
|
// Stays pressed on hover — no bevel re-raise, no brightness lift.
|
|
1154
1197
|
"&:hover": {
|
|
@@ -1156,8 +1199,8 @@ function buildComponents(tokens2) {
|
|
|
1156
1199
|
filter: "none",
|
|
1157
1200
|
borderTopWidth: 1,
|
|
1158
1201
|
borderBottomWidth: 1,
|
|
1159
|
-
borderTopLeftRadius: radius4.
|
|
1160
|
-
borderTopRightRadius: radius4.
|
|
1202
|
+
borderTopLeftRadius: radius4.lg,
|
|
1203
|
+
borderTopRightRadius: radius4.lg
|
|
1161
1204
|
}
|
|
1162
1205
|
},
|
|
1163
1206
|
// variant="outlined" (Forest wrapper class): the outlined <Button> /
|
|
@@ -1201,7 +1244,7 @@ function buildComponents(tokens2) {
|
|
|
1201
1244
|
borderTopWidth: 1,
|
|
1202
1245
|
borderRightWidth: 1,
|
|
1203
1246
|
borderLeftWidth: 1,
|
|
1204
|
-
borderBottomWidth:
|
|
1247
|
+
borderBottomWidth: 3,
|
|
1205
1248
|
"&::before": { display: "none" },
|
|
1206
1249
|
// selected+disabled keeps the pressed-in cue, greyed.
|
|
1207
1250
|
"&.Mui-selected": {
|
|
@@ -1218,7 +1261,7 @@ function buildComponents(tokens2) {
|
|
|
1218
1261
|
MuiToggleButtonGroup: {
|
|
1219
1262
|
styleOverrides: {
|
|
1220
1263
|
root: {
|
|
1221
|
-
borderRadius: radius4.
|
|
1264
|
+
borderRadius: radius4.lg,
|
|
1222
1265
|
overflow: "hidden"
|
|
1223
1266
|
},
|
|
1224
1267
|
// The child ToggleButton's selected/hover/active rules set per-corner
|
|
@@ -1235,14 +1278,14 @@ function buildComponents(tokens2) {
|
|
|
1235
1278
|
},
|
|
1236
1279
|
"&:first-of-type": {
|
|
1237
1280
|
"&, &:hover, &:active, &.Mui-selected": {
|
|
1238
|
-
borderTopLeftRadius: radius4.
|
|
1239
|
-
borderBottomLeftRadius: radius4.
|
|
1281
|
+
borderTopLeftRadius: radius4.lg,
|
|
1282
|
+
borderBottomLeftRadius: radius4.lg
|
|
1240
1283
|
}
|
|
1241
1284
|
},
|
|
1242
1285
|
"&:last-of-type": {
|
|
1243
1286
|
"&, &:hover, &:active, &.Mui-selected": {
|
|
1244
|
-
borderTopRightRadius: radius4.
|
|
1245
|
-
borderBottomRightRadius: radius4.
|
|
1287
|
+
borderTopRightRadius: radius4.lg,
|
|
1288
|
+
borderBottomRightRadius: radius4.lg
|
|
1246
1289
|
}
|
|
1247
1290
|
}
|
|
1248
1291
|
}
|
|
@@ -1268,7 +1311,27 @@ function buildComponents(tokens2) {
|
|
|
1268
1311
|
border: `1px solid ${border4.secondary}`,
|
|
1269
1312
|
backgroundColor: bg4.primary,
|
|
1270
1313
|
boxShadow: tokenShadows.xs,
|
|
1271
|
-
overflow: "hidden"
|
|
1314
|
+
overflow: "hidden",
|
|
1315
|
+
// Which surface a wrapped CardActionArea should paint. The action
|
|
1316
|
+
// area can't read the Card's own `background-color` (the Card goes
|
|
1317
|
+
// transparent when it wraps one, see below), so the colour is handed
|
|
1318
|
+
// down as a custom property instead. `<Card color="secondary">`
|
|
1319
|
+
// overrides it alongside its own background.
|
|
1320
|
+
"--forest-card-surface": bg4.primary,
|
|
1321
|
+
// A Card wrapping a CardActionArea hands its whole frame over: the
|
|
1322
|
+
// action area already draws the border, surface, radius and shadow,
|
|
1323
|
+
// and flips the radius on hover. Keeping the Card's own stacks a
|
|
1324
|
+
// second, static border just outside the moving one.
|
|
1325
|
+
"&:has(> .MuiCardActionArea-root)": {
|
|
1326
|
+
border: "none",
|
|
1327
|
+
borderRadius: 0,
|
|
1328
|
+
backgroundColor: "transparent",
|
|
1329
|
+
boxShadow: "none",
|
|
1330
|
+
// The action area clips its own content (it has overflow: hidden
|
|
1331
|
+
// for the glaze), so the Card must not also clip — its square
|
|
1332
|
+
// corners would cut the action area's rounded ones.
|
|
1333
|
+
overflow: "visible"
|
|
1334
|
+
}
|
|
1272
1335
|
}
|
|
1273
1336
|
}
|
|
1274
1337
|
},
|
|
@@ -2366,52 +2429,67 @@ function buildComponents(tokens2) {
|
|
|
2366
2429
|
}
|
|
2367
2430
|
},
|
|
2368
2431
|
// ─── CardActionArea ─────────────────────────────────────────────
|
|
2369
|
-
// Clickable-card affordance:
|
|
2370
|
-
// that flips bottom->top on hover),
|
|
2371
|
-
//
|
|
2372
|
-
//
|
|
2432
|
+
// Clickable-card affordance: the outlined Button's interaction at card
|
|
2433
|
+
// scale. Same faux-3D bevel (thick edge that flips bottom->top on hover),
|
|
2434
|
+
// same glaze sweep, same brightness darken on hover, same press-to-sink —
|
|
2435
|
+
// the only difference is the radius, which stays on the card steps
|
|
2436
|
+
// (xl / 2xl) rather than the button's (md / lg). Use
|
|
2437
|
+
// <Card><CardActionArea>…</CardActionArea></Card> for any interactive card;
|
|
2438
|
+
// the Card hands over its border and surface when it sees one.
|
|
2373
2439
|
MuiCardActionArea: {
|
|
2374
2440
|
styleOverrides: {
|
|
2375
2441
|
root: {
|
|
2376
2442
|
position: "relative",
|
|
2377
2443
|
overflow: "hidden",
|
|
2378
|
-
borderRadius: radius4
|
|
2444
|
+
borderRadius: radius4["2xl"],
|
|
2379
2445
|
borderStyle: "solid",
|
|
2380
|
-
|
|
2446
|
+
// The token the outlined Button reads, not `border.primary`, so the
|
|
2447
|
+
// two stay identical under any preset.
|
|
2448
|
+
borderColor: buttonColors4.secondaryColor.border,
|
|
2449
|
+
// Painted here rather than on the Card, which goes transparent so its
|
|
2450
|
+
// square box can't clip these corners. Falls back to the default card
|
|
2451
|
+
// surface when a CardActionArea is used outside a Card.
|
|
2452
|
+
backgroundColor: `var(--forest-card-surface, ${bg4.primary})`,
|
|
2381
2453
|
borderTopWidth: 1,
|
|
2382
2454
|
borderRightWidth: 1,
|
|
2383
2455
|
borderLeftWidth: 1,
|
|
2384
|
-
borderBottomWidth:
|
|
2385
|
-
borderBottomLeftRadius: radius4["2xl"],
|
|
2386
|
-
borderBottomRightRadius: radius4["2xl"],
|
|
2456
|
+
borderBottomWidth: 3,
|
|
2387
2457
|
boxShadow: tokenShadows.xs,
|
|
2388
|
-
transition: "
|
|
2389
|
-
|
|
2458
|
+
transition: "filter 300ms ease, border-width 300ms ease, border-radius 300ms ease, opacity 300ms ease, background-color 300ms ease",
|
|
2459
|
+
"&:focus-visible": {
|
|
2460
|
+
boxShadow: focusRings4.brandShadowXs
|
|
2461
|
+
},
|
|
2462
|
+
// Moving glaze — a soft light streak that sweeps top->bottom on
|
|
2463
|
+
// hover. Same parameters as the outlined Button's sweep.
|
|
2390
2464
|
"&::before": {
|
|
2391
2465
|
content: '""',
|
|
2392
2466
|
position: "absolute",
|
|
2393
2467
|
left: 0,
|
|
2394
2468
|
top: "-150%",
|
|
2395
2469
|
width: "100%",
|
|
2396
|
-
height:
|
|
2470
|
+
height: 5,
|
|
2397
2471
|
borderRadius: 4,
|
|
2398
|
-
backgroundColor: "color-mix(in srgb, currentColor
|
|
2399
|
-
boxShadow: "0 0
|
|
2400
|
-
opacity: 0.
|
|
2472
|
+
backgroundColor: "color-mix(in srgb, currentColor 45%, #fff)",
|
|
2473
|
+
boxShadow: "0 0 24px 4px color-mix(in srgb, currentColor 45%, #fff)",
|
|
2474
|
+
opacity: 0.2,
|
|
2401
2475
|
filter: "blur(3px)",
|
|
2402
2476
|
pointerEvents: "none",
|
|
2403
|
-
transition: "top
|
|
2477
|
+
transition: "top 500ms ease-in-out",
|
|
2404
2478
|
zIndex: 1
|
|
2405
2479
|
},
|
|
2406
2480
|
"&:hover": {
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2481
|
+
// Darken the whole surface via brightness, the same mechanism the
|
|
2482
|
+
// outlined Button uses — no border-color shift; the border stays
|
|
2483
|
+
// put and only the bevel geometry moves. Lighter than the Button's
|
|
2484
|
+
// 0.97 on purpose: the filter dims a card's media and copy along
|
|
2485
|
+
// with its surface, so the same amount reads much heavier here.
|
|
2486
|
+
filter: "brightness(0.995)",
|
|
2487
|
+
// The Button drops its resting shadow on hover (MUI's
|
|
2488
|
+
// disableElevation), so the raised edge is the only depth cue
|
|
2489
|
+
// mid-interaction. Matched here for parity.
|
|
2490
|
+
boxShadow: "none",
|
|
2491
|
+
borderTopWidth: 3,
|
|
2492
|
+
borderBottomWidth: 1
|
|
2415
2493
|
},
|
|
2416
2494
|
"&:hover::before": {
|
|
2417
2495
|
top: "150%"
|
|
@@ -2421,15 +2499,13 @@ function buildComponents(tokens2) {
|
|
|
2421
2499
|
"&:active": {
|
|
2422
2500
|
transition: "border-width 120ms ease, border-radius 120ms ease, opacity 120ms ease",
|
|
2423
2501
|
borderTopWidth: 1,
|
|
2424
|
-
|
|
2425
|
-
borderTopRightRadius: radius4.xl,
|
|
2426
|
-
opacity: 0.85
|
|
2427
|
-
},
|
|
2428
|
-
"&:hover .MuiCardActionArea-focusHighlight": {
|
|
2429
|
-
opacity: 0.04
|
|
2502
|
+
opacity: 0.75
|
|
2430
2503
|
},
|
|
2431
|
-
|
|
2432
|
-
|
|
2504
|
+
// MUI's own hover/focus tint overlay. The outlined Button has no
|
|
2505
|
+
// equivalent (it suppresses the variant hover background), so the
|
|
2506
|
+
// brightness darken above is the only hover feedback.
|
|
2507
|
+
"& .MuiCardActionArea-focusHighlight": {
|
|
2508
|
+
opacity: 0
|
|
2433
2509
|
},
|
|
2434
2510
|
"@media (prefers-reduced-motion: reduce)": {
|
|
2435
2511
|
transition: "none",
|
|
@@ -3184,7 +3260,12 @@ var display = {
|
|
|
3184
3260
|
var container = {
|
|
3185
3261
|
maxWidthDesktop: 1280,
|
|
3186
3262
|
paddingDesktop: 32,
|
|
3187
|
-
paddingMobile: 16
|
|
3263
|
+
paddingMobile: 16,
|
|
3264
|
+
// Corner radius of the App Shell's content surface where it meets the
|
|
3265
|
+
// chrome. Deliberately a layout value rather than a step on the `radius`
|
|
3266
|
+
// scale: that scale governs components (and the alkemy+ preset caps it at
|
|
3267
|
+
// 22), so a 24 sitting in it would misread as a component radius.
|
|
3268
|
+
shellRadius: 24
|
|
3188
3269
|
};
|
|
3189
3270
|
var widths = {
|
|
3190
3271
|
xxs: 320,
|
|
@@ -3450,15 +3531,15 @@ var alpha = {
|
|
|
3450
3531
|
var highlight = magenta;
|
|
3451
3532
|
var radius2 = {
|
|
3452
3533
|
...radius,
|
|
3453
|
-
xxs:
|
|
3454
|
-
xs:
|
|
3455
|
-
sm:
|
|
3456
|
-
md:
|
|
3457
|
-
lg:
|
|
3458
|
-
xl:
|
|
3459
|
-
"2xl":
|
|
3460
|
-
"3xl":
|
|
3461
|
-
"4xl":
|
|
3534
|
+
xxs: 2,
|
|
3535
|
+
xs: 4,
|
|
3536
|
+
sm: 6,
|
|
3537
|
+
md: 8,
|
|
3538
|
+
lg: 11,
|
|
3539
|
+
xl: 14,
|
|
3540
|
+
"2xl": 16,
|
|
3541
|
+
"3xl": 20,
|
|
3542
|
+
"4xl": 22
|
|
3462
3543
|
};
|
|
3463
3544
|
var text2 = {
|
|
3464
3545
|
primary: gray[50],
|
|
@@ -3773,15 +3854,15 @@ var colors = {
|
|
|
3773
3854
|
};
|
|
3774
3855
|
var radius3 = {
|
|
3775
3856
|
...radius,
|
|
3776
|
-
xxs:
|
|
3777
|
-
xs:
|
|
3778
|
-
sm:
|
|
3779
|
-
md:
|
|
3780
|
-
lg:
|
|
3781
|
-
xl:
|
|
3782
|
-
"2xl":
|
|
3783
|
-
"3xl":
|
|
3784
|
-
"4xl":
|
|
3857
|
+
xxs: 2,
|
|
3858
|
+
xs: 4,
|
|
3859
|
+
sm: 6,
|
|
3860
|
+
md: 8,
|
|
3861
|
+
lg: 11,
|
|
3862
|
+
xl: 14,
|
|
3863
|
+
"2xl": 16,
|
|
3864
|
+
"3xl": 20,
|
|
3865
|
+
"4xl": 22
|
|
3785
3866
|
};
|
|
3786
3867
|
var text3 = {
|
|
3787
3868
|
primary: gray[900],
|