@duskmoon-dev/core 1.19.4 → 1.19.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.
@@ -3746,7 +3746,8 @@
3746
3746
  }
3747
3747
 
3748
3748
  /* Modal Action */
3749
- .modal-action {
3749
+ .modal-action,
3750
+ .modal-footer {
3750
3751
  display: flex;
3751
3752
  justify-content: flex-end;
3752
3753
  gap: 0.5rem;
@@ -3777,10 +3778,18 @@
3777
3778
  max-width: 20rem;
3778
3779
  }
3779
3780
 
3781
+ .modal-md .modal-box {
3782
+ max-width: 32rem;
3783
+ }
3784
+
3780
3785
  .modal-lg .modal-box {
3781
3786
  max-width: 48rem;
3782
3787
  }
3783
3788
 
3789
+ .modal-xl .modal-box {
3790
+ max-width: 64rem;
3791
+ }
3792
+
3784
3793
  .modal-full .modal-box {
3785
3794
  max-width: calc(100vw - 2rem);
3786
3795
  max-height: calc(100vh - 2rem);
@@ -3803,6 +3812,38 @@
3803
3812
  align-items: center;
3804
3813
  }
3805
3814
 
3815
+ /* Animation Variants */
3816
+ .modal-slide-up .modal-box {
3817
+ transform: translateY(6rem) scale(0.95);
3818
+ }
3819
+
3820
+ .modal-slide-down .modal-box {
3821
+ transform: translateY(-6rem) scale(0.95);
3822
+ }
3823
+
3824
+ .modal-zoom .modal-box {
3825
+ transform: scale(0.75);
3826
+ }
3827
+
3828
+ :is(.modal-slide-up, .modal-slide-down, .modal-zoom).modal-open .modal-box,
3829
+ :is(.modal-slide-up, .modal-slide-down, .modal-zoom):target .modal-box {
3830
+ transform: translateY(0) scale(1);
3831
+ }
3832
+
3833
+ /* Backdrop Variants */
3834
+ .modal-backdrop-light {
3835
+ background-color: color-mix(in srgb, white 80%, transparent);
3836
+ }
3837
+
3838
+ .modal-backdrop-blur {
3839
+ background-color: color-mix(in srgb, var(--color-scrim) 30%, transparent);
3840
+ backdrop-filter: blur(8px);
3841
+ }
3842
+
3843
+ .modal-no-backdrop {
3844
+ background-color: transparent;
3845
+ }
3846
+
3806
3847
  /* Modal Close Button */
3807
3848
  .modal-close {
3808
3849
  position: absolute;
@@ -3851,6 +3892,22 @@
3851
3892
  line-height: 1.5;
3852
3893
  }
3853
3894
 
3895
+ .modal-scrollable .modal-body {
3896
+ max-height: 60vh;
3897
+ overflow-y: auto;
3898
+ }
3899
+
3900
+ .modal-no-padding .modal-body {
3901
+ padding: 0;
3902
+ }
3903
+
3904
+ .modal-centered .modal-body {
3905
+ display: flex;
3906
+ align-items: center;
3907
+ justify-content: center;
3908
+ text-align: center;
3909
+ }
3910
+
3854
3911
  /* Responsive Modal */
3855
3912
  @media (max-width: 640px) {
3856
3913
  .modal-box {
@@ -3972,6 +4029,10 @@
3972
4029
  white-space: nowrap;
3973
4030
  border: 0;
3974
4031
  }
4032
+
4033
+ body.modal-open {
4034
+ overflow: hidden;
4035
+ }
3975
4036
  }
3976
4037
 
3977
4038
 
@@ -12529,8 +12590,11 @@
12529
12590
  @layer components {
12530
12591
  /* Base Alert */
12531
12592
  .alert {
12532
- display: flex;
12533
- align-items: flex-start;
12593
+ display: grid;
12594
+ grid-template-columns: auto minmax(0, 1fr) auto auto;
12595
+ grid-template-areas:
12596
+ "icon content actions close";
12597
+ align-items: center;
12534
12598
  gap: 0.75rem;
12535
12599
  padding: 1rem;
12536
12600
  border-radius: var(--radius-sm);
@@ -12541,6 +12605,7 @@
12541
12605
 
12542
12606
  /* Alert Icon */
12543
12607
  .alert-icon {
12608
+ grid-area: icon;
12544
12609
  display: flex;
12545
12610
  align-items: center;
12546
12611
  justify-content: center;
@@ -12548,10 +12613,12 @@
12548
12613
  height: 1.5rem;
12549
12614
  font-size: 1.25rem;
12550
12615
  flex-shrink: 0;
12616
+ align-self: start;
12551
12617
  }
12552
12618
 
12553
12619
  /* Alert Content */
12554
12620
  .alert-content {
12621
+ grid-area: content;
12555
12622
  display: flex;
12556
12623
  flex-direction: column;
12557
12624
  gap: 0.25rem;
@@ -12559,13 +12626,42 @@
12559
12626
  min-width: 0;
12560
12627
  }
12561
12628
 
12629
+ .alert-content > p {
12630
+ margin: 0;
12631
+ }
12632
+
12633
+ /* Keep the compact single-message form vertically balanced against global typography margins. */
12634
+ .alert > p {
12635
+ margin: 0;
12636
+ }
12637
+
12638
+ .alert-horizontal { display: grid; }
12639
+ .alert-actions-end { grid-template-areas: "icon content actions close"; }
12640
+ .alert-actions-bottom {
12641
+ grid-template-columns: auto minmax(0, 1fr) auto;
12642
+ grid-template-areas:
12643
+ "icon content close"
12644
+ ". actions .";
12645
+ }
12646
+
12647
+ .alert-actions-bottom .alert-actions {
12648
+ justify-self: start;
12649
+ margin-top: 0.5rem;
12650
+ }
12651
+ .alert-vertical {
12652
+ display: flex;
12653
+ flex-direction: column;
12654
+ }
12655
+
12562
12656
  .alert-title {
12657
+ margin: 0;
12563
12658
  font-size: 0.875rem;
12564
12659
  font-weight: 600;
12565
12660
  line-height: 1.25rem;
12566
12661
  }
12567
12662
 
12568
12663
  .alert-description {
12664
+ margin: 0;
12569
12665
  font-size: 0.875rem;
12570
12666
  line-height: 1.25rem;
12571
12667
  opacity: 0.9;
@@ -12573,6 +12669,7 @@
12573
12669
 
12574
12670
  /* Alert Close Button */
12575
12671
  .alert-close {
12672
+ grid-area: close;
12576
12673
  display: flex;
12577
12674
  align-items: center;
12578
12675
  justify-content: center;
@@ -12786,6 +12883,7 @@
12786
12883
  /* Dismissible */
12787
12884
  .alert-dismissible {
12788
12885
  padding-right: 2.5rem;
12886
+ padding-inline-end: 2.5rem;
12789
12887
  position: relative;
12790
12888
  }
12791
12889
 
@@ -12793,6 +12891,7 @@
12793
12891
  position: absolute;
12794
12892
  top: 0.75rem;
12795
12893
  right: 0.75rem;
12894
+ inset-inline-end: 0.75rem;
12796
12895
  }
12797
12896
 
12798
12897
  /* Compact */
@@ -12812,11 +12911,25 @@
12812
12911
  font-size: 0.8125rem;
12813
12912
  }
12814
12913
 
12914
+ .alert-comfortable {
12915
+ padding: 1.25rem;
12916
+ gap: 1rem;
12917
+ }
12918
+
12815
12919
  /* Alert Actions */
12816
12920
  .alert-actions {
12921
+ grid-area: actions;
12817
12922
  display: flex;
12818
12923
  gap: 0.5rem;
12819
- margin-top: 0.5rem;
12924
+ margin-top: 0;
12925
+ flex-wrap: wrap;
12926
+ align-self: center;
12927
+ justify-self: end;
12928
+ }
12929
+
12930
+ .alert-vertical .alert-actions {
12931
+ align-self: stretch;
12932
+ width: 100%;
12820
12933
  }
12821
12934
 
12822
12935
  .alert-filled .alert-actions .btn-text {
@@ -12840,6 +12953,32 @@
12840
12953
  transition: none;
12841
12954
  }
12842
12955
  }
12956
+
12957
+ @media (max-width: 32rem) {
12958
+ .alert:not(.alert-vertical) .alert-content,
12959
+ .alert-horizontal .alert-content {
12960
+ flex-basis: min(100%, 18rem);
12961
+ }
12962
+ .alert:not(.alert-vertical),
12963
+ .alert-horizontal {
12964
+ grid-template-columns: auto minmax(0, 1fr) auto;
12965
+ grid-template-areas:
12966
+ "icon content close"
12967
+ ". actions actions";
12968
+ }
12969
+ .alert:not(.alert-vertical).alert-actions-end,
12970
+ .alert-horizontal.alert-actions-end {
12971
+ grid-template-columns: auto minmax(0, 1fr) auto;
12972
+ grid-template-areas:
12973
+ "icon content close"
12974
+ ". actions actions";
12975
+ }
12976
+ .alert:not(.alert-vertical) .alert-actions,
12977
+ .alert-horizontal .alert-actions {
12978
+ justify-self: start;
12979
+ margin-top: 0.5rem;
12980
+ }
12981
+ }
12843
12982
  }
12844
12983
 
12845
12984
  /**
@@ -13016,6 +13155,112 @@
13016
13155
  }
13017
13156
  }
13018
13157
 
13158
+ /**
13159
+ * Loading Component Styles
13160
+ * CSS-only activity indicators. State, aria-busy, and disabling remain consumer-owned.
13161
+ */
13162
+
13163
+ @layer components {
13164
+ .loading {
13165
+ --loading-size: 1.25rem;
13166
+ display: inline-flex;
13167
+ width: var(--loading-size);
13168
+ height: var(--loading-size);
13169
+ flex: 0 0 var(--loading-size);
13170
+ color: currentColor;
13171
+ vertical-align: middle;
13172
+ }
13173
+
13174
+ .loading-spinner {
13175
+ border: max(2px, calc(var(--loading-size) / 8)) solid color-mix(in oklch, currentColor 25%, transparent);
13176
+ border-top-color: currentColor;
13177
+ border-radius: var(--radius-full);
13178
+ animation: loading-spin 800ms linear infinite;
13179
+ }
13180
+
13181
+ .loading-dots,
13182
+ .loading-bars {
13183
+ align-items: center;
13184
+ justify-content: center;
13185
+ gap: max(2px, calc(var(--loading-size) / 8));
13186
+ }
13187
+
13188
+ .loading-dots::before,
13189
+ .loading-dots::after,
13190
+ .loading-bars::before,
13191
+ .loading-bars::after {
13192
+ content: "";
13193
+ display: block;
13194
+ background: currentColor;
13195
+ }
13196
+
13197
+ .loading-dots::before,
13198
+ .loading-dots::after {
13199
+ width: 25%;
13200
+ height: 25%;
13201
+ border-radius: var(--radius-full);
13202
+ box-shadow: calc(var(--loading-size) / 3) 0 currentColor;
13203
+ animation: loading-dots 900ms ease-in-out infinite;
13204
+ }
13205
+
13206
+ .loading-dots::after {
13207
+ display: none;
13208
+ }
13209
+
13210
+ .loading-bars {
13211
+ padding-inline: 10%;
13212
+ }
13213
+
13214
+ .loading-bars::before,
13215
+ .loading-bars::after {
13216
+ width: 18%;
13217
+ height: 65%;
13218
+ border-radius: var(--radius-xs);
13219
+ box-shadow: calc(var(--loading-size) / 3) 0 currentColor, calc(var(--loading-size) * 2 / 3) 0 currentColor;
13220
+ animation: loading-bars 900ms ease-in-out infinite;
13221
+ }
13222
+
13223
+ .loading-bars::after {
13224
+ display: none;
13225
+ }
13226
+
13227
+ .loading-xs { --loading-size: 0.75rem; }
13228
+ .loading-sm { --loading-size: 1rem; }
13229
+ .loading-md { --loading-size: 1.25rem; }
13230
+ .loading-lg { --loading-size: 1.75rem; }
13231
+ .loading-xl { --loading-size: 2.5rem; }
13232
+
13233
+ .loading-primary { color: var(--color-primary); }
13234
+ .loading-secondary { color: var(--color-secondary); }
13235
+ .loading-tertiary { color: var(--color-tertiary); }
13236
+ .loading-info { color: var(--color-info); }
13237
+ .loading-success { color: var(--color-success); }
13238
+ .loading-warning { color: var(--color-warning); }
13239
+ .loading-error { color: var(--color-error); }
13240
+
13241
+ @keyframes loading-spin {
13242
+ to { transform: rotate(360deg); }
13243
+ }
13244
+
13245
+ @keyframes loading-dots {
13246
+ 0%, 100% { opacity: 0.35; transform: scale(0.75); }
13247
+ 50% { opacity: 1; transform: scale(1); }
13248
+ }
13249
+
13250
+ @keyframes loading-bars {
13251
+ 0%, 100% { opacity: 0.35; transform: scaleY(0.65); }
13252
+ 50% { opacity: 1; transform: scaleY(1); }
13253
+ }
13254
+
13255
+ @media (prefers-reduced-motion: reduce) {
13256
+ .loading-spinner,
13257
+ .loading-dots::before,
13258
+ .loading-bars::before {
13259
+ animation: none;
13260
+ }
13261
+ }
13262
+ }
13263
+
13019
13264
  /**
13020
13265
  * Progress Component Styles
13021
13266
  * DuskMoonUI - Material Design 3 inspired progress system
@@ -13032,6 +13277,36 @@
13032
13277
  overflow: hidden;
13033
13278
  }
13034
13279
 
13280
+ /* Native progress keeps the platform's accessible value/max contract. */
13281
+ progress.progress {
13282
+ appearance: none;
13283
+ border: 0;
13284
+ display: block;
13285
+ }
13286
+
13287
+ progress.progress::-webkit-progress-bar {
13288
+ background: var(--color-surface-container-highest);
13289
+ border-radius: var(--radius-full);
13290
+ }
13291
+
13292
+ progress.progress::-webkit-progress-value {
13293
+ background: var(--color-primary);
13294
+ border-radius: var(--radius-full);
13295
+ transition: width 300ms ease-in-out;
13296
+ }
13297
+
13298
+ progress.progress::-moz-progress-bar {
13299
+ background: var(--color-primary);
13300
+ border-radius: var(--radius-full);
13301
+ transition: width 300ms ease-in-out;
13302
+ }
13303
+
13304
+ progress.progress:indeterminate::-webkit-progress-value,
13305
+ progress.progress:indeterminate::-moz-progress-bar {
13306
+ width: 30%;
13307
+ animation: progress-indeterminate 1.5s infinite ease-in-out;
13308
+ }
13309
+
13035
13310
  /* Progress Bar */
13036
13311
  .progress-bar {
13037
13312
  position: absolute;
@@ -13084,6 +13359,21 @@
13084
13359
  background-color: var(--color-base-content);
13085
13360
  }
13086
13361
 
13362
+ progress.progress-primary::-webkit-progress-value,
13363
+ progress.progress-primary::-moz-progress-bar { background: var(--color-primary); }
13364
+ progress.progress-secondary::-webkit-progress-value,
13365
+ progress.progress-secondary::-moz-progress-bar { background: var(--color-secondary); }
13366
+ progress.progress-tertiary::-webkit-progress-value,
13367
+ progress.progress-tertiary::-moz-progress-bar { background: var(--color-tertiary); }
13368
+ progress.progress-info::-webkit-progress-value,
13369
+ progress.progress-info::-moz-progress-bar { background: var(--color-info); }
13370
+ progress.progress-success::-webkit-progress-value,
13371
+ progress.progress-success::-moz-progress-bar { background: var(--color-success); }
13372
+ progress.progress-warning::-webkit-progress-value,
13373
+ progress.progress-warning::-moz-progress-bar { background: var(--color-warning); }
13374
+ progress.progress-error::-webkit-progress-value,
13375
+ progress.progress-error::-moz-progress-bar { background: var(--color-error); }
13376
+
13087
13377
  /* Size Variants */
13088
13378
  .progress-xs {
13089
13379
  height: 0.25rem;
@@ -13159,6 +13449,25 @@
13159
13449
  }
13160
13450
  }
13161
13451
 
13452
+ /* Buffer tracks belong to custom markup, not native <progress>. */
13453
+ .progress-buffer {
13454
+ position: relative;
13455
+ }
13456
+
13457
+ .progress-buffer-bar {
13458
+ position: absolute;
13459
+ inset-block: 0;
13460
+ inset-inline-start: 0;
13461
+ width: 0;
13462
+ background: color-mix(in oklch, var(--color-primary) 30%, transparent);
13463
+ border-radius: var(--radius-full);
13464
+ transition: width 300ms ease-in-out;
13465
+ }
13466
+
13467
+ .progress-buffer .progress-bar {
13468
+ z-index: 1;
13469
+ }
13470
+
13162
13471
  /* Circular Progress */
13163
13472
  .progress-circular {
13164
13473
  position: relative;
@@ -13258,7 +13567,17 @@
13258
13567
 
13259
13568
  /* Reduce Motion */
13260
13569
  @media (prefers-reduced-motion: reduce) {
13570
+ .progress-bar,
13571
+ progress.progress::-webkit-progress-value,
13572
+ progress.progress::-moz-progress-bar,
13573
+ .progress-circular-bar,
13574
+ .progress-buffer-bar {
13575
+ transition: none;
13576
+ }
13577
+
13261
13578
  .progress-indeterminate .progress-bar,
13579
+ progress.progress:indeterminate::-webkit-progress-value,
13580
+ progress.progress:indeterminate::-moz-progress-bar,
13262
13581
  .progress-striped.progress-animated .progress-bar,
13263
13582
  .progress-circular-indeterminate svg,
13264
13583
  .progress-circular-indeterminate .progress-circular-bar {
@@ -13267,6 +13586,54 @@
13267
13586
  }
13268
13587
  }
13269
13588
 
13589
+ /**
13590
+ * Radial Progress Component Styles
13591
+ * Determinate percentage progress without circumference arithmetic.
13592
+ */
13593
+
13594
+ @layer components {
13595
+ .radial-progress {
13596
+ --radial-progress-value: 0;
13597
+ --radial-progress-size: 3rem;
13598
+ --radial-progress-thickness: 0.375rem;
13599
+ --radial-progress-track: var(--color-surface-container-highest);
13600
+ position: relative;
13601
+ display: inline-grid;
13602
+ width: var(--radial-progress-size);
13603
+ height: var(--radial-progress-size);
13604
+ place-items: center;
13605
+ color: var(--color-primary);
13606
+ border-radius: var(--radius-full);
13607
+ background: conic-gradient(currentColor calc(clamp(0, var(--radial-progress-value), 100) * 1%), var(--radial-progress-track) 0);
13608
+ isolation: isolate;
13609
+ }
13610
+
13611
+ .radial-progress::before {
13612
+ content: "";
13613
+ position: absolute;
13614
+ inset: var(--radial-progress-thickness);
13615
+ z-index: 0;
13616
+ border-radius: inherit;
13617
+ background: var(--color-surface);
13618
+ }
13619
+
13620
+ .radial-progress-primary { color: var(--color-primary); }
13621
+ .radial-progress-secondary { color: var(--color-secondary); }
13622
+ .radial-progress-tertiary { color: var(--color-tertiary); }
13623
+ .radial-progress-info { color: var(--color-info); }
13624
+ .radial-progress-success { color: var(--color-success); }
13625
+ .radial-progress-warning { color: var(--color-warning); }
13626
+ .radial-progress-error { color: var(--color-error); }
13627
+
13628
+ .radial-progress-sm { --radial-progress-size: 2rem; --radial-progress-thickness: 0.25rem; }
13629
+ .radial-progress-lg { --radial-progress-size: 4rem; --radial-progress-thickness: 0.5rem; }
13630
+ .radial-progress-xl { --radial-progress-size: 6rem; --radial-progress-thickness: 0.625rem; }
13631
+
13632
+ @media (prefers-reduced-motion: reduce) {
13633
+ .radial-progress { transition: none; }
13634
+ }
13635
+ }
13636
+
13270
13637
  /**
13271
13638
  * Skeleton Component Styles
13272
13639
  * DuskMoonUI - Material Design 3 inspired skeleton loading system
@@ -13300,6 +13667,10 @@
13300
13667
  border-radius: var(--radius-sm);
13301
13668
  }
13302
13669
 
13670
+ .skeleton-static {
13671
+ animation: none;
13672
+ }
13673
+
13303
13674
  /* Size Variants */
13304
13675
  .skeleton-xs {
13305
13676
  height: 0.5rem;
@@ -13402,7 +13773,7 @@
13402
13773
  background: linear-gradient(
13403
13774
  90deg,
13404
13775
  transparent,
13405
- rgba(255, 255, 255, 0.3),
13776
+ color-mix(in oklch, var(--color-surface-bright) 35%, transparent),
13406
13777
  transparent
13407
13778
  );
13408
13779
  animation: skeleton-wave 1.5s infinite;
@@ -13480,6 +13851,14 @@
13480
13851
 
13481
13852
  .skeleton-wave::after {
13482
13853
  animation: none;
13854
+ transform: translateX(0);
13855
+ opacity: 0.35;
13856
+ }
13857
+
13858
+ .skeleton-static::after {
13859
+ animation: none;
13860
+ transform: translateX(0);
13861
+ opacity: 0.35;
13483
13862
  }
13484
13863
  }
13485
13864
  }
@@ -13696,49 +14075,49 @@
13696
14075
 
13697
14076
  /* Color Variants */
13698
14077
  .snackbar-info {
13699
- background-color: var(--color-info-container);
13700
- color: var(--color-on-info-container);
14078
+ background-color: var(--color-info);
14079
+ color: var(--color-info-content);
13701
14080
  }
13702
14081
 
13703
14082
  .snackbar-success {
13704
- background-color: var(--color-success-container);
13705
- color: var(--color-on-success-container);
14083
+ background-color: var(--color-success);
14084
+ color: var(--color-success-content);
13706
14085
  }
13707
14086
 
13708
14087
  .snackbar-warning {
13709
- background-color: var(--color-warning-container);
13710
- color: var(--color-on-warning-container);
14088
+ background-color: var(--color-warning);
14089
+ color: var(--color-warning-content);
13711
14090
  }
13712
14091
 
13713
14092
  .snackbar-error {
13714
- background-color: var(--color-error-container);
13715
- color: var(--color-on-error-container);
14093
+ background-color: var(--color-error);
14094
+ color: var(--color-error-content);
13716
14095
  }
13717
14096
 
13718
14097
  /* Brand Color Variants */
13719
14098
  .snackbar-primary {
13720
- background-color: var(--color-primary-container);
13721
- color: var(--color-on-primary-container);
14099
+ background-color: var(--color-primary);
14100
+ color: var(--color-primary-content);
13722
14101
  }
13723
14102
 
13724
14103
  .snackbar-secondary {
13725
- background-color: var(--color-secondary-container);
13726
- color: var(--color-on-secondary-container);
14104
+ background-color: var(--color-secondary);
14105
+ color: var(--color-secondary-content);
13727
14106
  }
13728
14107
 
13729
14108
  .snackbar-tertiary {
13730
- background-color: var(--color-tertiary-container);
13731
- color: var(--color-on-tertiary-container);
14109
+ background-color: var(--color-tertiary);
14110
+ color: var(--color-tertiary-content);
13732
14111
  }
13733
14112
 
13734
14113
  .snackbar-accent {
13735
- background-color: color-mix(in oklch, var(--color-accent) 15%, var(--color-surface));
13736
- color: var(--color-on-surface);
14114
+ background-color: var(--color-accent);
14115
+ color: var(--color-accent-content);
13737
14116
  }
13738
14117
 
13739
14118
  .snackbar-neutral {
13740
- background-color: color-mix(in oklch, var(--color-neutral) 15%, var(--color-surface));
13741
- color: var(--color-on-surface);
14119
+ background-color: var(--color-neutral);
14120
+ color: var(--color-neutral-content);
13742
14121
  }
13743
14122
 
13744
14123
  .snackbar-base {
@@ -13746,6 +14125,36 @@
13746
14125
  color: var(--color-base-content);
13747
14126
  }
13748
14127
 
14128
+ :is(
14129
+ .snackbar-info,
14130
+ .snackbar-success,
14131
+ .snackbar-warning,
14132
+ .snackbar-error,
14133
+ .snackbar-primary,
14134
+ .snackbar-secondary,
14135
+ .snackbar-tertiary,
14136
+ .snackbar-accent,
14137
+ .snackbar-neutral,
14138
+ .snackbar-base
14139
+ ) :is(.snackbar-action, .snackbar-close) {
14140
+ color: inherit;
14141
+ }
14142
+
14143
+ :is(
14144
+ .snackbar-info,
14145
+ .snackbar-success,
14146
+ .snackbar-warning,
14147
+ .snackbar-error,
14148
+ .snackbar-primary,
14149
+ .snackbar-secondary,
14150
+ .snackbar-tertiary,
14151
+ .snackbar-accent,
14152
+ .snackbar-neutral,
14153
+ .snackbar-base
14154
+ ) :is(.snackbar-action, .snackbar-close):hover {
14155
+ background-color: color-mix(in oklch, currentColor 12%, transparent);
14156
+ }
14157
+
13749
14158
  /* Dark Snackbar (default MD3 style) */
13750
14159
  .snackbar-dark {
13751
14160
  background-color: var(--color-on-surface);
@@ -13828,17 +14237,36 @@
13828
14237
  pointer-events: none;
13829
14238
  }
13830
14239
 
14240
+ /* Native command targets use the container as a manual popover. Reset the
14241
+ user-agent popover box while preserving the existing positioning API. */
14242
+ :where(.toast-container[popover]) {
14243
+ inset: auto;
14244
+ width: auto;
14245
+ height: auto;
14246
+ margin: 0;
14247
+ overflow: visible;
14248
+ color: inherit;
14249
+ background: transparent;
14250
+ border: 0;
14251
+ }
14252
+
14253
+ .toast-container[popover]:not(:popover-open) {
14254
+ display: none;
14255
+ }
14256
+
13831
14257
  /* Position Variants */
13832
14258
  .toast-container-top-right {
13833
14259
  top: 0;
13834
14260
  right: 0;
13835
14261
  align-items: flex-end;
14262
+ padding-top: max(1rem, env(safe-area-inset-top));
13836
14263
  }
13837
14264
 
13838
14265
  .toast-container-top-left {
13839
14266
  top: 0;
13840
14267
  left: 0;
13841
14268
  align-items: flex-start;
14269
+ padding-top: max(1rem, env(safe-area-inset-top));
13842
14270
  }
13843
14271
 
13844
14272
  .toast-container-top-center {
@@ -13846,18 +14274,21 @@
13846
14274
  left: 50%;
13847
14275
  transform: translateX(-50%);
13848
14276
  align-items: center;
14277
+ padding-top: max(1rem, env(safe-area-inset-top));
13849
14278
  }
13850
14279
 
13851
14280
  .toast-container-bottom-right {
13852
14281
  bottom: 0;
13853
14282
  right: 0;
13854
14283
  align-items: flex-end;
14284
+ padding-bottom: max(1rem, env(safe-area-inset-bottom));
13855
14285
  }
13856
14286
 
13857
14287
  .toast-container-bottom-left {
13858
14288
  bottom: 0;
13859
14289
  left: 0;
13860
14290
  align-items: flex-start;
14291
+ padding-bottom: max(1rem, env(safe-area-inset-bottom));
13861
14292
  }
13862
14293
 
13863
14294
  .toast-container-bottom-center {
@@ -13865,10 +14296,20 @@
13865
14296
  left: 50%;
13866
14297
  transform: translateX(-50%);
13867
14298
  align-items: center;
14299
+ padding-bottom: max(1rem, env(safe-area-inset-bottom));
13868
14300
  }
13869
14301
 
14302
+ /* Logical aliases add RTL-aware placement without changing left/right. */
14303
+ .toast-container-top-start { top: 0; inset-inline-start: 0; align-items: flex-start; }
14304
+ .toast-container-top-end { top: 0; inset-inline-end: 0; align-items: flex-end; }
14305
+ .toast-container-bottom-start { bottom: 0; inset-inline-start: 0; align-items: flex-start; }
14306
+ .toast-container-bottom-end { bottom: 0; inset-inline-end: 0; align-items: flex-end; }
14307
+
13870
14308
  /* Base Toast */
13871
14309
  .toast {
14310
+ --_toast-accent-color: var(--color-primary);
14311
+
14312
+ position: relative;
13872
14313
  display: flex;
13873
14314
  align-items: flex-start;
13874
14315
  gap: 0.75rem;
@@ -13899,9 +14340,28 @@
13899
14340
  /* Toast Open State */
13900
14341
  .toast.toast-open,
13901
14342
  .toast.show,
13902
- .toast-show {
14343
+ .toast.toast-show {
13903
14344
  opacity: 1;
13904
14345
  transform: translateX(0) translateY(0);
14346
+ visibility: visible;
14347
+ pointer-events: auto;
14348
+ }
14349
+
14350
+ /* A closed item cannot intercept input. Consumers should also use hidden,
14351
+ inert, or unmounting when removing it from the accessibility tree. */
14352
+ .toast:not(.toast-open):not(.show):not(.toast-show),
14353
+ .toast[hidden],
14354
+ .toast[inert],
14355
+ .toast[aria-hidden="true"] {
14356
+ pointer-events: none;
14357
+ visibility: hidden;
14358
+ }
14359
+
14360
+ .toast-container[popover]:popover-open .toast {
14361
+ opacity: 1;
14362
+ transform: translateX(0) translateY(0);
14363
+ visibility: visible;
14364
+ pointer-events: auto;
13905
14365
  }
13906
14366
 
13907
14367
  /* Toast Icon */
@@ -13952,7 +14412,7 @@
13952
14412
  cursor: pointer;
13953
14413
  transition: background-color 150ms ease-in-out, color 150ms ease-in-out;
13954
14414
  flex-shrink: 0;
13955
- margin-left: auto;
14415
+ margin-inline-start: auto;
13956
14416
  }
13957
14417
 
13958
14418
  .toast-close:hover {
@@ -13970,10 +14430,46 @@
13970
14430
  display: flex;
13971
14431
  gap: 0.5rem;
13972
14432
  margin-top: 0.5rem;
14433
+ flex-wrap: wrap;
14434
+ }
14435
+
14436
+ .toast-action {
14437
+ display: inline-flex;
14438
+ align-items: center;
14439
+ justify-content: center;
14440
+ width: fit-content;
14441
+ min-height: 2rem;
14442
+ padding: 0.375rem 0.75rem;
14443
+ color: var(--color-primary);
14444
+ font-size: 0.875rem;
14445
+ font-weight: 500;
14446
+ background-color: transparent;
14447
+ border: 1px solid currentColor;
14448
+ border-radius: var(--radius-sm);
14449
+ cursor: pointer;
14450
+ }
14451
+
14452
+ .toast-action:hover {
14453
+ background-color: color-mix(in oklch, currentColor 10%, transparent);
14454
+ }
14455
+
14456
+ .toast-action:focus-visible {
14457
+ outline: none;
14458
+ box-shadow: 0 0 0 3px color-mix(in oklch, currentColor 20%, transparent);
13973
14459
  }
13974
14460
 
13975
14461
  /* Type Variants */
14462
+ .toast-accent {
14463
+ --_toast-accent-color: var(--color-accent);
14464
+ border-color: var(--color-accent);
14465
+ }
14466
+
14467
+ .toast-accent .toast-icon {
14468
+ color: var(--color-accent);
14469
+ }
14470
+
13976
14471
  .toast-info {
14472
+ --_toast-accent-color: var(--color-info);
13977
14473
  border-color: var(--color-info);
13978
14474
  }
13979
14475
 
@@ -13982,6 +14478,7 @@
13982
14478
  }
13983
14479
 
13984
14480
  .toast-success {
14481
+ --_toast-accent-color: var(--color-success);
13985
14482
  border-color: var(--color-success);
13986
14483
  }
13987
14484
 
@@ -13990,6 +14487,7 @@
13990
14487
  }
13991
14488
 
13992
14489
  .toast-warning {
14490
+ --_toast-accent-color: var(--color-warning);
13993
14491
  border-color: var(--color-warning);
13994
14492
  }
13995
14493
 
@@ -13998,6 +14496,7 @@
13998
14496
  }
13999
14497
 
14000
14498
  .toast-error {
14499
+ --_toast-accent-color: var(--color-error);
14001
14500
  border-color: var(--color-error);
14002
14501
  }
14003
14502
 
@@ -14006,6 +14505,7 @@
14006
14505
  }
14007
14506
 
14008
14507
  .toast-primary {
14508
+ --_toast-accent-color: var(--color-primary);
14009
14509
  border-color: var(--color-primary);
14010
14510
  }
14011
14511
 
@@ -14014,6 +14514,7 @@
14014
14514
  }
14015
14515
 
14016
14516
  .toast-secondary {
14517
+ --_toast-accent-color: var(--color-secondary);
14017
14518
  border-color: var(--color-secondary);
14018
14519
  }
14019
14520
 
@@ -14022,6 +14523,7 @@
14022
14523
  }
14023
14524
 
14024
14525
  .toast-tertiary {
14526
+ --_toast-accent-color: var(--color-tertiary);
14025
14527
  border-color: var(--color-tertiary);
14026
14528
  }
14027
14529
 
@@ -14029,15 +14531,8 @@
14029
14531
  color: var(--color-tertiary);
14030
14532
  }
14031
14533
 
14032
- .toast-accent {
14033
- border-color: var(--color-accent);
14034
- }
14035
-
14036
- .toast-accent .toast-icon {
14037
- color: var(--color-accent);
14038
- }
14039
-
14040
14534
  .toast-neutral {
14535
+ --_toast-accent-color: var(--color-neutral);
14041
14536
  border-color: var(--color-neutral);
14042
14537
  }
14043
14538
 
@@ -14046,6 +14541,7 @@
14046
14541
  }
14047
14542
 
14048
14543
  .toast-base {
14544
+ --_toast-accent-color: var(--color-base-content);
14049
14545
  border-color: var(--color-base-content);
14050
14546
  }
14051
14547
 
@@ -14054,58 +14550,58 @@
14054
14550
  }
14055
14551
 
14056
14552
  /* Filled Variants */
14553
+ .toast-filled.toast-accent {
14554
+ background-color: var(--color-accent);
14555
+ border-color: transparent;
14556
+ color: var(--color-accent-content);
14557
+ }
14558
+
14057
14559
  .toast-filled.toast-info {
14058
- background-color: var(--color-info-container);
14560
+ background-color: var(--color-info);
14059
14561
  border-color: transparent;
14060
- color: var(--color-on-info-container);
14562
+ color: var(--color-info-content);
14061
14563
  }
14062
14564
 
14063
14565
  .toast-filled.toast-success {
14064
- background-color: var(--color-success-container);
14566
+ background-color: var(--color-success);
14065
14567
  border-color: transparent;
14066
- color: var(--color-on-success-container);
14568
+ color: var(--color-success-content);
14067
14569
  }
14068
14570
 
14069
14571
  .toast-filled.toast-warning {
14070
- background-color: var(--color-warning-container);
14572
+ background-color: var(--color-warning);
14071
14573
  border-color: transparent;
14072
- color: var(--color-on-warning-container);
14574
+ color: var(--color-warning-content);
14073
14575
  }
14074
14576
 
14075
14577
  .toast-filled.toast-error {
14076
- background-color: var(--color-error-container);
14578
+ background-color: var(--color-error);
14077
14579
  border-color: transparent;
14078
- color: var(--color-on-error-container);
14580
+ color: var(--color-error-content);
14079
14581
  }
14080
14582
 
14081
14583
  .toast-filled.toast-primary {
14082
- background-color: var(--color-primary-container);
14584
+ background-color: var(--color-primary);
14083
14585
  border-color: transparent;
14084
- color: var(--color-on-primary-container);
14586
+ color: var(--color-primary-content);
14085
14587
  }
14086
14588
 
14087
14589
  .toast-filled.toast-secondary {
14088
- background-color: var(--color-secondary-container);
14590
+ background-color: var(--color-secondary);
14089
14591
  border-color: transparent;
14090
- color: var(--color-on-secondary-container);
14592
+ color: var(--color-secondary-content);
14091
14593
  }
14092
14594
 
14093
14595
  .toast-filled.toast-tertiary {
14094
- background-color: var(--color-tertiary-container);
14095
- border-color: transparent;
14096
- color: var(--color-on-tertiary-container);
14097
- }
14098
-
14099
- .toast-filled.toast-accent {
14100
- background-color: color-mix(in oklch, var(--color-accent) 15%, var(--color-surface));
14596
+ background-color: var(--color-tertiary);
14101
14597
  border-color: transparent;
14102
- color: var(--color-on-surface);
14598
+ color: var(--color-tertiary-content);
14103
14599
  }
14104
14600
 
14105
14601
  .toast-filled.toast-neutral {
14106
- background-color: color-mix(in oklch, var(--color-neutral) 15%, var(--color-surface));
14602
+ background-color: var(--color-neutral);
14107
14603
  border-color: transparent;
14108
- color: var(--color-on-surface);
14604
+ color: var(--color-neutral-content);
14109
14605
  }
14110
14606
 
14111
14607
  .toast-filled.toast-base {
@@ -14118,16 +14614,25 @@
14118
14614
  .toast-title and .toast-message have explicit color rules that would otherwise
14119
14615
  override the filled variant's inherited on-container color. */
14120
14616
  .toast-filled .toast-title,
14121
- .toast-filled .toast-message {
14617
+ .toast-filled .toast-message,
14618
+ .toast-filled .toast-icon,
14619
+ .toast-filled .toast-close,
14620
+ .toast-filled .toast-action {
14122
14621
  color: inherit;
14123
14622
  }
14124
14623
 
14624
+ .toast-filled .toast-close:hover {
14625
+ color: inherit;
14626
+ background-color: color-mix(in oklch, currentColor 12%, transparent);
14627
+ }
14628
+
14125
14629
  /* Ghost Variant */
14126
14630
  .toast-ghost {
14127
14631
  background-color: transparent;
14128
14632
  border-color: transparent;
14129
14633
  }
14130
14634
 
14635
+ .toast-ghost.toast-accent { color: var(--color-accent); }
14131
14636
  .toast-ghost.toast-primary { color: var(--color-primary); }
14132
14637
  .toast-ghost.toast-secondary { color: var(--color-secondary); }
14133
14638
  .toast-ghost.toast-tertiary { color: var(--color-tertiary); }
@@ -14135,7 +14640,6 @@
14135
14640
  .toast-ghost.toast-success { color: var(--color-success); }
14136
14641
  .toast-ghost.toast-warning { color: var(--color-warning); }
14137
14642
  .toast-ghost.toast-error { color: var(--color-error); }
14138
- .toast-ghost.toast-accent { color: var(--color-accent); }
14139
14643
  .toast-ghost.toast-neutral { color: var(--color-neutral); }
14140
14644
  .toast-ghost.toast-base { color: var(--color-base-content); }
14141
14645
 
@@ -14144,6 +14648,49 @@
14144
14648
  color: inherit;
14145
14649
  }
14146
14650
 
14651
+ /* Size and density variants retained by the public API. */
14652
+ .toast-sm {
14653
+ width: 18rem;
14654
+ padding: 0.75rem;
14655
+ }
14656
+
14657
+ .toast-lg {
14658
+ width: 26rem;
14659
+ padding: 1.25rem;
14660
+ }
14661
+
14662
+ .toast-compact {
14663
+ padding: 0.75rem;
14664
+ gap: 0.5rem;
14665
+ }
14666
+
14667
+ .toast-compact .toast-icon {
14668
+ width: 1.25rem;
14669
+ height: 1.25rem;
14670
+ font-size: 1rem;
14671
+ }
14672
+
14673
+ .toast-compact .toast-title { font-size: 0.8125rem; }
14674
+ .toast-compact .toast-message { font-size: 0.8125rem; }
14675
+
14676
+ /* Accent edge and stacked presentation. */
14677
+ .toast-accent::before {
14678
+ content: "";
14679
+ position: absolute;
14680
+ inset-block: 0;
14681
+ inset-inline-start: 0;
14682
+ width: 0.25rem;
14683
+ background-color: var(--_toast-accent-color);
14684
+ border-start-start-radius: var(--radius-md);
14685
+ border-end-start-radius: var(--radius-md);
14686
+ }
14687
+
14688
+ .toast-container-stacked .toast:not(:first-child) {
14689
+ margin-top: -0.75rem;
14690
+ transform: scale(0.97);
14691
+ opacity: 0.9;
14692
+ }
14693
+
14147
14694
  /* Progress Bar (for auto-dismiss) */
14148
14695
  .toast-progress {
14149
14696
  position: absolute;
@@ -14174,6 +14721,22 @@
14174
14721
  .toast-progress {
14175
14722
  animation: none;
14176
14723
  }
14724
+
14725
+ .toast-container { scroll-behavior: auto; }
14726
+ }
14727
+
14728
+ @media (max-width: 40rem) {
14729
+ .toast-container[popover] {
14730
+ inset-inline: 0;
14731
+ width: 100%;
14732
+ transform: none;
14733
+ align-items: stretch;
14734
+ }
14735
+
14736
+ .toast {
14737
+ width: 100%;
14738
+ max-width: 100%;
14739
+ }
14177
14740
  }
14178
14741
  }
14179
14742
 
@@ -14255,53 +14818,8 @@
14255
14818
  position-area: right;
14256
14819
  }
14257
14820
 
14258
- /* ========================================
14259
- * Arrow (preferred position only; may be wrong after flip)
14260
- * ======================================== */
14261
-
14262
- .tooltip[popover]::before {
14263
- content: '';
14264
- position: absolute;
14265
- width: 0;
14266
- height: 0;
14267
- border: 0.375rem solid transparent;
14268
- }
14269
-
14270
- .tooltip-top[popover]::before,
14271
- .tooltip[popover]:not(.tooltip-bottom):not(.tooltip-left):not(.tooltip-right)::before {
14272
- top: 100%;
14273
- left: 50%;
14274
- transform: translateX(-50%);
14275
- border-top-color: var(--tooltip-bg);
14276
- }
14277
-
14278
- .tooltip-bottom[popover]::before {
14279
- bottom: 100%;
14280
- top: auto;
14281
- left: 50%;
14282
- transform: translateX(-50%);
14283
- border-bottom-color: var(--tooltip-bg);
14284
- border-top-color: transparent;
14285
- }
14286
-
14287
- .tooltip-left[popover]::before {
14288
- left: 100%;
14289
- top: 50%;
14290
- bottom: auto;
14291
- transform: translateY(-50%);
14292
- border-left-color: var(--tooltip-bg);
14293
- border-top-color: transparent;
14294
- }
14295
-
14296
- .tooltip-right[popover]::before {
14297
- right: 100%;
14298
- left: auto;
14299
- top: 50%;
14300
- bottom: auto;
14301
- transform: translateY(-50%);
14302
- border-right-color: var(--tooltip-bg);
14303
- border-top-color: transparent;
14304
- }
14821
+ /* Automatic placement can flip independently of the preferred side. The
14822
+ core stays arrowless instead of showing a misleading arrow. */
14305
14823
 
14306
14824
  /* ========================================
14307
14825
  * Color variants