@duskmoon-dev/core 1.9.0 → 1.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/README.md +3 -3
  2. package/dist/components/appbar.css +2 -2
  3. package/dist/components/autocomplete.css +1 -1
  4. package/dist/components/card.css +4 -4
  5. package/dist/components/cascader.css +1 -1
  6. package/dist/components/collapse.css +1 -1
  7. package/dist/components/datepicker.css +2 -2
  8. package/dist/components/dialog.css +1 -1
  9. package/dist/components/drawer.css +1 -1
  10. package/dist/components/file-upload.css +1 -1
  11. package/dist/components/form-group.css +33 -1
  12. package/dist/components/index.css +630 -42
  13. package/dist/components/modal.css +1 -1
  14. package/dist/components/multi-select.css +1 -1
  15. package/dist/components/navigation.css +2 -2
  16. package/dist/components/nested-menu.css +261 -0
  17. package/dist/components/popover.css +28 -16
  18. package/dist/components/snackbar.css +1 -1
  19. package/dist/components/theme-controller.css +281 -0
  20. package/dist/components/time-input.css +1 -1
  21. package/dist/components/toast.css +1 -1
  22. package/dist/components/toggle.css +274 -0
  23. package/dist/components/tooltip.css +2 -2
  24. package/dist/components/tree-select.css +1 -1
  25. package/dist/esm/components/appbar.js +2 -2
  26. package/dist/esm/components/autocomplete.js +1 -1
  27. package/dist/esm/components/card.js +4 -4
  28. package/dist/esm/components/cascader.js +1 -1
  29. package/dist/esm/components/collapse.js +1 -1
  30. package/dist/esm/components/datepicker.js +2 -2
  31. package/dist/esm/components/dialog.js +1 -1
  32. package/dist/esm/components/drawer.js +1 -1
  33. package/dist/esm/components/file-upload.js +1 -1
  34. package/dist/esm/components/form-group.js +33 -1
  35. package/dist/esm/components/modal.js +1 -1
  36. package/dist/esm/components/multi-select.js +1 -1
  37. package/dist/esm/components/navigation.js +2 -2
  38. package/dist/esm/components/nested-menu.js +268 -0
  39. package/dist/esm/components/popover.js +28 -16
  40. package/dist/esm/components/snackbar.js +1 -1
  41. package/dist/esm/components/theme-controller.js +288 -0
  42. package/dist/esm/components/time-input.js +1 -1
  43. package/dist/esm/components/toast.js +1 -1
  44. package/dist/esm/components/toggle.js +281 -0
  45. package/dist/esm/components/tooltip.js +2 -2
  46. package/dist/esm/components/tree-select.js +1 -1
  47. package/dist/index.css +702 -73
  48. package/dist/index.min.css +1 -0
  49. package/dist/themes/moonlight.css +34 -16
  50. package/dist/themes/ocean.css +16 -7
  51. package/dist/themes/sunset.css +5 -4
  52. package/dist/themes/sunshine.css +6 -4
  53. package/dist/types/types/plugin.d.ts +1 -1
  54. package/package.json +21 -1
@@ -501,12 +501,12 @@
501
501
  border-radius: 1rem;
502
502
  background-color: var(--color-surface);
503
503
  color: var(--color-on-surface);
504
- box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
504
+ box-shadow: var(--shadow-sm);
505
505
  transition: box-shadow 150ms ease-in-out, transform 150ms ease-in-out;
506
506
  }
507
507
 
508
508
  .card:hover {
509
- box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
509
+ box-shadow: var(--shadow-md);
510
510
  }
511
511
 
512
512
  /* Card Image */
@@ -659,11 +659,11 @@
659
659
 
660
660
  /* Elevated Variants */
661
661
  .card-elevated {
662
- box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
662
+ box-shadow: var(--shadow-lg);
663
663
  }
664
664
 
665
665
  .card-elevated:hover {
666
- box-shadow: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);
666
+ box-shadow: var(--shadow-xl);
667
667
  transform: translateY(-2px);
668
668
  }
669
669
 
@@ -1836,7 +1836,7 @@
1836
1836
  .tabs-boxed .tab[aria-selected="true"] {
1837
1837
  background-color: var(--color-surface);
1838
1838
  color: var(--color-on-surface);
1839
- box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
1839
+ box-shadow: var(--shadow-xs);
1840
1840
  }
1841
1841
 
1842
1842
  /* Tabs Lifted */
@@ -1888,7 +1888,7 @@
1888
1888
  background-color: var(--color-surface);
1889
1889
  border: 1px solid var(--color-outline);
1890
1890
  border-radius: 0.5rem;
1891
- box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
1891
+ box-shadow: var(--shadow-lg);
1892
1892
  opacity: 0;
1893
1893
  visibility: hidden;
1894
1894
  transform: translateY(-0.5rem);
@@ -2172,7 +2172,7 @@
2172
2172
  background-color: var(--color-surface);
2173
2173
  color: var(--color-on-surface);
2174
2174
  border-radius: 1rem;
2175
- box-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.25);
2175
+ box-shadow: var(--shadow-2xl);
2176
2176
  overflow-y: auto;
2177
2177
  transform: scale(0.95);
2178
2178
  transition: transform 200ms ease-out;
@@ -3436,7 +3436,7 @@
3436
3436
  background-color: var(--color-surface);
3437
3437
  border: 1px solid var(--color-outline);
3438
3438
  border-radius: 0.5rem;
3439
- box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
3439
+ box-shadow: var(--shadow-lg);
3440
3440
  overflow-y: auto;
3441
3441
  opacity: 0;
3442
3442
  visibility: hidden;
@@ -3782,7 +3782,7 @@
3782
3782
  background-color: var(--color-surface);
3783
3783
  border: 1px solid var(--color-outline-variant);
3784
3784
  border-radius: 0.5rem;
3785
- box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
3785
+ box-shadow: var(--shadow-md);
3786
3786
  overflow: hidden;
3787
3787
  }
3788
3788
 
@@ -4425,7 +4425,7 @@
4425
4425
  background-color: var(--color-surface);
4426
4426
  border: 1px solid var(--color-outline);
4427
4427
  border-radius: 0.75rem;
4428
- box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
4428
+ box-shadow: var(--shadow-lg);
4429
4429
  opacity: 0;
4430
4430
  visibility: hidden;
4431
4431
  transform: translateY(-0.5rem);
@@ -4451,7 +4451,7 @@
4451
4451
  background-color: var(--color-surface);
4452
4452
  border: 1px solid var(--color-outline);
4453
4453
  border-radius: 0.75rem;
4454
- box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
4454
+ box-shadow: var(--shadow-lg);
4455
4455
  }
4456
4456
 
4457
4457
  /* Calendar Header */
@@ -5337,7 +5337,7 @@
5337
5337
  }
5338
5338
 
5339
5339
  .file-upload-button:hover {
5340
- box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1);
5340
+ box-shadow: var(--shadow-md);
5341
5341
  }
5342
5342
 
5343
5343
  .file-upload-button:focus-visible {
@@ -5520,7 +5520,7 @@
5520
5520
  .fieldset-card {
5521
5521
  background-color: var(--color-surface);
5522
5522
  border-color: transparent;
5523
- box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
5523
+ box-shadow: var(--shadow-xs);
5524
5524
  padding: 1.5rem;
5525
5525
  }
5526
5526
 
@@ -5662,6 +5662,13 @@
5662
5662
  border-color: var(--color-error);
5663
5663
  }
5664
5664
 
5665
+ .form-group-error .input:focus-visible,
5666
+ .form-group-error .select:focus-visible,
5667
+ .form-group-error .textarea:focus-visible {
5668
+ border-color: var(--color-error);
5669
+ box-shadow: 0 0 0 3px color-mix(in oklch, var(--color-error) 10%, transparent);
5670
+ }
5671
+
5665
5672
  /* Success State on Form Group */
5666
5673
  .form-group-success .form-label {
5667
5674
  color: var(--color-success);
@@ -5673,6 +5680,31 @@
5673
5680
  border-color: var(--color-success);
5674
5681
  }
5675
5682
 
5683
+ .form-group-success .input:focus-visible,
5684
+ .form-group-success .select:focus-visible,
5685
+ .form-group-success .textarea:focus-visible {
5686
+ border-color: var(--color-success);
5687
+ box-shadow: 0 0 0 3px color-mix(in oklch, var(--color-success) 10%, transparent);
5688
+ }
5689
+
5690
+ /* Warning State on Form Group */
5691
+ .form-group-warning .form-label {
5692
+ color: var(--color-warning);
5693
+ }
5694
+
5695
+ .form-group-warning .input,
5696
+ .form-group-warning .select,
5697
+ .form-group-warning .textarea {
5698
+ border-color: var(--color-warning);
5699
+ }
5700
+
5701
+ .form-group-warning .input:focus-visible,
5702
+ .form-group-warning .select:focus-visible,
5703
+ .form-group-warning .textarea:focus-visible {
5704
+ border-color: var(--color-warning);
5705
+ box-shadow: 0 0 0 3px color-mix(in oklch, var(--color-warning) 10%, transparent);
5706
+ }
5707
+
5676
5708
  /* Disabled Form Group */
5677
5709
  .form-group-disabled {
5678
5710
  opacity: 0.5;
@@ -5873,7 +5905,7 @@
5873
5905
  background-color: var(--color-surface);
5874
5906
  border: 1px solid var(--color-outline-variant);
5875
5907
  border-radius: 0.5rem;
5876
- box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
5908
+ box-shadow: var(--shadow-md);
5877
5909
  overflow: hidden;
5878
5910
  }
5879
5911
 
@@ -8323,6 +8355,288 @@
8323
8355
  }
8324
8356
  }
8325
8357
 
8358
+ /**
8359
+ * Theme Controller Component Styles
8360
+ * DuskMoonUI - Two display modes for theme switching:
8361
+ *
8362
+ * 1. Switch (.theme-controller) — inline pill-shaped radio group, all options visible
8363
+ * 2. Dropdown (.theme-controller-dropdown) — <details>/<summary> with floating menu
8364
+ *
8365
+ * Both modes reuse .theme-controller-item (hidden radio) and .theme-controller-label
8366
+ * for CSS-only active state via :checked + label.
8367
+ */
8368
+
8369
+ @layer components {
8370
+ /* ========================================
8371
+ * SHARED — Radio input & label (used in both modes)
8372
+ * ======================================== */
8373
+
8374
+ /* Hidden Radio Input — visually hidden but accessible */
8375
+ .theme-controller-item {
8376
+ position: absolute;
8377
+ width: 1px;
8378
+ height: 1px;
8379
+ padding: 0;
8380
+ margin: -1px;
8381
+ overflow: hidden;
8382
+ clip: rect(0, 0, 0, 0);
8383
+ white-space: nowrap;
8384
+ border: 0;
8385
+ }
8386
+
8387
+ /* Visible Label — the clickable option */
8388
+ .theme-controller-label {
8389
+ display: inline-flex;
8390
+ align-items: center;
8391
+ justify-content: center;
8392
+ gap: 0.5rem;
8393
+ padding: 0.5rem 1rem;
8394
+ font-size: 0.875rem;
8395
+ font-weight: 500;
8396
+ line-height: 1.25rem;
8397
+ color: var(--color-on-surface-variant);
8398
+ background-color: transparent;
8399
+ border-radius: calc(var(--radius-box, 1.5rem) - 0.25rem);
8400
+ cursor: pointer;
8401
+ transition: background-color 150ms ease-in-out, color 150ms ease-in-out,
8402
+ box-shadow 150ms ease-in-out;
8403
+ user-select: none;
8404
+ white-space: nowrap;
8405
+ }
8406
+
8407
+ /* Hover state */
8408
+ .theme-controller-label:hover {
8409
+ background-color: var(--color-surface-container-high);
8410
+ }
8411
+
8412
+ /* Focus-visible ring on the label when its radio is focused */
8413
+ .theme-controller-item:focus-visible + .theme-controller-label {
8414
+ outline: 2px solid var(--color-primary);
8415
+ outline-offset: 2px;
8416
+ }
8417
+
8418
+ /* Active/checked state */
8419
+ .theme-controller-item:checked + .theme-controller-label {
8420
+ background-color: var(--color-primary-container);
8421
+ color: var(--color-on-primary-container);
8422
+ box-shadow: var(--shadow-xs);
8423
+ }
8424
+
8425
+ .theme-controller-item:checked + .theme-controller-label:hover {
8426
+ background-color: color-mix(in oklch, var(--color-primary-container), black 5%);
8427
+ }
8428
+
8429
+ /* ========================================
8430
+ * SWITCH MODE — inline pill radio group
8431
+ * ======================================== */
8432
+
8433
+ .theme-controller {
8434
+ display: inline-flex;
8435
+ align-items: stretch;
8436
+ background-color: var(--color-surface-container);
8437
+ border: 1px solid var(--color-outline-variant);
8438
+ border-radius: var(--radius-box, 1.5rem);
8439
+ padding: 0.25rem;
8440
+ gap: 0.125rem;
8441
+ }
8442
+
8443
+ /* ── Switch Size Variants ── */
8444
+
8445
+ .theme-controller-sm {
8446
+ padding: 0.125rem;
8447
+ border-radius: calc(var(--radius-box, 1.5rem) * 0.75);
8448
+ }
8449
+
8450
+ .theme-controller-sm .theme-controller-label {
8451
+ padding: 0.375rem 0.75rem;
8452
+ font-size: 0.75rem;
8453
+ line-height: 1rem;
8454
+ border-radius: calc(var(--radius-box, 1.5rem) * 0.75 - 0.125rem);
8455
+ }
8456
+
8457
+ .theme-controller-lg {
8458
+ padding: 0.375rem;
8459
+ gap: 0.25rem;
8460
+ border-radius: calc(var(--radius-box, 1.5rem) * 1.25);
8461
+ }
8462
+
8463
+ .theme-controller-lg .theme-controller-label {
8464
+ padding: 0.75rem 1.5rem;
8465
+ font-size: 1rem;
8466
+ line-height: 1.5rem;
8467
+ border-radius: calc(var(--radius-box, 1.5rem) * 1.25 - 0.375rem);
8468
+ }
8469
+
8470
+ /* ── Switch Icon-only Variant ── */
8471
+
8472
+ .theme-controller-icon .theme-controller-label {
8473
+ padding: 0.5rem;
8474
+ }
8475
+
8476
+ .theme-controller-icon.theme-controller-sm .theme-controller-label {
8477
+ padding: 0.375rem;
8478
+ }
8479
+
8480
+ .theme-controller-icon.theme-controller-lg .theme-controller-label {
8481
+ padding: 0.75rem;
8482
+ }
8483
+
8484
+ /* ========================================
8485
+ * DROPDOWN MODE — <details>/<summary> with floating menu
8486
+ * ======================================== */
8487
+
8488
+ .theme-controller-dropdown {
8489
+ position: relative;
8490
+ display: inline-block;
8491
+ }
8492
+
8493
+ /* Trigger button (<summary>) */
8494
+ .theme-controller-trigger {
8495
+ display: inline-flex;
8496
+ align-items: center;
8497
+ gap: 0.5rem;
8498
+ padding: 0.5rem 0.75rem;
8499
+ font-size: 0.875rem;
8500
+ font-weight: 500;
8501
+ line-height: 1.25rem;
8502
+ color: var(--color-on-surface);
8503
+ background-color: var(--color-surface-container);
8504
+ border: 1px solid var(--color-outline-variant);
8505
+ border-radius: var(--radius-field, 0.5rem);
8506
+ cursor: pointer;
8507
+ user-select: none;
8508
+ transition: background-color 150ms ease-in-out;
8509
+ list-style: none;
8510
+ }
8511
+
8512
+ .theme-controller-trigger::-webkit-details-marker {
8513
+ display: none;
8514
+ }
8515
+
8516
+ .theme-controller-trigger:hover {
8517
+ background-color: var(--color-surface-container-high);
8518
+ }
8519
+
8520
+ .theme-controller-trigger:focus-visible {
8521
+ outline: 2px solid var(--color-primary);
8522
+ outline-offset: 2px;
8523
+ }
8524
+
8525
+ /* Chevron indicator */
8526
+ .theme-controller-trigger::after {
8527
+ content: '';
8528
+ display: inline-block;
8529
+ width: 0.5rem;
8530
+ height: 0.5rem;
8531
+ border-right: 2px solid currentColor;
8532
+ border-bottom: 2px solid currentColor;
8533
+ transform: rotate(45deg);
8534
+ margin-top: -0.125rem;
8535
+ transition: transform 150ms ease-in-out;
8536
+ }
8537
+
8538
+ .theme-controller-dropdown[open] .theme-controller-trigger::after {
8539
+ transform: rotate(-135deg);
8540
+ margin-top: 0.125rem;
8541
+ }
8542
+
8543
+ /* Floating menu */
8544
+ .theme-controller-menu {
8545
+ position: absolute;
8546
+ top: calc(100% + 0.25rem);
8547
+ left: 0;
8548
+ z-index: 50;
8549
+ min-width: 100%;
8550
+ background-color: var(--color-surface-container);
8551
+ border: 1px solid var(--color-outline-variant);
8552
+ border-radius: var(--radius-field, 0.5rem);
8553
+ padding: 0.25rem;
8554
+ box-shadow: var(--shadow-md);
8555
+ display: flex;
8556
+ flex-direction: column;
8557
+ gap: 0.125rem;
8558
+ }
8559
+
8560
+ /* Menu labels are full-width and left-aligned */
8561
+ .theme-controller-menu .theme-controller-label {
8562
+ width: 100%;
8563
+ justify-content: flex-start;
8564
+ border-radius: calc(var(--radius-field, 0.5rem) - 0.25rem);
8565
+ }
8566
+
8567
+ /* ── Dropdown Size Variants ── */
8568
+
8569
+ .theme-controller-dropdown-sm .theme-controller-trigger {
8570
+ padding: 0.375rem 0.625rem;
8571
+ font-size: 0.75rem;
8572
+ line-height: 1rem;
8573
+ }
8574
+
8575
+ .theme-controller-dropdown-sm .theme-controller-menu {
8576
+ padding: 0.125rem;
8577
+ }
8578
+
8579
+ .theme-controller-dropdown-sm .theme-controller-menu .theme-controller-label {
8580
+ padding: 0.375rem 0.75rem;
8581
+ font-size: 0.75rem;
8582
+ line-height: 1rem;
8583
+ }
8584
+
8585
+ .theme-controller-dropdown-lg .theme-controller-trigger {
8586
+ padding: 0.75rem 1rem;
8587
+ font-size: 1rem;
8588
+ line-height: 1.5rem;
8589
+ }
8590
+
8591
+ .theme-controller-dropdown-lg .theme-controller-menu {
8592
+ padding: 0.375rem;
8593
+ }
8594
+
8595
+ .theme-controller-dropdown-lg .theme-controller-menu .theme-controller-label {
8596
+ padding: 0.75rem 1.5rem;
8597
+ font-size: 1rem;
8598
+ line-height: 1.5rem;
8599
+ }
8600
+
8601
+ /* ── Dropdown Icon-only Trigger ── */
8602
+
8603
+ .theme-controller-dropdown-icon .theme-controller-trigger {
8604
+ padding: 0.5rem;
8605
+ }
8606
+
8607
+ /* Hide chevron for icon-only trigger */
8608
+ .theme-controller-dropdown-icon .theme-controller-trigger::after {
8609
+ display: none;
8610
+ }
8611
+
8612
+ .theme-controller-dropdown-icon.theme-controller-dropdown-sm .theme-controller-trigger {
8613
+ padding: 0.375rem;
8614
+ }
8615
+
8616
+ .theme-controller-dropdown-icon.theme-controller-dropdown-lg .theme-controller-trigger {
8617
+ padding: 0.75rem;
8618
+ }
8619
+
8620
+ /* ── Dropdown Alignment ── */
8621
+
8622
+ .theme-controller-dropdown-end .theme-controller-menu {
8623
+ left: auto;
8624
+ right: 0;
8625
+ }
8626
+
8627
+ /* ========================================
8628
+ * REDUCED MOTION
8629
+ * ======================================== */
8630
+
8631
+ @media (prefers-reduced-motion: reduce) {
8632
+ .theme-controller-label,
8633
+ .theme-controller-trigger,
8634
+ .theme-controller-trigger::after {
8635
+ transition: none;
8636
+ }
8637
+ }
8638
+ }
8639
+
8326
8640
  /**
8327
8641
  * Toggle Button Component Styles
8328
8642
  * DuskMoonUI - Material Design 3 inspired toggle button
@@ -8490,7 +8804,7 @@
8490
8804
  .toggle-segmented .toggle-btn.active {
8491
8805
  background-color: var(--color-surface-variant);
8492
8806
  border-color: transparent;
8493
- box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
8807
+ box-shadow: var(--shadow-sm);
8494
8808
  }
8495
8809
 
8496
8810
  /* Chip-like toggle */
@@ -8798,7 +9112,7 @@
8798
9112
  background-color: var(--color-surface);
8799
9113
  border: 1px solid var(--color-outline-variant);
8800
9114
  border-radius: 0.5rem;
8801
- box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
9115
+ box-shadow: var(--shadow-md);
8802
9116
  }
8803
9117
 
8804
9118
  .time-picker-dropdown-open {
@@ -8989,7 +9303,7 @@
8989
9303
  background-color: var(--color-surface);
8990
9304
  border: 1px solid var(--color-outline-variant);
8991
9305
  border-radius: 0.5rem;
8992
- box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
9306
+ box-shadow: var(--shadow-md);
8993
9307
  overflow-y: auto;
8994
9308
  }
8995
9309
 
@@ -9548,7 +9862,7 @@
9548
9862
  background-color: var(--color-surface);
9549
9863
  color: var(--color-on-surface);
9550
9864
  border-radius: 1.5rem;
9551
- box-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.25);
9865
+ box-shadow: var(--shadow-2xl);
9552
9866
  overflow: hidden;
9553
9867
  }
9554
9868
 
@@ -10226,7 +10540,7 @@
10226
10540
  background-color: var(--color-surface-container-highest);
10227
10541
  color: var(--color-on-surface);
10228
10542
  border-radius: 0.5rem;
10229
- box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
10543
+ box-shadow: var(--shadow-md);
10230
10544
  pointer-events: auto;
10231
10545
  opacity: 0;
10232
10546
  transform: translateY(100%);
@@ -10539,7 +10853,7 @@
10539
10853
  color: var(--color-on-surface);
10540
10854
  border: 1px solid var(--color-outline);
10541
10855
  border-radius: 0.75rem;
10542
- box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
10856
+ box-shadow: var(--shadow-lg);
10543
10857
  pointer-events: auto;
10544
10858
  opacity: 0;
10545
10859
  transform: translateX(100%);
@@ -10747,7 +11061,7 @@
10747
11061
  background-color: var(--color-on-surface);
10748
11062
  color: var(--color-surface);
10749
11063
  border-radius: 0.25rem;
10750
- box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1);
11064
+ box-shadow: var(--shadow-md);
10751
11065
  opacity: 0;
10752
11066
  visibility: hidden;
10753
11067
  transition: opacity 150ms ease-out, visibility 150ms ease-out;
@@ -10876,7 +11190,7 @@
10876
11190
  background-color: var(--color-surface);
10877
11191
  color: var(--color-on-surface);
10878
11192
  border: 1px solid var(--color-outline);
10879
- box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
11193
+ box-shadow: var(--shadow-md);
10880
11194
  }
10881
11195
 
10882
11196
  .tooltip.tooltip-light .tooltip-content::before {
@@ -11029,7 +11343,7 @@
11029
11343
  padding: 0 1rem;
11030
11344
  background-color: var(--color-surface);
11031
11345
  color: var(--color-on-surface);
11032
- box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
11346
+ box-shadow: var(--shadow-sm);
11033
11347
  }
11034
11348
 
11035
11349
  /* Static App Bar (default) */
@@ -11070,7 +11384,7 @@
11070
11384
 
11071
11385
  /* App Bar with Shadow (elevated) */
11072
11386
  .appbar-elevated {
11073
- box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
11387
+ box-shadow: var(--shadow-sm);
11074
11388
  }
11075
11389
 
11076
11390
  /* Flat App Bar (no shadow) */
@@ -12090,7 +12404,7 @@
12090
12404
  display: flex;
12091
12405
  flex-direction: column;
12092
12406
  background-color: var(--color-surface-container-low);
12093
- box-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.25);
12407
+ box-shadow: var(--shadow-2xl);
12094
12408
  transition: transform 300ms ease-out;
12095
12409
  }
12096
12410
 
@@ -12433,6 +12747,268 @@
12433
12747
  }
12434
12748
  }
12435
12749
 
12750
+ /**
12751
+ * Nested Menu Component Styles
12752
+ * DuskMoonUI - Sidebar navigation with collapsible cascading levels via <details>/<summary>
12753
+ */
12754
+
12755
+ @layer components {
12756
+ /* ============================================
12757
+ * ROOT CONTAINER
12758
+ * ============================================ */
12759
+
12760
+ .nested-menu {
12761
+ display: flex;
12762
+ flex-direction: column;
12763
+ list-style: none;
12764
+ margin: 0;
12765
+ padding: 0.5rem;
12766
+ gap: 0.125rem;
12767
+ font-size: 0.875rem;
12768
+ color: var(--color-on-surface);
12769
+ }
12770
+
12771
+ /* ============================================
12772
+ * SECTION TITLES
12773
+ * ============================================ */
12774
+
12775
+ .nested-menu-title {
12776
+ padding: 0.75rem 0.75rem 0.25rem;
12777
+ font-size: 0.6875rem;
12778
+ font-weight: 600;
12779
+ text-transform: uppercase;
12780
+ letter-spacing: 0.05em;
12781
+ color: var(--color-on-surface-variant);
12782
+ user-select: none;
12783
+ }
12784
+
12785
+ /* ============================================
12786
+ * MENU ITEMS (links and buttons)
12787
+ * ============================================ */
12788
+
12789
+ .nested-menu li > a,
12790
+ .nested-menu li > button {
12791
+ display: flex;
12792
+ align-items: center;
12793
+ gap: 0.5rem;
12794
+ width: 100%;
12795
+ padding: 0.5rem 0.75rem;
12796
+ font-size: inherit;
12797
+ color: var(--color-on-surface);
12798
+ text-decoration: none;
12799
+ background-color: transparent;
12800
+ border: none;
12801
+ border-radius: var(--radius-field, 0.375rem);
12802
+ cursor: pointer;
12803
+ transition: background-color 150ms ease-in-out, color 150ms ease-in-out;
12804
+ }
12805
+
12806
+ .nested-menu li > a:hover,
12807
+ .nested-menu li > button:hover {
12808
+ background-color: var(--color-surface-container);
12809
+ }
12810
+
12811
+ .nested-menu li > a:focus-visible,
12812
+ .nested-menu li > button:focus-visible {
12813
+ outline: 2px solid var(--color-primary);
12814
+ outline-offset: -2px;
12815
+ }
12816
+
12817
+ /* Active state */
12818
+ .nested-menu li > a.active,
12819
+ .nested-menu li > button.active,
12820
+ .nested-menu li > a[aria-current="page"],
12821
+ .nested-menu li > button[aria-current="page"] {
12822
+ background-color: var(--color-primary-container);
12823
+ color: var(--color-on-primary-container);
12824
+ }
12825
+
12826
+ .nested-menu li > a.active:hover,
12827
+ .nested-menu li > button.active:hover,
12828
+ .nested-menu li > a[aria-current="page"]:hover,
12829
+ .nested-menu li > button[aria-current="page"]:hover {
12830
+ background-color: color-mix(in oklch, var(--color-primary-container), var(--color-on-primary-container) 8%);
12831
+ }
12832
+
12833
+ /* Disabled state */
12834
+ .nested-menu li.disabled {
12835
+ opacity: 0.5;
12836
+ pointer-events: none;
12837
+ }
12838
+
12839
+ /* ============================================
12840
+ * COLLAPSIBLE SUBMENUS (<details>/<summary>)
12841
+ * ============================================ */
12842
+
12843
+ .nested-menu details {
12844
+ width: 100%;
12845
+ }
12846
+
12847
+ /* Remove native marker */
12848
+ .nested-menu summary {
12849
+ display: flex;
12850
+ align-items: center;
12851
+ gap: 0.5rem;
12852
+ width: 100%;
12853
+ padding: 0.5rem 0.75rem;
12854
+ font-size: inherit;
12855
+ color: var(--color-on-surface);
12856
+ background-color: transparent;
12857
+ border: none;
12858
+ border-radius: var(--radius-field, 0.375rem);
12859
+ cursor: pointer;
12860
+ list-style: none;
12861
+ transition: background-color 150ms ease-in-out;
12862
+ }
12863
+
12864
+ .nested-menu summary::-webkit-details-marker {
12865
+ display: none;
12866
+ }
12867
+
12868
+ .nested-menu summary::marker {
12869
+ display: none;
12870
+ content: "";
12871
+ }
12872
+
12873
+ .nested-menu summary:hover {
12874
+ background-color: var(--color-surface-container);
12875
+ }
12876
+
12877
+ .nested-menu summary:focus-visible {
12878
+ outline: 2px solid var(--color-primary);
12879
+ outline-offset: -2px;
12880
+ }
12881
+
12882
+ /* Chevron indicator */
12883
+ .nested-menu summary::after {
12884
+ content: "";
12885
+ display: inline-block;
12886
+ margin-left: auto;
12887
+ width: 0.375rem;
12888
+ height: 0.375rem;
12889
+ border-right: 1.5px solid currentColor;
12890
+ border-bottom: 1.5px solid currentColor;
12891
+ transform: rotate(-45deg);
12892
+ transition: transform 200ms ease-in-out;
12893
+ flex-shrink: 0;
12894
+ opacity: 0.6;
12895
+ }
12896
+
12897
+ .nested-menu details[open] > summary::after {
12898
+ transform: rotate(45deg);
12899
+ }
12900
+
12901
+ /* Nested <ul> inside details — auto-indentation */
12902
+ .nested-menu details > ul {
12903
+ list-style: none;
12904
+ margin: 0;
12905
+ padding: 0.125rem 0 0.125rem 1rem;
12906
+ display: flex;
12907
+ flex-direction: column;
12908
+ gap: 0.125rem;
12909
+ }
12910
+
12911
+ /* ============================================
12912
+ * SIZE VARIANTS
12913
+ * ============================================ */
12914
+
12915
+ .nested-menu-xs {
12916
+ font-size: 0.75rem;
12917
+ padding: 0.25rem;
12918
+ }
12919
+
12920
+ .nested-menu-xs li > a,
12921
+ .nested-menu-xs li > button,
12922
+ .nested-menu-xs summary {
12923
+ padding: 0.25rem 0.5rem;
12924
+ gap: 0.375rem;
12925
+ }
12926
+
12927
+ .nested-menu-xs .nested-menu-title {
12928
+ padding: 0.5rem 0.5rem 0.125rem;
12929
+ font-size: 0.625rem;
12930
+ }
12931
+
12932
+ .nested-menu-sm {
12933
+ font-size: 0.8125rem;
12934
+ padding: 0.375rem;
12935
+ }
12936
+
12937
+ .nested-menu-sm li > a,
12938
+ .nested-menu-sm li > button,
12939
+ .nested-menu-sm summary {
12940
+ padding: 0.375rem 0.625rem;
12941
+ gap: 0.375rem;
12942
+ }
12943
+
12944
+ .nested-menu-sm .nested-menu-title {
12945
+ padding: 0.625rem 0.625rem 0.1875rem;
12946
+ font-size: 0.625rem;
12947
+ }
12948
+
12949
+ .nested-menu-lg {
12950
+ font-size: 1rem;
12951
+ padding: 0.625rem;
12952
+ }
12953
+
12954
+ .nested-menu-lg li > a,
12955
+ .nested-menu-lg li > button,
12956
+ .nested-menu-lg summary {
12957
+ padding: 0.625rem 1rem;
12958
+ gap: 0.625rem;
12959
+ }
12960
+
12961
+ .nested-menu-lg .nested-menu-title {
12962
+ padding: 0.875rem 1rem 0.375rem;
12963
+ font-size: 0.75rem;
12964
+ }
12965
+
12966
+ /* ============================================
12967
+ * MODIFIER VARIANTS
12968
+ * ============================================ */
12969
+
12970
+ /* Bordered — sidebar panel look */
12971
+ .nested-menu-bordered {
12972
+ background-color: var(--color-surface);
12973
+ border: 1px solid var(--color-outline-variant);
12974
+ border-radius: var(--radius-card, 0.75rem);
12975
+ box-shadow: var(--shadow-sm, 0 1px 2px 0 rgb(0 0 0 / 0.05));
12976
+ }
12977
+
12978
+ /* Compact — tighter padding throughout */
12979
+ .nested-menu-compact {
12980
+ padding: 0.25rem;
12981
+ gap: 0;
12982
+ }
12983
+
12984
+ .nested-menu-compact li > a,
12985
+ .nested-menu-compact li > button,
12986
+ .nested-menu-compact summary {
12987
+ padding: 0.3125rem 0.625rem;
12988
+ }
12989
+
12990
+ .nested-menu-compact .nested-menu-title {
12991
+ padding: 0.5rem 0.625rem 0.125rem;
12992
+ }
12993
+
12994
+ .nested-menu-compact details > ul {
12995
+ padding: 0 0 0 0.75rem;
12996
+ }
12997
+
12998
+ /* ============================================
12999
+ * REDUCED MOTION
13000
+ * ============================================ */
13001
+
13002
+ @media (prefers-reduced-motion: reduce) {
13003
+ .nested-menu li > a,
13004
+ .nested-menu li > button,
13005
+ .nested-menu summary,
13006
+ .nested-menu summary::after {
13007
+ transition: none;
13008
+ }
13009
+ }
13010
+ }
13011
+
12436
13012
  /**
12437
13013
  * Stepper Component Styles
12438
13014
  * DuskMoonUI - Material Design 3 inspired stepper/wizard system
@@ -13490,7 +14066,7 @@
13490
14066
  border: 1px solid var(--color-outline-variant);
13491
14067
  border-radius: 0.75rem;
13492
14068
  overflow: hidden;
13493
- box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1);
14069
+ box-shadow: var(--shadow-sm);
13494
14070
  }
13495
14071
 
13496
14072
  .collapse-card .collapse-toggle,
@@ -13793,8 +14369,8 @@
13793
14369
  */
13794
14370
 
13795
14371
  @layer components {
13796
- /* Popover Container */
13797
- .popover {
14372
+ /* Popover Container (class-based approach only, not native [popover]) */
14373
+ .popover:not([popover]) {
13798
14374
  position: relative;
13799
14375
  display: inline-block;
13800
14376
  }
@@ -13809,7 +14385,7 @@
13809
14385
  background-color: var(--color-surface);
13810
14386
  border: 1px solid var(--color-outline-variant);
13811
14387
  border-radius: 0.75rem;
13812
- box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
14388
+ box-shadow: var(--shadow-lg);
13813
14389
  opacity: 0;
13814
14390
  visibility: hidden;
13815
14391
  transform: scale(0.95);
@@ -13844,7 +14420,7 @@
13844
14420
  background-color: var(--color-surface);
13845
14421
  border: 1px solid var(--color-outline-variant);
13846
14422
  border-radius: 0.75rem;
13847
- box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
14423
+ box-shadow: var(--shadow-lg);
13848
14424
  opacity: 0;
13849
14425
  visibility: hidden;
13850
14426
  transition: opacity 150ms ease-out, visibility 150ms ease-out;
@@ -14298,7 +14874,7 @@
14298
14874
  background-color: var(--color-surface);
14299
14875
  border: 1px solid var(--color-outline-variant);
14300
14876
  border-radius: 0.75rem;
14301
- box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
14877
+ box-shadow: var(--shadow-lg);
14302
14878
  opacity: 0;
14303
14879
  transform: scale(0.95);
14304
14880
  transition: opacity 150ms ease-out, transform 150ms ease-out, overlay 150ms ease-out allow-discrete, display 150ms ease-out allow-discrete;
@@ -14440,53 +15016,65 @@
14440
15016
  style="anchor-name: --my-popover" */
14441
15017
  }
14442
15018
 
14443
- /* Anchored popover positioning */
15019
+ /* Anchored popover positioning
15020
+ * Uses anchor() functions instead of position-area to avoid
15021
+ * a Chrome rendering bug at HiDPI (DPR>=2) where position-area
15022
+ * computes correct CSS-pixel offsets but renders at physical-pixel
15023
+ * coordinates, doubling the distance from the anchor. */
14444
15024
  .popover[popover][style*="position-anchor"] {
14445
- position: absolute;
14446
- position-area: bottom;
15025
+ inset: unset;
15026
+ top: anchor(bottom);
15027
+ justify-self: anchor-center;
14447
15028
  margin-top: 0.5rem;
14448
15029
  }
14449
15030
 
14450
15031
  /* Position variants for anchored popovers */
14451
15032
  .popover-top[popover][style*="position-anchor"] {
14452
- position-area: top;
15033
+ top: unset;
15034
+ bottom: anchor(top);
14453
15035
  margin-top: 0;
14454
15036
  margin-bottom: 0.5rem;
14455
15037
  }
14456
15038
 
14457
15039
  .popover-bottom[popover][style*="position-anchor"] {
14458
- position-area: bottom;
15040
+ top: anchor(bottom);
14459
15041
  margin-top: 0.5rem;
14460
15042
  margin-bottom: 0;
14461
15043
  }
14462
15044
 
14463
15045
  .popover-left[popover][style*="position-anchor"] {
14464
- position-area: left;
15046
+ top: anchor(center);
15047
+ right: anchor(left);
15048
+ justify-self: unset;
15049
+ translate: 0 -50%;
14465
15050
  margin-top: 0;
14466
15051
  margin-right: 0.5rem;
14467
15052
  }
14468
15053
 
14469
15054
  .popover-right[popover][style*="position-anchor"] {
14470
- position-area: right;
15055
+ top: anchor(center);
15056
+ left: anchor(right);
15057
+ justify-self: unset;
15058
+ translate: 0 -50%;
14471
15059
  margin-top: 0;
14472
15060
  margin-left: 0.5rem;
14473
15061
  }
14474
15062
 
14475
15063
  /* Anchored popover alignment variants */
14476
15064
  .popover-start[popover][style*="position-anchor"] {
14477
- position-area: bottom start;
15065
+ justify-self: start;
14478
15066
  }
14479
15067
 
14480
15068
  .popover-end[popover][style*="position-anchor"] {
14481
- position-area: bottom end;
15069
+ justify-self: end;
14482
15070
  }
14483
15071
 
14484
15072
  .popover-top.popover-start[popover][style*="position-anchor"] {
14485
- position-area: top start;
15073
+ justify-self: start;
14486
15074
  }
14487
15075
 
14488
15076
  .popover-top.popover-end[popover][style*="position-anchor"] {
14489
- position-area: top end;
15077
+ justify-self: end;
14490
15078
  }
14491
15079
 
14492
15080
  /* Reduce Motion */