@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.
package/dist/index.css CHANGED
@@ -4720,7 +4720,8 @@ html {
4720
4720
  }
4721
4721
 
4722
4722
  /* Modal Action */
4723
- .modal-action {
4723
+ .modal-action,
4724
+ .modal-footer {
4724
4725
  display: flex;
4725
4726
  justify-content: flex-end;
4726
4727
  gap: 0.5rem;
@@ -4751,10 +4752,18 @@ html {
4751
4752
  max-width: 20rem;
4752
4753
  }
4753
4754
 
4755
+ .modal-md .modal-box {
4756
+ max-width: 32rem;
4757
+ }
4758
+
4754
4759
  .modal-lg .modal-box {
4755
4760
  max-width: 48rem;
4756
4761
  }
4757
4762
 
4763
+ .modal-xl .modal-box {
4764
+ max-width: 64rem;
4765
+ }
4766
+
4758
4767
  .modal-full .modal-box {
4759
4768
  max-width: calc(100vw - 2rem);
4760
4769
  max-height: calc(100vh - 2rem);
@@ -4777,6 +4786,38 @@ html {
4777
4786
  align-items: center;
4778
4787
  }
4779
4788
 
4789
+ /* Animation Variants */
4790
+ .modal-slide-up .modal-box {
4791
+ transform: translateY(6rem) scale(0.95);
4792
+ }
4793
+
4794
+ .modal-slide-down .modal-box {
4795
+ transform: translateY(-6rem) scale(0.95);
4796
+ }
4797
+
4798
+ .modal-zoom .modal-box {
4799
+ transform: scale(0.75);
4800
+ }
4801
+
4802
+ :is(.modal-slide-up, .modal-slide-down, .modal-zoom).modal-open .modal-box,
4803
+ :is(.modal-slide-up, .modal-slide-down, .modal-zoom):target .modal-box {
4804
+ transform: translateY(0) scale(1);
4805
+ }
4806
+
4807
+ /* Backdrop Variants */
4808
+ .modal-backdrop-light {
4809
+ background-color: color-mix(in srgb, white 80%, transparent);
4810
+ }
4811
+
4812
+ .modal-backdrop-blur {
4813
+ background-color: color-mix(in srgb, var(--color-scrim) 30%, transparent);
4814
+ backdrop-filter: blur(8px);
4815
+ }
4816
+
4817
+ .modal-no-backdrop {
4818
+ background-color: transparent;
4819
+ }
4820
+
4780
4821
  /* Modal Close Button */
4781
4822
  .modal-close {
4782
4823
  position: absolute;
@@ -4825,6 +4866,22 @@ html {
4825
4866
  line-height: 1.5;
4826
4867
  }
4827
4868
 
4869
+ .modal-scrollable .modal-body {
4870
+ max-height: 60vh;
4871
+ overflow-y: auto;
4872
+ }
4873
+
4874
+ .modal-no-padding .modal-body {
4875
+ padding: 0;
4876
+ }
4877
+
4878
+ .modal-centered .modal-body {
4879
+ display: flex;
4880
+ align-items: center;
4881
+ justify-content: center;
4882
+ text-align: center;
4883
+ }
4884
+
4828
4885
  /* Responsive Modal */
4829
4886
  @media (max-width: 640px) {
4830
4887
  .modal-box {
@@ -4946,6 +5003,10 @@ html {
4946
5003
  white-space: nowrap;
4947
5004
  border: 0;
4948
5005
  }
5006
+
5007
+ body.modal-open {
5008
+ overflow: hidden;
5009
+ }
4949
5010
  }
4950
5011
 
4951
5012
 
@@ -13503,8 +13564,11 @@ html {
13503
13564
  @layer components {
13504
13565
  /* Base Alert */
13505
13566
  .alert {
13506
- display: flex;
13507
- align-items: flex-start;
13567
+ display: grid;
13568
+ grid-template-columns: auto minmax(0, 1fr) auto auto;
13569
+ grid-template-areas:
13570
+ "icon content actions close";
13571
+ align-items: center;
13508
13572
  gap: 0.75rem;
13509
13573
  padding: 1rem;
13510
13574
  border-radius: var(--radius-sm);
@@ -13515,6 +13579,7 @@ html {
13515
13579
 
13516
13580
  /* Alert Icon */
13517
13581
  .alert-icon {
13582
+ grid-area: icon;
13518
13583
  display: flex;
13519
13584
  align-items: center;
13520
13585
  justify-content: center;
@@ -13522,10 +13587,12 @@ html {
13522
13587
  height: 1.5rem;
13523
13588
  font-size: 1.25rem;
13524
13589
  flex-shrink: 0;
13590
+ align-self: start;
13525
13591
  }
13526
13592
 
13527
13593
  /* Alert Content */
13528
13594
  .alert-content {
13595
+ grid-area: content;
13529
13596
  display: flex;
13530
13597
  flex-direction: column;
13531
13598
  gap: 0.25rem;
@@ -13533,13 +13600,42 @@ html {
13533
13600
  min-width: 0;
13534
13601
  }
13535
13602
 
13603
+ .alert-content > p {
13604
+ margin: 0;
13605
+ }
13606
+
13607
+ /* Keep the compact single-message form vertically balanced against global typography margins. */
13608
+ .alert > p {
13609
+ margin: 0;
13610
+ }
13611
+
13612
+ .alert-horizontal { display: grid; }
13613
+ .alert-actions-end { grid-template-areas: "icon content actions close"; }
13614
+ .alert-actions-bottom {
13615
+ grid-template-columns: auto minmax(0, 1fr) auto;
13616
+ grid-template-areas:
13617
+ "icon content close"
13618
+ ". actions .";
13619
+ }
13620
+
13621
+ .alert-actions-bottom .alert-actions {
13622
+ justify-self: start;
13623
+ margin-top: 0.5rem;
13624
+ }
13625
+ .alert-vertical {
13626
+ display: flex;
13627
+ flex-direction: column;
13628
+ }
13629
+
13536
13630
  .alert-title {
13631
+ margin: 0;
13537
13632
  font-size: 0.875rem;
13538
13633
  font-weight: 600;
13539
13634
  line-height: 1.25rem;
13540
13635
  }
13541
13636
 
13542
13637
  .alert-description {
13638
+ margin: 0;
13543
13639
  font-size: 0.875rem;
13544
13640
  line-height: 1.25rem;
13545
13641
  opacity: 0.9;
@@ -13547,6 +13643,7 @@ html {
13547
13643
 
13548
13644
  /* Alert Close Button */
13549
13645
  .alert-close {
13646
+ grid-area: close;
13550
13647
  display: flex;
13551
13648
  align-items: center;
13552
13649
  justify-content: center;
@@ -13760,6 +13857,7 @@ html {
13760
13857
  /* Dismissible */
13761
13858
  .alert-dismissible {
13762
13859
  padding-right: 2.5rem;
13860
+ padding-inline-end: 2.5rem;
13763
13861
  position: relative;
13764
13862
  }
13765
13863
 
@@ -13767,6 +13865,7 @@ html {
13767
13865
  position: absolute;
13768
13866
  top: 0.75rem;
13769
13867
  right: 0.75rem;
13868
+ inset-inline-end: 0.75rem;
13770
13869
  }
13771
13870
 
13772
13871
  /* Compact */
@@ -13786,11 +13885,25 @@ html {
13786
13885
  font-size: 0.8125rem;
13787
13886
  }
13788
13887
 
13888
+ .alert-comfortable {
13889
+ padding: 1.25rem;
13890
+ gap: 1rem;
13891
+ }
13892
+
13789
13893
  /* Alert Actions */
13790
13894
  .alert-actions {
13895
+ grid-area: actions;
13791
13896
  display: flex;
13792
13897
  gap: 0.5rem;
13793
- margin-top: 0.5rem;
13898
+ margin-top: 0;
13899
+ flex-wrap: wrap;
13900
+ align-self: center;
13901
+ justify-self: end;
13902
+ }
13903
+
13904
+ .alert-vertical .alert-actions {
13905
+ align-self: stretch;
13906
+ width: 100%;
13794
13907
  }
13795
13908
 
13796
13909
  .alert-filled .alert-actions .btn-text {
@@ -13814,6 +13927,32 @@ html {
13814
13927
  transition: none;
13815
13928
  }
13816
13929
  }
13930
+
13931
+ @media (max-width: 32rem) {
13932
+ .alert:not(.alert-vertical) .alert-content,
13933
+ .alert-horizontal .alert-content {
13934
+ flex-basis: min(100%, 18rem);
13935
+ }
13936
+ .alert:not(.alert-vertical),
13937
+ .alert-horizontal {
13938
+ grid-template-columns: auto minmax(0, 1fr) auto;
13939
+ grid-template-areas:
13940
+ "icon content close"
13941
+ ". actions actions";
13942
+ }
13943
+ .alert:not(.alert-vertical).alert-actions-end,
13944
+ .alert-horizontal.alert-actions-end {
13945
+ grid-template-columns: auto minmax(0, 1fr) auto;
13946
+ grid-template-areas:
13947
+ "icon content close"
13948
+ ". actions actions";
13949
+ }
13950
+ .alert:not(.alert-vertical) .alert-actions,
13951
+ .alert-horizontal .alert-actions {
13952
+ justify-self: start;
13953
+ margin-top: 0.5rem;
13954
+ }
13955
+ }
13817
13956
  }
13818
13957
 
13819
13958
  /**
@@ -13990,6 +14129,112 @@ html {
13990
14129
  }
13991
14130
  }
13992
14131
 
14132
+ /**
14133
+ * Loading Component Styles
14134
+ * CSS-only activity indicators. State, aria-busy, and disabling remain consumer-owned.
14135
+ */
14136
+
14137
+ @layer components {
14138
+ .loading {
14139
+ --loading-size: 1.25rem;
14140
+ display: inline-flex;
14141
+ width: var(--loading-size);
14142
+ height: var(--loading-size);
14143
+ flex: 0 0 var(--loading-size);
14144
+ color: currentColor;
14145
+ vertical-align: middle;
14146
+ }
14147
+
14148
+ .loading-spinner {
14149
+ border: max(2px, calc(var(--loading-size) / 8)) solid color-mix(in oklch, currentColor 25%, transparent);
14150
+ border-top-color: currentColor;
14151
+ border-radius: var(--radius-full);
14152
+ animation: loading-spin 800ms linear infinite;
14153
+ }
14154
+
14155
+ .loading-dots,
14156
+ .loading-bars {
14157
+ align-items: center;
14158
+ justify-content: center;
14159
+ gap: max(2px, calc(var(--loading-size) / 8));
14160
+ }
14161
+
14162
+ .loading-dots::before,
14163
+ .loading-dots::after,
14164
+ .loading-bars::before,
14165
+ .loading-bars::after {
14166
+ content: "";
14167
+ display: block;
14168
+ background: currentColor;
14169
+ }
14170
+
14171
+ .loading-dots::before,
14172
+ .loading-dots::after {
14173
+ width: 25%;
14174
+ height: 25%;
14175
+ border-radius: var(--radius-full);
14176
+ box-shadow: calc(var(--loading-size) / 3) 0 currentColor;
14177
+ animation: loading-dots 900ms ease-in-out infinite;
14178
+ }
14179
+
14180
+ .loading-dots::after {
14181
+ display: none;
14182
+ }
14183
+
14184
+ .loading-bars {
14185
+ padding-inline: 10%;
14186
+ }
14187
+
14188
+ .loading-bars::before,
14189
+ .loading-bars::after {
14190
+ width: 18%;
14191
+ height: 65%;
14192
+ border-radius: var(--radius-xs);
14193
+ box-shadow: calc(var(--loading-size) / 3) 0 currentColor, calc(var(--loading-size) * 2 / 3) 0 currentColor;
14194
+ animation: loading-bars 900ms ease-in-out infinite;
14195
+ }
14196
+
14197
+ .loading-bars::after {
14198
+ display: none;
14199
+ }
14200
+
14201
+ .loading-xs { --loading-size: 0.75rem; }
14202
+ .loading-sm { --loading-size: 1rem; }
14203
+ .loading-md { --loading-size: 1.25rem; }
14204
+ .loading-lg { --loading-size: 1.75rem; }
14205
+ .loading-xl { --loading-size: 2.5rem; }
14206
+
14207
+ .loading-primary { color: var(--color-primary); }
14208
+ .loading-secondary { color: var(--color-secondary); }
14209
+ .loading-tertiary { color: var(--color-tertiary); }
14210
+ .loading-info { color: var(--color-info); }
14211
+ .loading-success { color: var(--color-success); }
14212
+ .loading-warning { color: var(--color-warning); }
14213
+ .loading-error { color: var(--color-error); }
14214
+
14215
+ @keyframes loading-spin {
14216
+ to { transform: rotate(360deg); }
14217
+ }
14218
+
14219
+ @keyframes loading-dots {
14220
+ 0%, 100% { opacity: 0.35; transform: scale(0.75); }
14221
+ 50% { opacity: 1; transform: scale(1); }
14222
+ }
14223
+
14224
+ @keyframes loading-bars {
14225
+ 0%, 100% { opacity: 0.35; transform: scaleY(0.65); }
14226
+ 50% { opacity: 1; transform: scaleY(1); }
14227
+ }
14228
+
14229
+ @media (prefers-reduced-motion: reduce) {
14230
+ .loading-spinner,
14231
+ .loading-dots::before,
14232
+ .loading-bars::before {
14233
+ animation: none;
14234
+ }
14235
+ }
14236
+ }
14237
+
13993
14238
  /**
13994
14239
  * Progress Component Styles
13995
14240
  * DuskMoonUI - Material Design 3 inspired progress system
@@ -14006,6 +14251,36 @@ html {
14006
14251
  overflow: hidden;
14007
14252
  }
14008
14253
 
14254
+ /* Native progress keeps the platform's accessible value/max contract. */
14255
+ progress.progress {
14256
+ appearance: none;
14257
+ border: 0;
14258
+ display: block;
14259
+ }
14260
+
14261
+ progress.progress::-webkit-progress-bar {
14262
+ background: var(--color-surface-container-highest);
14263
+ border-radius: var(--radius-full);
14264
+ }
14265
+
14266
+ progress.progress::-webkit-progress-value {
14267
+ background: var(--color-primary);
14268
+ border-radius: var(--radius-full);
14269
+ transition: width 300ms ease-in-out;
14270
+ }
14271
+
14272
+ progress.progress::-moz-progress-bar {
14273
+ background: var(--color-primary);
14274
+ border-radius: var(--radius-full);
14275
+ transition: width 300ms ease-in-out;
14276
+ }
14277
+
14278
+ progress.progress:indeterminate::-webkit-progress-value,
14279
+ progress.progress:indeterminate::-moz-progress-bar {
14280
+ width: 30%;
14281
+ animation: progress-indeterminate 1.5s infinite ease-in-out;
14282
+ }
14283
+
14009
14284
  /* Progress Bar */
14010
14285
  .progress-bar {
14011
14286
  position: absolute;
@@ -14058,6 +14333,21 @@ html {
14058
14333
  background-color: var(--color-base-content);
14059
14334
  }
14060
14335
 
14336
+ progress.progress-primary::-webkit-progress-value,
14337
+ progress.progress-primary::-moz-progress-bar { background: var(--color-primary); }
14338
+ progress.progress-secondary::-webkit-progress-value,
14339
+ progress.progress-secondary::-moz-progress-bar { background: var(--color-secondary); }
14340
+ progress.progress-tertiary::-webkit-progress-value,
14341
+ progress.progress-tertiary::-moz-progress-bar { background: var(--color-tertiary); }
14342
+ progress.progress-info::-webkit-progress-value,
14343
+ progress.progress-info::-moz-progress-bar { background: var(--color-info); }
14344
+ progress.progress-success::-webkit-progress-value,
14345
+ progress.progress-success::-moz-progress-bar { background: var(--color-success); }
14346
+ progress.progress-warning::-webkit-progress-value,
14347
+ progress.progress-warning::-moz-progress-bar { background: var(--color-warning); }
14348
+ progress.progress-error::-webkit-progress-value,
14349
+ progress.progress-error::-moz-progress-bar { background: var(--color-error); }
14350
+
14061
14351
  /* Size Variants */
14062
14352
  .progress-xs {
14063
14353
  height: 0.25rem;
@@ -14133,6 +14423,25 @@ html {
14133
14423
  }
14134
14424
  }
14135
14425
 
14426
+ /* Buffer tracks belong to custom markup, not native <progress>. */
14427
+ .progress-buffer {
14428
+ position: relative;
14429
+ }
14430
+
14431
+ .progress-buffer-bar {
14432
+ position: absolute;
14433
+ inset-block: 0;
14434
+ inset-inline-start: 0;
14435
+ width: 0;
14436
+ background: color-mix(in oklch, var(--color-primary) 30%, transparent);
14437
+ border-radius: var(--radius-full);
14438
+ transition: width 300ms ease-in-out;
14439
+ }
14440
+
14441
+ .progress-buffer .progress-bar {
14442
+ z-index: 1;
14443
+ }
14444
+
14136
14445
  /* Circular Progress */
14137
14446
  .progress-circular {
14138
14447
  position: relative;
@@ -14232,7 +14541,17 @@ html {
14232
14541
 
14233
14542
  /* Reduce Motion */
14234
14543
  @media (prefers-reduced-motion: reduce) {
14544
+ .progress-bar,
14545
+ progress.progress::-webkit-progress-value,
14546
+ progress.progress::-moz-progress-bar,
14547
+ .progress-circular-bar,
14548
+ .progress-buffer-bar {
14549
+ transition: none;
14550
+ }
14551
+
14235
14552
  .progress-indeterminate .progress-bar,
14553
+ progress.progress:indeterminate::-webkit-progress-value,
14554
+ progress.progress:indeterminate::-moz-progress-bar,
14236
14555
  .progress-striped.progress-animated .progress-bar,
14237
14556
  .progress-circular-indeterminate svg,
14238
14557
  .progress-circular-indeterminate .progress-circular-bar {
@@ -14241,6 +14560,54 @@ html {
14241
14560
  }
14242
14561
  }
14243
14562
 
14563
+ /**
14564
+ * Radial Progress Component Styles
14565
+ * Determinate percentage progress without circumference arithmetic.
14566
+ */
14567
+
14568
+ @layer components {
14569
+ .radial-progress {
14570
+ --radial-progress-value: 0;
14571
+ --radial-progress-size: 3rem;
14572
+ --radial-progress-thickness: 0.375rem;
14573
+ --radial-progress-track: var(--color-surface-container-highest);
14574
+ position: relative;
14575
+ display: inline-grid;
14576
+ width: var(--radial-progress-size);
14577
+ height: var(--radial-progress-size);
14578
+ place-items: center;
14579
+ color: var(--color-primary);
14580
+ border-radius: var(--radius-full);
14581
+ background: conic-gradient(currentColor calc(clamp(0, var(--radial-progress-value), 100) * 1%), var(--radial-progress-track) 0);
14582
+ isolation: isolate;
14583
+ }
14584
+
14585
+ .radial-progress::before {
14586
+ content: "";
14587
+ position: absolute;
14588
+ inset: var(--radial-progress-thickness);
14589
+ z-index: 0;
14590
+ border-radius: inherit;
14591
+ background: var(--color-surface);
14592
+ }
14593
+
14594
+ .radial-progress-primary { color: var(--color-primary); }
14595
+ .radial-progress-secondary { color: var(--color-secondary); }
14596
+ .radial-progress-tertiary { color: var(--color-tertiary); }
14597
+ .radial-progress-info { color: var(--color-info); }
14598
+ .radial-progress-success { color: var(--color-success); }
14599
+ .radial-progress-warning { color: var(--color-warning); }
14600
+ .radial-progress-error { color: var(--color-error); }
14601
+
14602
+ .radial-progress-sm { --radial-progress-size: 2rem; --radial-progress-thickness: 0.25rem; }
14603
+ .radial-progress-lg { --radial-progress-size: 4rem; --radial-progress-thickness: 0.5rem; }
14604
+ .radial-progress-xl { --radial-progress-size: 6rem; --radial-progress-thickness: 0.625rem; }
14605
+
14606
+ @media (prefers-reduced-motion: reduce) {
14607
+ .radial-progress { transition: none; }
14608
+ }
14609
+ }
14610
+
14244
14611
  /**
14245
14612
  * Skeleton Component Styles
14246
14613
  * DuskMoonUI - Material Design 3 inspired skeleton loading system
@@ -14274,6 +14641,10 @@ html {
14274
14641
  border-radius: var(--radius-sm);
14275
14642
  }
14276
14643
 
14644
+ .skeleton-static {
14645
+ animation: none;
14646
+ }
14647
+
14277
14648
  /* Size Variants */
14278
14649
  .skeleton-xs {
14279
14650
  height: 0.5rem;
@@ -14376,7 +14747,7 @@ html {
14376
14747
  background: linear-gradient(
14377
14748
  90deg,
14378
14749
  transparent,
14379
- rgba(255, 255, 255, 0.3),
14750
+ color-mix(in oklch, var(--color-surface-bright) 35%, transparent),
14380
14751
  transparent
14381
14752
  );
14382
14753
  animation: skeleton-wave 1.5s infinite;
@@ -14454,6 +14825,14 @@ html {
14454
14825
 
14455
14826
  .skeleton-wave::after {
14456
14827
  animation: none;
14828
+ transform: translateX(0);
14829
+ opacity: 0.35;
14830
+ }
14831
+
14832
+ .skeleton-static::after {
14833
+ animation: none;
14834
+ transform: translateX(0);
14835
+ opacity: 0.35;
14457
14836
  }
14458
14837
  }
14459
14838
  }
@@ -14670,49 +15049,49 @@ html {
14670
15049
 
14671
15050
  /* Color Variants */
14672
15051
  .snackbar-info {
14673
- background-color: var(--color-info-container);
14674
- color: var(--color-on-info-container);
15052
+ background-color: var(--color-info);
15053
+ color: var(--color-info-content);
14675
15054
  }
14676
15055
 
14677
15056
  .snackbar-success {
14678
- background-color: var(--color-success-container);
14679
- color: var(--color-on-success-container);
15057
+ background-color: var(--color-success);
15058
+ color: var(--color-success-content);
14680
15059
  }
14681
15060
 
14682
15061
  .snackbar-warning {
14683
- background-color: var(--color-warning-container);
14684
- color: var(--color-on-warning-container);
15062
+ background-color: var(--color-warning);
15063
+ color: var(--color-warning-content);
14685
15064
  }
14686
15065
 
14687
15066
  .snackbar-error {
14688
- background-color: var(--color-error-container);
14689
- color: var(--color-on-error-container);
15067
+ background-color: var(--color-error);
15068
+ color: var(--color-error-content);
14690
15069
  }
14691
15070
 
14692
15071
  /* Brand Color Variants */
14693
15072
  .snackbar-primary {
14694
- background-color: var(--color-primary-container);
14695
- color: var(--color-on-primary-container);
15073
+ background-color: var(--color-primary);
15074
+ color: var(--color-primary-content);
14696
15075
  }
14697
15076
 
14698
15077
  .snackbar-secondary {
14699
- background-color: var(--color-secondary-container);
14700
- color: var(--color-on-secondary-container);
15078
+ background-color: var(--color-secondary);
15079
+ color: var(--color-secondary-content);
14701
15080
  }
14702
15081
 
14703
15082
  .snackbar-tertiary {
14704
- background-color: var(--color-tertiary-container);
14705
- color: var(--color-on-tertiary-container);
15083
+ background-color: var(--color-tertiary);
15084
+ color: var(--color-tertiary-content);
14706
15085
  }
14707
15086
 
14708
15087
  .snackbar-accent {
14709
- background-color: color-mix(in oklch, var(--color-accent) 15%, var(--color-surface));
14710
- color: var(--color-on-surface);
15088
+ background-color: var(--color-accent);
15089
+ color: var(--color-accent-content);
14711
15090
  }
14712
15091
 
14713
15092
  .snackbar-neutral {
14714
- background-color: color-mix(in oklch, var(--color-neutral) 15%, var(--color-surface));
14715
- color: var(--color-on-surface);
15093
+ background-color: var(--color-neutral);
15094
+ color: var(--color-neutral-content);
14716
15095
  }
14717
15096
 
14718
15097
  .snackbar-base {
@@ -14720,6 +15099,36 @@ html {
14720
15099
  color: var(--color-base-content);
14721
15100
  }
14722
15101
 
15102
+ :is(
15103
+ .snackbar-info,
15104
+ .snackbar-success,
15105
+ .snackbar-warning,
15106
+ .snackbar-error,
15107
+ .snackbar-primary,
15108
+ .snackbar-secondary,
15109
+ .snackbar-tertiary,
15110
+ .snackbar-accent,
15111
+ .snackbar-neutral,
15112
+ .snackbar-base
15113
+ ) :is(.snackbar-action, .snackbar-close) {
15114
+ color: inherit;
15115
+ }
15116
+
15117
+ :is(
15118
+ .snackbar-info,
15119
+ .snackbar-success,
15120
+ .snackbar-warning,
15121
+ .snackbar-error,
15122
+ .snackbar-primary,
15123
+ .snackbar-secondary,
15124
+ .snackbar-tertiary,
15125
+ .snackbar-accent,
15126
+ .snackbar-neutral,
15127
+ .snackbar-base
15128
+ ) :is(.snackbar-action, .snackbar-close):hover {
15129
+ background-color: color-mix(in oklch, currentColor 12%, transparent);
15130
+ }
15131
+
14723
15132
  /* Dark Snackbar (default MD3 style) */
14724
15133
  .snackbar-dark {
14725
15134
  background-color: var(--color-on-surface);
@@ -14802,17 +15211,36 @@ html {
14802
15211
  pointer-events: none;
14803
15212
  }
14804
15213
 
15214
+ /* Native command targets use the container as a manual popover. Reset the
15215
+ user-agent popover box while preserving the existing positioning API. */
15216
+ :where(.toast-container[popover]) {
15217
+ inset: auto;
15218
+ width: auto;
15219
+ height: auto;
15220
+ margin: 0;
15221
+ overflow: visible;
15222
+ color: inherit;
15223
+ background: transparent;
15224
+ border: 0;
15225
+ }
15226
+
15227
+ .toast-container[popover]:not(:popover-open) {
15228
+ display: none;
15229
+ }
15230
+
14805
15231
  /* Position Variants */
14806
15232
  .toast-container-top-right {
14807
15233
  top: 0;
14808
15234
  right: 0;
14809
15235
  align-items: flex-end;
15236
+ padding-top: max(1rem, env(safe-area-inset-top));
14810
15237
  }
14811
15238
 
14812
15239
  .toast-container-top-left {
14813
15240
  top: 0;
14814
15241
  left: 0;
14815
15242
  align-items: flex-start;
15243
+ padding-top: max(1rem, env(safe-area-inset-top));
14816
15244
  }
14817
15245
 
14818
15246
  .toast-container-top-center {
@@ -14820,18 +15248,21 @@ html {
14820
15248
  left: 50%;
14821
15249
  transform: translateX(-50%);
14822
15250
  align-items: center;
15251
+ padding-top: max(1rem, env(safe-area-inset-top));
14823
15252
  }
14824
15253
 
14825
15254
  .toast-container-bottom-right {
14826
15255
  bottom: 0;
14827
15256
  right: 0;
14828
15257
  align-items: flex-end;
15258
+ padding-bottom: max(1rem, env(safe-area-inset-bottom));
14829
15259
  }
14830
15260
 
14831
15261
  .toast-container-bottom-left {
14832
15262
  bottom: 0;
14833
15263
  left: 0;
14834
15264
  align-items: flex-start;
15265
+ padding-bottom: max(1rem, env(safe-area-inset-bottom));
14835
15266
  }
14836
15267
 
14837
15268
  .toast-container-bottom-center {
@@ -14839,10 +15270,20 @@ html {
14839
15270
  left: 50%;
14840
15271
  transform: translateX(-50%);
14841
15272
  align-items: center;
15273
+ padding-bottom: max(1rem, env(safe-area-inset-bottom));
14842
15274
  }
14843
15275
 
15276
+ /* Logical aliases add RTL-aware placement without changing left/right. */
15277
+ .toast-container-top-start { top: 0; inset-inline-start: 0; align-items: flex-start; }
15278
+ .toast-container-top-end { top: 0; inset-inline-end: 0; align-items: flex-end; }
15279
+ .toast-container-bottom-start { bottom: 0; inset-inline-start: 0; align-items: flex-start; }
15280
+ .toast-container-bottom-end { bottom: 0; inset-inline-end: 0; align-items: flex-end; }
15281
+
14844
15282
  /* Base Toast */
14845
15283
  .toast {
15284
+ --_toast-accent-color: var(--color-primary);
15285
+
15286
+ position: relative;
14846
15287
  display: flex;
14847
15288
  align-items: flex-start;
14848
15289
  gap: 0.75rem;
@@ -14873,9 +15314,28 @@ html {
14873
15314
  /* Toast Open State */
14874
15315
  .toast.toast-open,
14875
15316
  .toast.show,
14876
- .toast-show {
15317
+ .toast.toast-show {
14877
15318
  opacity: 1;
14878
15319
  transform: translateX(0) translateY(0);
15320
+ visibility: visible;
15321
+ pointer-events: auto;
15322
+ }
15323
+
15324
+ /* A closed item cannot intercept input. Consumers should also use hidden,
15325
+ inert, or unmounting when removing it from the accessibility tree. */
15326
+ .toast:not(.toast-open):not(.show):not(.toast-show),
15327
+ .toast[hidden],
15328
+ .toast[inert],
15329
+ .toast[aria-hidden="true"] {
15330
+ pointer-events: none;
15331
+ visibility: hidden;
15332
+ }
15333
+
15334
+ .toast-container[popover]:popover-open .toast {
15335
+ opacity: 1;
15336
+ transform: translateX(0) translateY(0);
15337
+ visibility: visible;
15338
+ pointer-events: auto;
14879
15339
  }
14880
15340
 
14881
15341
  /* Toast Icon */
@@ -14926,7 +15386,7 @@ html {
14926
15386
  cursor: pointer;
14927
15387
  transition: background-color 150ms ease-in-out, color 150ms ease-in-out;
14928
15388
  flex-shrink: 0;
14929
- margin-left: auto;
15389
+ margin-inline-start: auto;
14930
15390
  }
14931
15391
 
14932
15392
  .toast-close:hover {
@@ -14944,10 +15404,46 @@ html {
14944
15404
  display: flex;
14945
15405
  gap: 0.5rem;
14946
15406
  margin-top: 0.5rem;
15407
+ flex-wrap: wrap;
15408
+ }
15409
+
15410
+ .toast-action {
15411
+ display: inline-flex;
15412
+ align-items: center;
15413
+ justify-content: center;
15414
+ width: fit-content;
15415
+ min-height: 2rem;
15416
+ padding: 0.375rem 0.75rem;
15417
+ color: var(--color-primary);
15418
+ font-size: 0.875rem;
15419
+ font-weight: 500;
15420
+ background-color: transparent;
15421
+ border: 1px solid currentColor;
15422
+ border-radius: var(--radius-sm);
15423
+ cursor: pointer;
15424
+ }
15425
+
15426
+ .toast-action:hover {
15427
+ background-color: color-mix(in oklch, currentColor 10%, transparent);
15428
+ }
15429
+
15430
+ .toast-action:focus-visible {
15431
+ outline: none;
15432
+ box-shadow: 0 0 0 3px color-mix(in oklch, currentColor 20%, transparent);
14947
15433
  }
14948
15434
 
14949
15435
  /* Type Variants */
15436
+ .toast-accent {
15437
+ --_toast-accent-color: var(--color-accent);
15438
+ border-color: var(--color-accent);
15439
+ }
15440
+
15441
+ .toast-accent .toast-icon {
15442
+ color: var(--color-accent);
15443
+ }
15444
+
14950
15445
  .toast-info {
15446
+ --_toast-accent-color: var(--color-info);
14951
15447
  border-color: var(--color-info);
14952
15448
  }
14953
15449
 
@@ -14956,6 +15452,7 @@ html {
14956
15452
  }
14957
15453
 
14958
15454
  .toast-success {
15455
+ --_toast-accent-color: var(--color-success);
14959
15456
  border-color: var(--color-success);
14960
15457
  }
14961
15458
 
@@ -14964,6 +15461,7 @@ html {
14964
15461
  }
14965
15462
 
14966
15463
  .toast-warning {
15464
+ --_toast-accent-color: var(--color-warning);
14967
15465
  border-color: var(--color-warning);
14968
15466
  }
14969
15467
 
@@ -14972,6 +15470,7 @@ html {
14972
15470
  }
14973
15471
 
14974
15472
  .toast-error {
15473
+ --_toast-accent-color: var(--color-error);
14975
15474
  border-color: var(--color-error);
14976
15475
  }
14977
15476
 
@@ -14980,6 +15479,7 @@ html {
14980
15479
  }
14981
15480
 
14982
15481
  .toast-primary {
15482
+ --_toast-accent-color: var(--color-primary);
14983
15483
  border-color: var(--color-primary);
14984
15484
  }
14985
15485
 
@@ -14988,6 +15488,7 @@ html {
14988
15488
  }
14989
15489
 
14990
15490
  .toast-secondary {
15491
+ --_toast-accent-color: var(--color-secondary);
14991
15492
  border-color: var(--color-secondary);
14992
15493
  }
14993
15494
 
@@ -14996,6 +15497,7 @@ html {
14996
15497
  }
14997
15498
 
14998
15499
  .toast-tertiary {
15500
+ --_toast-accent-color: var(--color-tertiary);
14999
15501
  border-color: var(--color-tertiary);
15000
15502
  }
15001
15503
 
@@ -15003,15 +15505,8 @@ html {
15003
15505
  color: var(--color-tertiary);
15004
15506
  }
15005
15507
 
15006
- .toast-accent {
15007
- border-color: var(--color-accent);
15008
- }
15009
-
15010
- .toast-accent .toast-icon {
15011
- color: var(--color-accent);
15012
- }
15013
-
15014
15508
  .toast-neutral {
15509
+ --_toast-accent-color: var(--color-neutral);
15015
15510
  border-color: var(--color-neutral);
15016
15511
  }
15017
15512
 
@@ -15020,6 +15515,7 @@ html {
15020
15515
  }
15021
15516
 
15022
15517
  .toast-base {
15518
+ --_toast-accent-color: var(--color-base-content);
15023
15519
  border-color: var(--color-base-content);
15024
15520
  }
15025
15521
 
@@ -15028,58 +15524,58 @@ html {
15028
15524
  }
15029
15525
 
15030
15526
  /* Filled Variants */
15527
+ .toast-filled.toast-accent {
15528
+ background-color: var(--color-accent);
15529
+ border-color: transparent;
15530
+ color: var(--color-accent-content);
15531
+ }
15532
+
15031
15533
  .toast-filled.toast-info {
15032
- background-color: var(--color-info-container);
15534
+ background-color: var(--color-info);
15033
15535
  border-color: transparent;
15034
- color: var(--color-on-info-container);
15536
+ color: var(--color-info-content);
15035
15537
  }
15036
15538
 
15037
15539
  .toast-filled.toast-success {
15038
- background-color: var(--color-success-container);
15540
+ background-color: var(--color-success);
15039
15541
  border-color: transparent;
15040
- color: var(--color-on-success-container);
15542
+ color: var(--color-success-content);
15041
15543
  }
15042
15544
 
15043
15545
  .toast-filled.toast-warning {
15044
- background-color: var(--color-warning-container);
15546
+ background-color: var(--color-warning);
15045
15547
  border-color: transparent;
15046
- color: var(--color-on-warning-container);
15548
+ color: var(--color-warning-content);
15047
15549
  }
15048
15550
 
15049
15551
  .toast-filled.toast-error {
15050
- background-color: var(--color-error-container);
15552
+ background-color: var(--color-error);
15051
15553
  border-color: transparent;
15052
- color: var(--color-on-error-container);
15554
+ color: var(--color-error-content);
15053
15555
  }
15054
15556
 
15055
15557
  .toast-filled.toast-primary {
15056
- background-color: var(--color-primary-container);
15558
+ background-color: var(--color-primary);
15057
15559
  border-color: transparent;
15058
- color: var(--color-on-primary-container);
15560
+ color: var(--color-primary-content);
15059
15561
  }
15060
15562
 
15061
15563
  .toast-filled.toast-secondary {
15062
- background-color: var(--color-secondary-container);
15564
+ background-color: var(--color-secondary);
15063
15565
  border-color: transparent;
15064
- color: var(--color-on-secondary-container);
15566
+ color: var(--color-secondary-content);
15065
15567
  }
15066
15568
 
15067
15569
  .toast-filled.toast-tertiary {
15068
- background-color: var(--color-tertiary-container);
15069
- border-color: transparent;
15070
- color: var(--color-on-tertiary-container);
15071
- }
15072
-
15073
- .toast-filled.toast-accent {
15074
- background-color: color-mix(in oklch, var(--color-accent) 15%, var(--color-surface));
15570
+ background-color: var(--color-tertiary);
15075
15571
  border-color: transparent;
15076
- color: var(--color-on-surface);
15572
+ color: var(--color-tertiary-content);
15077
15573
  }
15078
15574
 
15079
15575
  .toast-filled.toast-neutral {
15080
- background-color: color-mix(in oklch, var(--color-neutral) 15%, var(--color-surface));
15576
+ background-color: var(--color-neutral);
15081
15577
  border-color: transparent;
15082
- color: var(--color-on-surface);
15578
+ color: var(--color-neutral-content);
15083
15579
  }
15084
15580
 
15085
15581
  .toast-filled.toast-base {
@@ -15092,16 +15588,25 @@ html {
15092
15588
  .toast-title and .toast-message have explicit color rules that would otherwise
15093
15589
  override the filled variant's inherited on-container color. */
15094
15590
  .toast-filled .toast-title,
15095
- .toast-filled .toast-message {
15591
+ .toast-filled .toast-message,
15592
+ .toast-filled .toast-icon,
15593
+ .toast-filled .toast-close,
15594
+ .toast-filled .toast-action {
15096
15595
  color: inherit;
15097
15596
  }
15098
15597
 
15598
+ .toast-filled .toast-close:hover {
15599
+ color: inherit;
15600
+ background-color: color-mix(in oklch, currentColor 12%, transparent);
15601
+ }
15602
+
15099
15603
  /* Ghost Variant */
15100
15604
  .toast-ghost {
15101
15605
  background-color: transparent;
15102
15606
  border-color: transparent;
15103
15607
  }
15104
15608
 
15609
+ .toast-ghost.toast-accent { color: var(--color-accent); }
15105
15610
  .toast-ghost.toast-primary { color: var(--color-primary); }
15106
15611
  .toast-ghost.toast-secondary { color: var(--color-secondary); }
15107
15612
  .toast-ghost.toast-tertiary { color: var(--color-tertiary); }
@@ -15109,7 +15614,6 @@ html {
15109
15614
  .toast-ghost.toast-success { color: var(--color-success); }
15110
15615
  .toast-ghost.toast-warning { color: var(--color-warning); }
15111
15616
  .toast-ghost.toast-error { color: var(--color-error); }
15112
- .toast-ghost.toast-accent { color: var(--color-accent); }
15113
15617
  .toast-ghost.toast-neutral { color: var(--color-neutral); }
15114
15618
  .toast-ghost.toast-base { color: var(--color-base-content); }
15115
15619
 
@@ -15118,6 +15622,49 @@ html {
15118
15622
  color: inherit;
15119
15623
  }
15120
15624
 
15625
+ /* Size and density variants retained by the public API. */
15626
+ .toast-sm {
15627
+ width: 18rem;
15628
+ padding: 0.75rem;
15629
+ }
15630
+
15631
+ .toast-lg {
15632
+ width: 26rem;
15633
+ padding: 1.25rem;
15634
+ }
15635
+
15636
+ .toast-compact {
15637
+ padding: 0.75rem;
15638
+ gap: 0.5rem;
15639
+ }
15640
+
15641
+ .toast-compact .toast-icon {
15642
+ width: 1.25rem;
15643
+ height: 1.25rem;
15644
+ font-size: 1rem;
15645
+ }
15646
+
15647
+ .toast-compact .toast-title { font-size: 0.8125rem; }
15648
+ .toast-compact .toast-message { font-size: 0.8125rem; }
15649
+
15650
+ /* Accent edge and stacked presentation. */
15651
+ .toast-accent::before {
15652
+ content: "";
15653
+ position: absolute;
15654
+ inset-block: 0;
15655
+ inset-inline-start: 0;
15656
+ width: 0.25rem;
15657
+ background-color: var(--_toast-accent-color);
15658
+ border-start-start-radius: var(--radius-md);
15659
+ border-end-start-radius: var(--radius-md);
15660
+ }
15661
+
15662
+ .toast-container-stacked .toast:not(:first-child) {
15663
+ margin-top: -0.75rem;
15664
+ transform: scale(0.97);
15665
+ opacity: 0.9;
15666
+ }
15667
+
15121
15668
  /* Progress Bar (for auto-dismiss) */
15122
15669
  .toast-progress {
15123
15670
  position: absolute;
@@ -15148,6 +15695,22 @@ html {
15148
15695
  .toast-progress {
15149
15696
  animation: none;
15150
15697
  }
15698
+
15699
+ .toast-container { scroll-behavior: auto; }
15700
+ }
15701
+
15702
+ @media (max-width: 40rem) {
15703
+ .toast-container[popover] {
15704
+ inset-inline: 0;
15705
+ width: 100%;
15706
+ transform: none;
15707
+ align-items: stretch;
15708
+ }
15709
+
15710
+ .toast {
15711
+ width: 100%;
15712
+ max-width: 100%;
15713
+ }
15151
15714
  }
15152
15715
  }
15153
15716
 
@@ -15229,53 +15792,8 @@ html {
15229
15792
  position-area: right;
15230
15793
  }
15231
15794
 
15232
- /* ========================================
15233
- * Arrow (preferred position only; may be wrong after flip)
15234
- * ======================================== */
15235
-
15236
- .tooltip[popover]::before {
15237
- content: '';
15238
- position: absolute;
15239
- width: 0;
15240
- height: 0;
15241
- border: 0.375rem solid transparent;
15242
- }
15243
-
15244
- .tooltip-top[popover]::before,
15245
- .tooltip[popover]:not(.tooltip-bottom):not(.tooltip-left):not(.tooltip-right)::before {
15246
- top: 100%;
15247
- left: 50%;
15248
- transform: translateX(-50%);
15249
- border-top-color: var(--tooltip-bg);
15250
- }
15251
-
15252
- .tooltip-bottom[popover]::before {
15253
- bottom: 100%;
15254
- top: auto;
15255
- left: 50%;
15256
- transform: translateX(-50%);
15257
- border-bottom-color: var(--tooltip-bg);
15258
- border-top-color: transparent;
15259
- }
15260
-
15261
- .tooltip-left[popover]::before {
15262
- left: 100%;
15263
- top: 50%;
15264
- bottom: auto;
15265
- transform: translateY(-50%);
15266
- border-left-color: var(--tooltip-bg);
15267
- border-top-color: transparent;
15268
- }
15269
-
15270
- .tooltip-right[popover]::before {
15271
- right: 100%;
15272
- left: auto;
15273
- top: 50%;
15274
- bottom: auto;
15275
- transform: translateY(-50%);
15276
- border-right-color: var(--tooltip-bg);
15277
- border-top-color: transparent;
15278
- }
15795
+ /* Automatic placement can flip independently of the preferred side. The
15796
+ core stays arrowless instead of showing a misleading arrow. */
15279
15797
 
15280
15798
  /* ========================================
15281
15799
  * Color variants